VBだけでは通常発生しないイベントを得る
<タイトルバーのクリックを感知>
宣 言 |
Public Declare Function CallWindowProc Lib "user32" Alias "CallWindowProcA" (ByVal PWF&,
ByVal hWnd&, ByVal Msg&, ByVal wParam&, ByVal lParam&) As Long Public Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hWnd&, ByVal nIndex&, ByVal dwNewLong&) As Long |
処 理 の 流 れ |
1、プログラム開始時にウィンドウプロシージャを自作のものにおきかえる
↓
2、メッセージが送られてきたら、必要な処理をする
↓
3、VB側にも処理を行わせるため(これがないと全てのイベントが発生しなくなる)、元のウィンドウプロシージャにメッセージを送る
↓
4、プログラム終了時にウィンドウプロシージャを自作のものから元に戻す。
サ ン プ ル プ ロ グ ラ ム |
まずフォームモジュールと標準モジュールを追加し以下のコードを張り付けて下さい。次にコマンドボタンと状況表示用のラベルをフォームに張り付けて下さい。そして実行してください。なお絶対にフォームのXボタンで終了するようにしてください。VB環境内の停止ボタンで終了すると、ページ違反が起こります(処理の流れ(4)が行えない)。タイトルバーをクリックするとデバックウィンドウにメッセージを表示します。
動作確認:Visual Basic 5.0(Visual Basic 4.0では動作しません(AddressOfを使用)),Windows98
フォームモジュール(Form1) |
Option Explicit Private Sub Form_Load() StartMsg End Sub Private Sub Form_QueryUnload(Cancel As Integer, UnloadMode As Integer) ExitMsg End Sub |
標準モジュール |
Option Explicit Public Declare Function CallWindowProc Lib "user32" Alias "CallWindowProcA" (ByVal PWF&, ByVal hWnd&, ByVal Msg&, ByVal wParam&, ByVal lParam As Long) As Long Public Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hWnd&, ByVal nIndex&, ByVal dwNewLong&) As Long Public Const GWL_WNDPROC = (-4) Public Const WM_NCLBUTTONDOWN = &HA1 Dim oad As Long Public Function WindowProc(ByVal hWnd As Long, ByVal uMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long If uMsg = WM_NCLBUTTONDOWN Then Debug.Print "非クライアント領域(タイトルバーなど)がクリックされました" End If WindowProc = CallWindowProc(oad, hWnd, uMsg, wParam, lParam) End Function Public Sub StartMsg() oad = SetWindowLong(Form1.hWnd, GWL_WNDPROC, AddressOf WindowProc) End Sub Public Sub ExitMsg() SetWindowLong Form1.hWnd, GWL_WNDPROC, oad End Sub |
備 考 |
以下のようなメッセージを得ることが出来ますが、VBだけで発生するものも多いので、VBだけで発生するものに関しては素直にそちらを使用したほうが良いと思います。
Public Const WM_ACTIVATE = &H6 'ウインドウがアクティブ・非アクティブになった Public Const WM_ACTIVATEAPP = &H1C '別のアプリケーションのウインドウがアクティブ・非アクティブになりつつある Public Const WM_ASKCBFORMATNAME = &H30C 'クリップボードのフォーマット名を文字列バッファにコピーを要求 Public Const WM_CANCELMODE = &H1F 'メッセージボックス等のダイアログボックスが表示されようとしている Public Const WM_CHAR = &H102 'キーボードから文字入力を受け取った Public Const WM_CHILDACTIVATE = &H22 'MDIコントロールの子ウインドウがアクティブになった Public Const WM_CLEAR = &H303 'テキストボックス、コンボボクスの選択テキストを削除 Public Const WM_CLOSE = &H10 'ウインドウあるいはアプリケーションをクローズされた Public Const WM_COMMAND = &H111 'メニューが選択されたあるいはコントロールにイベントが発生した Public Const WM_COMMNOTIFY = &H44 '通信用通知を受け取った Public Const WM_COMPACTING = &H41 'システムがメモリ不足の状態にある Public Const WM_COPY = &H301 'テキストボックス、コンボボックスの選択テキストをクリップボードにコピー Public Const WM_CREATE = &H1 'ウインドウが作成中 Public Const WM_CUT = &H300 'テキストボックス、コンボボックスの選択テキストをクリップボードにコピー Public Const WM_DEADCHAR = &H103 'アクセント記号のような文字と組合せた文字を受け取った Public Const WM_DELETEITEM = &H2D 'オーナ描画リストボックスの項目が削除された Public Const WM_DESTROY = &H2 'ウインドウが破棄された Public Const WM_DESTROYCLIPBOARD = &H307 'EmptyClipboard()によってクリップボードが空になった Public Const WM_DEVMODECHANGE = &H1B 'WIN.INI のデフォルトのデバイス名が変更された Public Const WM_DRAWCLIPBOARD = &H308 'クリップボードの内容が変わった Public Const WM_DROPFILES = &H233 'ファイルマネージャからの Drag & Drop Public Const WM_ENABLE = &HA 'ウインドウが有効・無効になった Public Const WM_ENDSESSION = &H16 'Windows が終了する Public Const WM_ENTERIDLE = &H121 'ダイアログボックス、メニューが入力待ち Public Const WM_ERASEBKGND = &H14 'バックグラウンドを消去(再ペイント) Public Const WM_FONTCHANGE = &H1D 'システムフォントが変更された Public Const WM_GETFONT = &H31 'テキストボックス、ラベル等が現在使っているフォントのハンドル Public Const WM_GETMINMAXINFO = &H24 'フォームの最大・最小化時に可能なサイズを取得 Public Const WM_GETTEXT = &HD 'コントロールのキャプション、テキストボックスのテキストをバッファにコピー Public Const WM_GETTEXTLENGTH = &HE 'WM_GETTEXT の前に文字数を調べる Public Const WM_HSCROLL = &H114 '水平スクロールバーを調整している Public Const WM_HSCROLLCLIPBOARD = &H30E 'クリップボードビューワで水平スルクールバーが使われた Public Const WM_ICONERASEBKGND = &H27 'クラスアイコンがある時、アイコンの描画前に通知 Public Const WM_IME_CHAR = &H286 'IMEが変換後の文字を受取った Public Const WM_IME_COMPOSITION = &H10F 'キー入力によってIMEが確定後の状態を変更した Public Const WM_IME_COMPOSITIONFULL = &H284 '確定後の文字を表示するウインドウにスペースがない Public Const WM_IME_CONTROL = &H283 'IMEにコマンドを送る Public Const WM_IME_ENDCOMPOSITION = &H10E '文字を確定した Public Const WM_IME_KEYDOWN = &H290 'キーを押した Public Const WM_IME_KEYUP = &H291 'キーを離した Public Const WM_IME_NOTIFY = &H282 'IMEウインドウの変化をアプリケーションに知らせる Public Const WM_IME_SELECT = &H285 'システムがIMEを変更しようとしている Public Const WM_IME_SETCONTEXT = &H281 'IMEの入力ウインドウがアクティブになった時アプリケーションに通知する Public Const WM_IME_STARTCOMPOSITION = &H10D '確定する前に通知する Public Const WM_INITDIALOG = &H110 'ダイアログボックスが表示される Public Const WM_INITMENU = &H116 'メニューが表示される直前に通知 Public Const WM_INITMENUPOPUP = &H117 'ポップアップメニューが表示される直前に通知 Public Const WM_KEYDOWN = &H100 'キーボードのキーが押された Public Const WM_KILLFOCUS = &H8 'フォーカスがなくなる直前に通知 Public Const WM_LBUTTONDBLCLK = &H203 '左のマウスボタンをダブルクリックした Public Const WM_LBUTTONDOWN = &H201 '左のマウスボタンを押した Public Const WM_LBUTTONUP = &H202 '左のマウスボタンが解放された Public Const WM_MBUTTONDBLCLK = &H209 '中央のマウスボタンがダブルクリックされた Public Const WM_MBUTTONDOWN = &H207 '中央のマウスボタンが押された Public Const WM_MBUTTONUP = &H208 '中央のマウスボタンが解放された Public Const WM_MDIACTIVATE = &H222 'MDIで指定した子ウインドウをアクティブにする Public Const WM_MDICASCADE = &H227 'MDI子ウインドウをカスケード表示にする Public Const WM_MDICREATE = &H220 'MDI子ウインドウを作成する Public Const WM_MDIDESTROY = &H221 'MDI子ウインドウを破棄する Public Const WM_MDIGETACTIVE = &H229 '現在アクティブなMDI子ウインドウのハンドルを取得 Public Const WM_MDIICONARRANGE = &H228 'MDI子ウインドウのアイコンを整列 Public Const WM_MDIMAXIMIZE = &H225 'MDI子ウインドウを最大化 Public Const WM_MDINEXT = &H224 '次の子ウインドウをアクティブにする Public Const WM_MDIRESTORE = &H223 '最大化・最小化されている子ウインドウを元のサイズに戻す Public Const WM_MDISETMENU = &H230 'メニューをMDIフレームウインドウにリンク Public Const WM_MDITILE = &H226 'MDI子ウインドウをタイル整列 Public Const WM_MENUCHAR = &H120 'メニューのアクセスキーの英文字と一致しない文字を受け取った Public Const WM_MENUSELECT = &H11F 'メニューが強調表示・選択された Public Const WM_MOUSEACTIVATE = &H21 'マウスクリックによりアクティブウインドウが移った Public Const WM_MOUSEMOVE = &H200 'マウスが移動した Public Const WM_MOVE = &H3 'ウインドウが移動した Public Const WM_NCACTIVATE = &H86 '非クライアント領域がアクティブ・非アクティブである Public Const WM_NCCALCSIZE = &H83 'ウインドウのサイズを再計算する Public Const WM_NCCREATE = &H81 'ウインドウのスタイルが変更された時に最初に送られるメッセージ Public Const WM_NCDESTROY = &H82 '非クライアント領域が破棄 Public Const WM_NCHITTEST = &H84 '非クライアント領域のどの部分でマウスが操作されたか調べる Public Const WM_NCLBUTTONDBLCLK = &HA3 '非クライアント領域で左ボタンをダブルクリック Public Const WM_NCLBUTTONDOWN = &HA1 '非クライアント領域で左ボタンを押す Public Const WM_NCLBUTTONUP = &HA2 '非クライアント領域で左ボタンを解放 Public Const WM_NCMBUTTONDBLCLK = &HA9 '非クライアント領域で中央ボタンをダブルクリック Public Const WM_NCMBUTTONDOWN = &HA7 '非クライアント領域で中央ボタンを押す Public Const WM_NCMBUTTONUP = &HA8 '非クライアント領域で中央ボタンを解放 Public Const WM_NCMOUSEMOVE = &HA0 '非クライアント領域でマウスが移動 Public Const WM_NCPAINT = &H85 '非クライアント領域で再ペイントが必要 Public Const WM_NCRBUTTONDBLCLK = &HA6 '非クライアント領域で右ボタンをダブルクリック Public Const WM_NCRBUTTONDOWN = &HA4 '非クライアント領域で右ボタンを押す Public Const WM_NCRBUTTONUP = &HA5 '非クライアント領域で右ボタンを解放 Public Const WM_NEXTDLGCTL = &H28 '入力フォーカスを別の子ウインドウに移動 Public Const WM_NULL = &H0 'これ自体は何もしないがメッセージを操作する場合に使う Public Const WM_PAINT = &HF 'ウインドウのクライアント領域を再描画しなければならない Public Const WM_PALETTECHANGED = &H311 'システムパレットが変更された Public Const WM_PALETTEISCHANGING = &H310 'システムパレットが別のウインドウによって変更されようとしている Public Const WM_PARENTNOTIFY = &H210 'あるイベントが子ウインドウで発生したことを親ウインドウに通知する Public Const WM_PASTE = &H302 'クリップボードからテキストをコピーした Public Const WM_POWER = &H48 'システムがパワー節約状態に入る・出ること通知する Public Const WM_QUERYDRAGICON = &H37 'アイコンを表示しようとする時にクラスアイコンを持たないウインドウに送る Public Const WM_QUERYENDSESSION = &H11 'Windowsを終了する時にすべてのウインドウに問合わせる Public Const WM_QUERYNEWPALETTE = &H30F '入力フォーカスを受取る時、論理パレットで置換えるかどうか問合わせる Public Const WM_QUERYOPEN = &H13 'アイコン化されたウインドウが復元する時、直前の位置とサイズを要求されているかどうか問合わせる Public Const WM_QUIT = &H12 'アプリケーションが処理する最後のメッセージ Public Const WM_RBUTTONDBLCLK = &H206 '右のマウスボタンをダブルクリックした Public Const WM_RBUTTONDOWN = &H204 '右マウスボタンを押した Public Const WM_RBUTTONUP = &H205 '右マウスボタンを解放した Public Const WM_SETCURSOR = &H20 'マウスをキャプチャしているウインドウがない時、マウスがあるウインドウに送られる Public Const WM_SETFOCUS = &H7 'ウインドウが入力フォーカスを得た Public Const WM_SETFONT = &H30 '論理フォントを設定する Public Const WM_SETREDRAW = &HB 'コントロールの再描画操作を制御する Public Const WM_SETTEXT = &HC 'ウインドウ(コントロール)のタイトル・テキストを変更 Public Const WM_SHOWWINDOW = &H18 'ウインドウが表示・非表示になった Public Const WM_SIZE = &H5 'ウインドウのサイズが変更 Public Const WM_SIZECLIPBOARD = &H30B ' Public Const WM_SPOOLERSTATUS = &H2A '印刷キューに印刷ジョブが追加・削除された Public Const WM_SYSCHAR = &H106 '[Alt]キーとの組合せ以外はWM_CHARと同じ Public Const WM_SYSCOLORCHANGE = &H15 'システムカラーが変更された Public Const WM_SYSCOMMAND = &H112 'システムメニューが操作された Public Const WM_SYSDEADCHAR = &H107 'アクセント記号のような別の文字と組合せた文字入力を受け取った Public Const WM_SYSKEYDOWN = &H104 'システム文字を意味するキーを押した Public Const WM_SYSKEYUP = &H105 'システム文字を意味するキーが解放された Public Const WM_TIMECHANGE = &H1E 'システムタイマが変更された Public Const WM_TIMER = &H113 'SetTimer()で設定した時間を経過 Public Const WM_UNDO = &H304 'テキストボックスで Undo 操作を実行する Public Const WM_USER = &H400 'ユーザーが定義できるメッセージの使用領域を表すだけでこれ自体に意味はない Public Const WM_VSCROLL = &H115 'ユーザーが垂直スクロールバーを調整した Public Const WM_WINDOWPOSCHANGED = &H47 'SetWindowPos()後に位置とサイズを変更したウインドウに送られる Public Const WM_WINDOWPOSCHANGING = &H46 'SetWindowPos()で位置とサイズを変更しているウインドウに送られる Public Const WM_WININICHANGE = &H1A 'WIN.INIが変更された |