我剛開始查看窗口區域,並試圖創建一個橢圓窗口,可以通過拖動客戶區來移動。不幸的是,當我拖動窗口時,窗口從橢圓來回閃爍到正常窗口(好像我從未稱呼過SetWindowRgn
),並且反覆快速地返回。我如何正確移動一個區域的窗口?
我在MSDN上讀到我必須調用SetWindowRgn(nullptr);
,然後移動窗口,然後重置我在代碼中已完成的區域。我通過撥SetWindowPos
與SWP_NOZORDER
,SWP_NOSIZE
和SWP_NOREDRAW
移動窗口,我試過在所有的SWP_NOSENDCHANGING
,和SWP_NOCOPYBITS
上加入,都沒有用。
這是我的窗口程序,重點是WM_MOUSEMOVE
。我知道如果我在窗口之外釋放按鈕,它將不起作用;我打算在這個工作後處理這個問題。我也沒有檢查錯誤。但是很明顯,這些調用確實有效,因爲窗口會隨着我拖動而移動。
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
static bool moving{};
switch (msg) {
case WM_DESTROY: {
PostQuitMessage(0);
return 0;
}
case WM_LBUTTONDOWN: {
moving = true;
return 0;
}
case WM_LBUTTONUP: {
moving = false;
return 0;
}
case WM_MOUSEMOVE: {
static POINT old{0, 0};
if (moving) {
RECT r;
GetWindowRect(hwnd, &r);
int x = GET_X_LPARAM(lParam);
int y = GET_Y_LPARAM(lParam);
RECT newPos;
newPos.left = r.left + x - old.x;
newPos.top = r.top + y - old.y;
SetWindowRgn(hwnd, nullptr, FALSE);
SetWindowPos(hwnd, nullptr, newPos.left, newPos.top, 0, 0,
SWP_NOZORDER | SWP_NOSIZE | SWP_NOREDRAW
);
SetWindowRgn(hwnd, CreateEllipticRgn(200, 200, 600, 400), FALSE);
}
old.x = GET_X_LPARAM(lParam);
old.y = GET_Y_LPARAM(lParam);
return 0;
}
}
return DefWindowProc(hwnd, msg, wParam, lParam);
}
我也試過在WM_MOUSEMOVE
末,這並不能改變什麼叫ValidateRgn(hwnd, nullptr);
。另外,我試圖在打電話的條件下返回0,如果設置moving
是爲了查看它是否只是其他一些正在發送的消息而已,它會導致窗口什麼也不做,拖累。然後,我將這個條件應用於WM_PAINT
和WM_ERASEBKGND
處理程序,但是在拖動時會導致相同的閃爍問題。
爲了更容易地測試,這裏的full code(只是簡單的窗口創建等)。我是否正確地移動窗戶?有一些信息或我應該處理的東西,但不?這發生在Window 7 Ultimate N.
工作出色,謝謝! – chris 2013-04-04 01:16:31