全國最多中醫師線上諮詢網站-台灣中醫網
發文 回覆 瀏覽次數:1999
推到 Plurk!
推到 Facebook!

ShellExecute 與 FindWindow組合使用還有什摩要注意?

尚未結案
chris_shieh
高階會員


發表:46
回覆:308
積分:240
註冊:2004-04-26

發送簡訊給我
#1 引用回覆 回覆 發表時間:2004-05-06 10:07:56 IP:218.167.xxx.xxx 未訂閱
我利用ShellExecute 執行一些外部程式 (xx.bat) 並在ShellExecute 指令後 立即使用 FindWindow 取得其 HWND 以便SetWindowPos 可以使用 發現一個奇怪現象 當外部程式數目很少時 可以順利動作 但是當外部程式數目較多時 部分(通常是較後面執行者)無法順利抓到HWND (為0) 但是又不是每次都會這樣, 這現象令我狐疑 結果我利用加入sleep()在ShellExecute之後, FindWindow 之前 試驗結果發現 當程式數目較少, 短的sleep時間時間即可正常運作, 當成是數目增多, 相對也需要增加sleep時間才能正常運作 (大約是8-10個 *.bat sleep(1500)) 不知道我是哪邊應注意而未注意呢? var psei:^TShellExecuteInfo; hwnd:THandle; windowCaption:String; for i=0 to scriptList.Count-1 do begin New(psei); with psei^ do begin FillChar(psei^, SizeOf(psei^), 0); cbSize:=Sizeof(psei^); fMask:=SEE_MASK_NOCLOSEPROCESS ; // 用來取得 ProcessID wnd:=0; lpVerb:=nil; lpFile:=PChar(scriptList[i]); lpParameters:=nil; lpDirectory:=nil; nShow:=SW_SHOWDEFAULT; end ; ShellExecuteEx(@psei^); sleep(1500); //少了這行, 通常會遺漏幾個視窗抓不到hwnd hwnd:=FindWindow(nil, PChar(windowCaption)); SetWindowPos(hwnd,0,10,10,200,200,SWP_SHOWWINDOW) end;
hagar
版主


發表:143
回覆:4056
積分:4445
註冊:2002-04-14

發送簡訊給我
#2 引用回覆 回覆 發表時間:2004-05-06 10:37:33 IP:202.39.xxx.xxx 未訂閱
改用如下這個方法試試 用法為傳入 exe 檔(含完整路徑),  其回傳值為執行該 exe 後的 window handle 資料來源: http://delphi.ktop.com.tw/topic.php?topic_id=35055
function PlayFlashExe(Exe: string): integer;
type
  PEnumInfo = ^TEnumInfo;
  TEnumInfo = record
    ProcessID: DWORD;
    HWND: THandle;
  end;      function EnumWindowsProc(Wnd: DWORD; var EI: TEnumInfo): Bool; stdcall;
  var
    PID: DWORD;
  begin
    GetWindowThreadProcessID(Wnd, @PID);
    Result := (PID <> EI.ProcessID) or
              (not IsWindowVisible(WND)) or
              (not IsWindowEnabled(WND));        if not result then EI.HWND := WND;
  end;      function FindMainWindow(PID: DWORD): DWORD;
  var
    EI: TEnumInfo;
  begin 
    EI.ProcessID := PID;
    EI.HWND := 0;
    EnumWindows(@EnumWindowsProc, Integer(@EI));
    Result := EI.HWND;
  end;
var
  SI: TStartupInfo;
  PI: TProcessInformation;
begin
  ZeroMemory(@SI, SizeOf(SI));
  ZeroMemory(@PI, SizeOf(PI));
  SI.cb := SizeOf(SI);
  if CreateProcess(nil, PChar(FlashExe), nil, nil, FALSE, 0 ,nil,nil, SI, PI) then
  begin
    WaitForInputIdle(PI.hProcess, INFINITE);        Result := FindMainWindow(PI.dwProcessID);
    CloseHandle(PI.hProcess);
    CloseHandle(PI.hThread);
  end;
end;
-- 悟嗎?
chris_shieh
高階會員


發表:46
回覆:308
積分:240
註冊:2004-04-26

發送簡訊給我
#3 引用回覆 回覆 發表時間:2004-05-06 18:09:23 IP:219.68.xxx.xxx 未訂閱
[quote] 改用如下這個方法試試 用法為傳入 exe 檔(含完整路徑),  其回傳值為執行該 exe 後的 window handle 資料來源: http://delphi.ktop.com.tw/topic.php?topic_id=35055
function PlayFlashExe(Exe: string): integer;
type
  PEnumInfo = ^TEnumInfo;
  TEnumInfo = record
    ProcessID: DWORD;
    HWND: THandle;
  end;      function EnumWindowsProc(Wnd: DWORD; var EI: TEnumInfo): Bool; stdcall;
  var
    PID: DWORD;
  begin
    GetWindowThreadProcessID(Wnd, @PID);
    Result := (PID <> EI.ProcessID) or
              (not IsWindowVisible(WND)) or
              (not IsWindowEnabled(WND));        if not result then EI.HWND := WND;
  end;      function FindMainWindow(PID: DWORD): DWORD;
  var
    EI: TEnumInfo;
  begin 
    EI.ProcessID := PID;
    EI.HWND := 0;
    EnumWindows(@EnumWindowsProc, Integer(@EI));
    Result := EI.HWND;
  end;
var
  SI: TStartupInfo;
  PI: TProcessInformation;
begin
  ZeroMemory(@SI, SizeOf(SI));
  ZeroMemory(@PI, SizeOf(PI));
  SI.cb := SizeOf(SI);
  if CreateProcess(nil, PChar(FlashExe), nil, nil, FALSE, 0 ,nil,nil, SI, PI) then
  begin
    WaitForInputIdle(PI.hProcess, INFINITE);        Result := FindMainWindow(PI.dwProcessID);
    CloseHandle(PI.hProcess);
    CloseHandle(PI.hThread);
  end;
end;
============================================================== 感謝hagar, 當然以 EnumWindow方式列舉更能精確從Process Handle找出其 handle, 但是很遺憾的, 我採用您的方式, 一樣必須在 CreateProcess與FindMainWindow之間加上sleep()才能正常抓到所有視窗, 過短的sleep 依然會遺漏部份視窗, 跟之前的程式碼結果一樣, 真是奇怪, 難道這跟所執行的程式有關嗎? (可是畢竟已經加上WaitForInputIdle了), ps.我所執行的*.bat 會去存取HDD一些不存在的目錄並且有loop動作
chris_shieh
高階會員


發表:46
回覆:308
積分:240
註冊:2004-04-26

發送簡訊給我
#4 引用回覆 回覆 發表時間:2004-05-06 18:21:05 IP:219.68.xxx.xxx 未訂閱
參考 http://delphi.ktop.com.tw/topic.php?TOPIC_ID=49601 跟小弟同樣情形, 改成多找幾次, 就都OK, 不過對於原因還是很納悶 而且也會拉長時間 >
系統時間:2024-05-21 19:41:19
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!