要操作的目标进程是别人用VC++开发的外部程序。
现在我要在自己的程序里模拟鼠标双击目标进程内的TreeView控件中的节点。
已经获得:
要操作的进程句柄、TreeView控件句柄、要双击的节点的句柄、目标进程句柄、目标进程ID。
可以正确展开TreeView节点、可以选择TreeView节点:
SendMessage(TreeViewHwnd, TVM_SELECTITEM, TVGN_CARET, ItemHwnd);
如何发送消息双击该节点?不要问我双击节点的用途是什么,我仅仅是模仿鼠标双击该节点的操作,而不是要选择该节点或展开该节点。
现在我要在自己的程序里模拟鼠标双击目标进程内的TreeView控件中的节点。
已经获得:
要操作的进程句柄、TreeView控件句柄、要双击的节点的句柄、目标进程句柄、目标进程ID。
可以正确展开TreeView节点、可以选择TreeView节点:
SendMessage(TreeViewHwnd, TVM_SELECTITEM, TVGN_CARET, ItemHwnd);
如何发送消息双击该节点?不要问我双击节点的用途是什么,我仅仅是模仿鼠标双击该节点的操作,而不是要选择该节点或展开该节点。
解决方案 »
- C# C++ 关于类中引用类型分配空间的疑问( 一段小程序)
- 微软中间语言IL
- asp.net中获取客户端连接信息
- 如何使用ALT+F2
- C#打造自己的文件浏览器 出现问题
- 一个本地文件把它压缩以后上传保存到sql数据库,数据库中字段的类型是Image类型的(二进制)。怎么压缩上传啊?又怎么从数据库中把它读取出来。保存到数据库中了。怎么把它取出来放到本地啊。谁有调试通过的代码?兄弟急等啊
- 查找字符串中字符的位置
- oa文档中的代码,有人看过吗?懂得帮我解释一下?
- 哪个可以给我解释下编码方式和字符集?
- c#如何写 让图片循环显示?
- Drawstring怎样绘制斜放的字体 望高手不吝赐教
- C# 哪个控件可以显示文本文档.txt的内容?
如果要展开节点或者要让TreeView的父窗口响应双击事件,可以用消息。
可以通过TVM_GETITEMRECT消息取得
SendMessage(TreeViewHwnd, TVM_GETITEMRECT, fItemRect , prc );TVM_GETITEMRECT:
fItemRect
Boolean value that specifies the portion of the item for which to retrieve the bounding rectangle. If set to TRUE, the bounding rectangle includes only the text of the item. If set to FALSE, it includes the entire line that the item occupies in the tree view control.
prc
Pointer to a RECT structure that, when sending the message, contains the handle of the item to retrieve the rectangle for. For more information on how to place the item handle in this parameter, see the Res section. After returning from the message, this parameter contains the bounding rectangle. The coordinates are relative to the upper-left corner of the tree view control.
WM_LBUTTONDBLCLK:
wParam
Indicates whether various virtual keys are down. This parameter can be one or more of the following values.
MK_CONTROL
The CTRL key is down.
MK_LBUTTON
The left mouse button is down.
MK_MBUTTON
The middle mouse button is down.
MK_RBUTTON
The right mouse button is down.
MK_SHIFT
The SHIFT key is down.
MK_XBUTTON1
Windows 2000/XP: The first X button is down.
MK_XBUTTON2
Windows 2000/XP: The second X button is down.
lParam
The low-order word specifies the x-coordinate of the cursor. The coordinate is relative to the upper-left corner of the client area. The high-order word specifies the y-coordinate of the cursor. The coordinate is relative to the upper-left corner of the client area.
Ensures that a tree-view item is visible, expanding the parent item or scrolling the tree-view control, if necessary. You can send this message explicitly or by using the TreeView_EnsureVisible macro. ParameterswParam
Must be zero.
hitem
Handle to the item.
Return ValueResIf the TVM_ENSUREVISIBLE message expands the parent item, the parent window receives the TVN_ITEMEXPANDING and TVN_ITEMEXPANDED notification messages.参考:
http://msdn.microsoft.com/en-us/library/bb773566(VS.85).aspx
public static extern IntPtr SendMessage(IntPtr hWnd, int Msg, int wParam, RECT rect); [DllImport("kernel32 ", CharSet = CharSet.Unicode)]
public static extern int CopyMemory(RECT Destination, IntPtr Source, int Length);[StructLayout(LayoutKind.Sequential)]
public struct RECT
{
public int left;
public int top;
public int right;
public int bottom;
}public static RECT GetItemRECT(IntPtr TreeViewHwnd, IntPtr ItemHwnd)
{
IntPtr rect = Marshal.SizeOf(typeof(RECT));
RECT itemRect = new RECT();
SendMessage(TreeViewHwnd, TVM_GETITEMRECT, 0, rect);
CopyMemory(itemRect, rect, Marshal.SizeOf(typeof(RECT)));
Marshal.FreeHGlobal(rect);
return itemRect;
}
public static RECT GetTreeViewItemRECT(IntPtr TreeViewHandle, IntPtr TreeItemHandle)
{
uint vProcessId;
GetWindowThreadProcessId(TreeViewHandle, out vProcessId);
IntPtr vProcess = OpenProcess(PROCESS_VM_OPERATION | PROCESS_VM_READ | PROCESS_VM_WRITE, false, vProcessId);
IntPtr vPointer = VirtualAllocEx(vProcess, IntPtr.Zero, 4096, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
RECT[] rect = new RECT[1];
try
{
uint vNumberOfBytesRead = 0;
WriteProcessMemory(vProcess, vPointer, Marshal.UnsafeAddrOfPinnedArrayElement(rect, 0), Marshal.SizeOf(typeof(RECT)), ref vNumberOfBytesRead);
SendMessage(TreeViewHandle, TVM_GETITEMRECT, false, (int)vPointer);
ReadProcessMemory(vProcess, (IntPtr)((int)vPointer + Marshal.SizeOf(typeof(RECT))), Marshal.UnsafeAddrOfPinnedArrayElement(rect, 0), Marshal.SizeOf(typeof(RECT)), ref vNumberOfBytesRead);
}
finally
{
VirtualFreeEx(vProcess, vPointer, 0, MEM_RELEASE);
CloseHandle(vProcess);
}
return rect[0];
}
bool GetTreeItemRect(HWND TreeView, HTREEITEM TreeItem, RECT& Rect)
{
bool result = false;
DWORD processId = 0;
GetWindowThreadProcessId(TreeView, &processId);
HANDLE process = OpenProcess(PROCESS_VM_OPERATION | PROCESS_VM_READ | PROCESS_VM_WRITE, FALSE, processId);
if (process != NULL)
{
LPVOID buffer = VirtualAllocEx(process, NULL, 4096, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
if (buffer != NULL)
{
SIZE_T bytes;
WriteProcessMemory(process, buffer, &TreeItem, sizeof(TreeItem), &bytes);
result = (SendMessage(TreeView, TVM_GETITEMRECT, FALSE, (LPARAM)buffer) != 0);
ReadProcessMemory(process, buffer, &Rect, sizeof(Rect), &bytes);
VirtualFreeEx(process, buffer, 0, MEM_RELEASE);
}
CloseHandle(process);
}
return result;
}
这一句每次都返回是false,每次调用这个API都不成功,不知道什么原因。。
读取内存后RECT结构都是0,0,0,0
{
bool result = false;
uint processId;
GetWindowThreadProcessId(TreeViewHandle, out processId);
IntPtr process = OpenProcess(PROCESS_VM_OPERATION | PROCESS_VM_READ | PROCESS_VM_WRITE, false, processId);
IntPtr buffer = VirtualAllocEx(process, IntPtr.Zero, 4096, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
try
{
uint bytes = 0;
WriteProcessMemory(process, buffer, TreeItemHandle, Marshal.SizeOf(TreeItemHandle), ref bytes);
result = SendMessage(TreeViewHandle, TVM_GETITEMRECT, false, buffer);
ReadProcessMemory(process, buffer, Marshal.UnsafeAddrOfPinnedArrayElement(Rect, 0), Marshal.SizeOf(typeof(RECT)), ref bytes);
}
finally
{
VirtualFreeEx(process, buffer, 0, MEM_RELEASE);
CloseHandle(process);
}
return result;
}
代码是这样的。
SendMessage(TreeViewHandle, TVM_GETITEMRECT, false, buffer);可是我这样发消息每次返回值都是false,说明不成功。。接下来从内存中复制出来的RECT肯定是0,0,0,0
因为SendMessage都没调用成功。。