Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
CODE PROJECT For Those Who Code
  • Home
  • Articles
  • FAQ
Community
  1. Home
  2. General Programming
  3. C#
  4. Passing an int array by refеrence to a shell function - how?

Passing an int array by refеrence to a shell function - how?

Scheduled Pinned Locked Moved C#
comlinuxdata-structureshelptutorial
12 Posts 2 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • I Offline
    I Offline
    iliyang
    wrote on last edited by
    #1

    Hello, I'm trying to send the HDM_GETORDERARRAY message to my ListView. The problem is that it requires a pointer to an array to write the indicies in. And I don't know how to pass an array of integers, so that I can read what's been written in it. Any suggestions? Thanks in advance!

    J 1 Reply Last reply
    0
    • I iliyang

      Hello, I'm trying to send the HDM_GETORDERARRAY message to my ListView. The problem is that it requires a pointer to an array to write the indicies in. And I don't know how to pass an array of integers, so that I can read what's been written in it. Any suggestions? Thanks in advance!

      J Offline
      J Offline
      jjansen
      wrote on last edited by
      #2

      I assume your already familiar with using unmanaged code (Introp calls etc.) Try this: int[] MyArrayOfInts = ... fixed(int* p_MyArrayOfInts = MyArrayOfInts) { ThatFunction(p_MyArrayOfInts); } Good luck.

      I 1 Reply Last reply
      0
      • J jjansen

        I assume your already familiar with using unmanaged code (Introp calls etc.) Try this: int[] MyArrayOfInts = ... fixed(int* p_MyArrayOfInts = MyArrayOfInts) { ThatFunction(p_MyArrayOfInts); } Good luck.

        I Offline
        I Offline
        iliyang
        wrote on last edited by
        #3

        OK, but the function prototype is: protected static extern IntPtr SendMessage(IntPtr hWnd, int msg, int wParam, ref int lParam) that is, I have to pass an integer, not an interger pointer...

        J 1 Reply Last reply
        0
        • I iliyang

          OK, but the function prototype is: protected static extern IntPtr SendMessage(IntPtr hWnd, int msg, int wParam, ref int lParam) that is, I have to pass an integer, not an interger pointer...

          J Offline
          J Offline
          jjansen
          wrote on last edited by
          #4

          iliyang wrote: that is, I have to pass an integer, not an interger pointer... The syntax is: lResult = SendMessage( // returns LRESULT in lResult (HWND) hWndControl, // handle to destination control (UINT) HDM_GETORDERARRAY, // message ID (WPARAM) wParam, // = (WPARAM) (int) iSize; (LPARAM) lParam // = (LPARAM) (LPINT) lpiArray; ); where lpiArray is: Pointer to an array of integers that receive the index values for items in the header. So you do have to pass an array (even if the array is only one element long). The pointer in the code of my previous post is merely a pointer to the FIRST integer in a row. From there the app can access the next integer, and the next, and so on. It will assume there are iSize integers in a row, starting at the address that is the pointer.

          I 1 Reply Last reply
          0
          • J jjansen

            iliyang wrote: that is, I have to pass an integer, not an interger pointer... The syntax is: lResult = SendMessage( // returns LRESULT in lResult (HWND) hWndControl, // handle to destination control (UINT) HDM_GETORDERARRAY, // message ID (WPARAM) wParam, // = (WPARAM) (int) iSize; (LPARAM) lParam // = (LPARAM) (LPINT) lpiArray; ); where lpiArray is: Pointer to an array of integers that receive the index values for items in the header. So you do have to pass an array (even if the array is only one element long). The pointer in the code of my previous post is merely a pointer to the FIRST integer in a row. From there the app can access the next integer, and the next, and so on. It will assume there are iSize integers in a row, starting at the address that is the pointer.

            I Offline
            I Offline
            iliyang
            wrote on last edited by
            #5

            OK, 10x a lot! It worked finde when I called the function like this: int[] MyArrayOfInts = ... fixed(int* p_MyArrayOfInts = MyArrayOfInts) { ThatFunction(*p_MyArrayOfInts); // not: ThatFunction(p_MyArrayOfInts); }

            J 1 Reply Last reply
            0
            • I iliyang

              OK, 10x a lot! It worked finde when I called the function like this: int[] MyArrayOfInts = ... fixed(int* p_MyArrayOfInts = MyArrayOfInts) { ThatFunction(*p_MyArrayOfInts); // not: ThatFunction(p_MyArrayOfInts); }

              J Offline
              J Offline
              jjansen
              wrote on last edited by
              #6

              Huh? :confused: That's not a pointer to an array you're putting in the function but the value of the first array element. Anyhow, I was going to recommend an alternative method. The Interop-call to SendMessage should look something like this: [DllImport("user32.dll"] public static extern int SendMessage(IntPtr hwnd, uint wMsg, IntPtr wParam, IntPtr lParam); You can get an IntPtr to your array using Marshal.Copy(Int[] source, int startIndex, IntPtr destination, int length). I've never used Marshal.Copy before, so if you're decide to try it this way let me know how it turns out.

              I 1 Reply Last reply
              0
              • J jjansen

                Huh? :confused: That's not a pointer to an array you're putting in the function but the value of the first array element. Anyhow, I was going to recommend an alternative method. The Interop-call to SendMessage should look something like this: [DllImport("user32.dll"] public static extern int SendMessage(IntPtr hwnd, uint wMsg, IntPtr wParam, IntPtr lParam); You can get an IntPtr to your array using Marshal.Copy(Int[] source, int startIndex, IntPtr destination, int length). I've never used Marshal.Copy before, so if you're decide to try it this way let me know how it turns out.

                I Offline
                I Offline
                iliyang
                wrote on last edited by
                #7

                Yes, I know that I'm passing the first element of the array, but I just tried and it worked fine :) The second method (with the IntPtr) I found ealier but I didn't know how to obtain an IntPtr object. I suppose with the IntPtr is better too. But how should I get an IntPtr object to copy the array into?

                J 1 Reply Last reply
                0
                • I iliyang

                  Yes, I know that I'm passing the first element of the array, but I just tried and it worked fine :) The second method (with the IntPtr) I found ealier but I didn't know how to obtain an IntPtr object. I suppose with the IntPtr is better too. But how should I get an IntPtr object to copy the array into?

                  J Offline
                  J Offline
                  jjansen
                  wrote on last edited by
                  #8

                  Just make one: int[] MyArray = ... IntPtr MyPointer = IntPtr.Zero; // make and initialize Marshal.Copy(MyArray, 0, MyPointer, MyArray.Length); (Note: Don't confuse the marshal-call with the overload Marshal.Copy(IntPtr, int[], int, int) .)

                  I 1 Reply Last reply
                  0
                  • J jjansen

                    Just make one: int[] MyArray = ... IntPtr MyPointer = IntPtr.Zero; // make and initialize Marshal.Copy(MyArray, 0, MyPointer, MyArray.Length); (Note: Don't confuse the marshal-call with the overload Marshal.Copy(IntPtr, int[], int, int) .)

                    I Offline
                    I Offline
                    iliyang
                    wrote on last edited by
                    #9

                    Nope, Marshal.Copy throws a NullReference exception when passing a null (0) IntPtr object. So for now, the "mystical" solution works the best :rolleyes:

                    J 1 Reply Last reply
                    0
                    • I iliyang

                      Nope, Marshal.Copy throws a NullReference exception when passing a null (0) IntPtr object. So for now, the "mystical" solution works the best :rolleyes:

                      J Offline
                      J Offline
                      jjansen
                      wrote on last edited by
                      #10

                      You're right, my mistake. I wrongly assumed that the Copy method returns a pointer to the array. On second thought this isn't what Copy does at all. Instead you have to allocate some space yourself using Marshal.AllocHGlobal with the appropriate number of bytes. This gives you a valid IntPtr. int Nr = ...; // number of elements in array int[] MyArray = new int[Nr]; IntPtr MyPtr = Marshal.AllocHGlobal(Nr * sizeof(int)) Then call SendMessage with MyPtr. Next use the Copy(IntPtr MyPtr, int[] MyArray, 0, MyArray.Length) method. Finally use Marshal.FreeHAlloc.

                      I 1 Reply Last reply
                      0
                      • J jjansen

                        You're right, my mistake. I wrongly assumed that the Copy method returns a pointer to the array. On second thought this isn't what Copy does at all. Instead you have to allocate some space yourself using Marshal.AllocHGlobal with the appropriate number of bytes. This gives you a valid IntPtr. int Nr = ...; // number of elements in array int[] MyArray = new int[Nr]; IntPtr MyPtr = Marshal.AllocHGlobal(Nr * sizeof(int)) Then call SendMessage with MyPtr. Next use the Copy(IntPtr MyPtr, int[] MyArray, 0, MyArray.Length) method. Finally use Marshal.FreeHAlloc.

                        I Offline
                        I Offline
                        iliyang
                        wrote on last edited by
                        #11

                        Well, this time works but the values returned are messed. But, you know, this does work fine: _columnOrder = new int[this.Columns.Count]; int size = 0; IntPtr pHeader = SendMessage(this.Handle, (int) Win32.Consts.LVM_GETHEADER, 0, ref size); SendMessage(pHeader, (int) Win32.Consts.HDM_GETORDERARRAY, _columnOrder.Length, ref _columnOrder[0]); See the ref _columnOrder[0] in the second SendMessage call ;)

                        J 1 Reply Last reply
                        0
                        • I iliyang

                          Well, this time works but the values returned are messed. But, you know, this does work fine: _columnOrder = new int[this.Columns.Count]; int size = 0; IntPtr pHeader = SendMessage(this.Handle, (int) Win32.Consts.LVM_GETHEADER, 0, ref size); SendMessage(pHeader, (int) Win32.Consts.HDM_GETORDERARRAY, _columnOrder.Length, ref _columnOrder[0]); See the ref _columnOrder[0] in the second SendMessage call ;)

                          J Offline
                          J Offline
                          jjansen
                          wrote on last edited by
                          #12

                          OK, good luck with your project.

                          1 Reply Last reply
                          0
                          Reply
                          • Reply as topic
                          Log in to reply
                          • Oldest to Newest
                          • Newest to Oldest
                          • Most Votes


                          • Login

                          • Don't have an account? Register

                          • Login or register to search.
                          • First post
                            Last post
                          0
                          • Categories
                          • Recent
                          • Tags
                          • Popular
                          • World
                          • Users
                          • Groups