私のアプリケーションの1つでは、ウィンドウを「クライアント領域をドラッグ可能」と呼んでいるものにしたいとも思っていました。残念ながら、前述のソリューション(HTCLIENTをHTCAPTIONに置き換える)には重大な欠陥があります。
クライアント領域をダブルクリックすると、キャプションをダブルクリックした場合と同じ動作が表示されるようになりました(つまり、ウィンドウを最小化/最大化)。
これを解決するために、メッセージハンドラーで次のことを行いました(抜粋)。
case WM_MOUSEMOVE:
// Move window if we are dragging it
if (mIsDragging) // variable: bool mIsDragging;
{
POINT mousePos = {GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)};
mIsDragging = (ClientToScreen(hWnd, &mousePos) &&
SetWindowPos(hWnd,
NULL,
mDragOrigin.left + mousePos.x - mDragPos.x,
mDragOrigin.top + mousePos.y - mDragPos.y,
0,
0,
SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE));
}
break;
case WM_LBUTTONDOWN:
// Check if we are dragging and safe current cursor position in case
if (wParam == MK_LBUTTON)
{
POINT mousePos = {GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)};
if (ClientToScreen(hWnd, &mousePos) &&
DragDetect(hWnd, mousePos))
{
// Check if the cursor is pointing to your new caption here!!!!
mIsDragging = true;
mDragPos = mousePos;
GetWindowRect(hWnd, &mDragOrigin);
SetCapture(hWnd);
}
}
break;
// Remove this case when ESC key handling not necessary
case WM_KEYDOWN:
// Restore original window position if ESC is pressed and dragging active
if (!mIsDragging || wParam != VK_ESCAPE)
{
break;
}
// ESC key AND dragging... we restore original position of window
// and fall through to WM_LBUTTONUP as if mouse button was released
// (i.o.w. NO break;)
SetWindowPos(hWnd, NULL, mDragOrigin.left, mDragOrigin.top, 0, 0,
SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE);
case WM_LBUTTONUP:
ReleaseCapture();
break;
case WM_CAPTURECHANGED:
mIsDragging = false;
break;
(擬似)コードは戻り値(デフォルト:0)と変数定義を省略しますが、とにかく手順を明確にする必要があります!?(そうでない場合は、私に1行削除してください。コードを追加するか、すべて追加します)。
ps:これら2つのソリューションの違いを説明する別の包括的な説明を見つけました:http://tinyurl.com/bqtyt3q