Thread: Uniform resize of a window

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

    Uniform resize of a window

    Greetings,

    I was wondering if anyone here knew how to forcefully constrict a window to a certain aspect ratio. For example, if a user tries to horizontally scale a window, the vertical would compensate and resize (in real time) so that the aspect ratio is unchanged. I know some games do this when in windowed mode, for example World of Warcraft.

    I did a bit of research and Here are my findings (maybe you guys can offer other suggestions). First, is a hook to my own window. It would intercept the WM_SIZE event and modify the RECT that governs the window size. It would then uniformly adjust the size. This method is a bit ugly! Secondly, is to use the WM_NCHITTEST message. I would then capture the mouse movements and manually send them back into the Message queue so that WM_SIZE would be handled later on. Its cleaner then the previous way but still a bit nutty.

    Any suggestions??
    Founder and avid member of the Internationsl Typo Associateion

  2. #2
    Malum in se abachler's Avatar
    Join Date
    Apr 2007
    Posts
    3,195
    SetWindowPos()

    Intercept WM_SIZE and when wParam == SIZE_RESTORED call GetWindowRect() for the new size, then fix it up for the proper ratio and call SetWindowPos() to change it to the right size.

    If you want the client area ( the part you draw in excluding the menus etc,) then call GetClientRect() and then AdjustWindowRect() then SetWindowPos()
    Last edited by abachler; 02-13-2008 at 09:24 AM.

  3. #3
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    You can just watch for WM_SIZE messages and call SetWindowPos I think.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  4. #4
    Codebot
    Join Date
    Jun 2004
    Location
    Toronto
    Posts
    195
    The problem with WM_SIZE is its called AFTER the window has been resized. It is an event that is fired when the user completes one tick of the resize. And its called per Tick. So the problem is that when the user starts resizing the window using the very corner of the window as its handle, the window will resize as its supposed to and once it does, it will notify my program with a WM_SIZE event.

    Hence WM_SIZE is not what I'm looking for.
    Founder and avid member of the Internationsl Typo Associateion

  5. #5
    Malum in se abachler's Avatar
    Join Date
    Apr 2007
    Posts
    3,195
    When your program recieves WM_SIZE and then calls those functions it will resize the window 'again' to the correct size. If this looks sloppy, then try changing the position of the mouse as well.

    You can also try WM_SIZING
    Last edited by abachler; 02-13-2008 at 10:36 AM.

  6. #6
    Codebot
    Join Date
    Jun 2004
    Location
    Toronto
    Posts
    195
    WM_SIZE is reactive, WM_SIZING is proactive so I went with the latter. But I got all working, thanks to all! Here is my code, and it works perfectly:

    Code:
    LRESULT Window::onSizing(WPARAM wParam, LPARAM lParam)
    {
    	RECT sz;
    	intw, h;
    
    	// If the aspect is locked, resize the window equally
    	if (lockAspect)
    	{
    		// Copy over the new size that was determined by windows
    		memcpy(&sz, (const Void *) lParam, sizeof(RECT));
    
    		// Calculate the width and height of the window
    		w = sz.right - sz.left;
    		h = sz.bottom - sz.top;
    
    		switch (wParam)
    		{
    			case WMSZ_LEFT:
    			case WMSZ_RIGHT:
    				// Modify the Heigh of the window
    				sz.bottom = LONG(w * aspectRatio) + sz.top;
    				break;
    
    			case WMSZ_TOP:
    			case WMSZ_BOTTOM:
    				// Modify the Width of the window
    				sz.right = LONG(h * (1 / aspectRatio)) + sz.left;
    				break;
    
    			case WMSZ_TOPRIGHT:
    			case WMSZ_TOPLEFT:
    			case WMSZ_BOTTOMRIGHT:
    			case WMSZ_BOTTOMLEFT:
    				// Adjust the width and height of the window to match aspect ratio
    				if (float(h) / float(w) > aspectRatio)
    				{
    					w = int(float(h) / aspectRatio);
    				}else{
    					h = int(float(w) * aspectRatio);
    				}
    
    				// Adjust Height
    				if (wParam == WMSZ_TOPLEFT || wParam == WMSZ_TOPRIGHT)
    				{
    					sz.top = sz.bottom - h;
    				}else{
    					sz.bottom = sz.top + h;
    				}
    
    				// Adjust Width
    				if (wParam == WMSZ_TOPLEFT || wParam == WMSZ_BOTTOMLEFT)
    				{
    					sz.left = sz.right - w;
    				}else{
    					sz.right = sz.left + w;
    				}
    				break;
    		}
    
    		// Copy back the size of the window
    		memcpy((Void *) lParam, &sz, sizeof(RECT));
    
    		return TRUE;
    	}
    
    	return FALSE;
    }
    Last edited by Mastadex; 02-13-2008 at 02:45 PM.
    Founder and avid member of the Internationsl Typo Associateion

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. C or C++
    By AcerN30 in forum Game Programming
    Replies: 41
    Last Post: 05-30-2008, 06:57 PM
  2. WM_CAPTION causing CreateWindowEx() to fail.
    By Necrofear in forum Windows Programming
    Replies: 8
    Last Post: 04-06-2007, 08:23 AM
  3. 6 measly errors
    By beene in forum Game Programming
    Replies: 11
    Last Post: 11-14-2006, 11:06 AM
  4. Linking OpenGL in Dev-C++
    By linkofazeroth in forum Game Programming
    Replies: 4
    Last Post: 09-13-2005, 10:17 AM
  5. OpenGL Window
    By Morgul in forum Game Programming
    Replies: 1
    Last Post: 05-15-2005, 12:34 PM