471,624 Members | 1,833 Online
Bytes | Software Development & Data Engineering Community
Post +

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 471,624 software developers and data experts.

Interop question

When executing some win32 messages in c# I get unexpected results.
The following example is suppose to return the handle of an image in a
button control of another application but it return a negative
handle...is anybody know why it return an invalid handle like
"-989523277" ??

IntPtr ImageHandle =
Win32.SendMessage(Handle,BM_GETIMAGE,IntPtr.Zero,I ntPtr.Zero);
MessageBox.Show(ImageHandle.ToString());

Note : the third param is set to IMAGE_BITMAP (0); it return 0 if
the button contain no image.

Thanks...
Aug 22 '08 #1
11 2247
On Thu, 21 Aug 2008 20:35:26 -0700, michelqa <mi******@yahoo.cawrote:
When executing some win32 messages in c# I get unexpected results.
The following example is suppose to return the handle of an image in a
button control of another application but it return a negative
handle...is anybody know why it return an invalid handle like
"-989523277" ??
Can you be more specific? Why do you believe the value "-989523277" to be
an invalid handle value? Have you actually tried to use it as an HBITMAP
and had that fail? Can you show a concise-but-complete code sample that
reliably demonstrates whatever problem you're actually having?

Pete
Aug 22 '08 #2
On Aug 21, 11:44*pm, "Peter Duniho" <NpOeStPe...@nnowslpianmk.com>
wrote:
On Thu, 21 Aug 2008 20:35:26 -0700, michelqa <miche...@yahoo.cawrote:
When executing some win32 messages in c# *I get unexpected results.
The following example is suppose to return the handle of an image in a
button control of another application but it return a negative
handle...is anybody know why it return an invalid handle like
"-989523277" ??

Can you be more specific? *Why do you believe the value "-989523277" tobe *
an invalid handle value? *Have you actually tried to use it as an HBITMAP *
and had that fail? *Can you show a concise-but-complete code sample that *
reliably demonstrates whatever problem you're actually having?

Pete
I suppose it's invalid since it's negative and since i'm not able to
recreate the bitmap in my application...it return a "Generic
exception"

//Handle = button handle of another application
IntPtr ImageHandle =
Win32.SendMessage(Handle,BM_GETIMAGE,IntPtr.Zero,I ntPtr.Zero);
MessageBox.Show(ImageHandle.ToString());
System.Drawing.Bitmap Bitmap =
System.Drawing.Bitmap.FromHbitmap(ImageHandle); //generic exception
from gdi..invalid handle?
// Just want to get a usable bitmap here

Aug 22 '08 #3
Ok , I'll try to explain the problem :
1- I know that WM_GETIMAGE is suppose to return an hImage hex
c50512b3 (3305444019) ... I know that because I'm logging the message
in SPY++
2- My sendMessage in my c# app return -989523277 (or
8975925797277995699 when modifying sendmessage definition to return a
long instead of a IntPtr) *** Why this difference???? ****
3- Even with the correct image handle hardcoded like this :
System.Drawing.Image MyImg=
System.Drawing.Image.FromHbitmap((IntPtr)330544401 9);
I get the error : Arithmetic operation resulted in an overflow.

As I understand it FromHbitmap want an IntPtr and 3305444019 is to big
for a Integer

Dont think a more complete example will help to understand the problem
but here is my example...I have a Win32 application and I want to copy
Button image from it and put the image in a button or a picturebox in
my c#

[DllImport("user32.dll")]
public static extern IntPtr SendMessage(IntPtr hwnd, int msg, IntPtr
wparam, IntPtr lparam);
int BM_GETIMAGE = 0x00F6;
IntPtr ImageHandle =
SendMessage(Handle,BM_GETIMAGE,IntPtr.Zero,IntPtr. Zero);
MessageBox.Show(ImageHandle.ToString());
System.Drawing.Image MyImg=
System.Drawing.Image.FromHbitmap((IntPtr)330544401 9); //Arithmetic
operation resulted in an overflow.
//System.Drawing.Image MyImg=
System.Drawing.Image.FromHbitmap(ImageHandle); //Exception
Button Button1 = new Button();
Button1.Image=MyImg;
Aug 22 '08 #4
On Thu, 21 Aug 2008 22:07:33 -0700, michelqa <mi******@yahoo.cawrote:
Ok , I'll try to explain the problem :
1- I know that WM_GETIMAGE is suppose to return an hImage hex
c50512b3 (3305444019) ... I know that because I'm logging the message
in SPY++
2- My sendMessage in my c# app return -989523277 (or
8975925797277995699 when modifying sendmessage definition to return a
long instead of a IntPtr) *** Why this difference???? ****
Um. The handle is a 32-bit value. The hex value 0xc50512b3 is _exactly_
the same as the _signed_ decimal value -989523277.
3- Even with the correct image handle hardcoded like this :
System.Drawing.Image MyImg=
System.Drawing.Image.FromHbitmap((IntPtr)330544401 9);
I get the error : Arithmetic operation resulted in an overflow.
Yes, of course it would. The value 3305444019 won't fit into a _signed_
32-bit integer.
As I understand it FromHbitmap want an IntPtr and 3305444019 is to big
for a Integer

