外部程序 控制扫雷 程序 菜单
ollydbg(od反汇编工具)功能介绍
spy++
如何利用Python和win32编程避免重复性体力劳动(二)——菜单操作:GetMenu,GetSubMenu,GetMenuItemID以及wParam的HIWORD&LOWORD
如何控制另一个exe程序中的菜单操作
FindWindow(FindWindowEx) → 得到hWnd
GetMenu → 得到主菜单 hMenu
GetSubMenu → 得到子菜单(从0开始算) hSubMenu
GetMenuItemID → 得到子菜单中某个项目的ID(从0开始算) hID
SendMessage hWnd, WM_COMMAND, hID, hSubMenu
SendMessage 中的第四个参数加上ByVal
下面是win7系统自带的扫雷程序:
void CMineSweepConDlg::OnBnClickedButton1()
{
// TODO: 在此添加控件通知处理程序代码
HWND hMineWindow = ::FindWindow(NULL, _T("扫雷"));
int firstX = 90;
int firstY = 130;
int sizeBlock = 36;
int x = 0, y = 0;
POINT pt;
//获得扫雷的窗口位置
RECT rt;
if (!::GetWindowRect(hMineWindow, &rt))
{
AfxMessageBox(_T("取得扫雷窗口位置失败!"));
return;
}
AfxMessageBox(_T("取得扫雷窗口位置成功!"));
firstX += rt.left;
firstY += rt.top;
//发送一次按键以生成地雷信息
x = firstX, y = firstY;
::GetCursorPos(&pt); //备份当前鼠标位置
::SetCursorPos(x, y);
::SendMessage(hMineWindow, WM_LBUTTONDOWN, 0, (y << 16) | x); //发送第一次按键使得第一个方块获得焦点
::SendMessage(hMineWindow, WM_LBUTTONUP, 0, (y << 16) | x);
::SendMessage(hMineWindow, WM_LBUTTONDOWN, 0, (y << 16) | x); //发送第二次按键使得第一个方块被按下
::SendMessage(hMineWindow, WM_LBUTTONUP, 0, (y << 16) | x);
::SetCursorPos(pt.x, pt.y); //恢复鼠标位置
}
上面的操作是 点击一下 扫雷程序,左上角的那个方格。
如何定位 控制菜单呢?
spy++捕获窗口消息
https://www.cnblogs.com/chenyangchun/p/7262457.html
Spy++是32位的 只能控制 搜到 32位 程序的消息
需要找一个 spy++ 64位的 再次试试
控制菜单:
取菜单条目ID GetMenuItemID函数
指定条目的菜单ID。如条目属于一个弹出式菜单,就返回-1;如指定的条目属于一个分隔符(比如一条分隔线)则返回0
HWND FindWindow(
LPCTSTR lpClassName,
LPCTSTR lpWindowName
);
UINT GetMenuItemID(
[in] HMENU hMenu,
[in] int nPos
);
The return value is the identifier of the specified menu item. If the menu item identifier is NULL or if the specified item opens a submenu, the return value is -1.
void CMineSweepConDlg::OnBnClickedButton2()
{
// TODO: 在此添加控件通知处理程序代码
HWND hMineWindow = ::FindWindow(NULL, _T("扫雷"));
if (hMineWindow == NULL) {
cout << "OnBnClickedButton2 FindWindow Error" << endl;
return;
}
HMENU hMenu;
HMENU menu1;
hMenu = ::GetMenu(hMineWindow);
if (hMenu == NULL) {
cout << "GetMenu Error" << endl;
return;
}
menu1 = ::GetSubMenu(hMenu, 0);
if (menu1 == NULL) {
cout << "GetSubMenu Error" << endl;
return;
}
UINT cmd_ID = ::GetMenuItemID(menu1, 2);
cout << "cmd_ID =" << cmd_ID << endl;
::PostMessage(hMineWindow, WM_COMMAND, cmd_ID, 0);
//::PostMessage(hMineWindow, WM_CLOSE, cmd_ID, 0);
}
控制 子窗口的 按钮
HWND hMineWindow = ::FindWindow(NULL, _T("扫雷"));
if (hMineWindow == NULL) {
cout << "OnBnClickedButton2 FindWindow Error" << endl;
return;
}
HMENU hMenu;
HMENU menu1;
hMenu = ::GetMenu(hMineWindow);
if (hMenu == NULL) {
cout << "GetMenu Error" << endl;
return;
}
menu1 = ::GetSubMenu(hMenu, 0);
if (menu1 == NULL) {
cout << "GetSubMenu Error" << endl;
return;
}
UINT cmd_ID = ::GetMenuItemID(menu1, 2);
cout << "cmd_ID =" << cmd_ID << endl;
::PostMessage(hMineWindow, WM_COMMAND, cmd_ID, 0);
//::PostMessage(hMineWindow, WM_CLOSE, cmd_ID, 0);
Sleep(100);
HWND hMineTjWindow = ::FindWindow(NULL, _T("扫雷统计信息 - JACK"));
if (hMineTjWindow == NULL) {
cout << "OnBnClickedButton2 FindWindow 扫雷统计信息 Error " << endl;
return;
}
cout << "find 扫雷统计信息 success " << endl;
HWND hButtonWindow = ::FindWindowEx(hMineTjWindow, 0, NULL, _T("重置(&R)"));
if (hButtonWindow == NULL) {
cout << "OnBnClickedButton2 FindWindow 重置 Error " << endl;
return;
}
cout <<"find button" <<endl;
::SendMessage(hButtonWindow, WM_LBUTTONDOWN, MK_LBUTTON, 0);//给子窗体上button发送鼠标点击消息,
::SendMessage(hButtonWindow, WM_LBUTTONUP, MK_LBUTTON, 0);
cout << "find button and sendmessage" << endl;
上面这段可以在 主机名称为JACk的win7 64位系统下面运行
首先需要 启动系统自带扫雷 程序