Hello, I'm trying to get HBitmap from Graphics Control handle.
I do it like here:
var controlGraphics = m_control.CreateGraphics();
var controlHdc = controlGraphics.GetHdc();
var controlHBitmap = PInvoke.GetCurrentObject( controlHdc, PInvoke.OBJ_BITMAP );
I working with Windows 7 and VS2010 (C# .NET 4.0).
I use standard WinAPI functions like u can see.
It's working good in normal situation, but when I set Win 7 system options to "Fit to best performance" (its turning off nice graphics Win 7 effects and set simplest possible themes i think) this method don't work.
Method "GetCurrentObject" return me handle to desktop HBitmap - not to control. It can be fixed in some way, or it smth with system whereof i dont know?
Wrong Some kind of control not supported this method - just draw black screen always. And my control - AxShockwaveFlash - is one from this kind.
And I need very fast draw - some of 30-100 frame per second. And its working - except case that I depict in first post.
Thanks for reply but I need other method. Throw that in I try bypass that much managed structures how I can. For performance.
Wrong Some kind of control not supported this method - just draw black screen always.
You're quite right, sorry, I misread your original post. I thought you're just experimenting with interop feaatures on simple controls like buttons and such. Anyway, what I suggested is not appropriate for what you're trying to do even if DrawToBitmap() worked.
I know it's been a while, but I wasn't around on the forum up until now, so you may have solved the problem in the meanwhile.
I've been experimenting and noticed some drawbacks of the approach - the internal bitmap selected into the device context may not mach the client area of a control even when Aero is not off, and when it is, it represents the whole screen, I suspect it's an OS optimization.
However, what exactly are you doing with the bitmap? Are you doing some processing on the actual pixel data? Draw something on it? Or just displaying it?
As for the drawing operations, the origin is still set right and anything drawn outside the area of the control is still clipped (if you use the original graphics/device context), so there's no much problem there.
An interesting approach (when Aero is off - "Fit to best performance") would be to lock a rectangular region of the returned bitmap, which would return a BitmapData object containing an IntPtr to the bitmap data associated with the region, along with other parameters (width, height, stride, pixel format...). Then you can use this Bitmap constructor to create a Bitmap object that basically references the same data as the original controlBitmap, but only the selected subsection. Then you can use it to obtain a handle to that sub-bitmap, or you can use the Graphics.FromImage(...) static method to create a graphics associated with the sub-bitmap, and anything you draw will be reflected on the original controlBitmap.
Basically - it's two Bitmap instances referencing the same data source, only that one represents the whole thing, an the other just a subset of it.
The problem is, I don't know if there's an API method that enables you to find out where the area corresponding to the control is located in the controlBitmap. You can maybe use window/client rectangle locations to calculate this, translated to the screen coordinates, since the bitmap spans the entire screen, but then you would have a special case, and would thus need to keep track of the display settings.
It's an interesting problem, and if you already came up with a solution, I'd really like to hear how you managed to do it - if you'd like to share.
P.S. Have you considered any other approaches, something not based on the retrieval of the device context handle maybe?
Last edited by TheGreatCthulhu; September 4th, 2010 at 02:57 PM.
Nice idea, but not in my case I try do some kind of hack - i draw WinForms Flash control on one, simple window - but this window is no display in user working area. I set its position left to int.MaxValue - far away from visible desktop part. And I try use "screenshot" from this control to craete my own WPF flash playling control.
I need it to my work, but I dont find anywhere reliable, free ( or cheap, 200$ down ) control who do it. I mean do it well - with all effects - i need that this control can be transformed, rendered to 3D objects itp.
Naturally it must be very fast - in real-time.
My solution fit this conditions - but like u say only when Areo is on.
I cant do it in u way - because desktop bitmap dont contain this control graphics. Like I say it is above working area.
If somebody known simplest way to manage Flash files in WPF - in real time, and with all WPF advantage I'm all ears.
Last edited by Psychowico; September 5th, 2010 at 04:28 AM.
I try do some kind of hack - i draw WinForms Flash control on one, simple window - but this window is no display in user working area. I set its position left to int.MaxValue - far away from visible desktop part. And I try use "screenshot" from this control to craete my own WPF flash playling control.
In that case, when Aero is off, I'm thinking there's a good chance that the control doesn't get drawn at all. I'm not sure though, but if so, than it can't be done that way.
You may need a different approach, if possible. Have you searched the web for some open source projects.
Now I'm going to exactly check this piece of code and maybe it will be ok for me.
Ok i do it by:
* Load flash to WinForms Window with Opacity = 0
* in all frame
* I use PInvoke.PrintWindow to copy flash to Bitmap
* lock bits in this Bitmap
* update data in WriteableBitmap using WritePixels method
* unlock bits of Bitmap
It is average speed but looking and working good.
Last edited by Psychowico; October 21st, 2010 at 01:13 AM.