Solved

Why won't this code show an image?

Posted on 2004-09-01
13
338 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 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
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!

 

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
 
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

Independent Software Vendors: 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!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
if loop in java 3 174
conditional code and condition difference 9 87
wait notify demo infinite loop 3 151
Sed question 2 139
Here is how to use MFC's automatic Radio Button handling in your dialog boxes and forms.  Beginner programmers usually start with a OnClick handler for each radio button and that's just not the right way to go.  MFC has a very cool system for handli…
Introduction: Dialogs (2) modeless dialog and a worker thread.  Handling data shared between threads.  Recursive functions. Continuing from the tenth article about sudoku.   Last article we worked with a modal dialog to help maintain informat…
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.

752 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