Advertisement
Guest User

Expose data grid listveiw item with P/Invoke and Marshaling

a guest
May 20th, 2012
1,026
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 6.00 KB | None | 0 0
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Runtime.InteropServices;
  6.  
  7. namespace ConsoleApplication7
  8. {
  9.     class Program
  10.     {
  11.  
  12. const int LVM_GETITEM = 0x1005;
  13.   const int LVM_SETITEM = 0x1006;
  14.   const int LVIF_TEXT   = 0x0001;
  15.   const uint PROCESS_ALL_ACCESS = (uint)(0x000F0000L | 0x00100000L | 0xFFF);
  16.   const uint MEM_COMMIT         = 0x1000;
  17.   const uint MEM_RELEASE        = 0x8000;
  18.   const uint PAGE_READWRITE     = 0x04;
  19.  
  20.   [DllImport("user32.dll", SetLastError = true)]
  21.   static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
  22.  
  23.   [DllImport("user32.dll", SetLastError = true)]
  24.   public static extern IntPtr FindWindowEx(IntPtr parentHandle, IntPtr childAfter, string className, string windowTitle);
  25.  
  26.  
  27.   [DllImport("user32.dll")]
  28.   static extern bool SendMessage(IntPtr hWnd, Int32 msg, Int32 wParam, IntPtr lParam);
  29.  
  30.   [DllImport("user32")]
  31.   static extern IntPtr GetWindowThreadProcessId( IntPtr hWnd, out int lpwdProcessID );    
  32.  
  33.   [DllImport("kernel32")]
  34.   static extern IntPtr OpenProcess(uint dwDesiredAccess, bool bInheritHandle,
  35.     int dwProcessId);
  36.  
  37.   [DllImport("kernel32")]
  38.   static extern IntPtr VirtualAllocEx( IntPtr hProcess, IntPtr lpAddress,
  39.     int dwSize, uint flAllocationType, uint flProtect);
  40.  
  41.   [DllImport("kernel32")]
  42.   static extern bool VirtualFreeEx( IntPtr hProcess, IntPtr lpAddress, int dwSize,
  43.     uint dwFreeType );
  44.  
  45.   [DllImport("kernel32")]
  46.   static extern bool WriteProcessMemory( IntPtr hProcess, IntPtr lpBaseAddress,
  47.     ref LV_ITEM buffer, int dwSize, IntPtr lpNumberOfBytesWritten );
  48.  
  49.   [DllImport("kernel32")]
  50.   static extern bool ReadProcessMemory( IntPtr hProcess, IntPtr lpBaseAddress,
  51.     IntPtr lpBuffer, int dwSize, IntPtr lpNumberOfBytesRead );
  52.  
  53.   [DllImport("kernel32")]
  54.   static extern bool CloseHandle( IntPtr hObject );
  55.  
  56.   [StructLayout(LayoutKind.Sequential)]
  57.   public struct LV_ITEM
  58.   {
  59.     public uint   mask;
  60.     public int    iItem;
  61.     public int    iSubItem;
  62.     public uint   state;
  63.     public uint   stateMask;
  64.     public IntPtr pszText;
  65.     public int    cchTextMax;
  66.     public int    iImage;
  67.   }
  68.  
  69.  
  70.   [StructLayout(LayoutKind.Sequential)]
  71.   private struct POINT
  72.   {
  73.       public int x;
  74.       public int y;
  75.   };
  76.  
  77.   [DllImport("user32.dll")]
  78.   private static extern IntPtr WindowFromPoint(POINT pt);
  79.  
  80.   [DllImport("user32.dll")]
  81.  
  82.   private static extern int GetCursorPos(out POINT pt);
  83.   static void Main(string[] args)
  84.   {
  85.  
  86.             Console.WriteLine("Place pointer over listview and hit return...");
  87.             Console.ReadLine();
  88.  
  89.             // Get cursor position, then the window handle at that point...
  90.             POINT pt;
  91.             GetCursorPos(out pt);
  92.             IntPtr hwnd = WindowFromPoint(pt);
  93.             string str = ReadListViewItem(hwnd, 0, 1);
  94.  
  95.             Console.WriteLine("str = " + str.ToString() + Environment.NewLine + " !! done !!");
  96.  
  97.             Console.ReadKey();
  98.  
  99.  
  100.   }
  101.  
  102.   public static string ReadListViewItem(IntPtr hWnd, int item, int subitem)
  103.   {
  104.     const int dwBufferSize = 1024;
  105.          
  106.     int         dwProcessID;
  107.     LV_ITEM     lvItem;      
  108.     string      retval;
  109.     bool        bSuccess;
  110.     IntPtr      hProcess        = IntPtr.Zero;
  111.     IntPtr      lpRemoteBuffer  = IntPtr.Zero;
  112.     IntPtr      lpLocalBuffer   = IntPtr.Zero;
  113.     IntPtr      threadId        = IntPtr.Zero;
  114.          
  115.     try
  116.     {
  117.       lvItem = new LV_ITEM();
  118.       lpLocalBuffer = Marshal.AllocHGlobal(dwBufferSize);
  119.       // Get the process id owning the window
  120.       threadId = GetWindowThreadProcessId( hWnd, out dwProcessID );
  121.       if ( (threadId == IntPtr.Zero) || (dwProcessID == 0) ) throw new ArgumentException( "hWnd" );
  122.  
  123.       // Open the process with all access
  124.       hProcess = OpenProcess( PROCESS_ALL_ACCESS, false, dwProcessID );
  125.       if ( hProcess == IntPtr.Zero )  throw new ApplicationException( "Failed to access process" );
  126.  
  127.       // Allocate a buffer in the remote process
  128.       lpRemoteBuffer = VirtualAllocEx( hProcess, IntPtr.Zero, dwBufferSize, MEM_COMMIT,  PAGE_READWRITE );
  129.       if ( lpRemoteBuffer == IntPtr.Zero ) throw new SystemException( "Failed to allocate memory in remote process" );
  130.      
  131.       // Fill in the LVITEM struct, this is in your own process
  132.       // Set the pszText member to somewhere in the remote buffer,
  133.       // For the example I used the address imediately following the LVITEM stuct
  134.       lvItem.mask = LVIF_TEXT;
  135.       lvItem.iItem = item;
  136.       lvItem.iSubItem = subitem;
  137.       lvItem.pszText = (IntPtr)(lpRemoteBuffer.ToInt32() + Marshal.SizeOf(typeof(LV_ITEM)));
  138.       lvItem.cchTextMax = 50;
  139.  
  140.       // Copy the local LVITEM to the remote buffer
  141.       bSuccess = WriteProcessMemory( hProcess, lpRemoteBuffer, ref lvItem,
  142.         Marshal.SizeOf(typeof(LV_ITEM)), IntPtr.Zero );
  143.       if ( !bSuccess )
  144.         throw new SystemException( "Failed to write to process memory" );
  145.  
  146.       // Send the message to the remote window with the address of the remote buffer
  147.       SendMessage( hWnd, LVM_GETITEM, 0, lpRemoteBuffer);
  148.      
  149.       // Read the struct back from the remote process into local buffer
  150.       bSuccess = ReadProcessMemory( hProcess, lpRemoteBuffer, lpLocalBuffer, dwBufferSize,     IntPtr.Zero );
  151.       if ( !bSuccess )    throw new SystemException( "Failed to read from process memory" );
  152.      
  153.       // At this point the lpLocalBuffer contains the returned LV_ITEM structure
  154.       // the next line extracts the text from the buffer into a managed string
  155.       retval = Marshal.PtrToStringAnsi((IntPtr)(lpLocalBuffer.ToInt32() +
  156.         Marshal.SizeOf(typeof(LV_ITEM))));
  157.     }
  158.     finally
  159.     {
  160.       if ( lpLocalBuffer != IntPtr.Zero )
  161.         Marshal.FreeHGlobal( lpLocalBuffer );
  162.       if ( lpRemoteBuffer != IntPtr.Zero )
  163.         VirtualFreeEx( hProcess, lpRemoteBuffer, 0, MEM_RELEASE );
  164.       if ( hProcess != IntPtr.Zero )
  165.         CloseHandle( hProcess );
  166.     }
  167.     return retval;
  168.  
  169.  
  170.         }
  171.     }
  172. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement