HSPのbutton命令やmesbox命令、combox命令などを使って作成することができるオブジェクト(HSPオブジェクト)は、Windowsでは総称して『コントロール』と呼ばれます。これは、Windowsによって提供されているウィンドウクラスのセットのことで、簡単に言ってしまうと、Windowsより提供されている、独自の機能を持ったウィンドウといったところです。
Windowsが提供しているコントロールには、コントロールを提供しているDLLによっていくつかのグループに分類され、それぞれのグループで次のような種類のコントロールが存在します。
上記のコントロールのうち、user32.dllが提供する標準コントロールのいくつかは、HSPの標準命令で作成することができるようになっています。
コントロール | HSP命令 |
---|---|
ボタンコントロール | button命令 |
エディットコントロール | mesbox命令およびinput命令 |
コンボボックス | combox命令 |
リストボックス | listbox命令 |
上で新なしたコントロールの中で、これから作成していこうとしているコントロールは、ツールバーやステータスバー、ツリービューなどといったコモンコントロールです。今回は、コモンコントロールについてを簡単に紹介しておきます。また、今後コモンコントロールを使っていく上で、必要となることも、あわせて述べていくことにしましょう。
コモンコントロールは、Windowsのコモンコントロールライブラリによって提供されるウィンドウセットです。上でも記述しましたが、コモンコントロールには以下のようなものがあります。
これらのコントロールがコモンコントロールライブラリにより提供されていると述べましたが、このライブラリの正体はcomctl32.dllです。このDLLによって提供されている関数を呼び出していくことで、コモンコントロールを作成することができるのです。
コモンコントロールライブラリは、コモンコントロール以外にも、それらをサポートするための機能として、イメージリストと呼ばれる機能も提供しています。イメージリストは、主にアイコンなどのイメージを使用するコモンコントロールで使われます。
コモンコントロールを提供しているcomctl32.dllのバージョンアップに伴い、いろいろな機能が追加されてきています。こういった、あとから追加された機能を使用する場合、古いバージョンのDLLがインストールされているマシンでは、そのソフトウェアが正常に動かなくなってしまう可能性があります。新しい機能を使用したソフトウェアを公開する場合には、その動作環境をはっきりと明記しておきましょう。
comctl32.dllのバージョンとその動作環境の対応は、以下のようになります。
Ver. | 動作環境 |
---|---|
4.0 | Windows 95 / NT 4.0 がインストールされた環境 |
4.70 | Internet Explorer 3.x がインストールされた環境 |
4.71 | Internet Explorer 4.0 がインストールされた環境 |
4.72 | Internet Explorer 4.01 / Windows 98 がインストールされた環境 |
5.8 | Internet Explorer 5 がインストールされた環境 |
5.81 | Windows Me / 2000 がインストールされた環境 |
6.0 | Windows XP がインストールされた環境 |
コモンコントロールを使うためには、まずコモンコントロールライブラリを初期化しなければいけません。これには、comctl32.dllが提供するInitCommonControls関数またはInitCommonControlsEx関数を呼び出す必要があります。
これらの関数は、コモンコントロールを使いますよー、ということをcomctl32.dllに伝えて、準備をするためのものです。詳しく言うと、この関数は、それぞれのコモンコントロールに対するウィンドウクラスをWindowsシステムに登録します。
ウィンドウクラスというのは、ウィンドウに関するデータと、ウィンドウの動作を決める関数(ウィンドウプロシージャ)を定義した情報を含めた、いわばウィンドウの雛形、あるいは設計図のようなものです。これから作成されるウィンドウがどのようなスタイルを持っていて、ウィンドウメッセージにどのように反応するウィンドウプロシージャを持っているのか、といった情報をウィンドウクラスという形で保持してあるのです。ウィンドウクラスに関する情報は、Windowsの管理するメモリ上のデータベースに格納されます。Windowsは、この情報を元にして、ウィンドウの作成や表示、メッセージの送信などを行うのです。
通常、アプリケーションがウィンドウを作成する際には、ウィンドウ情報を含むウィンドウクラスを登録しなければいけません。HSPのウィンドウも例外ではなく、HSP内部ではウィンドウクラスを登録してウィンドウを作成しているのです。一方、Windows標準コントロールは、Windowsの提供するウィンドウとしてはじめからウィンドウクラスが登録されていて、アプリケーションはそれを自由に使うことができます。また、コモンコントロールの場合には、初期化関数を呼び出すことによって、自動的にウィンドウクラスが登録されるようになっています。
InitCommonControls関数は、次のように定義されています。
void InitCommonControls(VOID);
InitCommonControls関数は、コモンコントロールライブラリが持つすべての種類のコモンコントロールのウィンドウクラスを登録します。どの種類のコントロールを、いくつ作成する場合であっても、プログラムの最初に一度だけ呼び出せばOKです。1つのプログラム中でInitCommonControls関数を2回以上呼び出した場合、2回目以降の呼び出しでは何もせずにすぐに制御が返ります。
コモンコントロール初期化用の関数にはInitCommonControls関数の他にもう1つあります。それは、comctl32.dllのバージョンアップに伴って新しく追加されたInitCommonControlsEx関数です。comctl32.dllのバージョン4.70以降で使用することができます。
BOOL InitCommonControlsEx(
LPINITCOMMONCONTROLSEX pInitCtrls
);
pInitCtrlsパラメータには、INITCOMMONCONTROLSEX構造体のアドレスを指定します。この構造体は以下のように定義されているものです。
typedef struct tagINITCOMMONCONTROLSEX { DWORD dwSize; // structure size DWORD dwICC; // control class } INITCOMMONCONTROLSEX, *LPINITCOMMONCONTROLSEX;
この構造体のdwSizeメンバには、INITCOMMONCONTROLSEX構造体のサイズをバイト単位で指定します。この構造体のサイズは8バイトであるので、このメンバに8を格納しておきます。
dwICCメンバには、使用するコントロールの種類を表す値を格納しておきます。この値は、以下に示す値を組み合わて指定することができます。
定数名 | 値 | コントロールの種類 |
---|---|---|
ICC_LISTVIEW_CLASSES | 0x00000001 | リストビュー ヘッダーコントロール |
ICC_TREEVIEW_CLASSES | 0x00000002 | ツリービュー ツールチップ |
ICC_BAR_CLASSES | 0x00000004 | ツールバー ステータスバー トラックバー ツールチップ |
ICC_TAB_CLASSES | 0x00000008 | タブコントロール ツールチップ |
ICC_UPDOWN_CLASS | 0x00000010 | アップダウンコントロール |
ICC_PROGRESS_CLASS | 0x00000020 | プログレスバー |
ICC_HOTKEY_CLASS | 0x00000040 | ホットキーコントロール |
ICC_ANIMATE_CLASS | 0x00000080 | アニメートコントロール |
ICC_WIN95_CLASSES | 0x000000FF | アニメートコントロール ヘッダーコントロール ホットキーコントロール リストビュー プログレスバー ステータスバー タブコントロール ツールチップ ツールバー トラックバー ツリービュー アップダウンコントロール |
ICC_DATE_CLASSES | 0x00000100 | DTPコントロール |
ICC_USEREX_CLASSES | 0x00000200 | 拡張コンボボックス |
ICC_COOL_CLASSES | 0x00000400 | レバーコントロール |
ICC_INTERNET_CLASSES | 0x00000800 | IPアドレスコントロール |
InitCommonControlsEx関数では、上記のdwICCメンバで指定されたコントロールのウィンドウクラスだけを登録するようになっています。必要なコントロールクラスのみをロードすることができるので、InitCommonControls関数を使ってすべてのコモンコントロールクラスを登録するよりも、使用されるメモリを節約し、初期化の時間を短縮することができるということです。
上述の通り、InitCommonControlsEx関数は新しく追加された関数であるため、バージョン依存性があります。この関数はcomctl32.dllのバージョン4.70以降が提供しており、Windows 98/MeやWindows 2000/XPがインストールされている環境、またはInternet Explorer 3.0以降がインストールされている環境で呼び出すことができます。
これよりも古いバージョンのDLLがインストールされている環境ではInitCommonControlsEx関数を使用することができないので、そういった環境でも動くプログラムを作成するには、常にInitCommonControls関数を呼び出すようにすればよいでしょう。
もしくは、DLLにInitCommonControlsEx関数が存在するかどうかを調べて、存在する場合のみ、その関数を呼び出すようにすることもできます。
DLLにその関数が存在するかどうかを、HSP標準関数のvarptrを使って調べることができます。通常、varptr関数は変数のアドレスを取得するために使用するものですが、変数名の変わりに関数名を指定すると、関数のアドレスを取得することができるようになっています。そして、DLLにその関数が含まれていない場合には0になるのです。
たとえば、ツールバーやステータスバーなどを作成したい場合には、次のようにすることができます。
#uselib "comctl32.dll"
#func InitCommonControls "InitCommonControls"
#func InitCommonControlsEx "InitCommonControlsEx" int
#const ICC_BAR_CLASSES 0x00000004
; comctl32.dll に InitCommonControlsEx() があるかどうか
if ( varptr(InitCommonControlsEx) != 0 ) {
icc = 8, ICC_BAR_CLASSES
InitCommonControlsEx varptr(icc)
} else {
InitCommonControls
}
一方、バージョン4.70よりも古いDLLでは提供されていない種類のコモンコントロールを使いたい場合には、はじめからInitCommonControlsExを使用するようにするといいでしょう。たとえば、IPアドレスコントロールはバージョン4.71以降で使用することができるコントロールですが、これを使用するには以下のようにすることができるでしょう。
#uselib "comctl32.dll" #func InitCommonControlsEx "InitCommonControlsEx" int #const ICC_INTERNET_CLASSES 0x00000004 gosub *InitComctlLib ; 初期化ルーチンにジャンプ ; (中略) stop *InitComctlLib ; ======== IPアドレスコントロール用に初期化 ======== ; comctl32.dll に InitCommonControlsEx() があるかどうか if ( varptr(InitCommonControlsEx) != 0 ) { icc = 8, ICC_INTERNET_CLASSES InitCommonControlsEx varptr(icc) if stat != 0 : return } ; 初期化エラー dialog "古いバージョンのcomctl32.dllです", 1, "初期化エラー" end
コモンコントロールの実体は、Windowsから提供されているウィンドウです。したがって、ウィンドウ作成用のAPI関数であるCreateWindow関数を使って作成することができます。この関数はuser32.dllによって提供されており、次のように定義されています。
HWND CreateWindowA( PCTSTR pszClassName, // window class PCTSTR pszWindowName, // window name DWORD dwStyle, // window style int x, // x-position int y, // y-position int nWidth, // width int nHeight, // height HWND hWndParent, // parent window HMENU hMenu, // menu handle or control ID HINSTANCE hInstance, // instance handle PVOID pParam // CREATESTRUCT structure );
最初のpszClassNameパラメータには、ウィンドウクラスの名前を表す文字列へのポインタを指定します。ウィンドウクラスはそれぞれ名前が付けられていて、その名前によって識別されます。通常、自身でウィンドウクラスを登録して、そのウィンドウクラスを指定する場合には、クラスの登録時に指定した名前を指定します。ただし、Windowsが提供する標準コントロールについてはすでにそのウィンドウクラスが登録されていますし、コモンコントロールは上記のライブラリ初期化によってウィンドウクラスが自動的に登録されているので、Windowsが定める定義済みのウィンドウクラス名を指定することで、それぞれのコントロールを作成することができます。コモンコントロールのウィンドウクラス名は次のようになっています。ここでは、クラス名に大文字と小文字が混ざって書かれていますが、実際には大文字・小文字は区別されません。
ウィンドウクラス名 | 作成されるコモンコントロール |
---|---|
"SysAnimate32" | アニメートコントロール |
"msctls_hotkey32" | ホットキーコントロール |
"msctls_progress32" | プログレスバー |
"msctls_statusbar32" | ステータスバー |
"ToolbarWindow32" | ツールバー |
"tooltips_class32" | ツールチップコントロール |
"msctls_trackbar32" | トラックバー |
"msctls_updown32" | アップダウンコントロール |
"ComboBoxEx32" | 拡張コンボボックス |
"SysHeader32" | ヘッダーコントロール |
"SysListView32" | リストビュー |
"SysTabControl32" | タブコントロール |
"SysTreeView32" | ツリービュー |
"SysDateTimePick32" | Ver. 4.70以降: DTPコントロール |
"SysMonthCal32" | Ver. 4.70以降: 月間カレンダーコントロール |
"ReBarWindow32" | Ver. 4.70以降: レバーコントロール |
"SysIPAddress32" | Ver. 4.71以降: IPアドレスコントロール |
"SysPager" | Ver. 4.71以降: ページャーコントロール |
次のpszWindowNameパラメータには、ウィンドウに割り当てる文字列を指定します。通常、タイトルバーが表示される種類のウィンドウの場合には、ここで指定された文字列がウィンドウのタイトルバーに表示されます。また、コントロールを作成する場合には、コントロールの種類によって異なります。たとえば、ボタンやエディットコントロールの場合には、コントロール内に表示される文字列を指定します。
次のdwStyleパラメータには、ウィンドウスタイルを指定します。これらは、すべてのウィンドウに共通なスタイルもありますが、作成するコントロールによって指定できる値が変わってくるスタイルもあります。すべてのウィンドウに共通のウィンドウスタイルには次のものがあります。複数のスタイルはOR演算子で組み合わせて指定します。とくに指定する必要ではありません。
定数名 | 値 | 意味 |
---|---|---|
WS_OVERLAPPED | 0x00000000 | オーバーラップスタイル |
WS_POPUP | 0x80000000 | ポップアップ |
WS_CHILD | 0x40000000 | 子ウィンドウ |
WS_MINIMIZE | 0x20000000 | 最小化状態 |
WS_VISIBLE | 0x10000000 | 可視状態 |
WS_DISABLED | 0x08000000 | 無効状態 |
WS_CLIPSIBLINGS | 0x04000000 | 兄弟ウィンドウのクリッピング |
WS_CLIPCHILDREN | 0x02000000 | 子ウィンドウのクリッピング |
WS_CAPTION | 0x00C00000 | タイトルバー付き |
WS_BORDER | 0x00800000 | 境界線付き |
WS_DLGFRAME | 0x00400000 | ダイアログボックス用境界 |
WS_VSCROLL | 0x00200000 | 垂直スクロールバー |
WS_HSCROLL | 0x00100000 | 水平スクロールバー |
WS_SYSMENU | 0x00080000 | ウィンドウメニュー付き |
WS_THICKFRAME | 0x00040000 | サイズ変更境界線 |
WS_GROUP | 0x00020000 | グループ開始ウィンドウ |
WS_TABSTOP | 0x00010000 | [Tab]キーで移動 |
WS_MINIMIZEBOX | 0x00020000 | 最小化ボタン付き |
WS_MAXIMIZEBOX | 0x00010000 | 最大化ボタン付き |
これ以外にも、コントロールの種類によって、標準コントロールごとに固有のスタイルやコモンコントロールごとに固有のスタイルが存在します。これらについては、必要に応じて説明していきます。
ただし、どのコントロールを作成する場合も、あるウィンドウの子ウィンドウにならなければならないので、WS_CHILDスタイルを指定しておかなければなりません。また、表示された状態にするにはWS_VISIBLEスタイルも組み合わせて指定されていなければなりません。
以降に続くx, y, nWidth, nHeightの各パラメータにはウィンドウの位置座標とサイズを指定します。ウィンドウスタイルに子ウィンドウスタイル(WS_CHILD)を含んでいる場合には、ウィンドウの位置はクライアント座標で指定することになります。
8番目のhWndParentパラメータには、作成されるウィンドウを所有するオーナーウィンドウのハンドルを指定します。新しいウィンドウが子ウィンドウスタイルを持つ場合には、このウィンドウは親ウィンドウと呼ばれます。コントロールは子ウィンドウとして作成しなければならないので、親ウィンドウを指定しなければいけません。HSPでは、システム変数hwndを指定することで、現在の描画中ウィンドウを指定することができます。
9番目のhMenuパラメータには、ウィンドウがポップアップスタイルかオーバーラップスタイルを持つ場合にはメニューハンドルを指定します。ウィンドウが子ウィンドウスタイルの場合には、子ウィンドウID(コントロールID)と呼ばれる識別値を指定します。
次のhInstanceパラメータには、インスタンスハンドルと呼ばれる値を指定します。インスタンスとは、メモリ上にロードされたプログラムの実体のことを指します。このインスタンスはハンドルによって識別されます。インスタンスハンドルは、HSPの場合には、システム変数hinstanceが実行中プログラムのインスタンスハンドルになります。
11番目のlpParamパラメータには通常使用されないもので、ここでは0 (NULL) を指定しておきます。
CreateWindow関数は、戻り値として、作成されたコントロールのウィンドウハンドルを返します。エラーが発生してウィンドウを作成できなかった場合には0 (NULL) が返ります。コントロールを作成した後、コントロールに対して操作を行う場合には、このハンドルが必要になります。
ウィンドウを作成する関数には、もう1つ、CreateWindowEx関数が存在します。
HWND CreateWindowExA( DWORD dwExStyle, // extended window style PCTSTR pszClassName, // window class PCTSTR pszWindowName, // window name DWORD dwStyle, // window style int x, // x-position int y, // y-position int nWidth, // width int nHeight, // height HWND hWndParent, // parent window HMENU hMenu, // menu handle or control ID HINSTANCE hInstance, // instance handle PVOID pParam // CREATESTRUCT structure );
この関数がCreateWindow関数と異なるのは、最初のdwExStyleパラメータで、拡張ウィンドウスタイルを指定することができるようになっている点です。これ以外のパラメータについては、CreateWindow関数とまったく同じです。
一般的なコントロールでは、あえて特定の拡張ウィンドウスタイルを指定する必要はないと思います。この関数のdwExStyleパラメータに0を指定するか、またはCreateWindow関数の方を使用すればよいでしょう。
さて、HSP3では、このCreateWindowEx関数を呼び出すラッパー命令であるwinobj命令が標準で提供されています。
winobj命令は、現在の描画先ウィンドウをオーナーウィンドウ(または親ウィンドウ)とするウィンドウを作成します。作成されたウィンドウは、他のHSPオブジェクトと同等に管理されます。すなわち、作成された順に0, 1, 2,... のオブジェクトIDが割り当てられていくことになります(HSPのオブジェクトIDとCreateWindowEx関数の子ウィンドウIDとは関連性はありません)。このHSPオブジェクトIDは、winobj命令実行直後にシステム変数statにも格納されます。ウィンドウハンドルについては、HSP標準関数のobjinfo関数またはobjinfo_hwndマクロにオブジェクトIDを渡すことで取得することができます。すなわち、
; オブジェクトID = 0 のコントロールのハンドルを取得
hControl = objinfo(0,2)
または、
; オブジェクトID = 0 のコントロールのハンドルを取得
hControl = objinfo_hwnd(0)
のようにします。
ところで、初期状態で非表示のコントロールを作成するために、CreateWindow関数やCreateWindowEx関数(またはwinobj命令)のウィンドウスタイルにWS_VISIBLEスタイルを指定しないでコントロールを作成することができます。この場合は、コントロールが作成された時点では表示されていないので、コントロールを後から表示させる必要があります。非表示状態のコントロールを表示させるには、user32.dllのShowWindow関数を呼び出します。
BOOL ShowWindow( HWND hWnd, // window handle int nCmdShow // show state );
この関数は、ウィンドウの表示状態を変更するためのものです。コントロールはすべてウィンドウであるので、この関数で表示状態を変更することができます。
hWndパラメータには、表示状態を変更するウィンドウのハンドルを指定します。非表示状態のコントロールを表示させるためには、このパラメータにコントロールのハンドルを指定する必要があります。
nCmdShowパラメータには、ウィンドウの表示状態を表す値を指定します。非表示状態のコントロールを表示させるには、このパラメータに1 (SW_SHOWNORMAL) を指定します。逆に、表示されていたコントロールを非表示状態にしたい場合には0 (SW_HIDE) を指定します。
作成したコモンコントロールを操作するためには、専用のAPI関数を使うよりもむしろ、そのコントロールにメッセージを送るということが行なわれます。アプリケーションがSendMessage関数でコントロールにある特定のメッセージを送ると、そのメッセージを受け取ったコントロールは、そのメッセージに応じた処理を行なって、必要ならば戻り値も返します。メッセージの送信によって、まるでAPI関数を使っているかのようにコントロールを操作することができます。このとき、引数を同じ役割を果たすのは、メッセージとともに送られるwParamパラメータとlParamパラメータです。HSP標準命令のobjsend命令でHSPオブジェクトにメッセージを送るといろいろな操作ができますが、あれとまったく同じです。
どんなメッセージコードを送ればどんな操作ができるのかはコントロールの種類によって異なります。
llmodモジュールを使ったメッセージの送信には、モジュール定義命令のsendmsg命令を使うことができます。このページでも、メッセージの送信にはこの命令を頻繁に使用していきます。
ウィンドウメッセージの送信およびsendmsg命令については、『メッセージの送信とポスト』の節を参照してください。
ウィンドウメッセージを発生させるにはSendMessage関数によるメッセージ送信と、PostMessage関数によるメッセージのポストがありましたが、コントロールに対してのメッセージはすべてSendMessage 関数を使います。
コモンコントロールは、何らかのイベントが起こったとき、例えばコントロール内にユーザーからの入力があったときに、たいていの場合そのことを通知メッセージ という形で親ウィンドウに知らせます。アプリケーションは、この通知メッセージに応じて、どんな処理をするかを決定していくことができます。ツールバーやステータスバーなどを使う場合にはあまり必要のないことなのですが、ツリービューやリストビューなどでは使うことがしばしばあるので、ここで述べておくことにします。
コモンコントロールからの通知メッセージは
メッセージの形で送られてきます。このメッセージコードは次のように定義されています。このメッセージのwParamパラメータはコモンコントロールのIDを、lParamパラメータはNMHDR構造体のアドレス、もしくはNMHDR構造体を第1メンバに持つ構造体のアドレスを示しています。この構造体には、通知メッセージを含む、コモンコントロールで発生したイベントの情報が含まれています。
NMHDR構造体は以下のように定義されています。
typedef struct tagNMHDR { HWND hwndFrom; // control handle UINT idFrom; // control ID UINT code; // notification code } NMHDR;
この構造体のhwndFromメンバはコントロールのウィンドウハンドルを、idFromメンバはコントロールIDを、そしてcodeメンバは通知コードを表しています。この構造体を変数nmhdrにとってみたとき、
というようになります。
ところで、「NMHDR構造体を第1メンバに持つ構造体」というのがどういった構造体であるのかは、やや分かりにくいかもしれませんね。簡単に説明すると、先頭にNMHDR構造体のデータが丸ごと入っていると考えます。例えば、多くのコモンコントロールは、コントロールにキーボードフォーカスがあるときにキーが押されると、通知メッセージNM_KEYDOWN (コード-15)を送るのですが、この場合は メッセージのlParamパラメータはNMKEYという構造体のアドレスとなっています。
typedef struct tagNMKEY { NMHDR hdr; // NMHDR structure UINT nVKey; // virtual key-code UINT uFlags; // key-state flag } NMKEY, FAR *LPNMKEY;
このNMKEY構造体は、その第1メンバにNMHDR構造体を持ちます。ここで、この構造体を変数nmkeyにとってみたとき、
というようになります。こうして考えるとだいたい仕組みが分かると思います。どの構造体が送られてくるかは、コモンコントロールの種類と、そのコントロールから送られてくる通知メッセージの種類によって異なります。
HSP3では、ほかのメッセージと同様にoncmd命令で メッセージの処理を登録することによって、通知メッセージに対する処理を行うことができるようになります。
#define WM_NOTIFY 0x004E oncmd gosub *OnNotify, WM_NOTIFY
通知メッセージを受け取ると指定ラベルにジャンプします。そのとき、lParamパラメータ(システム変数lparamの値)がNMHDR構造体のアドレスになっているので、そのアドレスがさす構造体の中を参照するため、dupptr命令を使って、その構造体領域をHSPの変数に割り当てます。このとき、構造体サイズの12を指定します。
*OnNoify dupptr nmhdr, lparam, 12 ; NMHDR 構造体の割り当て hCondrol = nmhdr(0) ; コントロールのハンドル idControl = nmhdr(1) ; コントロールID code = nmhdr(2) ; 通知コード ; (ここでメッセージに対する処理を行う) return 0
通知コードによっては、lParamパラメータに渡されるポインタが、NMHDR構造体ではなく、NMHDR構造体を第1メンバとするような構造体になることがあります。そのような場合には、通知コードを判断した後、再びdupptr命令で割り当てます。
*OnNoify dupptr nmhdr, lparam, 12 ; NMHDR 構造体の割り当て hCondrol = nmhdr(0) ; コントロールのハンドル idControl = nmhdr(1) ; コントロールID code = nmhdr(2) ; 通知コード if code == NM_KEYDOWN { dupptr nmkey, lparam, 20 vkey = nmkey(3) ; (仮想キーコード) keyflag = nmkey(4) ; (キー状態を表すフラグ) ; (ここでメッセージに対する処理を行う) } return 0
コモンコントロールは、コントロール内で起こったイベントを親ウィンドウに知らせるのに、
メッセージを使うことがあります。例えば、ツールバーは、ツールボタンが押されたときにそのボタンのアイテムIDを メッセージのパラメータに含ませて親ウィンドウに送るのです。親ウィンドウはそのメッセージを取得することで、ツールボタンが押されたことを知ることができます。このとき、 メッセージのlParamパラメータには、コントロールのハンドルが指定されます。これについてはここでは詳しく述べません。必要になったときにそれぞれ述べていくことにします。
今回はかなり長くなってしまいましたが、コモンコントロールを扱う上での前置きとしてはこのぐらいでしょう。次回からは何か具体的なコモンコントロールを使っていきたいと思います。