我使用WINEXEC来启动一个程序,然后用FINDWINDOWS句柄来确定一个是否已经启动,如果启动就进行相关操作。
但是这个程序比较大,需要启动许久,故FINDWINDOWS找到主窗口体的时候,也许WINEXEC启动的程序并没有完成,所以相关操作都是白操作。
   
 请问有什么办法或思路能解决这个问题呢。

解决方案 »

  1.   

    笨方法,循环里死等。
      hWin := FindWindow(类名,标题);  while (hWin = 0) do
      begin
        Sleep(100);
        Application.ProcessMessages;
        hWin:=  FindWindow(类名,标题);
      end;如果你用CreateProcess的话,可以这样等待:
      WaitForInputIdle(hProcess, INFINITE);  // hProcess为创建的进程句柄
      

  2.   

    用CreateProcess+WaitForInputIdle(hProcess, INFINITE)方法,建议不要用FindWindow。下面是我以前回复一个贴子的内容,
    参与一下吧procedure TForm1.Button1Click(Sender: TObject);
    type
      //定义一个结构体,用来返回启动窗体的句柄
      PFindData = ^TFindData;
      TFindData = record
        hProcess: THandle;
        hWindow: THandle;
      end;  function EnumWindowsProc(Handle: THandle; lParam: LPARAM): Boolean; stdcall;
      var
        hProcess: THandle;
        FindData: PFindData;
      begin
        Result := True; //继续枚举一下窗体
        FindData := PFindData(lParam);
        GetWindowThreadProcessId(Handle, hProcess); //取得窗体进程ID号
        if hProcess = FindData^.hProcess then
        begin
          FindData^.hWindow := Handle; //已经找到!!
          Result := False;
        end;
      end;var
      FileName: string;
      ProcessInfo: TProcessInformation;
      StartUpInfo: TStartupInfo;
      hButton: THandle;
      AFindData: TFindData;
    begin
      FileName := ExtractFilePath(ParamStr(0)) + 'Project2.exe';  FillChar(StartUpInfo, SizeOf(StartUpInfo), $00);
      StartUpInfo.dwFlags := STARTF_USESHOWWINDOW;
      StartUpInfo.wShowWindow := SW_SHOW;  if CreateProcess(nil, PChar(FileName), nil, nil,
        False, IDLE_PRIORITY_CLASS, nil, nil, StartUpInfo,
        ProcessInfo) then
      begin
        //等就直到另外一下程序都准备好了
        WaitForInputIdle(ProcessInfo.hProcess, INFINITE);    AFindData.hProcess := ProcessInfo.dwProcessId;
        AFindData.hWindow := 0;
        EnumWindows(@EnumWindowsProc, Integer(@AFindData));
        if AFindData.hWindow <> 0 then
        begin
          hButton := FindWindowEx(AFindData.hWindow, 0, 'TButton', 'Button1');
          if hButton <> 0 then
            SendMessage(hButton, CN_COMMAND, BN_CLICKED, 0);
        end;    CloseHandle(ProcessInfo.hThread);
        CloseHandle(ProcessInfo.hProcess);
      end;
    end;
      

  3.   

    谢谢你,我已经测试,测试普通的生成的EXE没有问题。但是我需要操作的程序AFindData.hWindow有的时候并不是程序窗口句柄.
    这样的启动的时候窗口标题会变,也就是“正在连接服务器”待程序运行完成后再显示“已成功连接服务器”。
      

  4.   

    那就把窗口标题和窗口类名的判断也加上去

     function EnumWindowsProc(Handle: THandle; lParam: LPARAM): Boolean; stdcall;
      var
        hProcess: THandle;
        FindData: PFindData;
      begin
        Result := True; //继续枚举一下窗体
        FindData := PFindData(lParam);
        GetWindowThreadProcessId(Handle, hProcess); //取得窗体进程ID号
        if hProcess = FindData^.hProcess then
        begin
          FindData^.hWindow := Handle; //已经找到!!
          //根据句柄取类名以及标题,然后判断      Result := False;
        end;
      end;