Link to home
Start Free TrialLog in
Avatar of dpeyton
dpeyton

asked on

Using StretchDIBits in CDialog::OnPaint

I have created a CDialog-derived class that contains four CStatic member variables that are simply frames into which bitmaps are to be drawn.  Because the frames and bitmaps are of differing sizes, I believe I need to call StretchDIBits(...) to accomplish this task.  However, since I start with only a CPaintDC, how do I get the handle to the DC for the StretchDIBits call?  Also, how do I make sure of getting the correct coordinates for the frame rectangles and the bitmap rectangles (I'm calling LoadBitmap(IDB_BITMAP) for each one)?  Finally, can I access *lpBits and *lpBitsInfo directly from CBitmap, or do I have to take some other approach?  
ASKER CERTIFIED SOLUTION
Avatar of nietod
nietod

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of nietod
nietod

Using the CDC::StretchBlt() you won't need the DC handle  (though if you ever do  need it is in the member m_hDC).  Since you are dealing with a DIB, you don;t need to have a pointer to the bits.  (Though that can be obtained with GetDIBits().)
>> Also, how do I make sure of getting the correct coordinates for the
>> frame rectangles and the bitmap rectangles
what do you mean?

Finally, if you are using a CStatic, why are you displaying the bitmap manually?  It has a SetBitMap() function to be used for this purpose.
Avatar of dpeyton

ASKER

Before I grade your response, I'd like to try to answer the questions you posted in your comments.  If you could acknowledge this response when you get a chance, it would help "close some loops."  

Regarding my question on frame and bitmap rectangle coordinates (which may not apply now anyway, since you said I should not be using StretchDIBits), I simply wanted to know whether I needed to read them in device units or logical units.  In either case, I assume the origins would have to be relative to the top-left corner of the dialog.  If I use StretchBlt(), will it understand rect's in device units (relative to the dialog origin) correctly?  

As concerns the SetBitmap() function, I had thought about using it, but my understanding was that it simply displayed the bitmap at the CStatic origin without any kind of scaling.  Am I right?  If I am, can I still use SetBitmap() in conjunction with StretchBlt()?  

Finally, as a matter of interest, any idea why BitBlt() would require the DC handle and not StretchBlt()?  

>> I'd like to try to answer the questions you posted in your comments
Always a good idea.

>> I simply wanted to know whether I needed to read them in
>> device units or logical units.
The first 4 values (the coordinates of the destination) are in the logical units of the DC.  If coordinates are associated with a DC (These are since they specify a location in the DC to be altered), then they almost always are in the logical coordinates of the DC.  The next 4 values (the source coordinates) are not associated with a DC (The DIB is not in a DC), so they are in pixels.

>> I assume the origins would have to be relative to the top-left corner of the dialog.
The destination coordinates are relative to the DC's "window origin"  (pretty much was nothing to do with a window, its just called the "window origin")  This origin can be moved.   If it is not moved, what it is set at, depends on how you got the DC.  If the DC is a CPaintDC, then it is set to the upper-left corner of the client area window being painted.  Thus when painting the dialog, it would be set to the upper-left corner of the dialog's client area.  However, the dialog should not paint over child windows.  So that DC should be used to draw only to portions that are not covered by child windows.  If you want to draw in a child window, you should do that with the child window's CPaintDC from tthe child window's OnPaint() function (or elsewhere).
>> If I use StretchBlt(), will it understand rect's in device units
>> (relative to the dialog origin) correctly?  
It uses a DC for both the source and destination.  The source coordinates will be in logical source units and the destination coordinates in logical destiantion units.  Again for this case the destination origin should be relative to the top-left corner of the client area of the window being painted  (but you may want to rethink with window is being painted.)   The source origin will start out at the top-left corner of the DDB bitmap.  Also the souce DC will start out in set to device units (pixels) so the coordinates to move the entire bitmap specify 0 for the x and y, and specify the width and hieght of the bitmap (in pixels).  

>> As concerns the SetBitmap() function, I had thought about using it,
>> but my understanding was that it simply displayed the bitmap at the
>> CStatic origin without any kind of scaling
Probably true.  I don't use MFC so I don't know for sure, but it certainly seems right.

Then your options are

1.  to not use CStatic at all, and just have the dialog paint the images in itself   (There is no point in having a CStatic and having its parent draw on top of it.  No window should draw on another.)  
2.  derive your own class from CStatic--or right from CWnd. and draw the images in that window's OnPaint function.  This is probably the preferable way to do it.

>> any idea why BitBlt() would require the DC handle and not StretchBlt()?
Both require two DCs.  One to be painted to--destination, one containing the source image.  If you are using the MFC functions the DCs, the destination DC is the object you call the function for and  the source DC is specfied in the parameters.  In the non-MFC function, both DCs are specified using DC handles.   The two functions are nearly identical to each other both in MFC and non-MFC.
Avatar of dpeyton

ASKER

Okay, I think that's enough information to go back and get my hands dirty again.  Thanks for your help!