Graphics.FromHwnd(IntPtr hwnd) For The Entire Screen?

  • Thread starter Thread starter NvrBst
  • Start date Start date
N

NvrBst

Hello. I can pInvoke "GetDC" with NULL or "IntPtr.Zero" and get the
hDC for the entire screen. I can use the hDC for stuff like "GetPixel"
and it works fine.

When I try to do the...

System.Drawing.Graphics myDC =
System.Drawing.Graphics.FromHwnd(IntPtr.Zero);

then a "myDC.GetHdc()" and use that with "GetPixel" it doesn't seem to
work.


If I do the ".FromHwnd(myGameHwnd);" then use the "myDC.GetHdc()" with
the "GetPixel" it works fine.

is there a way for me to use the managed "System.Drawing.Graphics" to
get a hDC for the entire screen like the pInvoke "GetDC" does?

Thanks
 
Sathyaish said:
Did you check the StatusException?

I'm sorry, I don't think I did... How do I? This is basically all I
do...

System.Drawing.Graphics myGraph =
System.Drawing.Graphics.FromHwnd(IntPtr.Zero);
uint nCol = GetPixel(myGraph.GetHdc(), xCoord, yCoord);
myGraph.ReleaseHdc();
return nCol;


nCol is always 0xFFFFFFFF (Which is CLR_INVALID), I've tried a lot of
different xCoord, yCoord's. IE 100,100. If .FromHwnd(IntPtr.Zero) is
returning the entire screen DC, how can I be getting CLR_INVALID?
 
Before you get to the GetPixel, put a try catch just for FromHwnd().

try
{
System.Drawing.Graphics myGraph =
System.Drawing.Graphics.FromHwnd(IntPtr.Zero);

if (myGraph != null)
uint nCol = GetPixel(myGraph.GetHdc(), xCoord, yCoord);

}
catch(System.Exception ex)
{
Debug.Assert(false);
Debug.WriteLine(ex.Message);
}

I am guessing that there was no exception thrown by the FromHwnd method
and that you are getting a valid graphics object.

I think the problem might be with the device (desktop) not supporting
ICM (color management). This would be because (I am guessing again) the
Graphics class's FromHwnd calls GdipCreateFromHWND API which disabled
color management and thus disables GetPixel.

One good way to check would be to call GetDeviceCaps on the desktop
hWnd before you call GetPixel().


Before you get to the GetPixel, put a try catch just for FromHwnd().

try
{
System.Drawing.Graphics myGraph =
System.Drawing.Graphics.FromHwnd(IntPtr.Zero);

if (myGraph != null)
if (GetDeviceCaps(COLORMGMTCAPS) != CM_NONE)
uint nCol = GetPixel(myGraph.GetHdc(), xCoord, yCoord);

}
catch(System.Exception ex)
{
Debug.Assert(false);
Debug.WriteLine(ex.Message);
}

And then, step through the debugger.


Note: GetDeviceCaps is an API you'll have to PInvoke.
 
if (GetDeviceCaps(COLORMGMTCAPS) != CM_NONE)


Oops! Sorry I forget the HDC as the argument to GetDevCaps. You'll send
the HDC you got from Graphics.GetHDC(). Make that a separate call.
Don't package in the call as the argument.
 
Okay :) This is what it is now....

/* Color Management caps */
public const int COLORMGMTCAPS = 121;
public const int CM_NONE = 0x00000000;
public const int CM_DEVICE_ICM = 0x00000001;
public const int CM_GAMMA_RAMP = 0x00000002;
public const int CM_CMYK_COLOR = 0x00000004;

/*Inside the Function Call*/
try {
System.Drawing.Graphics myGraph =
System.Drawing.Graphics.FromHwnd(IntPtr.Zero);
uint nCol = 0;
IntPtr myGraphHDC = myGraph.GetHdc();
int myGraphDevCaps = GetDeviceCaps(myGraphHDC, COLORMGMTCAPS);

if(myGraph != null && myGraphDevCaps != CM_NONE) nCol =
GetPixel(myGraphHDC, 100, 100);

myGraph.ReleaseHdc();
return nCol;
} catch(System.Exception ex) {
System.Diagnostics.Debug.Assert(false);
System.Diagnostics.Debug.WriteLine(ex.Message);
}
return 0;



GetDeviceCaps Returns "2" which is "CM_GAMMA_RAMP" means my desktop
should support it? nCol is still always 0xffffffff and thats what gets
returned. My desktop is 1600x1200 so the (100,100) should be fine.


Note: If I just do the pInvoke method like so

IntPtr myGraphHDC = GetDC(IntPtr.Zero);
nCol = GetPixel(myGraphHDC, 100, 100);
ReleaseDC(IntPtr.Zero, myGraphHDC);
return nCol;

Then GetPixel returns "0x00849ebd" which is most likly my Desktop
Color.

But I've also tried using the exact same code at the begining of this
post except chaning ".FromHwnd(IntPtr.Zero);" to
".FromHwnd(myGameHwnd);" and for point (100,100) (When Game is Up,
Windowed Mode) I get "0x00a5bece", and "int myGraphDevCaps = ..." gives
"2" like when using "IntPtr.Zero".

:) At this point its just more-so curiosity, I don't mind using the
pInvoke method with "GetDC" but wondering a little (for future
reference) if its possible to use the managed method to get the entire
screen DC like "GetDC" does with null. Is there anything else ya can
think of that I can try? I've with multiple points (not just 100,100),
and they all return "0xFFFFFFFF".


NvrBst
 
NvrBst,
If you are using .NET 2.0 I would recommend:

Graphics.CopyFromScreen to get a bitmap that contains the colors of pixels
on the screen.

http://msdn2.microsoft.com/en-us/library/system.drawing.graphics.copyfromscreen.aspx


--
Hope this helps
Jay B. Harlow [MVP - Outlook]
..NET Application Architect, Enthusiast, & Evangelist
T.S. Bradley - http://www.tsbradley.net


| Hello. I can pInvoke "GetDC" with NULL or "IntPtr.Zero" and get the
| hDC for the entire screen. I can use the hDC for stuff like "GetPixel"
| and it works fine.
|
| When I try to do the...
|
| System.Drawing.Graphics myDC =
| System.Drawing.Graphics.FromHwnd(IntPtr.Zero);
|
| then a "myDC.GetHdc()" and use that with "GetPixel" it doesn't seem to
| work.
|
|
| If I do the ".FromHwnd(myGameHwnd);" then use the "myDC.GetHdc()" with
| the "GetPixel" it works fine.
|
| is there a way for me to use the managed "System.Drawing.Graphics" to
| get a hDC for the entire screen like the pInvoke "GetDC" does?
|
| Thanks
|
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Back
Top