Jump to content
  • Advertisement
Sign in to follow this  
transformation

win32 - when I change the window style, the old style still shows on the background.

This topic is 4764 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I have a normal style window - window with title bar, and frame (the WS_OVERLAPPEDWINDOW style). When I change the style to WS_POPUPWINDOW the window becomes smaller because I have to keep the client area the same, and without the title bar the window decreases in size. The problem is that a horizontal and vertical bar (of whatever the client area color was) remains on the right and bottom side of the newly styled window. I've tried UpdateWindow, I've tried calling SetWindowPos with WSP_FRAMECHANGED in the options paremeter (that's what you're supposed to do right?), but still no good. Can anyone help? Thanks.

Share this post


Link to post
Share on other sites
Advertisement
ok, I've found a hack that works, but I'm still not happy with it. What I was doing before was this:


function setFramed( bool use_frame )
{
if( window_has_frame )
change style to popup
else
change style to overlapped.

SetWindowPos( hwnd, x, y, w, h, SWP_FRAMECHANGED )
UpdateWindow( hwnd );
ShowWindow ( hwnd, SW_SHOW );
}


That would cause problems when switching from a framed window to a non-framed window. And now for the hack which I found while randomly trying different things. What the hack does is first if moves the window to the bottom of the z-order, then moves it back. It's stupid, but it works.

Here's the exact code, does anyone have an "official fix" ?

bool cWindow::setFramed( bool frame )
{
if( frame == m_framed )
return false;

m_framed = frame;

DWORD dwOptions = 0;//SWP_FRAMECHANGED;// | SWP_NOSIZE | SWP_NOMOVE;

if( m_framed == false ) {
SetWindowLong( m_hwnd, GWL_STYLE, WS_POPUPWINDOW );
}
else {
SetWindowLong( m_hwnd, GWL_STYLE, WS_TILEDWINDOW );
}

// This is nasty, but if you don't do this then when you change from a framed
// window to a non framed then the framed window leaves its shit all over the
// place.
s2dDim<int> d = adjustWinDim( m_dim );
UpdateWindow( m_hwnd );
ShowWindow( m_hwnd, SW_SHOW );
SetWindowPos( m_hwnd, HWND_BOTTOM, m_xpos, m_ypos, d.width, d.height, dwOptions );
SetWindowPos( m_hwnd, HWND_TOP, m_xpos, m_ypos, d.width, d.height, dwOptions );

return true;
}

Share this post


Link to post
Share on other sites
MSDN states -->

Certain window data is cached, so changes you make using SetWindowLong will not take effect until you call the SetWindowPos function.


bool cWindow::setFramed( bool frame )
{
if( frame == m_framed )
return false;

m_framed = frame;
( !m_framed )
? SetWindowLong( m_hwnd, GWL_STYLE, WS_POPUPWINDOW | WS_VISIBLE )
: SetWindowLong( m_hwnd, GWL_STYLE, WS_TILEDWINDOW | WS_VISIBLE );

s2dDim<int> d = adjustWinDim( m_dim );
SetWindowPos( m_hwnd, HWND_TOP, m_xpos, m_ypos, d.width, d.height, SWP_FRAMECHANGED );

return true;
}

Share this post


Link to post
Share on other sites
Quote:
Certain window data is cached, so changes you make using SetWindowLong will not take effect until you call the SetWindowPos function.


Which he already mentions doing in the original post.

transformation: When calling SetWindowPos, you don't have to specify the width and location of the window, simply do:

SetWindowPos (m_hwnd, NULL, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED);


Also, instead of UpdateWindow, try calling RedrawWindow:

RedrawWindow (m_hwnd, NULL, NULL, RDW_INVALIDATE | RDW_FRAME | RDW_UPDATENOW);

Share this post


Link to post
Share on other sites
Kippesoep:

I've tried that before, problem with that method is that the non-framed window becomes the size of the window with the frame, and that makes the client area bigger (becasue there's no frame). And this will mean I'll have to invalidate all graphics surfaces and what not and recrete them because of the unnecessary size change in the client area - which implies change in the back buffer. The other problem is that even though you specify NOSIZE, the window will still get a WM_NCSIZE (Or somthing similar) message telling it to recalculate the size.

I've also tried handling that message and messing around with that completley alien structure that you get in the WPARAM parameter when you get that message, but no good there. I think that's probably where the fix can happen.

RedrawWindow didn't work either :(

Thanks for trying though.

Share this post


Link to post
Share on other sites
I take it you're trying to change your window for switching between windowed and fullscreen at runtime, or something similar.

I do the following:

// Figure out the window styles.
DWORD style = WS_SYSMENU | WS_MINIMIZEBOX | WS_CLIPSIBLINGS;
DWORD exStyle = 0;
if (config.fullscreen)
{
style |= WS_POPUP;
exStyle |= WS_EX_TOPMOST;
}
else
{
style |= WS_OVERLAPPED | WS_CAPTION;
exStyle |= 0;
}

// Calculate the window rect.
RECT rect;
rect.left = (GetSystemMetrics(SM_CXSCREEN) - config.width) / 2;
rect.top = (GetSystemMetrics(SM_CYSCREEN) - config.height) / 2;
rect.right = rect.left + config.width;
rect.bottom = rect.top + config.height;
AdjustWindowRect(&rect, style, FALSE);

// Update the window.
SetWindowLong(window, GWL_EXSTYLE, exStyle);
SetWindowLong(window, GWL_STYLE, style);
SetWindowPos(window, 0,
0, 0, 0, 0,
SWP_NOMOVE | SWP_NOSIZE | SWP_FRAMECHANGED);
ShowWindow(window, SW_SHOW);
MoveWindow(window, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, TRUE);
UpdateWindow(GetDesktopWindow());




It seems to work, although I can't promise it's the best way. Note that I use AdjustWindowRect to keep the same client area size in windowed and fullscreen modes.

Hope this helps,

Pete

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!