Interop question

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • michelqa

    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.SendMessa ge(Handle,BM_GE TIMAGE,IntPtr.Z ero,IntPtr.Zero );
    MessageBox.Show (ImageHandle.To String());

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

    Thanks...
  • Peter Duniho

    #2
    Re: Interop question

    On Thu, 21 Aug 2008 20:35:26 -0700, michelqa <michelqa@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

    Comment

    • michelqa

      #3
      Re: Interop question

      On Aug 21, 11:44 pm, "Peter Duniho" <NpOeStPe...@nn owslpianmk.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...i t return a "Generic
      exception"

      //Handle = button handle of another application
      IntPtr ImageHandle =
      Win32.SendMessa ge(Handle,BM_GE TIMAGE,IntPtr.Z ero,IntPtr.Zero );
      MessageBox.Show (ImageHandle.To String());
      System.Drawing. Bitmap Bitmap =
      System.Drawing. Bitmap.FromHbit map(ImageHandle ); //generic exception
      from gdi..invalid handle?
      // Just want to get a usable bitmap here

      Comment

      • michelqa

        #4
        Re: Interop question

        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
        897592579727799 5699 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.FromHbitm ap((IntPtr)3305 444019);
        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("user 32.dll")]
        public static extern IntPtr SendMessage(Int Ptr hwnd, int msg, IntPtr
        wparam, IntPtr lparam);
        int BM_GETIMAGE = 0x00F6;
        IntPtr ImageHandle =
        SendMessage(Han dle,BM_GETIMAGE ,IntPtr.Zero,In tPtr.Zero);
        MessageBox.Show (ImageHandle.To String());
        System.Drawing. Image MyImg=
        System.Drawing. Image.FromHbitm ap((IntPtr)3305 444019); //Arithmetic
        operation resulted in an overflow.
        //System.Drawing. Image MyImg=
        System.Drawing. Image.FromHbitm ap(ImageHandle) ; //Exception
        Button Button1 = new Button();
        Button1.Image=M yImg;

        Comment

        • Peter Duniho

          #5
          Re: Interop question

          On Thu, 21 Aug 2008 22:07:33 -0700, michelqa <michelqa@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
          897592579727799 5699 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.FromHbitm ap((IntPtr)3305 444019);
          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

          Comment

          • michelqa

            #6
            Re: Interop question

            Just to make things correctly :

            1- Download controlSpy from

            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.Collecti ons;
            using System.Componen tModel;
            using System.Windows. Forms;
            using System.Runtime. InteropServices ;
            using System.Diagnost ics;
            using System.Data;

            namespace GetWin32ButtonI mage
            {
            public class Form1 : System.Windows. Forms.Form
            {
            private System.Componen tModel.Containe r components = null;

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

            #region Windows Form Designer generated code

            private void InitializeCompo nent()
            {

            this.AutoScaleB aseSize = new System.Drawing. Size(5, 13);
            this.ClientSize = new System.Drawing. Size(292, 266);
            this.Name = "Form1";
            this.Text = "Form1";
            this.Load += new System.EventHan dler(this.Form1 _Load);

            }
            #endregion

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

            [STAThread]
            static void Main()
            {
            Application.Run (new Form1());
            }
            private void Form1_Load(obje ct sender, System.EventArg s e)
            {
            IntPtr Handle=(IntPtr) 666666; //*** REPLACE THE HANDLE HERE ***//
            int BM_GETIMAGE = 246;
            IntPtr ImageHandle =
            SendMessage(Han dle,BM_GETIMAGE ,IntPtr.Zero,In tPtr.Zero);
            System.Drawing. Image MyImg=
            System.Drawing. Image.FromHbitm ap(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)

            Comment

            • Stephen Martin

              #7
              Re: Interop question

              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" <michelqa@yahoo .cawrote in message
              news:e5cac47e-7b2d-45e5-a7be-0b86605ccd76@v5 7g2000hse.googl egroups.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.SendMessa ge(Handle,BM_GE TIMAGE,IntPtr.Z ero,IntPtr.Zero );
              MessageBox.Show (ImageHandle.To String());
              >
              Note : the third param is set to IMAGE_BITMAP (0); it return 0 if
              the button contain no image.
              >
              Thanks...

              Comment

              • Peter Duniho

                #8
                Re: Interop question

                On Fri, 22 Aug 2008 00:00:19 -0700, michelqa <michelqa@yahoo .cawrote:
                Just to make things correctly :
                >
                1- Download controlSpy from

                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

                Comment

                • michelqa

                  #9
                  Re: Interop question

                  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 ?

                  Comment

                  • Peter Duniho

                    #10
                    Re: Interop question

                    On Fri, 22 Aug 2008 12:08:27 -0700, michelqa <michelqa@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

                    Comment

                    • michelqa

                      #11
                      Re: Interop question

                      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.ImageLis t 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. :)

                      Comment

                      • Peter Duniho

                        #12
                        Re: Interop question

                        On Fri, 22 Aug 2008 14:41:00 -0700, michelqa <michelqa@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.ImageLis t 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

                        Comment

                        Working...