win32 not to redraw while resize (openGL)+custom window skin+others

Started by
17 comments, last by szecs 14 years, 1 month ago
Quote:Original post by jwezorek
Quote:Original post by szecs
The original question is still a mystery for me. I mean how can the window be updated, when I don't call update/invalidaterect in the WM_SIZE handler?


Off the top of my head, I don't know. Are you concerned about the time that the redraws take or is is that they are creating a flicker? Because if it's a flicker you want to get rid of, you could double-buffer in your WM_PAINT.
After all, it's not a big issue.
Sometimes in takes about 100 ms to render the scene, and this produces a bit choppy feel, which is okay in the application (mostly things are redrawn on events), but a bit annoying with resizing/moving the window.
And I want to understand why causes this behavior, because I want to as much control of the redrawing as possible.
I use double buffering BTW.
Advertisement
Other question:
I want to maximize the window, but it will cover the taskbar, and I don't want that.
This is related to the window type: I have borderless/titlebar-less window:
CreateWindowEx(WS_EX_APPWINDOW|WS_EX_WINDOWEDGE,		WIND_CLASS_NAME,		WIND_CLASS_NAME,		WS_POPUP | WS_CLIPCHILDREN | WS_CLIPSIBLINGS,		...

I tried the followings:
if( maximize ){		SetWindowLong(	win_state.hWnd,GWL_STYLE,							WS_POPUP|WS_CLIPCHILDREN|WS_CLIPSIBLINGS|WS_THICKFRAME);	ShowWindow(win_state.hWnd,SW_MAXIMIZE);	SetWindowPos(win_state.hWnd,HWND_TOP,0,0,0,0,						SWP_NOMOVE|SWP_NOSIZE|SWP_NOZORDER|SWP_FRAMECHANGED);			}else{	SetWindowLong(	win_state.hWnd,GWL_STYLE,							WS_POPUP|WS_CLIPCHILDREN|WS_CLIPSIBLINGS);	ShowWindow(win_state.hWnd,SW_RESTORE);	SetWindowPos(win_state.hWnd,HWND_TOP,0,0,0,0,						SWP_NOMOVE|SWP_NOSIZE|SWP_NOZORDER|SWP_FRAMECHANGED);}

if( maximize ){		SetWindowLong(	win_state.hWnd,GWL_STYLE,							WS_POPUP|WS_CLIPCHILDREN|WS_CLIPSIBLINGS|WS_THICKFRAME);	SetWindowPos(win_state.hWnd,HWND_TOP,0,0,0,0,						SWP_NOMOVE|SWP_NOSIZE|SWP_NOZORDER|SWP_FRAMECHANGED);	ShowWindow(win_state.hWnd,SW_MAXIMIZE);			}else{	SetWindowLong(	win_state.hWnd,GWL_STYLE,							WS_POPUP|WS_CLIPCHILDREN|WS_CLIPSIBLINGS);	SetWindowPos(win_state.hWnd,HWND_TOP,0,0,0,0,						SWP_NOMOVE|SWP_NOSIZE|SWP_NOZORDER|SWP_FRAMECHANGED);	ShowWindow(win_state.hWnd,SW_RESTORE);}
Neither did the trick, plus the window can't be restored to its original size (without SetWindowLong/SetWindowPos the restoration is fine)

Is there a way around this, or I have to set (and keep track of) the window coordinates myself? And calculate the width of the taskbar somehow?

Thanks in advance!
You can prevent WM_PAINT from triggering if you call ValidateRect after you resize the window or do anything which would otherwise result in a WM_PAINT message being sent.

You can find out the size of various (non window) elements on the screen by using GetSystemMetrics. Also SystemParametersInfo.
Quote:Original post by szecs
The question is the opposite as usual: why is the window redrawing constantly when resized/moved?
I know this is the behavior most of us want, but I don't (for performance reasons).

To override full window drag (or size) you should detect the WM_ENTERSIZEMOVE / WM_EXITSIZEMOVE messages and set a flag that tells your WM_PAINT handler whether it should draw or not.
-Mike
Thanks, I'll look into it (since I use my own rezizing function (with MoveWindow) it will be tricky).
But I realized, that it's not a big issue after all. It's a game, so the user won't want to drag it or resize it too often, if so, the choppiness is acceptable.
And I tried resizing Visual Studio, well it's choppy as hell.
The maximize/minimize thing is still not solved.
I can use systemmetrics to maximize myself, but this way the small "transition animation" would be missed (when the titlebar transitions smoothly (interestingly, I have that titlebar in the "animation", even the window doesn't have one)).
And for some reason, SM_CYFULLSCREEN returns wrong value (smaller, than the possible y resolution).
It would be the best to get the ShowWindow(win_state.hWnd,SW_MAXIMIZE/SW_RESTORE) thing working.

Thanks.
Quote:And for some reason, SM_CYFULLSCREEN returns wrong value (smaller, than the possible y resolution).


It returns the height of the client area of a fullscreen window. Which the the screen resolution minus the taskbar size minus the window title bar and borders, etc.
Sometimes you need to take into account the menu bar size too
Someone solved this problem on another message board:

You call ShowWindow with the SW_SHOWMAXIMIZED flag, which causes the popup window to take up the entire screen. Then you catch the following message and adjust the size of the parameters:

case WM_GETMINMAXINFO:  	 	      {  	 	         RECT WorkArea; SystemParametersInfo( SPI_GETWORKAREA, 0, &WorkArea, 0 );  	 	         ( ( MINMAXINFO * )lParam )->ptMaxSize.x = ( WorkArea.right - WorkArea.left );  	         ( ( MINMAXINFO * )lParam )->ptMaxSize.y = ( WorkArea.bottom - WorkArea.top );  	         ( ( MINMAXINFO * )lParam )->ptMaxPosition.x = WorkArea.left;  	         ( ( MINMAXINFO * )lParam )->ptMaxPosition.y = WorkArea.top;  	 	         return 0;  	 	      }  


This code just prevents the task bar from being hidden, but Windows will treat the maximized size as whatever size you specify.
Thank you very much man!

I tried to catch WM_GETMINMAXINFO before, but with

minmax->ptMaxTrackSize.x = width;
minmax->ptMaxTrackSize.y = height;

which did nothing. So many parameters in so many combinations

Thanks again!

Only one thing left: layered window, I hope it can be used with openGL context.

This topic is closed to new replies.

Advertisement