Mesoscopic Programming

タコさんプログラミング専門

Tips #027 WM_SETCURSOR イベントの発生タイミングに対する不満

憤りメモ

マウスカーソルが移動したときにしか WM_SETCURSOR が発生しないのは貧弱すぎるのではないか。
何故ならば、キーボードの状態が変化したときにもカーソル形状を変更したいからだ。
かと言って、キーボードイベントはフォーカス所有者にしか来ないし。
WM_SETCURSOR はフォーカスと無関係にカーソル位置にあるウィンドウに来るのにさ。ぷんぷん。
ヘルプを読んだりぐ~ぐる先生に聞いたりしてもエレガントな解決方法は見つからなかった。
現時点で考えられる解決方法としては、
タイマーによる定期的チェックと、または最上層でのメッセージフックによる方法があるが、
タイマーリソースがもったいないのでフックにした。

BOOL App :: HookMessage( LPMSG pmsg )
{
    POINT pt;
    HWND  hChild;
    RECT  rc;

    if ( GetCapture() == NULL && ( pmsg->message == WM_KEYDOWN || pmsg->message == WM_KEYUP ) )
    {
        GetCursorPos( & pt );

        hChild = WindowFromPoint( pt );

        if ( IsChild( hwnd, hChild ) )
        {
            GetClientRect( hChild, & rc );
            ClientToScreen( hChild, ( LPPOINT ) & rc.left );
            ClientToScreen( hChild, ( LPPOINT ) & rc.right );

            if ( PtInRect( & rc, pt ) )
            {
                SendMessage( hChild, WM_SETCURSOR, 0, MAKELPARAM( HTCLIENT, 0 ) );
            }
        }
    }

    return FALSE;
}
解説

マウスが誰にもキャプチャされてない状態で、誰かにキーボードイベントが来たら、
カーソル位置のウィンドウに WM_SETCURSOR を送りまんねん。

以上です。