2010年08月04日


Win32 コンソール アプリケーション キット


ブラウザでダウンロード
一般的にマイナーですが、プログラマ的にはとてもメジャーなウインドウハンドル
を扱う処理ですが、いくつかのコマンドプロンプトプログラムを作ってパッケージ
しました。

以下はそのうちのメインとなるアプリケーションで、ウインドウを持つ外部プログ
ラムを実行して、そのウインドウハンドルを取得して標準出力へ出力しています。

run_and_win_handle.cpp
#include <stdio.h>
#include <tchar.h>
#include <windows.h>

BOOL CALLBACK EnumWindowsProc( HWND hWnd, LPARAM lParam );

static DWORD pid;
static HWND hTarget;

int _tmain(int argc, _TCHAR* argv[])
{

	// プログラムを実行して、PID を取得し
	// PID から Window ハンドルを取得
	int ret;
	PROCESS_INFORMATION pi;
	STARTUPINFO si;

	ZeroMemory( &pi , sizeof(PROCESS_INFORMATION)); 
	ZeroMemory( &si , sizeof(STARTUPINFO));
	si.cb = sizeof(STARTUPINFO);

	// 実行
	ret = CreateProcess(
		NULL,
		argv[1], 
		NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);

	// ユーザーからの入力を待っている状態になるまで待つ
	// ( タイムアウト 60 秒 
	WaitForInputIdle(pi.hProcess,60000);
	CloseHandle(pi.hThread);
	CloseHandle(pi.hProcess);

	pid = pi.dwProcessId;

	// Window ハンドルを Callback で取得
	EnumWindows( EnumWindowsProc, 0 );

	printf("%u\n", hTarget );

	return 0;
}

// *********************************************************
// トップレベル用 ウインドウの列挙
// *********************************************************
BOOL CALLBACK EnumWindowsProc( HWND hWnd, LPARAM lParam )
{
	DWORD ProcessId;

	GetWindowThreadProcessId( hWnd, &ProcessId );
	// 実行したプロセス内で表示されるウインドウを選ぶ
	if ( pid == ProcessId && IsWindowVisible( hWnd ) ) {
		hTarget = hWnd;
		return false;
	}

	return true;

}

他にも4つのアプリケーションが入っています。他のアプリケーションの
ソースコードと説明は、以下のリンク先にあります

ソース掲示板
以下は、実行サンプルですが、あくまでうまく行くと言う前提でのサンプル なので、内容の良く解らない場合は実行しないで下さい。 メモ帳を実行してウインドウハンドルを取得して、そのハンドルを使って メモ帳のメニューの「貼り付け」を postmessage.exe で呼び出しています。 メモ帳は、編集された事になるので、WM_CLOSE をポストして終了させようと しても、メッセージボックスが出るので、スクリプトでキーストロークを送 信して強制的に終わらせています sample.bat
@echo off

REM メモ帳強制終了用のスクリプトを作成
echo Wscript.Sleep 500 > %TEMP%\test.vbs 
echo Set WshShell = WScript.CreateObject("WScript.Shell") >> %TEMP%\test.vbs 
echo WshShell.SendKeys "%%(N)" >> %TEMP%\test.vbs 


REM メモ帳を実行して、クリップボードの内容を貼り付けます。
FOR /F %%i IN ('run_and_win_handle.exe notepad.exe') DO (
	postmessage.exe %%i 273 770 0

)
FOR /F %%i IN ('run_and_win_handle.exe notepad.exe') DO (
	postmessage.exe %%i 273 770 0

)
FOR /F %%i IN ('run_and_win_handle.exe notepad.exe') DO (
	postmessage.exe %%i 273 770 0

)


REM 終了確認に応答して全てのメモ帳を終了させる
:do_next
FOR /F %%i IN ('findwindow.exe "無題 - メモ帳"') DO (
	if "%%i"=="0" (
		goto end
	)
	postmessage.exe %%i 16 0 0
	foreground.exe %%i
	cscript.exe %TEMP%\test.vbs
	goto do_next
)

:end



posted by at 17:44 | パッケージ | このブログの読者になる | 更新情報をチェックする




Microsoft サポート オンライン