Thread: Getting client coordinates after resizing

  1. #1
    Registered User
    Join Date
    Apr 2008
    Posts
    610

    Getting client coordinates after resizing

    Code:
    	case WM_SIZE:
    		{
    			cxClient = LOWORD(lParam);
    			cyClient = HIWORD(lParam);
    
    			return 0;
    		}
    gives me width and height... I need to get coordinates rather (x.top, y.top, x.bottom, y.bottom)... Reason i need to use these to FillRect() the client window's background color every time the window is resize... My background is black because i use back-buffer (or memory DC), not sure why is that but yeah, that's the case i have. BTW what's the use of MoveWindow()? my thinking is whether or not i call MoveWindow, dragging or resizing the window will move/respond anyway!
    Last edited by csonx_p; 06-06-2008 at 02:19 AM.

  2. #2
    Reverse Engineer maxorator's Avatar
    Join Date
    Aug 2005
    Location
    Estonia
    Posts
    2,318
    Code:
    RECT rcClient;
    GetClientRect(hwnd,&rcClient);
    As easy as that.
    "The Internet treats censorship as damage and routes around it." - John Gilmore

  3. #3
    Registered User
    Join Date
    Apr 2008
    Posts
    610
    Quote Originally Posted by maxorator View Post
    Code:
    RECT rcClient;
    GetClientRect(hwnd,&rcClient);
    As easy as that.
    Mhh.. tried this already didn't work... Well then i guess my prob is not getting coordinates, is where i FillRect....

    Here was my first attempt...
    Code:
    case WM_SIZE:
    {
    	GetClientRect(hwnd, &ctRect);
    	return 0;
    }
    
    case WM_PAINT:
    {
    	hdc = BeginPaint(hwnd, &pntS);
    
    	// Paint screen background grey 
    	hBrush = CreateSolidBrush( RGB(0xD3, 0xD3, 0xD3) );
    	FillRect(hdc, &ctRect, hBrush);
    	DeleteObject(hBrush);
    
    	BitBlt(hdc, 0, 0, cScreenX, cScreenY, memDC, 0, 0, SRCCOPY);	
    
    	EndPaint(hwnd, &pntS);
    
    return 0;
    }
    note that i have two device contexts in red (hdc & memDC). Problem, if i FillRect on memDC
    Code:
    	FillRect(memDC, &ctRect, hBrush);
    , then the background is painted once with the original size recalling that repaint does not update memDC, just copies whatever was on it by using bitblt (to avoid flickering)... So repainting with new sizes forces the color background to cover the memDC rectangle but not the new resized rectangle of client area... So i end up with a portion being colored, the rest (new area) becomes black...

  4. #4
    Reverse Engineer maxorator's Avatar
    Join Date
    Aug 2005
    Location
    Estonia
    Posts
    2,318
    Why are you using double buffering for a simple background? You don't even need to handle WM_SIZE actually.
    Code:
    case WM_PAINT:
        hdc = BeginPaint(hwnd, &pntS);
        hBrush = CreateSolidBrush( RGB(0xD3, 0xD3, 0xD3) );
        GetClientRect(hwnd, &ctRect);
        FillRect(hdc, &ctRect, hBrush);
        DeleteObject(hBrush);
        EndPaint(hwnd, &pntS);
        break;
    "The Internet treats censorship as damage and routes around it." - John Gilmore

  5. #5
    Registered User
    Join Date
    Apr 2008
    Posts
    610
    Quote Originally Posted by maxorator View Post
    Why are you using double buffering for a simple background?
    Sho! this comes a long way (here), which i doubt you want to entertain now...

    Code:
    case WM_PAINT:
        hdc = BeginPaint(hwnd, &pntS);
        hBrush = CreateSolidBrush( RGB(0xD3, 0xD3, 0xD3) );
        GetClientRect(hwnd, &ctRect);
        FillRect(hdc, &ctRect, hBrush);
        DeleteObject(hBrush);
        EndPaint(hwnd, &pntS);
        break;
    Calling GetClientRect within WM_PAINT causes flickers maybe has to do with timer...
    Interesting thing is if i move GetClientRect to WM_SIZE and FillRect to WM_CREATE where i create and render to memDC, background remains black.. But then moving GetClientRect to WM_CREATE works, but then am back to my initial problem... (resizing)

    /me sense yet another long thread

  6. #6
    Registered User
    Join Date
    Apr 2008
    Posts
    610
    GetWindowRect() is giving me these coordinates [left: 66, top:87, right:1026, bottom:806]...

    this is how my window is created
    Code:
    	hwnd=CreateWindowEx(WS_EX_OVERLAPPEDWINDOW,			
    		classname,			
    		_T("Radar FS Range Calculator"),			
    		WS_OVERLAPPEDWINDOW,		
    		CW_USEDEFAULT,
    		CW_USEDEFAULT,
    		CW_USEDEFAULT,
    		CW_USEDEFAULT,
    		NULL,
    		NULL,
    		hInst,					
    		NULL);
    with
    Code:
    ShowWindow(hwnd,SW_SHOWDEFAULT);
    What's the default size of the window & what are these values references to?

  7. #7
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    GetWindowRect retrieves the coordinates of your window relative to the upper-left point of your screen.
    So...
    top is screen.size.top - window.pos.top
    left is screen.size.left - window.pos.left
    right is screen.size.right - window.pos.right
    bottom is screen.size.bottom - window.pos.bottom
    (Pseudo. Hope that makes sense.)
    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.

  8. #8
    Registered User
    Join Date
    Apr 2008
    Posts
    610
    Quote Originally Posted by Elysia View Post
    GetWindowRect retrieves the coordinates of your window relative to the upper-left point of your screen.
    So...
    top is screen.size.top - window.pos.top
    left is screen.size.left - window.pos.left
    right is screen.size.right - window.pos.right
    bottom is screen.size.bottom - window.pos.bottom
    (Pseudo. Hope that makes sense.)
    does thnx.. though When i called FillRect with those coordinates, the filled aread was even smaller than client area (more like it referenced from client area than PC screen).. found that strange

  9. #9
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Note that FillRect takes coordinates relative to the DC (I believe), not to the screen!
    So the top-left pixel is 0 to FillRect. You must learn to differentiate between these types.
    Use GetClientRect to get coordinates relative to your window.
    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.

  10. #10
    train spotter
    Join Date
    Aug 2001
    Location
    near a computer
    Posts
    3,868
    Part of the issue is that the window has changed size and the memDC may now be too small/large.

    You need to resize the DC, unless you created it the size of the full screen.

    This is (similar) to how I do this.....

    Code:
    case WM_SIZE:
    {
    	GetClientRect(hwnd, &ctRect);//I use the lParam and fill in a RECT
    	//add check for wParam==SIZE_MINIMISED ie has a size
    
    	DrawScreen(hwnd,ctRect):
    	return 0;
    }
    
    //a fast PAINT does nothing but a single BitBlt(), IMO it should NEVER do anything else
    case WM_PAINT:
    {
    	hdc = BeginPaint(hwnd, &pntS);
    
    	BitBlt(hdc, pntS.rcPaint.left, pntS.rcPaint.top, pntS.rcPaint.right-pntS.rcPaint.left, pntS.rcPaint.bottom-pntS.rcPaint.top, memDC, pntS.rcPaint.left, pntS.rcPaint.top, SRCCOPY);	
    
    	EndPaint(hwnd, &pntS);
    
    return 0;
    }
    
    void DrawScreen(HWND hwnd,RECT ctRect)
    {
    
    	//TODO 
    	//add check of OLD size to NEW size
    	//if the new size is not the same as the old size
    	//clearup the current HDC and BMP
    	//create a new one the right size
    	if(rectOLD!=ctRect)//NOTE: this is a placeholder, will not work
    		CreateBuffer(hwnd,ctRect);
    
    	// Paint screen background grey 
    	hBrush = CreateSolidBrush( RGB(0xD3, 0xD3, 0xD3) );
    	FillRect(memDC, &ctRect, hBrush);
    	DeleteObject(hBrush);
    	
    	//call for paint
    	InvalidateRect(hwnd,ctRect);
    	UpdateWindow(hwnd);
    	return;
    }
    
    //other methods, also used in WM_CREATE and WM_DESTROY
    
    void CreateBuffer(HWND , RECT);
    {
    	if(memDC)
    		KillBuffers();
    
    	//TODO 
    	//create new HDC and BMP based on HWND and RECT
    	//remember to catch the original 1x1 monochrom bmp created in the HDC
    	//as BMPs are not 100% of deleting if still selected into a DC
    
    }
    void KillBuffers()
    {
    	//check that DC has been created
    	if(!memDC)
    		return;
    
    	SelectObject(memDC, hOriginalBMP);
    	DeleteObject(hNewBMP);
    	DeleteDC(memDC);
    	memDC=NULL;//so our error check works
    }
    Last edited by novacain; 06-08-2008 at 07:58 PM.
    "Man alone suffers so excruciatingly in the world that he was compelled to invent laughter."
    Friedrich Nietzsche

    "I spent a lot of my money on booze, birds and fast cars......the rest I squandered."
    George Best

    "If you are going through hell....keep going."
    Winston Churchill

  11. #11
    Registered User
    Join Date
    Apr 2008
    Posts
    610
    Quote Originally Posted by novacain View Post
    Part of the issue is that the window has changed size and the memDC may now be too small/large.

    You need to resize the DC, unless you created it the size of the full screen.

    This is (similar) to how I do this.....

    Code:
    case WM_SIZE:
    {
    	GetClientRect(hwnd, &ctRect);//I use the lParam and fill in a RECT
    	//add check for wParam==SIZE_MINIMISED ie has a size
    
    	DrawScreen(hwnd,ctRect):
    	return 0;
    }
    
    //a fast PAINT does nothing but a single BitBlt(), IMO it should NEVER do anything else
    case WM_PAINT:
    {
    	hdc = BeginPaint(hwnd, &pntS);
    
    	BitBlt(hdc, pntS.rcPaint.left, pntS.rcPaint.top, pntS.rcPaint.right-pntS.rcPaint.left, pntS.rcPaint.bottom-pntS.rcPaint.top, memDC, pntS.rcPaint.left, pntS.rcPaint.top, SRCCOPY);	
    
    	EndPaint(hwnd, &pntS);
    
    return 0;
    }
    
    void DrawScreen(HWND hwnd,RECT ctRect)
    {
    
    	//TODO 
    	//add check of OLD size to NEW size
    	//if the new size is not the same as the old size
    	//clearup the current HDC and BMP
    	//create a new one the right size
    	if(rectOLD!=ctRect)//NOTE: this is a placeholder, will not work
    		CreateBuffer(hwnd,ctRect);
    
    	// Paint screen background grey 
    	hBrush = CreateSolidBrush( RGB(0xD3, 0xD3, 0xD3) );
    	FillRect(memDC, &ctRect, hBrush);
    	DeleteObject(hBrush);
    	
    	//call for paint
    	InvalidateRect(hwnd,ctRect);
    	UpdateWindow(hwnd);
    	return;
    }
    
    //other methods, also used in WM_CREATE and WM_DESTROY
    
    void CreateBuffer(HWND , RECT);
    {
    	if(memDC)
    		KillBuffers();
    
    	//TODO 
    	//create new HDC and BMP based on HWND and RECT
    	//remember to catch the original 1x1 monochrom bmp created in the HDC
    	//as BMPs are not 100% of deleting if still selected into a DC
    
    }
    void KillBuffers()
    {
    	//check that DC has been created
    	if(!memDC)
    		return;
    
    	SelectObject(memDC, hOriginalBMP);
    	DeleteObject(hNewBMP);
    	DeleteDC(memDC);
    	memDC=NULL;//so our error check works
    }
    opted for function PatBlt() instead, fills the entire background with no probs...

  12. #12
    train spotter
    Join Date
    Aug 2001
    Location
    near a computer
    Posts
    3,868
    For a simple colour the background black that will work. It will not work well for any complex drawing.


    This is what you were originally looking for.

    Code:
    case WM_SIZE:
    
    RECT DrawRect;
    
    DrawRect.left=0;
    DrawRect.top=0;
    DrawRect.right=LOWORD(lParam);
    DrawRect.bottom=HIWORD(lParam);
    As I pointed out, the BMP may not be big enough, depending on the size you created it.
    "Man alone suffers so excruciatingly in the world that he was compelled to invent laughter."
    Friedrich Nietzsche

    "I spent a lot of my money on booze, birds and fast cars......the rest I squandered."
    George Best

    "If you are going through hell....keep going."
    Winston Churchill

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. How to Send Mac Address From Client to Server
    By Lieyza197 in forum C Programming
    Replies: 2
    Last Post: 05-27-2009, 09:58 AM
  2. Socket Programming Problem!!!!
    By bobthebullet990 in forum Networking/Device Communication
    Replies: 2
    Last Post: 02-21-2008, 07:36 PM
  3. WSAAsyncSelect Socket Model. She's Not Hot.
    By Tonto in forum Networking/Device Communication
    Replies: 2
    Last Post: 03-24-2007, 08:34 AM
  4. Converting from Screen to World Coordinates
    By DavidP in forum Game Programming
    Replies: 9
    Last Post: 05-11-2004, 12:51 PM
  5. Help resizing client area
    By Unregistered in forum Windows Programming
    Replies: 4
    Last Post: 07-07-2002, 08:33 PM