[英]I want to make a window dynamically move the elements. How exactly would I do that?
[英]How do I properly move a window with a region?
我剛剛開始研究窗口區域,我正在嘗試創建一個橢圓窗口,我可以通過拖動客戶區來移動它。 不幸的是,當我拖動窗口時,窗口從橢圓到正常窗口來回閃爍(好像我從未調用過SetWindowRgn
),然后反復快速地返回。
我在MSDN上讀到我必須調用SetWindowRgn(nullptr);
,然后移動窗口,然后重置我已經在我的代碼中完成的區域。 我通過調用帶有SWP_NOZORDER
, SWP_NOSIZE
和SWP_NOREDRAW
SetWindowPos
移動窗口,並且我嘗試添加所有SWP_NOSENDCHANGING
, SWP_DEFERERASE
和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);
}
我也試過調用ValidateRgn(hwnd, nullptr);
在WM_MOUSEMOVE
結束時,它不會改變任何東西。 同樣,我已經嘗試在一個條件下包裝DefWindowProc
調用,如果設置了moving
就返回0,以便查看是否只是發送的其他消息正在弄亂它,但是這導致窗口什么都不做拖累。 然后我將該條件應用於WM_PAINT
和WM_ERASEBKGND
處理程序,但是在拖動時會導致相同的閃爍問題。
為了更容易地測試它,這里是完整的代碼 (只是基本的窗口創建等)。 我要以正確的方式移動窗戶嗎? 是否有一些我應該處理的消息或事情,但不是嗎? 這種情況發生在Window 7 Ultimate N.
處理移動邏輯的一種更簡單的方法是處理WM_NCHITTEST
消息,返回HTCAPTION
。 這使得Windows可以為您處理所有移動邏輯。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.