Windows 模拟用户点击桌面图标(双击、右击)
2017-06-22 17:13
381 查看
前言:2014-04-22记录在hi baidu上,现移过来。
思路:1、获取指定图标的坐标;2、发送右击、双击操作;
继续……
到此,获取到桌面的指定图标坐标,下一步开始模拟点击
用python来模拟双击
右击
右击操作主要是通过COM Shell32实现
需要注意的是,64位系统和32位系统获取坐标方法一样,只是ITEM结构不一样:
思路:1、获取指定图标的坐标;2、发送右击、双击操作;
第一步: 获取坐标
/* * Purpose: 获取32位桌面图标坐标 * Arguments: * hDeskWnd => 桌面窗口句柄 * pszName => 图标名称 * lpPoint => 图标坐标 * Returns: * TRUE => 获取成功 * FALSE => 获取失败 */ BOOL WINAPI GetXY32( HWND hDeskWnd, char *pszName, LPPOINT lpPoint) { BOOL bRet = FALSE; // 遍历外部进程所有图标 DWORD dwThreadId = 0; GetWindowThreadProcessId( hDeskWnd, &dwThreadId ); HANDLE hProcess = OpenProcess( PROCESS_VM_READ|PROCESS_VM_OPERATION|PROCESS_VM_WRITE, FALSE, dwThreadId ); if( hProcess == NULL ) { printf( "OpenProcess Failed.\n" ); } else { LVITEMA* plvItem = (LVITEMA*)VirtualAllocEx( hProcess, NULL, sizeof(LVITEMA), MEM_COMMIT, PAGE_READWRITE ); char *pszText = (char*)VirtualAllocEx( hProcess, NULL, 512,MEM_COMMIT, PAGE_READWRITE); POINT *pItemPt= (POINT*)VirtualAllocEx( hProcess, NULL, sizeof(POINT), MEM_COMMIT, PAGE_READWRITE); POINT pt; if( !pItemPt || !plvItem || !pszText ) { printf( "AllocEx Failed.\n" ); } else { LVITEMA lvItem; lvItem.mask = LVIF_TEXT; lvItem.cchTextMax = 512; lvItem.pszText = pszText; char szItemBuf[512] = {0}; int nMaxItem = ::SendMessage( hDeskWnd, LVM_GETITEMCOUNT, 0, 0 ); for( int nItem = 0; nItem < nMaxItem; nItem++ ) { lvItem.iItem = nItem; lvItem.iSubItem = 0; // 将设置好的结构插入目标进程 WriteProcessMemory( hProcess, plvItem, &lvItem, sizeof(lvItem), NULL); // 发送LVM_GETITEM消息 BOOL retValue = (BOOL)::SendMessage( hDeskWnd, LVM_GETITEMTEXTA, nItem, (LPARAM)plvItem ); // 获取pszText ReadProcessMemory( hProcess, pszText, szItemBuf, 512,NULL ); if( _stricmp( szItemBuf, pszName ) == 0 ) { // Send LVM_GETITEMPOSITION Get position ::SendMessage( hDeskWnd, LVM_GETITEMPOSITION, nItem, (LPARAM)pItemPt); ReadProcessMemory( hProcess, pItemPt, &pt, sizeof(POINT), NULL ); memcpy_s( lpPoint, sizeof(POINT), &pt, sizeof(POINT) ); bRet=TRUE; break; } } VirtualFreeEx( hProcess, plvItem, 0, MEM_RELEASE); VirtualFreeEx( hProcess, pszText, 0, MEM_RELEASE); VirtualFreeEx( hProcess, pItemPt, 0, MEM_RELEASE); } CloseHandle(hProcess); } return bRet; }
继续……
/* * Purpose: 获取桌面图标坐标,在此处获取桌面窗口句柄,区分32位跟64位,以及Windows7和WindowsXP * Arguments: * pszName => 图标名称 * lpPoint => 图标坐标 * Returns: * TRUE => 获取成功 * FALSE => 获取失败 */ BOOL WINAPI GetDesktop( char *pszName, LPPOINT lpPoint ) { // 桌面上SysListView32的窗口句柄 HWND hDeskWnd=NULL; // find windows7 HWND hWnd= ::FindWindow( L"WorkerW", NULL ); while( hWnd ) { HWND hShellView = ::FindWindowEx( hWnd, NULL, L"SHELLDLL_DefView", NULL ); if( hShellView ){ hDeskWnd=::FindWindowEx( hShellView, NULL, L"SysListView32", NULL); break; } hWnd = ::GetWindow( hWnd, GW_HWNDNEXT ); } // 在XP下找 if( !hDeskWnd ) { hWnd = ::FindWindow( L"ProgMan" , L"Program Manager" ); if( hWnd ) { hWnd = ::FindWindowEx( hWnd, NULL, L"SHELLDLL_DefView", NULL); hDeskWnd = ::FindWindowEx( hWnd, NULL, L"SysListView32", NULL); } } if( !hDeskWnd ){ printf( "Find Desktop Failed.\n" ); return FALSE; } BOOL bRet = FALSE; if( Is64BitOS() ) { bRet = GetXY64( hDeskWnd, pszName, lpPoint ); } else { bRet = GetXY32( hDeskWnd, pszName, lpPoint ); } return bRet; }
到此,获取到桌面的指定图标坐标,下一步开始模拟点击
第二步:双击、右击
双击用python来模拟双击
################################################################################ # class FakeUserClicked: 模拟用户点击桌面指定坐标 # 传入参数:pos = [X,Y] ################################################################################ class FakeUserClicked: """docstring for FakeUserClicked""" def __init__(self, pos): self.posXY = pos # 模拟点击 def FakeClicked(self): # 移动箭头到指定坐标 autopy.mouse.move(self.posXY[0], self.posXY[1]) autopy.mouse.click() time.sleep(0.03) autopy.mouse.click() return True # 获取的坐标为原始坐标,也就是起点坐标 posXY[0] += 10 # 需要计算图标的高度,这里默认为30 posXY[1] += 30 print posXY[0],posXY[1] # step2: 模拟执行 fakeClick = FakeUserClicked(posXY) fakeClick.FakeClicked()
右击
右击操作主要是通过COM Shell32实现
/* * path ==> 指定程序目录 * file_name ==> 程序名称 * item_name ==> 菜单项 * InvokeItemInPopupMenu("d:\\mydesktop", "PCHunter64.exe", "&load into pe editor"); */ int InvokeItemInPopupMenu(const char * path, const char * file_name, const char * item_name) { CoInitialize(NULL); Shell32::IShellDispatchPtr ptrShell; ptrShell.CreateInstance(__uuidof(Shell32::Shell)); _variant_t var((short)Shell32::ssfRECENT); Shell32::FolderPtr ptrFolder = ptrShell->NameSpace(path); Shell32::FolderItemPtr ptrItem = ptrFolder->ParseName(file_name); Shell32::FolderItemVerbsPtr t_verbs = ptrItem->Verbs(); for (long i = 0; i < t_verbs->Count; ++i) { Shell32::FolderItemVerbPtr t_verb = t_verbs->Item(i); cout << t_verb->Name << endl; if (!_stricmp(t_verb->Name, item_name)) { t_verb->DoIt(); Sleep(100); } } ptrItem.Release(); ptrFolder.Release(); ptrShell.Release(); CoUninitialize(); return 0; }
需要注意的是,64位系统和32位系统获取坐标方法一样,只是ITEM结构不一样:
// 64位系统下ITEM结构 typedef struct tagLVITEM64A { UINT mask; int iItem; int iSubItem; UINT state; UINT stateMask; INT64 pszText; int cchTextMax; int iImage; LPARAM lParam; #if (_WIN32_IE >= 0x0300) int iIndent; #endif #if (_WIN32_WINNT >= 0x501) int iGroupId; UINT cColumns; // tile view columns PUINT puColumns; #endif } LVITEM64A, *LPLVITEM64A;
相关文章推荐
- windows下点击任务栏“显示桌面”图标弹出记事本故障解决
- android双击返回键退回桌面,然后点击图标进入还是最近任务列表点击进入,app都会重新启动,如何才能直接进入主页?
- winxp双击驱动器图标不能进入,必须点击右键"打开"
- 关于双击桌面上的IE图标却显示“打开方式”对话框的解决办法
- Q01: gnome桌面图标不见了,点击右键也不管用。怎么办?
- 点击图标打开方式引起的桌面图标全部变成一类程序的关联的解决方法
- 卸载掉firefox后,QQ上图标点击了失效了,发送到桌面的网页快捷方式也失效。
- 中秋玩游戏:用Windows XP桌面图标玩贪吃蛇
- Windows 2000中桌面图标颜色失真的解决方法
- 隐藏Windows的工具栏和桌面图标
- Windows应用程序用户体验UX(三)桌面相关
- 庆中秋:用Windows XP桌面图标玩贪吃蛇(原理)
- 玩转Windows桌面图标
- windows远程桌面缺陷-单用户和多用户
- 玩转Windows桌面图标
- [LU桌面应用] Q01: gnome桌面图标不见了,点击右键也不管用。怎么办?
- 模拟ASP.NET的Windows集成验证用户标识
- 利用 SHDocVw::IShellWindowsPtr m_spSHWinds 遍历所有IE浏览器,得到里面的所有元素 还有一个是查找IE窗口里的submit按钮,模拟点击
- Windows安全桌面与用户桌面间的通信
- 彻底解决Windows 7桌面无IE8图标问题