本来であれば ShellExecuteEx (exec) 実行後、起動したプロセスID を取得できるのですが HSP がその情報を破棄している為、別の方法でしか取得できません。
まず、自分自身のプロセスID を比較対象としてすべてのプロセス の ParentID (親となっているプロセスID)を検索します。
その結果のプロセスID を今度はウィンドウハンドルの所属プロセスID として検索します。
その検索結果から表示されているウィンドウ(トップウィンドウ)を取得すると、exec で実行されたプロセスのトップウィンドウハンドルを取得できます。
それを今度は、ウィンドウタイトルを取得する関数に渡すと、ウィンドウのタイトルが取得できます。
以下モジュールとサンプル(Windows 限定)
#module GET_PROCESSID
#uselib "Psapi.dll"
#func _EnumProcesses "EnumProcesses" var,int,var
#uselib "kernel32.dll"
#cfunc _GetCurrentProcessID "GetCurrentProcessId"
#cfunc _CreateToolhelp32Snapshot "CreateToolhelp32Snapshot" int,int
#func _CloseHandle "CloseHandle" int
#cfunc _Process32First "Process32First" int,var
#cfunc _Process32Next "Process32Next" int,var
#uselib "user32.dll"
#cfunc _FindWindowEx "FindWindowExA" int,int,int,int
#func _GetWindowThreadProcessId "GetWindowThreadProcessId" int,var
#func _GetWindowText "GetWindowTextA" int,var,int
#cfunc _IsWindowVisible "IsWindowVisible" int
#define TH32CS_SNAPPROCESS 0x00000002
/*******************************************************
自分自身の子プロセスを列挙します。
MyChildProcess p1,p2
p1 : プロセスID を代入する配列変数
p2 : 配列変数に代入できる最大数
*******************************************************/
#defcfunc MyChildProcess array PutList,int MaxLen
MyProcessID = _GetCurrentProcessID()
SaveListMax = 0
//スナップショット
hSnap = _CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,MyProcessID)
if (hSnap){
dim ProcessEntry,139 //PROCESSENTRY32 (A) Struct 296 Byte
ProcessEntry(0) = 296 //構造体のサイズ(必ず指定する事)
//プロセス名の取り出し用
dupptr ProcessName,varptr(ProcessEntry(9)),260,2
Result = _Process32First(hSnap,ProcessEntry)
repeat
if Result == 0 : break
if (ProcessEntry(6) == MyProcessID){
if (SaveListMax == MaxLen) : break
PutList(SaveListMax) = ProcessEntry(2)
SaveListMax++
}
Result = _Process32Next(hSnap,ProcessEntry)
loop
_CloseHandle hSnap
}
return SaveListMax
/*******************************************************
対象プロセスID のウィンドウが表示されるまで待機します。
ChildWindowWait p1
p1 : 対象のプロセスID
*******************************************************/
#defcfunc ChildWindowWait int _MyProcessID
waitBreak = 0
repeat 50
hCurWnd = 0
GetWindowProcessID = 0
repeat
hCurWnd = _FindWindowEx(NULL, hCurWnd, NULL, NULL)
_GetWindowThreadProcessId hCurWnd,GetWindowProcessID
if (GetWindowProcessID == _MyProcessID){
if (_IsWindowVisible(hCurWnd)){
waitBreak = 1 : break
}
}
loop
if waitBreak : break
await 100
loop
return waitBreak
/*******************************************************
対象プロセスID に所属しているすべてのウィンドウを列挙します。(非表示を除く)
MyChildWindowHandle p1,p2,p3
p1 : ウィンドウハンドルを代入する配列変数
p2 : 配列変数に代入できる最大数
p3 : 対象プロセスのID
*******************************************************/
#defcfunc MyChildWindowHandle array PutList,int MaxLen,int _MyProcessID
GetWindowProcessID = 0
hCurWnd = 0
SaveListMax2 = 0
sdim WindowTexts,1024
//ウィンドウが作成されるまで待機
result = ChildWindowWait(_MyProcessID)
if (result){
hCurWnd = 0
repeat
hCurWnd = _FindWindowEx(NULL, hCurWnd, NULL, NULL)
if (hCurWnd == 0) : break
GetWindowProcessID = 0
_GetWindowThreadProcessId hCurWnd,GetWindowProcessID
if (GetWindowProcessID == _MyProcessID){
if (_IsWindowVisible(hCurWnd)){
PutList(SaveListMax2) = hCurWnd
SaveListMax2++
}
}
if (SaveListMax2 == MaxLen) : break
loop
}
return SaveListMax2
#global
//以下サンプル
#uselib "user32.dll"
#func GetWindowText "GetWindowTextA" int,var,int
exec "notepad.exe"
dim ProcessIDs,10
mes "プロセス取得完了 : "+MyChildProcess(ProcessIDs,10)+" 個"
dim ChildWindowHandle,10
ChildWindowLength = MyChildWindowHandle(ChildWindowHandle,10,ProcessIDs(0))
mes "ウィンドウハンドル : "+ChildWindowLength+" 個"
//取得完了したウィンドウハンドルからウィンドウタイトルを取得
sdim WindowTitle,1024
GetWindowText ChildWindowHandle(cnt),WindowTitle,1024
mes "HWND : "+ChildWindowHandle(cnt)+" / ["+WindowTitle+"]"