• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 275
  • Last Modified:

copying color bitmap to clipboard?

I successfully copy a rectanglular area that the user has "rubberbanded" and paste it to the clipboard but only in black&white - HOW DO I KEEP THE COLOR? (MSVC++5.0)
Within OnLButtonUp I have:
      CDC *windowDC = GetDC();
      CDC memDC;
      CBitmap memBitmap, *oldBitmap;
      memDC.CreateCompatibleDC(&memDC);
      memBitmap.CreateCompatibleBitmap(&memDC, w, h);
      memDC.SelectObject(memBitmap);
      memDC.BitBlt(0, 0, w, h,windowDC,
                rubberBand.left+borderSize,
            rubberBand.top+borderSize, SRCCOPY);
0
borghard
Asked:
borghard
  • 5
  • 3
1 Solution
 
nietodCommented:
You need to create a compatible bitmap using a display DC, not the memory DC.

details follow.
0
 
nietodCommented:
Most DCs can handle only a single bitmap format.  For example, a DC for the display (console,screen, what ever you want to call it) can handle bitmaps that use the same color format as the screen.  A DC for a printer can handle only bitmaps for the same color fromat as the printer, ussually monochrome.  But memory DCs are special and can handle a variety of color formats.  When you do

memDC.CreateCompatibleDC(&windowDC);

it creates a memory DC that is capable of being compatible with the screen DC, but it is also capable of being compatible with other DCs  (Mostly it is capable of being compatible with all the common VGA color formats.)  So what?  Well selected inside this memory DC is its inital bitmap.  This is a 1 pixel square MONOCHROME bitmap.  Thus even though you wanted a DC compatible with the screen, it gave you one whose current bitmap is monochrome.  No problem yet, but then you do

memBitmap.CreateCompatibleBitmap(&memDC, w, h)

In other word you create a bitmap that is compatible with the memory DC.  Well the memory DC can work in lots of color formats which one should the new bitmap be in?  Answer the same one as the memory DC's current bitmap.  That bitmap is monochrome so the new bitmap is monochrome and thus it doesn't match the screen format, even though you requested a memory DC  that does.  

The way around this is to create the bitmap using the display DC, not the memory DC.  Then the bitmap will have the same color fromat as the display.

One more thing, when you select the new bitmap into the memory DC it selectes out that 1 pixel bitmap.  You must reselect that 1 pixel bitmap back into the memory DC before your destroy the memory DC.  That is very important.

Let me know if you have questions.
0
 
nietodCommented:
By the way, once you get this working, you might want to consider a big change.  I believe you would be best off putting a device independant bitmap onto the clipboard instead.  
0
Cloud Class® Course: Certified Penetration Testing

This CPTE Certified Penetration Testing Engineer course covers everything you need to know about becoming a Certified Penetration Testing Engineer. Career Path: Professional roles include Ethical Hackers, Security Consultants, System Administrators, and Chief Security Officers.

 
borghardAuthor Commented:
Thanks!  Will wait for your details - Bogey.
0
 
nietodCommented:
Those were the details.  Do you have questions?
0
 
borghardAuthor Commented:
Ahhhhh.  Will try out first thing in the morning -
Thanks - Bogey
0
 
borghardAuthor Commented:
Coooool!  It is now working. Thanks for the well written detailed explanation (I answered your first e-mail before the rest came over).  Hopefully I coded this correctly.  I'm going to try to do this using a DIB sometime in the future, (as I am a novice to C++ ).
Thanks again -
Bogey

FYI, here is the code now:
            CDC *windowDC = GetDC();
            CDC memDC;
            CBitmap memBitmap, *oldBitmap;
                            memDC.CreateCompatibleDC(windowDC);
            memBitmap.CreateCompatibleBitmap(windowDC, w, h);
            memDC.SelectObject(memBitmap);
            memDC.BitBlt(0, 0, w, h, windowDC, rubberBand.left+borderSize,
                              rubberBand.top+borderSize, SRCCOPY);
                        memDC.SelectObject(oldBitmap);
                        ReleaseDC(&memDC);
                        ReleaseDC(windowDC);
                        OpenClipboard();
                        EmptyClipboard();
                        SetClipboardData(CF_BITMAP, memBitmap);
                        CloseClipboard();


0
 
nietodCommented:
The line

memDC.SelectObject(oldBitmap);

returns a pointer to the CBitmap that was previously selected into the DC.  It is your responsibility to save that pointer and when you are done with the DC, you must select that bitmap back in before you release the DC.  I don't use MFC, but that is the way the regular API works and I don't think that MFC works differently in this respect.
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

Join & Write a Comment

Featured Post

Cloud Class® Course: Microsoft Exchange Server

The MCTS: Microsoft Exchange Server 2010 certification validates your skills in supporting the maintenance and administration of the Exchange servers in an enterprise environment. Learn everything you need to know with this course.

  • 5
  • 3
Tackle projects and never again get stuck behind a technical roadblock.
Join Now