Last Updated 2004/09/08
MFC ダイアログ

キャプションのないダイアログの移動


ダイアログでないウィンドウでキャプションがない場合は,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() が
呼ばれるからである.
2002/07/10

参照
ダイアログプロシージャの戻り値
擬似タイトルバー


MFC ダイアログ