Я только начал изучать области окна, и я пытаюсь создать эллиптическое окно, которое я могу перемещать, перетаскивая область клиента. К сожалению, когда я перетаскиваю окно, окно мигает от эллипса до нормального окна (как будто я никогда не звонил SetWindowRgn
) и обратно, многократно и быстро.Как правильно перемещать окно с областью?
Я прочитал в MSDN, что мне нужно позвонить SetWindowRgn(nullptr);
, а затем переместить окно, а затем сбросить регион, который я уже сделал в своем коде. Я перемещаю окно, вызывая SetWindowPos
с SWP_NOZORDER
, SWP_NOSIZE
и SWP_NOREDRAW
, и я попытался добавить все 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
в состоянии, которое просто возвращает 0, если установлено moving
, чтобы узнать, было ли это просто какое-то другое сообщение, которое отправлялось с ним, но это привело к тому, что окно ничего не делало, когда тащили. Затем я применил это условие к обработчикам WM_PAINT
и WM_ERASEBKGND
, но это привело к той же проблеме мерцания при перетаскивании.
Чтобы легче было протестировать его, вот full code (просто рудиментарное создание окна и т. Д.). Я собираюсь переместить окно правильно? Есть ли какое-то сообщение или что-то, что я должен обработать, но не так ли? Это происходит на Window 7 Ultimate N.
Это работает блестяще, спасибо! – chris