MFCはWindowsAPIをクラス化しただけのものです。特にコントロール周り(エディットボックスやリストボックスなどの)はMFCで機能が実装されているわけではありません。もともとWindowsに実装されている機能を使いやすいようにクラス化しているだけです。
イベントが多いので例としてリストボックスを挙げます。WindowsAPIはオブジェクト指向とはなっていないので、リストボックスのインスタンスというものはありません(ウインドウに関してはハンドルが実体です)。では、ダイアログ上のリストボックスに項目を追加したり、項目が選択されたというイベントを受け取る場合、メッセージというWindowsの機能を使います。
すなわち、
ではMFCではこれがどのようになっているかというと、
すなわち、MFCはWindowsSDKで開発する時に毎回書くことになる同じ内容部分を再利用可能な形でまとめたものに過ぎません(それでも毎回同じことを書くことが多い仕様になっていますが)。
逆に、MFCに無い機能はWindowsAPIで実装されていない(不可能ではない)機能であることが多いです。例えばリストボックスで現在選択されている項目上で右クリックしたというイベントを受け取るにはどうすればよいかというと、WindowsAPIのリストボックスには選択されている項目上での右クリックを検知してメッセージを送るという機能は実装されていません。このような時には、リストボックス側の実装を拡張する必要がでてきます。これをWindowsではサブクラス化と呼びます。
すなわち、
- CreateWindowでリストボックスのウィンドウを作る(リソーススクリプトを使う場合は自動的)。ハンドルという実体が得られる。
- リストボックスに指示する場合は、SendMessageで■どこかにあるリストボックスの実装部分■に意図を伝える。例えば項目を追加する場合にはLB_ADDSTRINGというメッセージをリストボックスのハンドル宛に送る。
- 項目をクリックなどのダイアログ上で生じたイベントは、先ず■どこかにあるリストボックスの実装部分■でキャッチされます。例えば項目をダブルクリックしたというイベントは実装部分でキャッチされ、実装部分はSendMessageでWM_COMMAND, LBN_DBLCLKというメッセージを■送ってきます■。
ではMFCではこれがどのようになっているかというと、
- すべてのウィンドウはCWndの派生クラスです。CWndは自身のウインドウハンドルを持っています。
- CListBox::AddStringやSetCurSelはウィンドウハンドル宛にSendMessageするだけです。(MFC持っている人はafxwin2.inlにあります)
- リソースエディタ上で追加したダブルクリックなどのイベントに対する関数は、結局のところWM_COMMANDのLBN_DBCLKというメッセージが飛んできたら実行する関数を登録するだけです。
すなわち、MFCはWindowsSDKで開発する時に毎回書くことになる同じ内容部分を再利用可能な形でまとめたものに過ぎません(それでも毎回同じことを書くことが多い仕様になっていますが)。
逆に、MFCに無い機能はWindowsAPIで実装されていない(不可能ではない)機能であることが多いです。例えばリストボックスで現在選択されている項目上で右クリックしたというイベントを受け取るにはどうすればよいかというと、WindowsAPIのリストボックスには選択されている項目上での右クリックを検知してメッセージを送るという機能は実装されていません。このような時には、リストボックス側の実装を拡張する必要がでてきます。これをWindowsではサブクラス化と呼びます。
コメントをかく