CreateProcessで起動したプロセスをフォアグラウンドに持ってくるには
2006年1月6日
CreateProcessで新たに起動されたプロセスは、フォアグラウンドにならずに、他のウィンドウの下に隠れてしまう。フォアグランドにするには、SetForegroundWindowを用いるのだが、このAPIは現在フォアグランドになっているプロセスのみに許された機能である。従って、CreateProcessを行ったプロセス中でこの処理を行わなければならない。その方法をまとめてみた。
テストプログラムのソースは、以下の通り。
このプログラム中では、WinMainの中でCreateProcessによりNotepad.exeを呼び出している。このままだとメモ帳がフォアグラウンドにならない。
そこでまず、WaitForSingleObjectで新たなプロセスが走り出すまで待ち、次にEnumWindowsで全てのウィンドウを列挙する。
EnumWindowsProc中では、列挙されたウィンドウの中から同じスレッドIDを持ったものをGetWindowThreadProcessIdを用いて見つけ出し、見つかればSetForegroundWindowを用いてそのウィンドウをフォアグラウンドにする処理を行っている。
これが成功すればEnumWindowsがFALSEを返すので、作業は終了である。テストプログラム中では、WaitForSingleObjectで呼び出したプロセスが終了するのを待って、戻り値を取得するなどの後処理をしている。
テストプログラムのソースは、以下の通り。
#include <windows.h>
BOOL CALLBACK EnumWindowsProc(HWND hwnd,DWORD dwThreadId){
if (GetWindowThreadProcessId(hwnd,NULL)==dwThreadId) {
if (SetForegroundWindow(hwnd)) return FALSE;
}
return TRUE;
}
void DoEvents(){
MSG msg;
if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
int WINAPI WinMain( HINSTANCE hInst, HINSTANCE hPrevInst,
LPSTR lpCmdLine, int intShowCmd)
{
int i;
STARTUPINFO si;
PROCESS_INFORMATION pi;
ZeroMemory(&si, sizeof(si));
ZeroMemory(&pi, sizeof(pi));
si.cb = sizeof(si);
si.dwFlags=STARTF_USESHOWWINDOW;
si.wShowWindow=intShowCmd;
//Start Process
if (CreateProcess(NULL, "notepad.exe", NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi)) {
while (WaitForSingleObject(pi.hProcess,0)!=WAIT_TIMEOUT) DoEvents;
while (EnumWindows((WNDENUMPROC)*EnumWindowsProc,pi.dwThreadId)) {
DoEvents;
if (WaitForSingleObject(pi.hProcess,0)!=WAIT_TIMEOUT) break;//check if process is still acvite.
}
WaitForSingleObject(pi.hProcess,INFINITE);//wait until end of process
GetExitCodeProcess(pi.hProcess,(LPDWORD)&i);
CloseHandle(pi.hThread);
CloseHandle(pi.hProcess);
return i;
} else return 1;
}このプログラム中では、WinMainの中でCreateProcessによりNotepad.exeを呼び出している。このままだとメモ帳がフォアグラウンドにならない。
そこでまず、WaitForSingleObjectで新たなプロセスが走り出すまで待ち、次にEnumWindowsで全てのウィンドウを列挙する。
EnumWindowsProc中では、列挙されたウィンドウの中から同じスレッドIDを持ったものをGetWindowThreadProcessIdを用いて見つけ出し、見つかればSetForegroundWindowを用いてそのウィンドウをフォアグラウンドにする処理を行っている。
これが成功すればEnumWindowsがFALSEを返すので、作業は終了である。テストプログラム中では、WaitForSingleObjectで呼び出したプロセスが終了するのを待って、戻り値を取得するなどの後処理をしている。