public void DoubleClickListview(IntPtr handle,int index)
{
AccessWin aw = new AccessWin();
int vItemCount;
int ColumnCount;
IntPtr vHandle = handle;
if (vHandle == IntPtr.Zero) return; //选中Listview的某个Item 测试已工作,不过就是如果原来已经点中一个Item那么这次就变成复选了
vItemCount = NativeMethods.SendMessageW(vHandle, NativeMethods.LVM_GETITEMCOUNT, 0, 0);
IntPtr handleHeader = new IntPtr(NativeMethods.SendMessageW(vHandle, NativeMethods.LVM_GETHEADER, 0, 0));
ColumnCount = NativeMethods.SendMessageW(handleHeader, NativeMethods.HDM_GETITEMCOUNT, 0, 0);
uint vProcessId;
NativeMethods.GetWindowThreadProcessId(vHandle, out vProcessId);
IntPtr vProcess = NativeMethods.OpenProcess(NativeMethods.PROCESS_VM_OPERATION | NativeMethods.PROCESS_VM_READ | NativeMethods.PROCESS_VM_WRITE, false, vProcessId);
IntPtr vPointer = NativeMethods.VirtualAllocEx(vProcess, IntPtr.Zero, 4096, NativeMethods.MEM_RESERVE | NativeMethods.MEM_COMMIT, NativeMethods.PAGE_READWRITE);
NativeMethods.LVITEM[] vItem = new NativeMethods.LVITEM[1];
vItem[0].state = NativeMethods.LVIS_SELECTED | NativeMethods.LVIS_FOCUSED | NativeMethods.LVIS_ACTIVATING;
vItem[0].stateMask = NativeMethods.LVIS_SELECTED;
uint vNumberOfBytesRead = 0;
NativeMethods.WriteProcessMemory(vProcess, vPointer, Marshal.UnsafeAddrOfPinnedArrayElement(vItem, 0), Marshal.SizeOf(typeof(NativeMethods.LVITEM)), ref vNumberOfBytesRead);
NativeMethods.SendMessageW(handle, NativeMethods.LVM_SETITEMSTATE, (uint)index, vPointer.ToInt32());
//伪造 WM_NOTIFY message并发给父窗口,这段完全不工作,也不报错误,不知道问题在哪,高人啊,快出来
NativeMethods.NMHDR[] myNMHDR=new NativeMethods.NMHDR[1];
IntPtr pNMHDR = NativeMethods.VirtualAllocEx(vProcess, IntPtr.Zero, (uint)Marshal.SizeOf(typeof(NativeMethods.NMHDR)), NativeMethods.MEM_COMMIT, NativeMethods.PAGE_READWRITE);
myNMHDR[0].code = NativeMethods.NM_DBLCLK;
myNMHDR[0].hwndFrom = handle;
myNMHDR[0].idFrom = (uint)NativeMethods.GetWindowLongW(handle, NativeMethods.GWL_ID);
NativeMethods.WriteProcessMemory(vProcess, pNMHDR, Marshal.UnsafeAddrOfPinnedArrayElement(myNMHDR, 0), Marshal.SizeOf(typeof(NativeMethods.NMHDR)), ref vNumberOfBytesRead);
IntPtr parenthwnd = NativeMethods.GetParent(handle);
NativeMethods.SendMessageW(parenthwnd, NativeMethods.WM_NOTIFY, myNMHDR[0].idFrom, pNMHDR.ToInt32()); NativeMethods.CloseHandle(vProcess);
NativeMethods.VirtualFreeEx(vProcess, vPointer, 0, NativeMethods.MEM_RELEASE);
NativeMethods.VirtualFreeEx(vProcess, pNMHDR,0, NativeMethods.MEM_RELEASE); }
{
AccessWin aw = new AccessWin();
int vItemCount;
int ColumnCount;
IntPtr vHandle = handle;
if (vHandle == IntPtr.Zero) return; //选中Listview的某个Item 测试已工作,不过就是如果原来已经点中一个Item那么这次就变成复选了
vItemCount = NativeMethods.SendMessageW(vHandle, NativeMethods.LVM_GETITEMCOUNT, 0, 0);
IntPtr handleHeader = new IntPtr(NativeMethods.SendMessageW(vHandle, NativeMethods.LVM_GETHEADER, 0, 0));
ColumnCount = NativeMethods.SendMessageW(handleHeader, NativeMethods.HDM_GETITEMCOUNT, 0, 0);
uint vProcessId;
NativeMethods.GetWindowThreadProcessId(vHandle, out vProcessId);
IntPtr vProcess = NativeMethods.OpenProcess(NativeMethods.PROCESS_VM_OPERATION | NativeMethods.PROCESS_VM_READ | NativeMethods.PROCESS_VM_WRITE, false, vProcessId);
IntPtr vPointer = NativeMethods.VirtualAllocEx(vProcess, IntPtr.Zero, 4096, NativeMethods.MEM_RESERVE | NativeMethods.MEM_COMMIT, NativeMethods.PAGE_READWRITE);
NativeMethods.LVITEM[] vItem = new NativeMethods.LVITEM[1];
vItem[0].state = NativeMethods.LVIS_SELECTED | NativeMethods.LVIS_FOCUSED | NativeMethods.LVIS_ACTIVATING;
vItem[0].stateMask = NativeMethods.LVIS_SELECTED;
uint vNumberOfBytesRead = 0;
NativeMethods.WriteProcessMemory(vProcess, vPointer, Marshal.UnsafeAddrOfPinnedArrayElement(vItem, 0), Marshal.SizeOf(typeof(NativeMethods.LVITEM)), ref vNumberOfBytesRead);
NativeMethods.SendMessageW(handle, NativeMethods.LVM_SETITEMSTATE, (uint)index, vPointer.ToInt32());
//伪造 WM_NOTIFY message并发给父窗口,这段完全不工作,也不报错误,不知道问题在哪,高人啊,快出来
NativeMethods.NMHDR[] myNMHDR=new NativeMethods.NMHDR[1];
IntPtr pNMHDR = NativeMethods.VirtualAllocEx(vProcess, IntPtr.Zero, (uint)Marshal.SizeOf(typeof(NativeMethods.NMHDR)), NativeMethods.MEM_COMMIT, NativeMethods.PAGE_READWRITE);
myNMHDR[0].code = NativeMethods.NM_DBLCLK;
myNMHDR[0].hwndFrom = handle;
myNMHDR[0].idFrom = (uint)NativeMethods.GetWindowLongW(handle, NativeMethods.GWL_ID);
NativeMethods.WriteProcessMemory(vProcess, pNMHDR, Marshal.UnsafeAddrOfPinnedArrayElement(myNMHDR, 0), Marshal.SizeOf(typeof(NativeMethods.NMHDR)), ref vNumberOfBytesRead);
IntPtr parenthwnd = NativeMethods.GetParent(handle);
NativeMethods.SendMessageW(parenthwnd, NativeMethods.WM_NOTIFY, myNMHDR[0].idFrom, pNMHDR.ToInt32()); NativeMethods.CloseHandle(vProcess);
NativeMethods.VirtualFreeEx(vProcess, vPointer, 0, NativeMethods.MEM_RELEASE);
NativeMethods.VirtualFreeEx(vProcess, pNMHDR,0, NativeMethods.MEM_RELEASE); }
myNMHDR[0].code = NativeMethods.NM_DBLCLK;
myNMHDR[0].hwndFrom = handle; //ListView的窗口句柄
myNMHDR[0].idFrom = (uint)NativeMethods.GetWindowLongW(handle,NativeMethods.GWL_ID);
NativeMethods.SendMessageW(parenthwnd, NativeMethods.WM_NOTIFY, myNMHDR[0].idFrom, pNMHDR.ToInt32()); //这句是向ListView的父窗口发送WM_NOTIFY消息。 因为我要操作的ListView是Delphi的VCL控件 Class名字是TXPListview,不知道是不是不支持这个消息啊
你的代码没改好现在是双击啊,这是第一点错误。第二点我在vb版已经强调了,不能使用SendMessage发送消息,所以这句“NativeMethods.SendMessageW(parenthwnd, NativeMethods.WM_NOTIFY, myNMHDR[0].idFrom, pNMHDR.ToInt32());”要改成PostMessage来发送即可
NativeMethods.NMHDR[] myNMHDR = new NativeMethods.NMHDR[1];
IntPtr pNMHDR = NativeMethods.VirtualAllocEx(vProcess, IntPtr.Zero, (uint)Marshal.SizeOf(typeof(NativeMethods.NMHDR)), NativeMethods.MEM_COMMIT, NativeMethods.PAGE_READWRITE); myNMHDR[0].code = NativeMethods.NM_DBLCLK;
myNMHDR[0].hwndFrom = handle;
myNMHDR[0].idFrom = (uint)NativeMethods.GetWindowLongW(handle, NativeMethods.GWL_ID);
NativeMethods.WriteProcessMemory(vProcess, pNMHDR, Marshal.UnsafeAddrOfPinnedArrayElement(myNMHDR, 0), Marshal.SizeOf(typeof(NativeMethods.NMHDR)), ref vNumberOfBytesRead);
IntPtr parenthwnd = NativeMethods.GetParent(NativeMethods.GetParent(handle));
NativeMethods.PostMessageW(parenthwnd, NativeMethods.WM_NOTIFY, myNMHDR[0].idFrom, pNMHDR.ToInt32()); NativeMethods.VirtualFreeEx(vProcess, pNMHDR, 0, NativeMethods.MEM_RELEASE); //另外这句运行的时候,远程端程序会报一个内存访问冲突的错误 NativeMethods.CloseHandle(vProcess);
看下你PostMessage怎么声明的,然后那句内存访问错误是因为PostMessage是立即返回函数,所以会这样建议把两句VirtualFreeEx注释下再试
我就用c#写过两个程序后就没碰了,现在没装.net不然可以帮你调试下,应该是可以通用的我估计是你哪里没转换好
{
NativeMethods.PostMessageW(handle,NativeMethods.WM_KEYDOWN,NativeMethods.VK_F2,0);
}调试OK,立马放分!
public const int NM_FIRST = 0;
public const int NM_DBLCLK = (NM_FIRST - 3);
public const int GWL_ID = -12;
public const int WM_NOTIFY = 78;[System.Runtime.InteropServices.DllImportAttribute("user32.dll", EntryPoint = "GetWindowLongW")]public static extern int GetWindowLongW([System.Runtime.InteropServices.InAttribute()] System.IntPtr hWnd, int nIndex);[System.Runtime.InteropServices.DllImportAttribute("user32.dll", EntryPoint = "GetParent")]public static extern System.IntPtr GetParent([System.Runtime.InteropServices.InAttribute()] System.IntPtr hWnd);
[System.Runtime.InteropServices.DllImportAttribute("user32.dll", EntryPoint = "GetDlgCtrlID")]public static extern int GetDlgCtrlID([System.Runtime.InteropServices.InAttribute()] System.IntPtr hWnd);用SPY++监视ListView窗口消息发送如下:
<00396> 00010C74 S message:0x1004[用于定义:WM_USER+3076] wParam:00000000 IParam:00000000
<00397> 00010C74 R message:0x1004[用户定义:WM_USER+3076] IResult 00000005
<00398> 00010C74 S message:0x101F[用户定义:WM_USER+3103] wParam:00000000 IParam:00000000
<00399> 0010C74 R message 0x101F[用户定义:WM_USER+3103] IRESULT=00010C78