由于当前进程和使用该进程启动的其他进程的之后,其他进程就会独立运行了,所以当主线程想使用其他进程的控件地址的时候,那么就会出现两种独立的虚拟地址的映射问题。
void CTWndToolbar::SetCtrlAction(HWNDhWnd,int nIndex)
{
if (!hWnd)
return;
int nBtnCount =::SendMessage(hWnd,TB_BUTTONCOUNT,(WPARAM)0,(LPARAM)0);
if(nIndex >= nBtnCount)
return;
HWND hMainWnd =::GetAncestor(hWnd,GA_ROOT);//回复句柄到指定窗口的父窗口
//鼠标事件
POINT ptOld = {0};
GetCursorPos(&ptOld);//屏幕坐标显示光标的位置
DWORD dwProcessID = 0;
unsigned long nSize=0;
RECT rectItem={0};
HANDLE hProcess = NULL;
RECT *pRect = NULL;
GetWindowThreadProcessId(hWnd,&dwProcessID);//找到指定窗口的创建者并返回其线程ID
hProcess =OpenProcess(PROCESS_ALL_ACCESS,false,dwProcessID);//打开一个已经存在的线程对象,并返回其句柄
if (!hProcess)
{
//::MessageBox(NULL,_T("获取进程句柄操作失败!"),_T("错误!"),MB_OK);//在程序运行过程中消息提示窗体
return ;
}
//
pRect=(RECT*)VirtualAllocEx(hProcess, NULL,sizeof(RECT), MEM_COMMIT,PAGE_READWRITE);//储备或提交的内存区域内的指定进程的虚拟地址空间
if (!pRect)
{
//MessageBox(NULL,_T("无法分配内存!"),_T("错误!"),MB_OK);
return ;
}
WriteProcessMemory(hProcess, pRect,&rectItem, sizeof(RECT), NULL);//写rectItem到指定的进程的内存区域
::SendMessage(hWnd, TB_GETITEMRECT,(WPARAM)nIndex, (LPARAM)pRect);
ReadProcessMemory(hProcess,pRect,&rectItem,sizeof(RECT),&nSize);//Thisfunction reads memory in a specified process. The entire area to beread must be accessible
POINT pt={0};
pt.x = rectItem.left +(rectItem.right-rectItem.left)/2;
pt.y = rectItem.top +(rectItem.bottom-rectItem.top)/2;
::ClientToScreen(hWnd,&pt);//转换成屏幕坐标
SetCursorPos(pt.x, pt.y);//该函数把光标移到屏幕的指定位置
//将该窗口置顶
HWND hForeWnd =NULL;
DWORDdwForeID;
DWORDdwCurID;
hForeWnd =::GetForegroundWindow();
dwCurID = ::GetCurrentThreadId();
dwForeID = ::GetWindowThreadProcessId(hForeWnd,NULL );
::AttachThreadInput( dwCurID, dwForeID,TRUE);//共享输入队列,将两个线程连接到一起
SetWndTopmost(hMainWnd,TRUE);//窗口置顶
Sleep(80);
mouse_event(MOUSEEVENTF_LEFTDOWN, 0, 0,0,0);
mouse_event(MOUSEEVENTF_LEFTUP, 0, 0, 0,0);
Sleep(30);
SetWndTopmost(hMainWnd,FALSE);
::AttachThreadInput(dwCurID,dwForeID,FALSE);//取消连接
VirtualFreeEx(hProcess, pRect, 0,MEM_RELEASE);
SetCursorPos(0, 0);
CloseHandle(hProcess);
}