19

次のコードを使用して、他のアプリケーションのボタンを押そうとしています:

HWND ButtonHandle;
if( (wnd = FindWindow(0, "Do you want to save?")) )
{   
   ButtonHandle = FindWindowEx(wnd, 0, "SaveButton", "&Save");
   SendMessage(wnd, WM_COMMAND, MAKEWORD(GetDlgCtrlID(ButtonHandle), BN_CLICKED ), (LPARAM)ButtonHandle);

}

うまくいきません。MAKEWORD に別のハンドルを渡して、WPARM と LPARAM を変更しようとしましたが、何もしませんでした。

別のアプリケーションのウィンドウでボタンをクリックする方法についてのアイデアはありますか?

コードは大歓迎です。ありがとう。

編集:権限が機能しないように見える理由。PostMessage() を送信したところ、GetLastError() = 5 (または Access Denied) のエラーが返されました。何か案は?

EDIT2失礼なつもりはありませんが、お願いします。ボタンの領域の取得と設定、ボタンダウンとボタンアップの送信、コントロールIDの取得、クラスIDの取得、クラスIDの取得など、すべてのAPIをすでに検索しましたさらに無数。そもそもここで質問した理由は、すでにインターネットで検索を使い果たしたからです。PLEASE POST CODEという答えがわかっている場合は、API を提案しないでください。それは難しいことではありません。ありがとうございました。

編集 3: 賞金が終了すると、質問の回答が自動的に選択されました。疑問はまだ答えが出ていない。

4

12 に答える 12

21
  1. 「SaveButton」クラス名が有効であることを確認しますか?ボタンの取っ手はありますか?
  2. ButtonHandleウィンドウに(ボタンに直接)メッセージを送信してみてください。

更新:これはうまくいくはずだと思います、

SendMessage(ButtonHandle, BM_CLICK, 0, 0);
于 2009-08-03T18:51:51.027 に答える
3
SendMessage(btnHandle, WM_LBUTTONDOWN, 0, 0);
SendMessage(btnHandle, WM_LBUTTONUP, 0, 0);
SendMessage(btnHandle, WM_LBUTTONDOWN, 0, 0);
SendMessage(btnHandle, WM_LBUTTONUP, 0, 0);

ボタンのクリックを 2 回送信する必要があります。理由はわかりませんが (最初のクリックでボタンのウィンドウがアクティブになるだけかもしれません)、私はこのコードを長い間使用しており、常に機能していました。

于 2009-09-17T11:28:45.570 に答える
2

次のソリューションを参照してください。また、使用することもできます

SendMessage(ButtonHandle, WM_LBUTTONDOWN, 0, 0);
SendMessage(ButtonHandle, WM_LBUTTONUP, 0, 0);

または

SendMessage(ButtonHandle, BM_CLICK, 0, 0);

HWND buttonHandle = 0;

BOOL CALLBACK GetButtonHandle(HWND handle, LPARAM)
{
 char label[100];
 int size = GetWindowTextA(handle,label,sizeof(label));
 if(strcmp(label,"&Save") == 0)
 {
  buttonHandle = handle;
  return false;
 }
 return true;
}
void main()
{
 HWND windowHandle = FindWindowA(NULL,"Do you want to Save?");
 if(windowHandle != 0)
 {
  BOOL ret = EnumChildWindows(windowHandle,GetButtonHandle,0);

  if(buttonHandle != 0)
  {
   LRESULT res = SendMessage(buttonHandle,BM_CLICK,0,0);
   //SendMessage(buttonHandle,WM_LBUTTONDOWN,0,0); 
   //SendMessage(buttonHandle,WM_LBUTTONUP,0,0);
  }

 }



}

注:ウィンドウのテキスト、ボタンのテキストから確認してください(ウィンドウのタイトルの最後にスペースがあるかどうかを確認してください)

于 2009-09-17T11:16:54.333 に答える
2

多分これが役立つかもしれません: http://www.cplusplus.com/forum/beginner/8806/

于 2009-08-03T21:42:37.407 に答える
1

