Thread: Changing windows Styles on the Fly.

  1. #1
    Codebot
    Join Date
    Jun 2004
    Location
    Toronto
    Posts
    195

    Changing windows Styles on the Fly.

    Hi, I am writing an OpenGL based application in which I need to change the styles of the window when it goes from full screen to windowed mode. The problem is that when I change the style, the window does not accept any type of move or resize input from the user. When I hover my mouse over the border, the cursor should change to a resize cursor, rather it doesn't and just passes the input of a click into my Game. The two styles I have are shown in the code below:

    Code:
    	if (windowMode)
    	{
    		// Create a bordered window
    		SetWindowLong(windowHwnd, GWL_STYLE, GetWindowLong(windowHwnd, GWL_STYLE) | WS_OVERLAPPEDWINDOW);
    
    		// Refresh it by repainting
    		winWidth -= 100;
    		winHeight -= 100;
    		SetWindowPos(windowHwnd, 0, 50, 50, winWidth, winHeight, SWP_SHOWWINDOW);
    
    	}else{
    
    		// New Values for the Window size
    		SystemParametersInfo(SPI_GETWORKAREA, 0, &size, 0);
    		winWidth = size.right;
    		winHeight = size.bottom;
    
    		// Restore it back to Users area size, without borders
    		SetWindowLong(windowHwnd, GWL_STYLE, WS_POPUP | WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_SYSMENU);
    		SetWindowPos(windowHwnd, 0, 0, 0, winWidth, winHeight, SWP_SHOWWINDOW);
    	}
    The top part of the If statement changes the window into a regular Window with a border and title bar, and the bottom portion makes the window borderless. So basically once I turn the window's borders on, doesn't matter how many times I click on the title bar or any of the buttons (close, minimize, maximize), they do not work and just pass the clicks into my game, as if the window was still borderless.
    Founder and avid member of the Internationsl Typo Associateion

  2. #2
    erstwhile
    Join Date
    Jan 2002
    Posts
    2,227
    You need to apply the SWP_FRAMECHANGED flag, too, when you call SetWindowPos.
    CProgramming FAQ
    Caution: this person may be a carrier of the misinformation virus.

  3. #3
    Codebot
    Join Date
    Jun 2004
    Location
    Toronto
    Posts
    195
    Added the flag, it didn't work. I have a context menu that pops up on right click and once I pop it up, everything starts working as it should. And its only the one time that you have to do it. After the context menu goes up, you can resize and grab the title bar to move the window.
    Founder and avid member of the Internationsl Typo Associateion

  4. #4
    erstwhile
    Join Date
    Jan 2002
    Posts
    2,227
    Try UpdateWindow immediately after the SetWindowPos call.

    For something like this I'd normally:
    • hide the window
    • apply style changes
    • SetWindowPos (SWP_FRAMECHANGED|SWP_SHOWWINDOW) which shows the window again, too.
    • UpdateWindow (for good measure)

    This reduces the sometimes annoying flicker when switching display settings and should render each window 'style' properly.

    You may want to try SetForegroundWindow or SetFocus, too, if you're still having problems with mouse/keyboard input.
    CProgramming FAQ
    Caution: this person may be a carrier of the misinformation virus.

  5. #5
    Codebot
    Join Date
    Jun 2004
    Location
    Toronto
    Posts
    195
    Still is not doing it. I wonder what is inside the Context Menu code that is forcing our window to act normally. Possibly a Paint Message thats repainting the window?? Here is what I have tried:

    Code:
    		ShowWindow(windowHwnd, SW_HIDE);
    
    		// Create a bordered window
    		SetWindowLong(windowHwnd, GWL_STYLE, GetWindowLong(windowHwnd, GWL_STYLE) | WS_OVERLAPPEDWINDOW);
    
    		// Refresh it by repainting
    		winWidth -= 100;
    		winHeight -= 100;
    		SetWindowPos(windowHwnd, 0, 50, 50, winWidth, winHeight, SWP_FRAMECHANGED | SWP_SHOWWINDOW);
    		UpdateWindow(windowHwnd);
    		SetFocus(windowHwnd);
    Founder and avid member of the Internationsl Typo Associateion

  6. #6
    erstwhile
    Join Date
    Jan 2002
    Posts
    2,227
    Try breaking down the actions of SetWindowPos into unique, single action calls to see if you can identify where it's failing - it might be an idea as a first test to check the return value to ensure it's non-zero. While you're at it, make sure that the SetWindowLong/SetWindowLongPtr calls are changing the style bits as you intend. Alternatively, just hide/show(ShowWindow) the window separately from the other SetWindowPos flagged changes.

    For example:
    Quote Originally Posted by SetWindowPos, remarks
    If the SWP_SHOWWINDOW or SWP_HIDEWINDOW flag is set, the window cannot be moved or sized.

    If you have changed certain window data using SetWindowLong, you must call SetWindowPos for the changes to take effect. Use the following combination for uFlags: SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED.
    CProgramming FAQ
    Caution: this person may be a carrier of the misinformation virus.

  7. #7
    Codebot
    Join Date
    Jun 2004
    Location
    Toronto
    Posts
    195
    I have tested extensively and every style change that I apply succeeds. I have also tried to force windows messages to my program using SendMessage(). I have tried WM_ACTIVE, WM_WINDOWPOSCHANGED, etc. But no luck. Any other suggestions?
    Founder and avid member of the Internationsl Typo Associateion

  8. #8
    Codebot
    Join Date
    Jun 2004
    Location
    Toronto
    Posts
    195
    I have also noticed that when I switch to windowed mode (without WS_POPUP), the windows and desktop that is underneath the window does not get redrawn. As if the environment does not register that the window has changed and does not initiate a repaint to the windows that are underneath my window.

    Does this shed any light on my problem?
    Founder and avid member of the Internationsl Typo Associateion

  9. #9
    erstwhile
    Join Date
    Jan 2002
    Posts
    2,227
    I wouldn't have thought so - that's solved by InvalidateRect(0,0,1); to refresh the desktop.

    It might be an idea to post a minimal, compilable example that replicates the problem for us to try out.
    CProgramming FAQ
    Caution: this person may be a carrier of the misinformation virus.

  10. #10
    Codebot
    Join Date
    Jun 2004
    Location
    Toronto
    Posts
    195
    Turns out that the problem was with some of the code I had when handling WM_ACTIVATE. Check it out:

    Code:
    			case WM_ACTIVATE:
    				winActive = (LOWORD(wParam) != WA_INACTIVE);
    				winMinimized = ((BOOL) HIWORD(wParam) != 0);
    
    				if (winActive)
    				{
    					SetCapture(windowHwnd);
    				}else{
    					ReleaseCapture();
    				}
    The SetCapture and ReleaseCapture are the culprits. Do I have them in the wrong order? Is there something that I dont know about these two functions that can cause a window's border to be unavailable but still drawn?

    Thanks all for the help.
    Founder and avid member of the Internationsl Typo Associateion

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Virtual keys
    By Arkanos in forum Windows Programming
    Replies: 4
    Last Post: 12-12-2005, 10:00 AM
  2. Windows XP visual styles in C#?
    By Shag in forum C# Programming
    Replies: 3
    Last Post: 03-26-2003, 06:25 AM
  3. How come this only works in Windows nt/2000?
    By Unregistered in forum Windows Programming
    Replies: 1
    Last Post: 08-30-2002, 06:54 PM
  4. OpenGL and Windows
    By sean345 in forum Game Programming
    Replies: 5
    Last Post: 06-24-2002, 10:14 PM
  5. shutting down windows
    By DavidP in forum A Brief History of Cprogramming.com
    Replies: 3
    Last Post: 01-02-2002, 12:28 PM