Thread: Repainting over what's already there

  1. #1
    the Corvetter
    Join Date
    Sep 2001
    Posts
    1,584

    Repainting over what's already there

    In my knowledge, when the WM_PAINT message is received, the client area is invalid. Well, you see, I have this problem.

    I want to draw rects on the client over and over each other. But then, when the client is invalid, I won't get them back. Do you understand what I mean?

    I'll have one rectangle drawn. Than the user does something to draw another. But then won't the client be cleared and then painted all over again?

    --Garfield
    1978 Silver Anniversary Corvette

  2. #2
    of Zen Hall zen's Avatar
    Join Date
    Aug 2001
    Posts
    1,007
    You could try an handle the WM_ERASEBKGND message, but probably your best bet is to draw everything to a memory dc and the whenever your application receives a paint message, Blit this memory dc.
    zen

  3. #3
    the Corvetter
    Join Date
    Sep 2001
    Posts
    1,584
    How would I create this memory dc and then callback? And what do you mean,"Blit"?

    Thanks.

    --Garfield
    1978 Silver Anniversary Corvette

  4. #4
    of Zen Hall zen's Avatar
    Join Date
    Aug 2001
    Posts
    1,007
    If you're still going through Petzold, you might be getting a bit ahead of yourself. This wndproc will draw random rectangles to a memory dc and then the WM_PAINT Blits it -

    Code:
    LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
    {
    	PAINTSTRUCT ps;
    	HDC hdc;
    	static HDC memDC;
    	static HBITMAP hBitmap;
    	static int cScreenX,cScreenY;
    	HBRUSH hBrush;
    	
    
    	switch (message) 
    	{
    
    	case WM_CREATE:
    		srand((unsigned)time(NULL));
    		//Get Dimensions for Memory DC
    		cScreenX=GetSystemMetrics(SM_CXSCREEN);
    		cScreenY=GetSystemMetrics(SM_CYSCREEN);
    		hdc=GetDC(hWnd);
    		memDC = CreateCompatibleDC(hdc);
    		//Create Bitmap to 'select' into Memory DC
    		//to paint onto
    		hBitmap = CreateCompatibleBitmap(hdc,cScreenX,cScreenY);
    		SelectObject(memDC,hBitmap);
    		//Get brush used for main window, so that 
    		//Memory DC will match
    		hBrush = (HBRUSH)GetClassLong(hWnd,GCL_HBRBACKGROUND);
    		SelectObject(memDC,hBrush);
    		//Blit Brush to fill whole dimension of Memory DC
    		PatBlt(memDC,0,0,cScreenX,cScreenY,PATCOPY);
    		ReleaseDC(hWnd,hdc);
    
    	case WM_SIZE:
    		{
    			int a = rand()%250;
    			int b = rand()%250;
    			//Draw Rectangle to Memory DC
    			Rectangle(memDC,a,b,50,50);
    			InvalidateRect(hWnd,0,TRUE);
    		}
            return 0 ;
              
         case WM_PAINT:
    		hdc = BeginPaint (hWnd, &ps) ;
    		//Blit Memory DC to window
    		BitBlt(hdc,0,0,cScreenX,cScreenY,memDC,0,0,SRCCOPY);
    	    EndPaint (hWnd, &ps) ;
            return 0 ;
    
    	 
    	case WM_DESTROY:
    		DeleteDC(memDC);
    		DeleteObject(hBitmap);
    		PostQuitMessage(0);
    		break;
    	default:
    		return DefWindowProc(hWnd, message, wParam, lParam);
    	}
    	return 0;
    }
    zen

  5. #5
    the Corvetter
    Join Date
    Sep 2001
    Posts
    1,584
    Okay, I think I pretty much understand what you are doing, but you are right, that is ahead of me. I haven't learned the BitBlt function yet, but (from context), I understand what you mean.

    Thanks.

    --Garfield
    1978 Silver Anniversary Corvette

  6. #6
    Just one more wrong move. -KEN-'s Avatar
    Join Date
    Aug 2001
    Posts
    3,227
    Yeah, I was aoubt to post the same thing...

    it's basically a bitmap in memory, which you draw to as well as the normal hdc of your window, then you use BitBlt() to paint it to your window every time everything gets erased.

  7. #7
    the Corvetter
    Join Date
    Sep 2001
    Posts
    1,584
    Okay, so then you have this "memory" hdc, you write a rectangle to this hdc every time something (programmer provided) happens. Then you, in WM_PAINT, paint it (as a bitmap) to the client area without "losing" the previous rects. Am I correct?

    /*** Thanks ***/

    --Garfield
    1978 Silver Anniversary Corvette

  8. #8
    of Zen Hall zen's Avatar
    Join Date
    Aug 2001
    Posts
    1,007
    Yes, because this DC is kept around until your program finishes, it acts as a back buffer that you can draw to. Unless you do something to clear it all previous paints will remain (if you're painting rectangles that are filled with a solid brush then you'll probably make portions of the inner rectangles dissapear).

    This also becomes useful if your application is minimised. If you were drawing to the display dc then you'd have to keep a record of all the GDI objects that had been painted to it (eg an array of rectangles) and then re-paint them all when your program was maximised. By painting them to a memory dc you always have a record of what the output should look like, and so just have to transfer the data with a blit (bit block transfer) which will probably be faster an easier.

    However, if the app you're producing needs to keep a record of it's output anyway (eg word processor), then you probably wouldn't use this method, but just read the information from your data structure and re-paint the relevant stuff to your client area.
    zen

  9. #9
    the Corvetter
    Join Date
    Sep 2001
    Posts
    1,584
    /*** Thanks ***/ zen and Ken. Just what I needed.

    --Garfield
    1978 Silver Anniversary Corvette

  10. #10
    train spotter
    Join Date
    Aug 2001
    Location
    near a computer
    Posts
    3,868
    If you use SelectObject() catch the return and save until you have finished using the GDI object. Then RETURN the original before using DeleteObject().

    Save your GDI resources.

    To clear the HDC

    BitBlt(hdcScreen, 0, 0, iWidth, iHeight,hdcScreen, 0, 0, WHITENESS);
    "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. Parent not repainting Bitmp after child window closes
    By CodeX in forum Windows Programming
    Replies: 5
    Last Post: 10-05-2006, 12:03 AM
  2. forcing window repainting after putting back caption
    By underthesun in forum Windows Programming
    Replies: 2
    Last Post: 02-05-2005, 10:13 PM
  3. [newbie] repainting window
    By Rage7531 in forum Windows Programming
    Replies: 3
    Last Post: 06-09-2002, 10:02 PM
  4. repainting again...
    By Unregistered in forum Windows Programming
    Replies: 3
    Last Post: 01-21-2002, 01:41 AM
  5. repainting a window
    By larry in forum Windows Programming
    Replies: 3
    Last Post: 01-15-2002, 10:58 PM