Solved

Why won't this code show an image?

Posted on 2004-09-01
13
326 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
Netscaler Common Configuration How To guides

If you use NetScaler you will want to see these guides. The NetScaler How To Guides show administrators how to get NetScaler up and configured by providing instructions for common scenarios and some not so common ones.

 

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

Does Powershell have you tied up in knots?

Managing Active Directory does not always have to be complicated.  If you are spending more time trying instead of doing, then it's time to look at something else. For nearly 20 years, AD admins around the world have used one tool for day-to-day AD management: Hyena. Discover why

Question has a verified solution.

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

Introduction: Load and Save to file, Document-View interaction inside the SDI. Continuing from the second article about sudoku.   Open the project in visual studio. From the class view select CSudokuDoc and double click to open the header …
Have you tried to learn about Unicode, UTF-8, and multibyte text encoding and all the articles are just too "academic" or too technical? This article aims to make the whole topic easy for just about anyone to understand.
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.
Microsoft Active Directory, the widely used IT infrastructure, is known for its high risk of credential theft. The best way to test your Active Directory’s vulnerabilities to pass-the-ticket, pass-the-hash, privilege escalation, and malware attacks …

778 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