HOME | プログラミングTClock |


03/11/13更新。

TClockの概要

TClockとは、フックとサブクラス化によって、explorer.exeが管理している時計ウィンドウを強引に乗っ取り、動作を変更するプログラムです。

ウィンドウ

Windowsでは、GUIの部品はすべてウィンドウになっています。ブラウザーやメールソフトのように、タイトルバーがあってマウスで動かせるものだけがウィンドウではありません。ボタンやテキスト入力欄、リストのような部品もウィンドウです。

ウィンドウの中にボタンが載っているような場合は、そのウィンドウをボタンの「親ウィンドウ」、ボタンを「子ウィンドウ」と呼びます。

Windowsのタスクバーも1つのウィンドウです。タスクトレイはタスクバーの子ウィンドウで、時計はタスクトレイの子ウィンドウになっています。

タスクバーの構造

このタスクバーウィンドウを動かしているプログラムは、explorer.exeです。explorer.exeは、左にツリーがあって右にフォルダの中身があるお馴染みの「エクスプローラ」だけでなく、デスクトップ全体やタスクバーも作ります。explorer.exeはWindowsを起動すると(ログインすると)、自動的に実行されます。

サブクラス化

Windowsのウィンドウには、マウスやキーボードを操作するたびに、メッセージが送られてきます。C言語とAPIでWindowsプログラムを作るときは、そのプログラム用のウィンドウを作り、メッセージが送られるたびに何か動作をさせる、というスタイルになります。

ウィンドウに送られてくるメッセージを処理する関数をウィンドウプロシージャと呼びます。

ボタンやテキスト入力欄もウィンドウプロシージャを持っていますが、Windowsのシステム内(user32.dll)にあるので、プログラマには見えません。ただし、APIによってウィンドウプロシージャのアドレスを取り出すことはできます。また、ウィンドウが使用するウィンドウプロシージャを変更することもできます。

ボタンのウィンドウプロシージャを取り出し、自分が作ったウィンドウプロシージャに差し替えれば、ボタンの動作を変更できます。ボタンにデフォルトの動作をさせたいときは、取り出しておいた元のウィンドウプロシージャを呼び出します。

サブクラス化の流れ

こうした処理をサブクラス化と呼びます。タスクバーの時計を改造するには、時計のウィンドウをサブクラス化すればいいわけです。

フック

しかし、自分のプログラム内で時計ウィンドウをサブクラス化しようとしても、失敗します。

Windowsのような現代的なOSでは、プログラムを実行するたびにプロセスが作られ、プロセスの間にはメモリ保護が働いています。他人のプログラムが使っているメモリに手を出して変更しようとすると、そのプログラムはアクセス違反で強制終了します。

自分のプログラムと時計を動かしているexplorer.exeのプログラムは、別のプロセス内で動いているので、サブクラス化できません。

他のプロセスにあるウィンドウはサブクラス化できない

しかし、Windowsには汚い抜け道が用意されています。フックです。フックとは、Windows全体や特定のアプリケーションに送られるメッセージやキーボード、マウスを監視する機能です。

DLLを作成し、DLLの中で別のアプリケーションに対してフックをインストールすると、そのDLLは別のアプリケーションのプロセス内にも読み込まれます。TClockでは、tcdll.tclock(拡張子は.tclockですが、DLLです)の中でexplorer.exeに対してフックをかけて、explorer.exeにtcdll.tclockを潜り込ませます。

explorer.exeに侵入したtcdll.tclockは、explorer.exeと同じプロセスにありますから、サブクラス化によって時計のウィンドウを自由に改造できるようになります。

TClockでのフックとサブクラス化

exeとdllの役割分担

tcdll.tclock(DLLプログラム)はexplorer.exeのプロセス内で動きますから、たかが時計のプログラムがタスクバーなどの動きを重くしては問題です。TClockでは、負荷のかかることはなるべくtclock.exeにやらせ、tcdll.tclockはDLLにしかできないことをする、という役割分担をしています。

tclock.exeは実行されると、見えないウィンドウを作ります。このウィンドウを中心として、次の仕事をします。

explorer.exeに潜り込んだtcdll.tclockは、次の仕事をします。