Thread: Manual rendering disappears

  1. #1
    Confused Magos's Avatar
    Join Date
    Sep 2001
    Location
    Sweden
    Posts
    3,145

    Manual rendering disappears

    I'm trying to render a bitmap. The actual rendering seems to work fine, however since I'm rendering on top of another controls (a tab control to be precise) my own rendering doesn't show up. It's overwritten by the tab control's rendering. If I disable the default renderings my bitmap showsup but then , of course, the controls won't.

    I did the default drawings first and then my own (I thought mine would overwrite theirs then, but nope...).

    This is my WM_PAINT handler:
    Code:
    //Render
    case WM_PAINT:
    {
    	//Render the normal windows
    	DefWindowProc(Handle, Message, wParam, lParam);
    
    	//Render the image (if neccessary)
    	if(CurrentBitmap != NULL)
    	{
    		RenderImage();
    	}
    	return 0;
    }
    and my RenderImage function basically looks like this:

    Code:
    //Data
    PAINTSTRUCT PaintStruct;
    HDC SourceDevice;
    HDC TargetDevice;
    
    //Retrieves a target device
    TargetDevice = BeginPaint(ImageFrame, &PaintStruct);
    if(TargetDevice == NULL)
    {
    	return FALSE;
    }
    
    //Retrieves a source device
    SourceDevice = CreateCompatibleDC(TargetDevice);
    if(SourceDevice == NULL)
    {
    	EndPaint(ImageFrame, &PaintStruct);
    	return FALSE;
    }
    
    //Select a handle to the bitmap object
    if(!SelectObject(SourceDevice, CurrentBitmap))
    {
    	DeleteDC(SourceDevice);
    	EndPaint(ImageFrame, &PaintStruct);
    	return FALSE;
    }
    
    //Blits an image
    if(!BitBlt(TargetDevice, 1, 1, ImageFrameWidth, ImageFrameHeight, SourceDevice, 0, 0, SRCCOPY))
    {
    	DeleteDC(SourceDevice);
    	EndPaint(ImageFrame, &PaintStruct);
    	return FALSE;
    }
    
    //Clean up
    DeleteDC(SourceDevice);
    EndPaint(ImageFrame, &PaintStruct);
    Any suggestions?
    MagosX.com

    Give a man a fish and you feed him for a day.
    Teach a man to fish and you feed him for a lifetime.

  2. #2
    erstwhile
    Join Date
    Jan 2002
    Posts
    2,227
    Try invalidating the areas your bitmap will be updating prior to calling your Render function. BeginPaint validates the update region and this is presumably happening when the default, system painting of your window occurs. You may wish to track how the update region changes by using GetUpdateRect.

    Don't know if any of that will help much, though.
    CProgramming FAQ
    Caution: this person may be a carrier of the misinformation virus.

  3. #3
    train spotter
    Join Date
    Aug 2001
    Location
    near a computer
    Posts
    3,868
    Try using the TAB controls HDC

    ie
    hdc = GetDC(hTabCrtl);

    and its client rect in the paint function

    I suggest creating a compat HDC to hold your bmp when the TAB control is created, deleteing it when the TAB control is destroyed. As opposed to creating one every paint.

    Unless using a .NET compiler this is a GDI resource leak

    if(!SelectObject(SourceDevice, CurrentBitmap))
    "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

  4. #4
    Confused Magos's Avatar
    Join Date
    Sep 2001
    Location
    Sweden
    Posts
    3,145
    Ok, I retrieved the device from the tab control and moved the bitmap -> source device into the image loader. It works fine now, however if I want the image to be drawn immediately I have to invalidate the tab control and manually call WM_PAINT through SendMessage(MainWindow, WM_PAINT, NULL, NULL).

    If I only invalidate the rect the image will only be drawn if I min/max it or move it outside the screen and back. Is this normal?

    Anyway, it works so I shouldn't complain. It just seems weird to send a WM_PAINT message manually.
    MagosX.com

    Give a man a fish and you feed him for a day.
    Teach a man to fish and you feed him for a lifetime.

  5. #5
    erstwhile
    Join Date
    Jan 2002
    Posts
    2,227
    Originally posted by Magos
    It works fine now, however if I want the image to be drawn immediately I have to invalidate the tab control and manually call WM_PAINT through SendMessage(MainWindow, WM_PAINT, NULL, NULL).....It just seems weird to send a WM_PAINT message manually.
    UpdateWindow sends the WM_PAINT for you, if you prefer. RedrawWindow will do the invalidation/update in one fn call, given the right parameters.
    CProgramming FAQ
    Caution: this person may be a carrier of the misinformation virus.

  6. #6
    train spotter
    Join Date
    Aug 2001
    Location
    near a computer
    Posts
    3,868
    to be picky

    InvalidateRect() sends the paint msg

    UpdateWindow() bypasses the msg que and processes the paint immediately
    "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

  7. #7
    erstwhile
    Join Date
    Jan 2002
    Posts
    2,227
    Picky's good - so long as you don't mind pedantic.
    msdn for InvalidateRect:
    The InvalidateRect function adds a rectangle to the specified window's update region.
    msdn for UpdateWindow:
    The UpdateWindow function updates the client area of the specified window by sending a WM_PAINT message to the window
    CProgramming FAQ
    Caution: this person may be a carrier of the misinformation virus.

  8. #8
    train spotter
    Join Date
    Aug 2001
    Location
    near a computer
    Posts
    3,868
    Raise your pedantic to bordering on obsessive....

    I suppose it shows the diversity of info, on the same function, available in MSDN

    MFC
    The UpdateWindow member function sends a WM_PAINT message directly, bypassing the application queue. If the update region is empty, WM_PAINT is not sent.

    SDK
    The UpdateWindow function updates the client area of the specified window by sending a WM_PAINT message to the window if the window's update region is not empty. The function sends a WM_PAINT message directly to the window procedure of the specified window, bypassing the application queue. If the update region is empty, no message is sent.
    "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. Required Reading Unix Manual - Help!
    By wise_ron in forum Tech Board
    Replies: 3
    Last Post: 09-05-2006, 05:47 AM
  2. scene graph rendering techniques
    By ichijoji in forum Game Programming
    Replies: 7
    Last Post: 03-19-2006, 12:17 AM
  3. About rendering in a far point
    By Niara in forum Game Programming
    Replies: 8
    Last Post: 05-26-2005, 05:24 AM
  4. Mesh Rendering: Z-Buffer and Lighting
    By Epo in forum Game Programming
    Replies: 6
    Last Post: 04-20-2005, 07:11 AM
  5. voxel based rendering
    By Silvercord in forum Game Programming
    Replies: 1
    Last Post: 03-20-2003, 05:14 PM