
こんにちは。
現在、WindowsXP、Visual Studio2005(以下VS)にて既存のアプリケーションの操作を行うツールを作成しようとしています。
Findwindow関数で親のハンドルをとり、EnumChildWindow関数でコントロールのハンドルを取得しましたが、操作したいボタンの情報が取れません。
参考にさせていただいたコードは以下です。
http://blog.goo.ne.jp/masaki_goo_2006/e/cea1b601 …
VS付属spy++の調査も同様の結果で、そのボタンの情報が出てきませんでした。
コントロールの情報がとれないという事はあるのでしょうか?
ちなみにボタンはtoolbarの上にありtoolbarの情報は取れています。
情報が取れない場合、操作は出来ないということでしょうか?
No.3ベストアンサー
- 回答日時:
こんにちは。
ツールボタンのどの情報を取りたいのでしょうか。SendMessage() TB_???のメッセージで情報を受け取る際、構造体等のポインタを必要とするものが多数ありますが、他プロセスのウィンドウハンドルに向かって此方側のポインタを渡してみた所で、向こう側からしてみれば「寝耳に水」も良い所です。
プロセス間共有メモリを仲介して、データをやり取りする事になります。どちらにしろ、そんな簡単な事ではありません。
以下ではVirtualAllocEx()を使用していますが、windows xpで上手くいくかはわかりません(windows 2000sp4の上では上手くいっています)。
参考資料程度に。
#include<tchar.h>
#include<windows.h>
#include<commctrl.h>
#include<stdio.h>
typedef struct ProcessMemory
{
DWORD dwProcessID;
DWORD dwThreadID;
HANDLE hProcess;
union
{
LPVOID pVoid;
LPBYTE pByte;
LPARAM lParam;
};
} PROCESSMEMORY, *LPPROCESSMEMORY;
static BOOL OpenProcessMemory(LPPROCESSMEMORY p, HWND hWndOutProcess, DWORD dwSize)
{
p->dwThreadID = ::GetWindowThreadProcessId(hWndOutProcess, &p->dwProcessID);
if(!p->dwThreadID || !p->dwProcessID)
return FALSE;
p->hProcess = ::OpenProcess(PROCESS_ALL_ACCESS, FALSE, p->dwProcessID);
if(!p->hProcess)
return FALSE;
p->pVoid = ::VirtualAllocEx(p->hProcess, NULL, dwSize, MEM_COMMIT, PAGE_READWRITE);
return p->pVoid != NULL;
}
static BOOL CloseProcessMemory(LPPROCESSMEMORY p)
{
if(!p->hProcess)
return FALSE;
::VirtualFreeEx(p->hProcess, p->pVoid, 0, MEM_RELEASE);
::CloseHandle(p->hProcess);
::ZeroMemory(p, sizeof(PROCESSMEMORY));
return TRUE;
}
static DWORD WriteProcessMemory(LPPROCESSMEMORY p, DWORD dwByteOfOffset, const void* pIn, DWORD dwSizeOfIn)
{
DWORD dwLen = 0;
::WriteProcessMemory(p->hProcess, &p->pByte[dwByteOfOffset], pIn, dwSizeOfIn, &dwLen);
return dwLen;
}
static DWORD ReadProcessMemory(const LPPROCESSMEMORY p, DWORD dwByteOfOffset, void* pOut, DWORD dwSizeOfOut)
{
DWORD dwLen = 0;
::ReadProcessMemory(p->hProcess, &p->pByte[dwByteOfOffset], pOut, dwSizeOfOut, &dwLen);
return dwLen;
}
int main()
{
//見つかっているものとする
HWND hWndOutProcess = ::FindWindow(_T("Afx:400000:b:10011:6:7042d"), NULL);
HWND hWndCtlBar = ::FindWindowEx(hWndOutProcess, NULL, _T("AfxControlBar42d"), NULL);
HWND hWndToolBar = ::FindWindowEx(hWndCtlBar, NULL, TOOLBARCLASSNAME, NULL);
//他プロセスのメインウィンドウ
PROCESSMEMORY pm = {0};
::OpenProcessMemory(&pm, hWndOutProcess, sizeof(TBBUTTON));
//他プロセスのツールバーの数を取る
const int count = ::SendMessage(hWndToolBar, TB_BUTTONCOUNT, 0, 0);
for(int i = 0; i < count; ++i)
{
//受け皿
TBBUTTON tbb = {0};
//プロセス間共有メモリをゼロで初期化
::WriteProcessMemory(&pm, 0, &tbb, sizeof(TBBUTTON));
//他プロセスのツールボタンメッセージ→プロセス間共有メモリ
::SendMessage(hWndToolBar, TB_GETBUTTON, i, pm.lParam);
//プロセス間共有メモリ→受け皿
::ReadProcessMemory(&pm, 0, &tbb, sizeof(TBBUTTON));
//取りあえず表示
::printf("[ボタン番号 : %d][ボタン状態 : %d][ボタンスタイル : %d][ボタンID : %d][ビットマップ番号 : %d]\n", i, tbb.fsState, tbb.fsStyle, tbb.idCommand, tbb.iBitmap);
}
::CloseProcessMemory(&pm);
return 0;
}
具体的な例ありがとうございます。
とても参考になります。
>ツールボタンのどの情報を取りたいのでしょうか。
やりたいことはそれぞれのボタンを押すことです。
その為のツールバー上のボタンのハンドル?をどのようにとればよいかわかりませんでした。
なかなか難しい内容で時間がかかるかもしれませんが
いただいた情報を頼りになんとか確認してみたいと思います。
No.4
- 回答日時:
こんにちは。
御礼頂きました。すっかり見落としていました。プログラムからツールボタンを操作するのが目的でした。
此れに関して回答すると、WM_COMMANDをツールバーの親ウィンドウに送るか、WM_LBUTTONDOWN/WM_LBUTTONUPにツールボタンの座標を指定してクリックされた事にすれば出来ます。
//メモリの割り当て
PROCESSMEMORY pm = {0};
::OpenProcessMemory(&pm, hWndOutProcess, sizeof(TBBUTTON));
//受け皿
TBBUTTON tbb = {0};
//必要があれば此処でhWndOutProcessを最前面に持ってくる
//プロセス間共有メモリをゼロで初期化
::WriteProcessMemory(&pm, 0, &tbb, sizeof(TBBUTTON));
//2番目のツールボタンの情報を取る
::SendMessage(hWndToolBar, TB_GETBUTTON, 1, pm.lParam);
//プロセス間共有メモリ→受け皿
::ReadProcessMemory(&pm, 0, &tbb, sizeof(TBBUTTON));
//ツールバーの親ウィンドウにWM_COMMANDを送る
::SendMessage(hWndCtlBar/*ツールバーの親ウィンドウを指定*/, WM_COMMAND, tbb.idCommand, (LPARAM)hWndToolBar);
//メモリを閉じる
::CloseProcessMemory(&pm);
又は、
//メモリの割り当て
PROCESSMEMORY pm = {0};
::OpenProcessMemory(&pm, hWndOutProcess, sizeof(RECT));
//受け皿
RECT rc = {0};
//必要があれば此処でhWndOutProcessを最前面に持ってくる
//プロセス間共有メモリをゼロで初期化
::WriteProcessMemory(&pm, 0, &rc, sizeof(RECT));
//2番目のツールボタンの矩形領域を取る
::SendMessage(hWndToolBar, TB_GETITEMRECT, 1, pm.lParam);
//プロセス間共有メモリ→受け皿
::ReadProcessMemory(&pm, 0, &rc, sizeof(RECT));
//ツールバーのボタン上でマウスの左ボタンが押された事にする
::SendMessage(hWndToolBar, WM_LBUTTONDOWN, 0, MAKELONG(rc.left + 2, rc.top + 2));
//ツールバーのボタン上でマウスの左ボタンが離された事にする
::SendMessage(hWndToolBar, WM_LBUTTONUP, 0, MAKELONG(rc.left + 2, rc.top + 2));
//メモリを閉じる
::CloseProcessMemory(&pm);
と言った具合です(当方のPC上では両方とも動きます)。
動作確認のため返信遅れました。
申し訳ありません。
ほぼいただいたコード通りで無事に押すことが出来ました。
ありがとうございます。とても助かりました。
ただ、ボタンが8個しかないのに、"TB_BUTTONCOUNT"で取得した数は19を示しています。
(この数の違いは何を示しているのかは後ほど知らべたいと思います。)
押せるボタンは8個ですのでどの番号がどのボタンを示しているのか、総当りで探した次第です。
しかし調べてみたところTB_ISBUTTONCHECKEDなどの他のメッセージを使えばこの辺の特定がうまく出来そうなので組み込んでみたいと思います。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- SQL Server DBのテーブルの設計ができず困っています。 2 2023/06/29 16:43
- Visual Basic(VBA) 動かなくなってしまった古いVBAを動くようにしたい 8 2022/09/20 13:57
- CGI サイト訪問者の情報を取得したい 1 2023/02/21 11:03
- メディア・マスコミ もうNHKが旧統一教会を報道しなくなった訳とは? 8 2022/07/19 08:23
- デスクトップパソコン ん~…分からん 7 2022/06/10 10:47
- Android(アンドロイド) スマートフォンを盗まれた場合に備えて 3 2023/07/15 15:14
- ヤフオク! ヤフオク。入札価格が安すぎるから、ということで出品者都合でキャンセルするのはアリなのか? 5 2022/10/14 16:40
- Visual Basic(VBA) Vba LongPtrについて教えてください 2 2022/08/19 11:14
- その他(プログラミング・Web制作) Python でWindowsのショートカット(.lnk)のプロパティを参照したい 1 2023/02/01 15:09
- その他(データベース) Accessフォームからパラメーターで表示したレコードを指定のExcelのセルへ転送する方法について 2 2022/08/22 18:04
このQ&Aを見た人はこんなQ&Aも見ています
関連するカテゴリからQ&Aを探す
おすすめ情報
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
バックグラウンドのプロセスの...
-
VB6.0 SHELLで起動...
-
SendMessageが失敗するときがある
-
他のEXEが起動しているかの確認
-
Windowsでのfork方法
-
プロセスのアタッチ・デタッチ...
-
sleep関数の精度について
-
プロセスIDからウィンドウハ...
-
プロセスIDの取得方法について
-
デッドロックでダウンします。...
-
怪しいプロセス教えてください。
-
Visual C++からpingを実行して...
-
CGIからCGIを、CGI環境変数付き...
-
VC++6.0 「プロセスへ...
-
フレームワークとプロセスの違...
-
プロセスが実行中かどうか調べ...
-
コンピュータのCPU使用率が常に...
-
iPodの取り外しの際のエラーメ...
-
C言語のプログラムにて二つの処...
-
他のアプリケーションをクリッ...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
バックグラウンドのプロセスの...
-
VB6.0 SHELLで起動...
-
プロセスIDの取得方法について
-
C#でのbatファイル実行結果取得
-
タスクマネージャーのプロセス...
-
プロセスのアタッチ・デタッチ...
-
vb.netでEXCEL起動がうまくでき...
-
SendMessageが失敗するときがある
-
ADOでアクセスのレコードに...
-
非表示になったエクセルは?
-
explorer.exeが異様にメモリを食う
-
怪しいプロセス教えてください。
-
Process.Startの戻り値を後で取得
-
プロセスIDからウィンドウハ...
-
Linuxでのスレッド間メッセージ...
-
警告『 別のプロセスで使用され...
-
Visual C++からpingを実行して...
-
WSH.Runで待機できません
-
c言語でプロセスIDを調べたい
-
API関数 GetExitCodeProcess
おすすめ情報