Memory DC's
Hi:
I''m writing a game in Visual Basic. VB isn''t very good with graphics, so everyone bypasses the VB graphics and uses the GDI. For some reason, though, no-one makes their own device contexts. Everyone uses invisible PictureBox controls (a simple VB control that displays pictures) because they have a DC property.
For example, if someone wanted to blit a transparent picture on to the window, they would have three PictureBox controls, let''s say Pic1, Pic2, and Pic3. They would load the picture they want to blit onto in Pic1, the picture they want to blit in Pic2, and a mask in Pic3. They would import the GDI BitBlt function and use the following VB code:
BitBlt Pic1.hDC, 0, 0, 100, 100, Pic3.hDC, 0, 0, SRCAND
BitBlt Pic1.hDC, 0, 0, 100, 100, Pic2.hDC, 0, 0, SRCPAINT
BitBlt Me.hDC, 0, 0, 100, 100, Pic1.hDC, 0, 0, SRCCOPY.
This is all fine if your doing a little animation or something, but if I want to make a full game, perhaps using independant classes that may not have access to windows and their PictureBoxes, how do I use the GDI to make memory DC''s? I can''t find it anywhere. How do C programmers, who don''t have access to PictureBox controls, make memory DCs that can be used to temporarily Blt on to and off again?
Thanx in advance,
Shalom
You''ll have much better luck with this post in the general programming forum, so I''am moving it.
Windows apps have one or more windows. For any windows you can gets its DC by calling GetDC(hwnd) where hwnd is the handle of the window. This is usually done in response to a paint message (WM_PAINT) but can be done any time. This is what I do...
void Paint (HWND hwnd)
{
HDC dc = GetDC(hwnd);
int savedc = SaveDC(dc);
// there are many DC related draw functions:
// SelectObject(), MoveTo(), LineTo(), SetPixel(),
// BitBlt(), TextOut(), Rectangle(), Ellipse(),
// SetTextColor(), SetTextAlign(), on and on
RestoreDC(dc, savedc);
ReleaseDC(hwnd, dc);
}
DC''s have a ton of state information that you have to make sure is restored before you release them, or you get GDI leaks, so I always save/restore the whole thing.
void Paint (HWND hwnd)
{
HDC dc = GetDC(hwnd);
int savedc = SaveDC(dc);
// there are many DC related draw functions:
// SelectObject(), MoveTo(), LineTo(), SetPixel(),
// BitBlt(), TextOut(), Rectangle(), Ellipse(),
// SetTextColor(), SetTextAlign(), on and on
RestoreDC(dc, savedc);
ReleaseDC(hwnd, dc);
}
DC''s have a ton of state information that you have to make sure is restored before you release them, or you get GDI leaks, so I always save/restore the whole thing.
Hi, I can access the window''s DC, but how do I make a temporary DC? For example, let''s take a simple case - double buffering. How would I make a little animation in an imaginary DC and then BitBlt from that imaginary DC to the window''s DC? How do I make a sort of "buffer" DC?
Thanks,
Shalom
Thanks,
Shalom
hi shalom,
Device Contexts are just some sort of a "reference" to the device and they don''t anything on their own (they don''t hold the picture, they just point to the device that displays it...), and for that reason the term "temporary dc" doesn''t really mean anything cause it''s just a refernce to the device and you have to handle some sort of buffer yourself(by maybe having something hidden you draw into and then copying for the hidden object to the display object).
this is just a thought, havn''t been using VB for grahpics or the such
Device Contexts are just some sort of a "reference" to the device and they don''t anything on their own (they don''t hold the picture, they just point to the device that displays it...), and for that reason the term "temporary dc" doesn''t really mean anything cause it''s just a refernce to the device and you have to handle some sort of buffer yourself(by maybe having something hidden you draw into and then copying for the hidden object to the display object).
this is just a thought, havn''t been using VB for grahpics or the such
In other words, how do I make a buffer that I can point a device context to, with out having access to a window with my invisible objects and whatever?
I''m just writing this off the top of my head and its been a while since I''ve used DCs, but I think this will work:
That will create an offscreen DC you can use to draw to. You must create a bitmap object and select it into the DC or you won''t be able to use the DC. I''m sure that I messed up some of the parameters (I don''t remember them all), but you should be able to look up the API functions and see what the parameters should be.
I don''t really remember VB that well, but I''d guess that the VB code would be something like:
Im assuming that since you use BitBlt you know how to declare APIs for use in VB.
If you want direct access to the bits being displayed, I recomend that you create the bitmap object that you are going to select into the buffer DC with CreateDIBSection. That way you will have a pointer to the actual bits which will allow you to do things like alpha blending (I realize that alpha blending can be done with GetPixel/SetPixel, but that is to slow).
Feel free to email me any questions you might have
Mike010@netZero.net
HDC buffer;HDC window;HBITMAP temp;window = GetDC( window_hWnd );buffer = CreateCompatibleDC( window );temp = CreateCompatibleBitmap( buffer, width_of_image, height_of_image );SelectObject( buffer, temp );DeleteObject( temp );ReleaseDC( window_hWnd, window );
That will create an offscreen DC you can use to draw to. You must create a bitmap object and select it into the DC or you won''t be able to use the DC. I''m sure that I messed up some of the parameters (I don''t remember them all), but you should be able to look up the API functions and see what the parameters should be.
I don''t really remember VB that well, but I''d guess that the VB code would be something like:
DIM buffer as LongDIM window as LongDIM temp as LongSet window = GetDC( Form1.hWnd )Set buffer = CreateCompatibleDC( window );Set temp = CreateCompatibleBitmap( buffer, width, height )Call SelectObject( buffer, temp )Call DeleteObject( temp );Call ReleaseDC( Form1.hWnd, window );
Im assuming that since you use BitBlt you know how to declare APIs for use in VB.
If you want direct access to the bits being displayed, I recomend that you create the bitmap object that you are going to select into the buffer DC with CreateDIBSection. That way you will have a pointer to the actual bits which will allow you to do things like alpha blending (I realize that alpha blending can be done with GetPixel/SetPixel, but that is to slow).
Feel free to email me any questions you might have
Mike010@netZero.net
Thank you so much, Mike. It seems silly to get stuck on such a simple point. I have my entire game planned out and most of it programmed, and I don''t know how to use the GDI! Well, I''ll try it out.
Oh no! I used the following code exactly, and it makes a square the right size in the top left corner of the window, but its all black! What did I do wrong?
Sigh... I''m causing so much trouble with such a simple problem. Oh well.
Option ExplicitPrivate Sub Form_Load()Dim buffer As LongDim window As LongDim temp As Longwindow = GetDC(Form1.hwnd)buffer = CreateCompatibleDC(window)temp = CreateCompatibleBitmap(buffer, Picture1.ScaleWidth, Picture1.ScaleHeight)SelectObject buffer, tempDeleteObject tempReleaseDC Form1.hwnd, windowBitBlt buffer, 0, 0, Picture1.ScaleWidth, Picture1.ScaleHeight, Picture1.hdc, 0, 0, SRCCOPYBitBlt Me.hdc, 0, 0, Picture1.ScaleWidth, Picture1.ScaleHeight, buffer, 0, 0, SRCCOPYForm1.RefreshDeleteDC bufferEnd Sub
Sigh... I''m causing so much trouble with such a simple problem. Oh well.
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement