Go Premium for a chance to win a PS4. Enter to Win

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 345
  • Last Modified:

Why won't this code show an image?

Using VC++ 6.0 and MFC.  An "about box" dialog pops open, and I run this code to try to load logo.bmp (which sits in the same folder as the executable).
The code runs without any errors, but I see no image.

void CAboutDlg::OnPaint()
{
      CPaintDC dc( this ); // Device context for painting

      CBitmap bmp, *poldbmp;
      CDC memdc;

      // Load the logo bitmap
      HBITMAP hBmp = (HBITMAP)::LoadImage(NULL, "logo.bmp",IMAGE_BITMAP,0,0,LR_CREATEDIBSECTION | LR_LOADFROMFILE);

      bmp.FromHandle(hBmp);

      // Create a compatible memory DC
      memdc.CreateCompatibleDC( &dc );

      // Select the bitmap into the DC
      poldbmp = memdc.SelectObject( &bmp );

      // Copy (BitBlt) bitmap from memory DC to screen DC
      dc.BitBlt( 10, 10, 558, 266, &memdc, 0, 0, SRCCOPY );      // all logos are standard size.

      memdc.SelectObject( poldbmp );
}

Thanks!
-Paul
0
PMH4514
Asked:
PMH4514
  • 7
  • 6
1 Solution
 
KurtVonCommented:
LR_CREATEDIBSECTION creates a DIBitmap.  In that case you will have to get the palette and select it into teh device to see colors outside the 20 system colors. If you can be sure the computer has a truecolor display (or don't mind 256 color displays using a 16 color bitmap) you can leave off thsi option.  Otherwise you need to create the color palette and select it into the DC.

Look here for details: http://support.microsoft.com/default.aspx?scid=http://support.microsoft.com:80/support/kb/articles/q158/8/98.asp&NoWebContent=1

Hope this helps.
0
 
PMH4514Author Commented:
actually in my case I can be sure the system supports trucolor.. you say I can leave off this option - you are referring to 'LR_CREATEDIBSECTION' I take it?  I tried that, but the same thing - I see no image whatsoever
0
 
KurtVonCommented:
Humor me and try adding this to the paint routine right after the BitBlt:

dc.PatBlt(0, 0, 100, 100, WHITENESS);
dc.MoveTo(0, 0);
dc.LineTo(100, 100);
dc.MoveTo(100, 0);
dc.LineTo(0, 100);

Does a white square with a black X appear in the upper left corner?
0
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
PMH4514Author Commented:
yup, it put a white box with a black X in the upper left corner.
0
 
KurtVonCommented:
Hmm, stumper.

I know you said none of the functions were returning an error, but just to be safe, lets add that test in.  Right after the LoadBitmap add the line

if (bmp == NULL)
    TRACE("The bitmap file could not be loaded.\n");

Maybe put a breakpoint on it too, just to be safe.

Also change the obvious line to

    VERIFY(memdc.CreateCompatibleDC( &dc ));

Which shoudl assert under debug but be harmless under release.

0
 
PMH4514Author Commented:
>>Maybe put a breakpoint on it too, just to be safe.
yeah, that's the first thing I did.. bmp is not NULL.


does it matter that I saved the bitmap out of photoshop as a 24bit image?
0
 
KurtVonCommented:
Erm, okay.  I'm stupid.

Try replacing the line

    bmp.FromHandle(hBmp);

with

    if (bmp.GetSafeHwnd())
        bmp.Detach();
    bmp.Attach(hBmp);

and run it.
0
 
PMH4514Author Commented:
weird.. it can't compile

error C2039: 'GetSafeHwnd' : is not a member of 'CBitmap'
0
 
KurtVonCommented:
Oops, sorry, that should be GetSafeHandle();

I guess I've become to complacent with autocomplete.
0
 
PMH4514Author Commented:
ahhh.. now it works! Thanks :)
0
 
PMH4514Author Commented:
so, what exactly is happening with Detach and Attach that made this work now? why didn't it work prior to that?
0
 
KurtVonCommented:
The FormHandle function does not alter the bitmap the function is called on.  Instead it looks through teh object tables and tries to find an existing bitmap object that uses that handle.  It then returns a pointer to that object (creating a new object pointer if it doesn't exist).

It's used very rarely, so my eye kept gliding over it until I took the moment to consider how we could test it for a failure condition.

Attach actually makes the CBitmap object use the bitmap handle as if it had made the bitmap itself.  The detach was just in case something was already attached to the bitmap.  Given the code right there I probably could have left it off, but I always detach just in case the code gets switched around some time in the future.  It would also be just as safe to ASSERT that GetSafeHandle is NULL.

0
 
PMH4514Author Commented:
ahh.. I see..  see I had just assumed that since I had a handle to a bitmap:
 HBITMAP hBmp = (HBITMAP)::LoadImage(NULL, "logo.bmp",IMAGE_BITMAP,0,0,LR_CREATEDIBSECTION | LR_LOADFROMFILE);

that to get a CBitmap from it, I would use "fromHandle" ..  wouldn't that make sense to a newbie? ;-)

thanks for the explanation!

-Paul
0

Featured Post

Free Tool: Subnet Calculator

The subnet calculator helps you design networks by taking an IP address and network mask and returning information such as network, broadcast address, and host range.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

  • 7
  • 6
Tackle projects and never again get stuck behind a technical roadblock.
Join Now