Last Updated 2004/01/26
Programming Tips Visual C++ MFC ダイアログ  索 引 
キャプションのないダイアログの移動
2004/01/26

ダイアログでないウィンドウでキャプションがない場合は,WM_NCHITTEST のハンドラで HTCAPTION を返せばウィンドウを移動できる.
が,ダイアログではそのままでは移動できない.
それはダイアログプロシージャは戻り値として TRUE か FALSE しか持たない為である.
そこで ダイアログプロシージャから値を返す SetWindowLong() の登場である.

BOOL CALLBACK DlgProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    switch(uMsg){
    case ...

    case WM_NCHITTEST:
        /* メッセージの戻り値はSetWindowLongで設定する */
        SetWindowLong(hwnd, DWL_MSGRESULT, HTCAPTION);
        return TRUE; /* メッセージを処理したのでTRUEを返す */
    }
    return FALSE; /* メッセージを処理しないときはFALSEを返す */
}

上記でウィンドウの移動は出来るが,WM_RBUTTONDOWN WM_LBUTTONDOWN などのメッセージが受け取れなくなる.
その場合,システムメニューを使用する方法にてウィンドウの移動が可能である.

    case WM_LBUTTONDOWN:
        SendMessage(hwnd, WM_SYSCOMMAND, SC_MOVE | 2, lParam);
        return TRUE; /* メッセージを処理したのでTRUEを返す */


余談だが,ダイアログプロシージャでは処理しないメッセージはそのまま放置する.
switch の default にて DefWindowProc() や DefDlgProc() を呼び出す必要はない.(呼び出してはいけない)
ダイアログプロシージャから抜けた際に,戻り値によって自動的に DefDlgProc() が呼ばれ,さらに DefDlgProc() から DefWindowProc() が呼ばれるからである.


参照
ダイアログプロシージャの戻り値
擬似タイトルバー
前後のTips
キャプションのないダイアログの移動

DSS ProgrammingTipsCGI Ver2.01