2)在CreateProcess的时候,指定程序在我新生成的Desktop上运行: var StartInfo:TStartupInfo;
FillChar(StartInfo, sizeof(StartInfo), 0); StartInfo.cb:=sizeof(StartInfo); StartInfo.lpDesktop:=PChar(DesktopName); //指定Desktop的名称即可 StartInfo.wShowWindow:=SW_HIDE; StartInfo.dwFlags:=STARTF_USESHOWWINDOW; StartInfo.hStdError:=0; StartInfo.hStdInput:=0; StartInfo.hStdOutput:=0; if not CreateProcess(PChar(FileName),nil,nil,nil,true,CREATE_NEW_CONSOLE+HIGH_PRIORITY_CLASS,nil,PChar(ExtractFilePath(FilePath)),StartInfo,FProceInfo) then begin MessageBox(Application.Handle,'Error when init voice (5).',PChar(Application.Title),MB_ICONWARNING); exit; end;
3)用FindWindow去找程序的主窗口 开始我直接写下了这样的代码: for I:=0 to 60 do begin //wait 30 seconds for open the main window WindowHandle:=FindWindow(nil,'WindowCaption'); if WindowHandle<>0 then begin break; end; Sleep(500); end; 但是,实践证明,这样是找不到不在当前Desktop中的Window的,那怎么办呢: 答案是,可以用SetThreadDesktop()函数,这个函数可以设置当前Thread工作所在的Desktop,于是我在以上代码前又加了一句: if not SetThreadDesktop(FDesktop) then begin exit; end; 但是,程序运行后,该函数却返回了false,说明方法调用失败了,再仔细看MSDN,发现有这么一句话:
The SetThreadDesktop function will fail if the calling thread has any windows or hooks on its current desktop (unless the hDesktop parameter is a handle to the current desktop).
procedure TFindWindowThread.Execute(); var I:Integer; begin //make the current thread find window on the new desktop! if not SetThreadDesktop(FDesktop) then begin exit; end; for I:=0 to 60 do begin //wait 30 seconds for open the main window FWindowHandle:=FindWindow(nil,PChar('WindowCaption')); if FWindowHandle<>0 then begin break; end; Sleep(500); end; end;
constructor TFindWindowThread.Create(ACreateSuspended:Boolean;const ADesktop:THandle); begin inherited Create(ACreateSuspended); FDesktop:=ADesktop; end;
而主程序中的代码变成这样: FindWindowThread:=TFindWindowThread.Create(false,FDesktop); try FindWindowThread.WaitFor; FMainWindowHandle:=FindWindowThread.WindowHandle; finally FindWindowThread.Free; end; if FMainWindowHandle=0 then begin MessageBox(Application.Handle,'Error when init voice (6).',PChar(Application.Title),MB_ICONWARNING); exit; end;
if (FMainWindowHandle=0) or (FEditWindow=0) then begin exit; end; SendMessage(FEditWindow,WM_SETTEXT,0,LongInt(@AText[1])); SendMessage(FMainWindowHandle,WM_COMMAND,$8012,$0); 其中$8012这个数字,也是用Spy++来得到的资源ID。
最后,别忘了关闭程序,以及释放虚拟Desktop: if FProceInfo.hProcess<>0 then begin TerminateProcess(FProceInfo.hProcess,0); end; if FDesktop<>0 then begin CloseDesktop(FDesktop); end;