Solved

Why won't this code show an image?

Posted on 2004-09-01
13
306 Views
Last Modified: 2013-11-20
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
Comment
Question by:PMH4514
  • 7
  • 6
13 Comments
 
LVL 11

Expert Comment

by:KurtVon
ID: 11955538
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
 

Author Comment

by:PMH4514
ID: 11955797
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
 
LVL 11

Expert Comment

by:KurtVon
ID: 11955964
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
 

Author Comment

by:PMH4514
ID: 11955983
yup, it put a white box with a black X in the upper left corner.
0
 
LVL 11

Expert Comment

by:KurtVon
ID: 11956258
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
 

Author Comment

by:PMH4514
ID: 11956651
>>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
How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

 
LVL 11

Expert Comment

by:KurtVon
ID: 11957431
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
 

Author Comment

by:PMH4514
ID: 11962946
weird.. it can't compile

error C2039: 'GetSafeHwnd' : is not a member of 'CBitmap'
0
 
LVL 11

Expert Comment

by:KurtVon
ID: 11963145
Oops, sorry, that should be GetSafeHandle();

I guess I've become to complacent with autocomplete.
0
 

Author Comment

by:PMH4514
ID: 11963650
ahhh.. now it works! Thanks :)
0
 

Author Comment

by:PMH4514
ID: 11963655
so, what exactly is happening with Detach and Attach that made this work now? why didn't it work prior to that?
0
 
LVL 11

Accepted Solution

by:
KurtVon earned 50 total points
ID: 11963766
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
 

Author Comment

by:PMH4514
ID: 11963847
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

Threat Intelligence Starter Resources

Integrating threat intelligence can be challenging, and not all companies are ready. These resources can help you build awareness and prepare for defense.

Join & Write a Comment

Introduction: Displaying information on the statusbar.   Continuing from the third article about sudoku.   Open the project in visual studio. Status bar – let’s display the timestamp there.  We need to get the timestamp from the document s…
Introduction: Hints for the grid button.  Nested classes, templated collections.  Squash that darned bug! Continuing from the sixth article about sudoku.   Open the project in visual studio. First we will finish with the SUD_SETVALUE messa…
This video will show you how to get GIT to work in Eclipse.   It will walk you through how to install the EGit plugin in eclipse and how to checkout an existing repository.
This video discusses moving either the default database or any database to a new volume.

760 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

21 Experts available now in Live!

Get 1:1 Help Now