マイクロソフト系技術情報 Wiki」は、「Open棟梁Project」,「OSSコンソーシアム .NET開発基盤部会」によって運営されています。

目次

Windowsメッセージキュー

  • Windowsメッセージ(WM_XXXX)を格納するキュー
  • キーボードなどのハードウェア入力やプログラムが
    WindowsメッセージキューにWindowsメッセージをキューイングする。
  • プロセス間通信やCOMのSTAなどでも利用される。

Windowsメッセージ

Windowsメッセージキューに格納されたWindowsメッセージは、

  • メッセージ・ループによって取り出され、
  • ウィンドウプロシージャ(WndProc?)により処理される。

作成されるタイミング

ウィンドウを作成したスレッドには、Windowsメッセージキューが与えられる。

通常、1UIスレッドで複数ウィンドウを処理する。この場合も1Windowsメッセージキューになる。

  • Windows Formsアプリケーションでも、この形になる。
  • Windows Formsでは、通常、1プロセス、1UIスレッド、1Windowsメッセージキュー。
  • 必要に応じてスレッドを生成してFormを生成すると別のWindowsメッセージキューが生成される。
  • バックグラウンド・スレッドから上げたモーダル・ダイアログがモーダルにならない理由でもある。

メッセージ・ループ

メッセージ・ループで使用するWin32PI

メッセージの取り出し

  • GetMessage?
  • PeekMessage?
  • GetQueueStatus?(メッセージ状態確認)

メッセージの割り当て

  • DispatchMessage?WndProc?へ割り当て)

待機

  • WaitForMultipleObjects?
  • WaitForMultipleObjectsEx?

その他

  • TransrateMessage?(ショートカットの変換)

.NETでメッセージループ(WinProc?)を実装する方法

