質問: MOUSEEVENTF_LEFTDOWN | MOUSEEVENTF_LEFTUP; SendInput(1, &input, sizeof(INPUT)); //mouse_event(MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0); //mouse_event(MOUSEEVENTF_LEFTUP, 0, 0, 0, 0); } ``` ### 試したこと コメントアウトしている部分のソースでも試しましたが、結果は同じでした。 ウィンドウハンドルを取得して、メッセージを送信するという方法も行うと思いましたが、 少し調べるとメッセージボックスのウィンドウハンドルはWinApiでは取得できないと 情報があったので([リンク]別言語の情報ですが、同じWinApiのトピックなので参考にしました)、簡単にカーソル位置を移動させる方法にしようと思いました。 また、spy++も使いましたが、メッセージボックスのハンドルは取得できませんでした。 ### 補足情報(FW/ツールのバージョンなど) リンク 上記URLを参考にボタンクリックの処理は作成しました。 環境は MFC VisualStudio2017 windows7 です 表示されるメッセージボックスは、Windows標準のものになります(MessageBox関数で出るものと同じです)
回答: 標準のメッセージボックスについては RPA 等の自動操作分野で一般的になった手法があります。WinEvent フックと t_obara さんが提示されている、WM_COMMAND を送信する方式の組み合わせです。 以下に提示するサンプルのように特定のプロセスに対して SetWinEventHook の EVENT_SYSTEM_DIALOGSTART を仕掛けてダイアログ表示を検出し、検出したダイアログに対して SendMessage で WM_COMMAND を送信して閉じる手法になります。ダイアログはメッセージボックス以外にも検出されますが、検出したダイアログのサイズ等の情報によりメッセージボックスのみを閉じるようにしたりします。 ``` void Cteratail194066Dlg::OnBnClickedOk() { if (m_event == nullptr) { m_event = SetWinEventHook( EVENT_SYSTEM_DIALOGSTART, EVENT_SYSTEM_DIALOGSTART, NULL, WinEventProc, GetDlgItemInt(IDC_PROCESSID), 0, WINEVENT_OUTOFCONTEXT | WINEVENT_SKIPOWNPROCESS ); if (m_event != nullptr) { SetDlgItemText(IDOK, _T("停止")); } } else { UnhookWinEvent(m_event); m_event = nullptr; SetDlgItemText(IDOK, _T("開始")); } } void CALLBACK Cteratail194066Dlg::WinEventProc(HWINEVENTHOOK hWinEventHook, DWORD event, HWND hwnd, LONG idObject, LONG idChild, DWORD idEventThread, DWORD dwmsEventTime) { ::SendMessage(hwnd, WM_COMMAND, IDOK, 0); } ``` github に全体のサンプルを上げましたので、必要であれば内容を確認してみてください。 上記サンプルは Windows 10 のメモ帳相手に実験しています。他の環境ではこのままのコードでは駄目なようです。