I'm writing a Win7 desktop app and want to have it seamlessly transition from windowed to windowed-fullscreen (and vice-versa), and have mostly accomplished this by calling SetWindowLongPtr to update its style immediately followed by MoveWindow to update its size and position. The problem is that the window flashes for one frame to show its style updated, but the new size and position are not shown. The next frame everything looks correct but I'm trying to avoid this single-frame artifact.
I've tried reversing the order in which I call the APIs but it just changes what the artifact looks like. I've also tried hiding the window, calling the APIs, and then showing the window, but this just causes the window to disappear for the one frame.
I know that one option is to create a new window with the desired properties then destroy the old one, but I wanted to find a less expensive alternative.
So is there any way to call these APIs and have them be visually reflected atomically? As a bonus, it'd be nice to also have the multiple resulting WM_SIZE messages coalesced into a single event, but I can manage that myself in the message handler.
Doing this sort of thing reliably is difficult in Windows, particularly since Vista as the DWM can complicate things. It's often a matter of trial and error until you find a solution that works for you.
SetWindowPos has an
SWP_NOREDRAW flag that prevents the window from being redrawn in response to the call. So you could try changing the position first, then updating the styles, and finally a third call to redraw the window in its new location. For example,
SetWindowPos(hWnd, 0, x, y, w, h, SWP_NOREDRAW | SWP_NOZORDER); SetWindowLongPtr(hWnd, GWL_STYLE, dwNewStyles); RedrawWindow(hWnd, 0, 0, RDW_INVALIDATE | RDW_FRAME);
So this should work. Perhaps try using SetWindowPos instead of MoveWindow.
Are you doing anything interesting in your window proc when you get the events that are caused by these calls? In particular, are you "fixing" the size or anything like that?
WM_SETREDRAW; use it to disable redraw, change the window styles, and then call
RedrawWindow(hWnd, NULL, NULL, RDW_ERASE | RDW_FRAME | RDW_INVALIDATE | RDW_ALLCHILDREN) to display them atomically.
查看WM_SETREDRAW;用它來禁用重繪,更改窗口樣式,然后調用RedrawWindow(hWnd,NULL,NULL,RDW_ERASE | RDW_FRAME | RDW_INVALIDATE | RDW_ALLCHILDREN)以原子方式顯示它們。
What do you mean by "windowed-fullscreen"? Is it the same as maximized?
(hwnd, SW_MAXIMIZE) ?