プログラムで別のアプリケーションのボタンを押します(C、Windows)
質問
次のコードを使用して、他のアプリケーションのボタンを押します:
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(またはアクセス拒否)のエラーでした。 アイデアはありますか?
EDIT2 失礼なつもりはありませんが、ボタンのリージョンの取得と設定を含むすべてのAPIを検索してから、ボタンを押してからボタンを押して、コントロールID、クラスIDなどを取得します。 そもそも私がここで質問した理由は、すでにインターネットで検索を使い果たしたからです。 コードを投稿してくださいという答えがわかっている場合は、APIを提案しないでください。それで、そのAPIがどのように問題を解決するかを教えてください。それは厳しくない。 ありがとうございました。
編集3:賞金が終了すると、質問の回答が自動的に選択されました。質問はまだ回答がありません。
解決
- 本当に<!> quot; SaveButton <!> quot;クラス名は有効ですか?あなたはボタンを取得しますか ハンドル?
- (ボタンに直接)ButtonHandleウィンドウにメッセージを送信してみてください。
更新:これでうまくいくと思います
SendMessage(ButtonHandle, BM_CLICK, 0, 0);
他のヒント
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回クリックして送信する必要があります。なぜかはわかりません(最初のクリックでボタンのウィンドウがアクティブになるだけかもしれません)が、私はこのコードを長い間使用しており、常に機能していました。
これが役立つ場合があります: http://www.cplusplus.com/forum/beginner/8806/
次の解決策を参照してください。また、使用することもできます
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);
}
}
}
注: ウィンドウのテキスト、ボタンのテキストから確認する(ウィンドウのタイトルの最後にスペースがあるかどうかを確認する)
SendMessageまたはPostMessageのアクセス拒否エラーは、メッセージを送信するプロセスがターゲットプロセスより低い整合性レベルで実行されていない限り意味がありません。
これは、ターゲットウィンドウを所有するプロセスが<!> quot; asAdministrator <!> quot;で実行されていない限り、発生しないはずです。またはサービスです。また、Windows 6以降を使用して対話型デスクトップにウィンドウを作成するサービスは非常に困難です。
ここで整合性レベルについて読むことができますこの状況にリモートでも適用します。 Internet Explorerは、自身をより効果的にサンドボックス化するために、意図的に自身の整合性レベルを下げることにより整合性セキュリティモデルに「オプトイン」する他の唯一のアプリケーションです。
ボタンを含むウィンドウを上げることができる場合、生のマウスイベントをボタンの境界内の位置に送信できます。
マウスイベントをシミュレートする関数が2つあります SendInput および mouse_event
。 WM_CUSTOM
関数を使用することをお勧めします。ウィンドウを上げるには、 ShowWindow を使用できます。ボタンのハンドルを取得する方法はわかりませんが、hWndがある場合は GetWindowRect 関数。問題が発生した場合は、これらを使用してみてください。喜んでお手伝いします。
またはアプリケーション window 内でカスタムWMを定義して、保存要求を処理します。 WM_USER
または<=>(どちらかを覚えておいてください)は、ユーザー定義のウィンドウメッセージの開始をマークします。
このようなことをしなければならないときは、SendKeysを使用します。それはVBっぽく、C#は使いやすいインターフェースを提供しますが、C / C ++ではそれを行う必要があります<!> lt; この方法 <!> gt;。コードのハードコーディングを行う代わりに、スクリプトを作成して実行できる点が優れています。
Microsoftは現在、UIオートメーションの Active Accessibility(MSAA)を推進しています。 (長年にわたって何度も名前が変更されています)
を参照すみません<!>#8217;開始するための簡単なコードはありません。 As <!>#8220; SendMessage()<!>#8221; <!>#8217; <!>#8220; UI Automation <!>#8221;
以外の別のオプションを知らないメッセージが正しいボタンなどに送信されていることをSpy ++(MsDevと共にインストール)で確認していると想定しています<!>#8211;ボタンが標準のWindowsボタンであること。私の最初の瞬間はuse <!>#8220; SendMessage()<!> quot;または<!> quot; PostMessage()<!>#8221;しかし、<!>#8220; SendMessage()<!>#8221;についての回答数が与えられました。そしてそれがあなたのために働いていないという事実。誰かが行っていると思います<!>#8230;
sendkeys(tr3が述べたように)を使用して、マウスクリックを送信できます。これは、SendMessageの使用とは異なります。また、直接的ではなく、ハッキングのようですが、自動化(VBSで)に役立ちます。
また、単なる推測ですが、問題は、ベースクラスメンバを呼び出さないことによってメッセージ処理がどこかで壊れていることです。例:
void CMyClass::OnMessageY(CWnd *cwnd)
{
CBaseClass::OnMessageY(cwnd);
//... my code
}
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);
}
非Cアプローチ:Javaとjava.awt.Robotクラスを使用してマウスを動かし、実際のクリックを実行します(これにはWindows Worldにも何かがあると思います)。 問題:ボタンの位置を知る必要があります:D