ウィンドウプロシージャ(WndProc?

WndProc?で使用するWin32PI

WndProc?登録

  • RegisterClassA(ANSI)
  • RegisterClassW(Unicode)
  • IsWindowsUnicode?(ANSI?Unicode?のチェック)
  • ,etc.

WndProc?のサブクラス化

WndProc?のサブクラス化とは、WndProc?の置き換えと、元のWndProc?へのチェーンを実装すること。
オブジェクト指向のサブクラスではないが、それ相当のことをやっている(オーバーライド+base呼び出し)。

  • SetWindowLongPtrA(ANSI)
  • SetWindowLongPtrW(Unicode)
  • 差し替え前のWndProc?を直接呼び出す
    • CallWindowProcA(差し替え前のANSIのWndProc?を直接呼び出す)
    • CallWindowProcW(差し替え前のUnicodeのWndProc?を直接呼び出す)  
  • ,etc.

メッセージの送信

  • PostMessage
    メッセージループにキューイングする。
  • SendMessage
    WndProc?をサブルーチン的に呼び出す(イベントの実装に使用する)

ハードウェア入力

ハードウェア入力モデルとローカル入力状態

ハードウェア入力モデル

  • SHIQ(system hardware input queue:システムハードウェア入力キー)
  • RIT(raw input thread:現在の入力スレッド)/(SHIQを待機、取出、変換)
  • VIQ(virtual input queue:仮想入力キュー)/(THREADINFO構造体内)

RITが接続するVIQのスレッドを識別する

  • マウスポインタ:マウスカーソルの下のウィンドウのスレッド
  • キーストローク:フォアグラウンド・ウィンドウのスレッド
  • その他、Alt+Tabなどの特殊キー・シーケンスを処理する。

THREADINFO構造体

  • ポストメッセージ(PostMessage
  • 送信メッセージキュー(SendMessage、別スレッド)
  • 応答メッセージキュー(SendMessage、別スレッド)
  • 仮想入力キュー(ハードウェア入力)
  • ウェイクフラグ(PostQuitMessage?
  • nExitCode?PostQuitMessage?
  • スレッドローカル
  • 入力状態管理変数

ローカル入力状態(THREADINFO構造体内)

キーボード入力、ウィンドウフォーカス情報

  • フォーカス・ウィンドウ
  • アクティブ・ウィンドウ
  • 押下されているキー
  • キャレット(入力カーソル)の状態   

マウスカーソル管理情報

  • 表示/非表示の状態
  • キャプチャ

マウスによる切り替え

  • WM_KILLFOCUS

Win32API

SetFocus?

  • WM_SETFOCUS
  • VIQの切り替えはできない。
  • 通常、RITに接続されているときだけ呼び出す。
  • スレッド1がRITに接続している時にスレッド2のウィンドにSetFocus?を呼び出すと
    2つのフォーカス矩形が現れ問題(RITに接続するVIQは切り替わらないので)。

GetFocus?

ローカル入力状態からフォーカスを持つウィンドウのHWNDを返す。   

SetActiveWindow?

  • ウィンドウをアクティブにする。
  • RITに接続するVIQの切り替えはできない。
  • 通常、RITに接続されているときだけ呼び出す。   

GetActiveWindow?

ローカル入力状態からアクティブなウィンドウのHWNDを返す。   

BringWindowToTop?

HWND_TOPを指定しSetWindowPos?を呼び出す(RITに接続するVIQを変更可能)

SetWindowPos?

ウィンドウをアクティブにしてサイズ、位置、Zオーダの変更。
(RITに接続するVIQを変更可能)   

SetForgroundWindow?

ウィンドウをフォアグラウンドに移動するが(RITに接続するVIQを変更可能)
プログラマによって乱用されたため、MSはRITに接続されているか、RITに接続されている
別スレッドが一定時間以上、入力を受け取っていない場合にのみ成功するように機能を追加した。

失敗の際は、タスクバーをフラッシュさせる。

AllowSetForgroundWindow?

指定したプロセスのスレッドがSetForgroundWindow?を呼び出すことを許可する。

LockSetForgroundWindow?

他のSetForgroundWindow?呼出をロックする
(Windowsスタートメニューなどで使用されている)。 

GetForgroundWindow?

フォアグラウンドウィンドウのHWNDを返す。

GetKeyState?

最後のキー入力を返す。 入力フォーカスを持ったウィンドウを持ってる必要はない。   

GetAsyncKeyState?

  • キーが押されているか?
  • 前回の呼び出し以降にキーが押されたか?

を返す。

入力フォーカスを持ったウィンドウを持ていること。

SetCursor?

マウス・カーソルのセット(砂時計など)

ShowCursor?

マウス・カーソルの表示・非表示

ClipCursor?

マウス・カーソルの範囲を指定する。 (非同期的なアクティブ化イベントで中止)

SetCapture?

  • マウス・カーソルがウィンドウの範囲内にあるかどうかに関わり無く、すべてのマウス入力を受け取る。
  • 一度に 1 つのウィンドウだけがマウスをキャプチャできる。通常はマウスのボタン押下後に呼び出す。

ReleaseCapture?

上記のマウスのキャプチャを停止する。

AttachThreadInput?

複数のスレッドに複数のVIQとローカル入力状態を共有させる。

ただし、THREADINFO構造体の、

  • ポストメッセージ
  • 送信メッセージキュー
  • 応答メッセージキュー
  • ウェイクフラグ

については自分のものを使い続ける。

  • 用途としては
    • Windowを前面に出す
    • ジャーナルの記録・再生フックをインストールした場合。
    • このAPIはシステムの強度を損なう可能性がある。

ユーザオブジェクト

ユーザオブジェクト(プロセスに占有)

  • アイコン
  • カーソル
  • ウィンドウクラス、
  • メニュー
  • アクセラレータテーブル

参考


Tags: :Windows, :ウィンドウ・システム, :プログラミング


トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2018-11-08 (木) 01:29:27 (9d)