開発じたばた日誌

前へ●●●次へ
じたばた日誌目次へ戻る
TSUCHY Softへ戻る


Styx HWNDとCWnd編

 さて今回はMFCを使わない人にはつまらない話しです。

 このころやっとCWndなるものがなんなのかわかってきました。 これまで私はCWndでつくるウィンドウとAPIで作るウィンドウ(HWND)って違うものなんだろうか?? と漠然と疑問に思ってきました。

 たとえば自分のウィンドウからほかのアプリのウィンドウのCWndポインタを得ることができます。 ではそのウィンドウはCWndで作られたものなのでしょうか?まさか必ずしもそうではないはずです。 APIで作られたウィンドウもあるはずです。

 このからくりはどうなっているのでしょうか?

 そもそもCWndはウィンドウとはなんの関係もない単なるC++のクラスです。HWNDが本物のウィンドウです。 CWndは内部でこっそりAPIを使ってウィンドウを作り、自分でHWNDを保持しているだけです。

 ですからAPIでウィンドウを作りHWNDを取得し、ウィンドウをもっていないCWndに接続(Attach)できるのです。 Attachするってこういうことなのですね。 逆にCWndでウィンドウを作り、切り離し(Detach)するとCWndはウィンドウと無関係のただのオブジェクトに成り下がります。 Detachすると切り離されたHWNDはプログラマがDestroyWindowしないといけません。

 CWndが2段階でウィンドウを生成するとは、つまりコンストラクタでウィンドウを持っていない空のCWndをつくり それからCreateメンバー関数の内部でAPIを使ってHWNDを作るということなのですね。。

 本当はこんなことは基本中の基本なのでしょうが、私がこれを実感できたのはこのころだったのです。

 では先程の疑問の、APIで作られたウィンドウのCWndポインタはどうなるのでしょう? おそらくWindows(かMFC)が内部でCWndを一時的に生成し、該当するHWNDをそのCWndに接続して、CWndポインタをくれるのでしょうね。 ですからCWnd系のポインタを取得するメンバー関数のヘルプには次のような謎の文があります。

返されるポインタは、一時的なポインタです。後でこのポインタを使って値を格納することはできません。

 これは、Windowsが一時的に生成したCWndを削除してしまうから、そのポインタをずーっと記憶しておいて、後で使ったら クラッシュしてしまうという意味なのですね、きっと。

 こういう重要なことがヘルプにははっきり書いてないし、「後で」とはどれくらいあとがマズイのかもはっきり書かれてありません。 困ったものです。