Dont think a more complete example will help to understand the problem
but here is my example...I have a Win32 application and I want to copy
Button image from it and put the image in a button or a picturebox in
my c#
Well, first of all, that example doesn't compile. So it's really not much
of an example. Secondly, it's not a _complete_ example. If it were,
anyone would be able to take the example, run it through the C# compiler
without any changes or additions, and have a working executable that they
could run and see the exact problem.

Anything short of that is not "complete".

That said, in the little bit of code you did post, I don't see anything
that's obviously wrong. If I were you, I would check to see that the
basic concept works as you expect in unmanaged code, that you can get the
basic concept to work using _only_ managed code (i.e. create the Bitmap
standalone, get the HBITMAP from it and use that to create a new Bitmap),
and then verify that the format of the HBITMAP you get from SendMessage()
is compatible with what .NET expects (you can call the unmanaged function
GetObject() to get a BITMAP structure, or GetDIBits() to get a BITMAPINFO
structure).

With such a tiny snippet of sample code, I have to guess, and having to
guess it's my guess that you're getting a valid HBITMAP handle back, but
it represents a GDI bitmap object that .NET just doesn't want to bother
with (most likely because of the format of the bitmap).

Pete
Aug 22 '08 #5
Just to make things correctly :

1- Download controlSpy from
http://www.microsoft.com/downloads/d...displaylang=en
2- Run controlSpy6.exe. Go to the button section, Apply the BS_BITMAP
style, and then go to the Message tab and send the "SetImage" message.
3- With Spy++ get the handle of the button and convert it to integer
4- Replace the Handle value in for the Handle variable in the
Form_load of the following code
5- Run the code. (My code is .net 1.0)
<Code>
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Diagnostics;
using System.Data;

