Tips of VC++ > ウィンドウ > タイトルバー以外の部分をドラッグしてウィンドウを移動させる
前へ戻る ★ 次へ進む ★


タイトルバー以外の部分をドラッグしてウィンドウを移動させる

普通、ユーザーがウィンドウを移動したいと思ったときは、 タイトルバーをドラッグしてウィンドウを移動させます。 しかしクライアント領域をドラッグしても ウィンドウを移動させることができます。 しかも、あたかもタイトルバーを移動しているときのように 灰色の枠が出現します!
これはOSにドラッグされているのはタイトルバーだと 誤認識させることによって実現できます。 そんなに難しくないです。

方法1

case WM_NCHITTEST:
    UINT n;
    n=::DefWindowProc(in_hWnd,WM_NCHITTEST,
        in_wParam,in_lParam);
    if ( n==HTCLIENT )
        n=HTCAPTION;
    return n;

マウスイベントなどである一点のウィンドウの左上隅からの相対座標から、 その一点がウィンドウのどこを示しているかを調べるときに、OSが呼び出します。 例えばクリックされた場所がクライアント領域だった場合、 HTCLIENTを返したりします。 このHTで始まる戻り値は他にもいろいろあります。
以上をふまえて、 上のソースではWM_NCHITTTESTをオーバーロードしています。 まずWM_NCHITTTESTを送って、 クリックされた場所がクライアント領域だった場合のみ、 HTCAPTIONを返させます。
しかし、この方法を使うとデメリットが一点。 それはダブルクリックしたときにウィンドウが最大化してしまうことです。 そこで次の方法をとります。

方法2

case WM_LBUTTONDOWN:
    ::PostMessage(in_hWnd,WM_NCLBUTTONDOWN,
        HTCAPTION,in_lParam);
    break;

今度はじかにクリックされたときにソースを書きます。 といってもWM_NCLBUTTONDOWNを送るだけです。 これは第三引数にウィンドウのどこがクリックされたかを指定できます。 よってここにHTCAPTIONを送れば、 クライアント領域がクリックされたときのみ判別できます。
こっちのほうがオススメです。短いし…