このようなことをしなければならないときは、SendKeys を使用します。これは VB 風で、C# は使いやすいインターフェイスを提供しますが、C/C++ の場合は <この方法> で行う必要があります。これの優れている点は、コードにハードコーディングする代わりに、スクリプトを記述して実行できることです。

于 2009-09-17T10:21:19.420 に答える
1

ボタンを含むウィンドウを上げることができれば、生のマウス イベントをボタンの境界内の位置に送信できます。

マウスイベントSendInputとをシミュレートする 2 つの関数がありmouse_eventます。関数を使用することをお勧めしmouse_eventます。ウィンドウを上げるには、ShowWindowを使用できます。ボタンのハンドルを取得する方法はわかりませんが、hWnd があれば、GetWindowRect関数を使用して絶対位置を簡単に見つけることができます。これらを使用してみてください。問題が発生した場合は、喜んでお手伝いします。

または、アプリケーションウィンドウ内でカスタム WM を定義して、保存要求を処理します。 WM_CUSTOM またはWM_USER(覚えていない)ユーザー定義のウィンドウメッセージの開始をマークします。

于 2009-09-16T10:55:58.107 に答える
1

// 既に開いている calc.exe に数字 4 を送信します

HWND windowHandle;

windowHandle = FindWindowA(NULL,"Calculator");

if(windowHandle != 0)
   ret = EnumChildWindows(windowHandle,GetButtonHandle,0);

BOOL CALLBACK GetButtonHandle(HWND handle, LPARAM)
{
char label[100];
int size = GetWindowTextA(handle,label,sizeof(label));

if(strcmp(label,"4") == 0)
{
PostMessage(handle ,WM_LBUTTONDOWN,(WPARAM)0x0001,0);
PostMessage(handle ,WM_LBUTTONUP,(WPARAM)0x0001,0);

PostMessage(handle ,WM_LBUTTONDOWN,(WPARAM)0x0001,0);
PostMessage(handle ,WM_LBUTTONUP,(WPARAM)0x0001,0);

return false;
}
return true;
}
于 2020-08-01T18:25:53.780 に答える
1

Microsoft は現在、UI オートメーションのアクティブ アクセシビリティ (MSAA)を推進しています (これは、何年にもわたって何度も名前が変更されています)。

申し訳ありませんが、開始するための簡単なコードはありません。「SendMessage()」がうまくいかないようなので、「UI オートメーション」以外のオプションを知りません</p>

メッセージが正しいボタンなどに送信されていること、およびボタンが標準のWindowsボタンであることをSpy ++(MsDevとともにインストール)で確認したと仮定しています。私の最初の瞬間は、「SendMessage()」または「PostMessage()」を使用すると言いますが、「SendMessage()」に関する回答の数と、それが機能していないという事実を考えると. 誰かが行っていると思います…</p>

于 2009-09-21T11:43:48.797 に答える
0

Sendkeys(tr3が言ったように)を使用してマウスクリックを送信できます。これは、SendMessageを使用する場合とは異なります。また、直接的ではなく、ハックっぽいですが、自動化(VBS)には役立ちます。

また、単なる推測ですが、問題は、基本クラスのメンバーを呼び出さないことによって、メッセージ処理がどこかで壊れていることである可能性があります。例:

void CMyClass::OnMessageY(CWnd *cwnd)
{
    CBaseClass::OnMessageY(cwnd);
    //... my code
}
于 2009-09-15T23:34:17.827 に答える
0

ButtonHandle が有効なハンドルであることが確実な場合は、BN_CLICKED の代わりに WM_LBUTTONDOWN と WM_LBUTTONUP メッセージのペアを使用できます。

HWND ButtonHandle;
if( (wnd = FindWindow(0, "Do you want to save?")) )
{   
    SendMessage(ButtonHandle, WM_LBUTTONDOWN, MK_LBUTTON, 0);
    SendMessage(ButtonHandle, WM_LBUTTONUP, MK_LBUTTON, 0);
}
于 2009-09-16T18:12:46.950 に答える
0

C 以外のアプローチ: Java と java.awt.Robot クラスを使用してマウスを動かし、実際のクリックを実行します (Windows の世界にもこれ用の何かがあると思います)。問題: ボタンがどこにあるかを知る必要があります:D

于 2009-09-17T11:20:20.890 に答える