namespace GetWin32ButtonImage
{
public class Form1 : System.Windows.Forms.Form
{
private System.ComponentModel.Container components = null;

public Form1()
{
InitializeComponent();
}
protected override void Dispose( bool disposing )
{
if( disposing )
{
if (components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}

#region Windows Form Designer generated code

private void InitializeComponent()
{

this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
this.ClientSize = new System.Drawing.Size(292, 266);
this.Name = "Form1";
this.Text = "Form1";
this.Load += new System.EventHandler(this.Form1_Load);

}
#endregion

[DllImport("user32.dll")]
public static extern IntPtr SendMessage(IntPtr hwnd, int msg,
IntPtr
wparam, IntPtr lparam);

[STAThread]
static void Main()
{
Application.Run(new Form1());
}
private void Form1_Load(object sender, System.EventArgs e)
{
IntPtr Handle=(IntPtr)666666; //*** REPLACE THE HANDLE HERE ***//
int BM_GETIMAGE = 246;
IntPtr ImageHandle =
SendMessage(Handle,BM_GETIMAGE,IntPtr.Zero,IntPtr. Zero);
System.Drawing.Image MyImg=
System.Drawing.Image.FromHbitmap(ImageHandle);
MessageBox.Show("We have a valid bitmap!!! :
height="+MyImg.Height.ToString())
}
}
}
</Code>

Now we have a full working example! ;o) You can skip the 3 first step
if you can find a button with BS_BITMAP style and with an image. (not
an icon...BS_ICON)
Aug 22 '08 #6
The ImageHandle you are retrieving is relative to the button's process. In
the process in which you are trying to create the Bitmap that handle is
meaningless.

"michelqa" <mi******@yahoo.cawrote in message
news:e5**********************************@v57g2000 hse.googlegroups.com...
When executing some win32 messages in c# I get unexpected results.
The following example is suppose to return the handle of an image in a
button control of another application but it return a negative
handle...is anybody know why it return an invalid handle like
"-989523277" ??

IntPtr ImageHandle =
Win32.SendMessage(Handle,BM_GETIMAGE,IntPtr.Zero,I ntPtr.Zero);
MessageBox.Show(ImageHandle.ToString());

Note : the third param is set to IMAGE_BITMAP (0); it return 0 if
the button contain no image.

Thanks...

Aug 22 '08 #7
On Fri, 22 Aug 2008 00:00:19 -0700, michelqa <mi******@yahoo.cawrote:
Just to make things correctly :

1- Download controlSpy from
http://www.microsoft.com/downloads/d...displaylang=en
2- Run controlSpy6.exe. Go to the button section, Apply the BS_BITMAP
style, and then go to the Message tab and send the "SetImage" message.
3- With Spy++ get the handle of the button and convert it to integer
4- Replace the Handle value in for the Handle variable in the
Form_load of the following code
5- Run the code. (My code is .net 1.0)
Okay, I think I see your mistake. Handles are valid only within a given
process. You can't get a handle value from one process, and then use it
in some other process.

Pete
Aug 22 '08 #8
OK thanks....that's explain the weird unusable image handle... The
*only* way to do it will be by creating and a dll to inject into the
other process and setting a windows hook. Is there any other way to
execute my code into the other process ?

Aug 22 '08 #9
On Fri, 22 Aug 2008 12:08:27 -0700, michelqa <mi******@yahoo.cawrote:
OK thanks....that's explain the weird unusable image handle... The
*only* way to do it will be by creating and a dll to inject into the
other process and setting a windows hook. Is there any other way to
execute my code into the other process ?
Any way? Sure. But not without your code looking like malware, and not
without using malware-like techniques.

It's _possible_ that if you describe what you're really trying to do here,
from the high-level goal perspective, ignoring completely any particular
implementation details, someone could offer better advice.

Pete
Aug 22 '08 #10
It's _possible_ that if you describe what you're really trying to do here, *
*from the high-level goal perspective, ignoring completely any particular *
implementation details, someone could offer better advice.

Pete
I'm doing a tool like spy++. Win32 controls are interpreted (runtime
converted) as .net object
for example Win32 control properties are displayed in a managed
propertyGrid of my spy++ application just like any other .Net
control.

My question was about filling Button.Image in my property grid
(selectedObject is a button) when converting a Win32 control to a .net
control.

I was just wondering why WM_GETIMAGE return unusable image handle...
(never seen a negative handle since now) With your help I understand
that it return a negative unasable handle because it's in another
process.

I already use a dll and a windows hook to get things like
Button.ImageList with WM_GETIMAGELIST and will probably use the same
kind of code to get the image handle of WM_GETIMAGE from the other
process.

Pete : What you mean By malware-like techniques?? Is there any other
way to do this without hooking windows to inject a dll into the other
process???

Since you always trying to help me in different threads here , you now
know why i'm asking win32 to .net questions. :)
Aug 22 '08 #11
On Fri, 22 Aug 2008 14:41:00 -0700, michelqa <mi******@yahoo.cawrote:
[...]
I was just wondering why WM_GETIMAGE return unusable image handle...
(never seen a negative handle since now) With your help I understand
that it return a negative unasable handle because it's in another
process.
Just to clarify: the fact that the IntPtr appears as a negative number is
irrelevant. It would look that way (and does) in the process where it's
valid. The reason it's not usable is that it's relative to the process,
and your process isn't the one where the handle is defined.
I already use a dll and a windows hook to get things like
Button.ImageList with WM_GETIMAGELIST and will probably use the same
kind of code to get the image handle of WM_GETIMAGE from the other
process.

Pete : What you mean By malware-like techniques?? Is there any other
way to do this without hooking windows to inject a dll into the other
process???
A common malware technique is to take advantage of some vulnerability in a
process that fools it into loading the malware code into that process's
own address space and executing the code. Unless a process is
specifically designed to intentionally execute third-party code (e.g. has
some sort of plug-in interface), fooling it into running code is the only
alternative, and these techniques are all mainly used by malware, not by
legitimate applications.

Pete
Aug 22 '08 #12

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

2 posts views Thread by Le Thanh Thuan | last post: by
3 posts views Thread by ScottWPNY | last post: by
8 posts views Thread by Rob Edwards | last post: by
5 posts views Thread by Yoavo | last post: by
reply views Thread by Ferd Biffle | last post: by
5 posts views Thread by John | last post: by
1 post views Thread by XIAOLAOHU | last post: by
reply views Thread by leo001 | last post: by

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.