#2 実際に制御の部
の続きです。ハンドル経由でコントロールにイベント送って疑似操作します。直接マウスをクリックしなくてもおけです。まずソースを示しましょうかね。コマンドラインプログラムです。
#include <stdio.h>
#include <windows.h>
#include <string.h>
HWND movie;
HWND duration;
bool Launch(char* program)
{
STARTUPINFO si;
PROCESS_INFORMATION pi;
ZeroMemory(&si, sizeof(si));
si.cb = sizeof(si);
ZeroMemory(&pi, sizeof(pi));
//const char* programPath = "\".\\CRC_Mini.exe\"";
// 引数があれば: const char* args = "C:\\path\\to\\file.txt";
const char* args = nullptr;
// プロセス作成
if (CreateProcess(
NULL, // lpApplicationName (NULLならlpCommandLineから取得)
(LPSTR)program, // lpCommandLine (プログラム名と引数)
NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi))
{
//std::cout << "プロセス起動成功。ハンドル: " << pi.hProcess << std::endl;
// プロセスの終了を待つ場合: WaitForSingleObject(pi.hProcess, INFINITE);
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
return true;
}
else {
return false;
//std::cerr << "CreateProcess失敗: " << GetLastError() << std::endl;
}
}
// コールバック関数
BOOL CALLBACK EnumChildProc( HWND hWnd, LPARAM lParam )
{
TCHAR szBuff[1024];
TCHAR szBuff2[1024];
GetWindowText( hWnd, szBuff, sizeof(szBuff) );
printf( "├[%s] ", szBuff );
GetClassName( hWnd, szBuff2,sizeof(szBuff2));
printf("[%s]\n", szBuff2);
if(!strcmp(szBuff,"Movie"))
movie = hWnd;
if(!strcmp(szBuff2,"TLabeledEdit"))
duration = hWnd;
return TRUE;
}
// メイン関数
int main( int argc, char** argv)
{
HWND hCalc;
int sec;
char newtext[10];
if( argc == 1 )
sec = 5;
else
sec = atoi(argv[1]);
sprintf(newtext,"%d",sec);
if( !Launch("\".\\CRCMini.exe\"")){
printf("launch failed");
return 1;
}
if ( (hCalc = FindWindow(NULL,"CRCMini")) != NULL ){
printf( "CRC-Miniのコントロール列挙\n" );
EnumChildWindows( hCalc, EnumChildProc, NULL );
}
else {
printf("CRCMini not found");
return 1;
}
// setting text for test
if (SendMessageA(duration, WM_SETTEXT, 0, (LPARAM)newtext) == 0) {
printf("WM_SETTEXT message sent successfully.\n");
} else {
printf("WM_SETTEXT message sent, return value: non-zero.\n");
}
// movie button click
PostMessage(movie, BM_CLICK, 0, 0);
// getchar();
// shutdown CRC-Mini
//PostMessageW(hCalc, WM_CLOSE, 0, 0);
printf("done\n");
return 0;
}
最初にターゲットプログラム(CRCMini.exe)の各要素をダンプします。まずCRCMini.exeのbuildの時に、FormのキャプションをForm1以外の文字列にしておきます。この場合は、CRCMiniです。でないとForm1だらけになってしまいます。それは、

のようにForm1->Captionを好きな文字列に変更すればおけです。

からコントロールを抜き出して、
CRC-Miniのコントロール列挙
├[] [TProgressBar]
├[Movie] [TButton]
├[Still] [TButton]
├[Capture] [TButton]
├[5] [TLabeledEdit]
各コントロールのCaptionないしClassでセレクトします。まずやりたいことは、TLabeledEditの内容としてコマンドラインから与えられた秒数を書き込みます。それが、
// setting text for test
if (SendMessageA(duration, WM_SETTEXT, 0, (LPARAM)newtext) == 0) {
printf("WM_SETTEXT message sent successfully.\n");
} else {
printf("WM_SETTEXT message sent, return value: non-zero.\n");
}
“Movie”ボタンのクリックは、
// movie button click
PostMessage(movie, BM_CLICK, 0, 0);
になります。ここでSendMessage()でなくPostMessage()を使っているのが肝要です。SendMessage()だと待機することになりますから。durationやらmovieを拾っているのは、
GetWindowText( hWnd, szBuff, sizeof(szBuff) );
printf( "├[%s] ", szBuff );
GetClassName( hWnd, szBuff2,sizeof(szBuff2));
printf("[%s]\n", szBuff2);
if(!strcmp(szBuff,"Movie"))
movie = hWnd;
if(!strcmp(szBuff2,"TLabeledEdit"))
duration = hWnd;
の部分で、Callback関数内です。相手がVCLのプログラムだと拾いやすいです。FMXだとこう簡単には拾えないです。


コメント