wyrd Posted August 3, 2003 Posted August 3, 2003 (edited) Edit: I got the answers to my questions.. http://www.codeproject.com/csharp/flicker_free.asp I was looking at the Windows API functions for drawing. It looks easy enough (get handle from Bitmap, use it w/ BitBlt, DeleteObject on handle when done). I assume I'd have to do my own double buffering if I used the Windows API right? Also I take it putting the Bitmap.GetHbitmap() and DeleteObject() inside a loop would be bad right? I just want to clarify that it's not just getting a reference to a handle, but actually creating the object in memory THEN giving you the handle reference to that object? If that's the case, can I do Bitmap.Dispose() after Bitmap.GetHBitmap() w/o effecting it? That way I don't have two objects in memory of the same bitmap (assuming GetHbitmap is creating another object in memory). Lots of silly questions, but I'm unfamiliar with the Windows API. I just want to make sure I fully understand what it's doing so I can use it efficiently. Thanks in advance. Edited August 3, 2003 by wyrd Quote Gamer extraordinaire. Programmer wannabe.
wyrd Posted August 3, 2003 Author Posted August 3, 2003 (edited) Okay.. I think I understand now (maybe, heh). I was wondering if someone could answer the questions in the comments below, and also double check to see if everything *might* possibly work correctly. // DllImport Win32 API functions here. Bitmap _image; IntPtr _imgH; IntPtr _oldH; Bitmap _bitbuf; Graphics _buffer; Graphics _main; public Form() { // Create display area. _main = this.CreateGraphics(); // Create backbuffer. _bitbuf = new Bitmap(this.Width, this.Height); _buffer = Graphics.FromImage(_bitbuf); // Load image to draw. _image = new Bitmap("somefile.bmp"); _imgH = _image.GetHbitmap(); // Does this create a new copy or just reference?! // Select DC for image, which should be the DC I'm // going to draw it to, correct? IntPtr dc = _buffer.GetHdc(); _oldH = SelectObject(dc, _imgH); _buffer.ReleaseHdc(dc); _image.Dispose(); // Dispose GDI+ image here or does it have to stay in memory?! // I'm confused as to whether GetHbitmap creates a stand alone // object or not. } // At some point a keydown event will trigger this. private void _run() { // Imagine a game loop. :P while (true) { _drawBuffer(); _drawMain(); } } // Draws images to buffer. private void _drawBuffer() { IntPtr bufferDC = _buffer.GetHdc(); BitBlt(bufferDC, dstX, dstY, dstWidth, dstHeight, _imgH, srcX, srcY, srcWidth, srcHeight, RasterOperation); _buffer.ReleaseHdc(bufferDC); } // Draws buffer to main. private void _drawMain() { IntPtr _buffer.GetHdc(); IntPtr mainDC = _main.GetHdc(); BitBlt(mainDC, 0, 0, this.Width, this.Height, bufferDC, 0, 0, _bitbuf.Width, _bitbuf.Height, RasterOperation); _buffer.ReleaseHdc(bufferDC); _main.ReleaseHdc(mainDC); } // This would obviously be in Dispose but I don't want // to write out the whole Dispose pattern. ~Form() { IntPtr dc = _buffer.GetHdc(); // Return old handle to DC. // I do have do to this right? That's what the docs say... // It doesn't say why though? // Also, it should be returning my image handle right? // Or do I not accept the return handle at this point? _imgH = SelectObject(dc, _oldH); _buffer.ReleaseHdc(dc); // Delete image. DeleteObject(_imgH); // Dispose of backbuffer. _buffer.Dispose(); _bitbuf.Dispose(); // Dispose of display surface. _main.Dispose(); } Thanks in advance. :) Edited August 3, 2003 by wyrd Quote Gamer extraordinaire. Programmer wannabe.
*Experts* Volte Posted August 3, 2003 *Experts* Posted August 3, 2003 GetHBitmap gets the bitmap handle of the bitmap. When you dispose of the image, the handle becomes invalid. Quote
wyrd Posted August 4, 2003 Author Posted August 4, 2003 Another question; Is the speed of SelectObject fast, or should I use it sparingly? VF: The MSDN says it actually creates an HBITMAP object in memory, then gives you a pointer to its handle. I tested this out because it seemed rather odd to me. I loaded a bitmap like normal, then created HBITMAP with Bitmap.GetHbitmap(). After that I did Bitmap.Dispose() followed by GC.Collect() to make sure the Bitmap was no longer in memory. After all that, the IntPtr to HBITMAP was still valid (I was able to use it until I did DeleteObject()) Maybe my tests were inaccurate or I did something wrong to produce fantasy results. If your or someone else would like to confirm or deny this I'd appreciate it. Quote Gamer extraordinaire. Programmer wannabe.
*Experts* Volte Posted August 4, 2003 *Experts* Posted August 4, 2003 Well, the MSDN would know better than I, so I must be mistaken. Seems rather odd though. SelectObject should be used whenever you need it. There really is no way to go overboard with it, or conserve its use. Whenever you need to put a font or a pen into a DC, you need it. Quote
Menge Posted August 4, 2003 Posted August 4, 2003 hrm i use this method... it is true, it actually creates a hBitmap on memory. i always have to deleteobject later on :P Quote Menge
wyrd Posted August 4, 2003 Author Posted August 4, 2003 Sounds good then, thanks for the info. Quote Gamer extraordinaire. Programmer wannabe.
Recommended Posts