通过程序文件名得到窗口handle? (200分)

我暂时想到的苯方法:<br>&nbsp; 查所有进程--&gt;保存需要的进程ID<br>&nbsp; 枚举窗口--&gt;根据窗口得到句柄--&gt;得到进程ID--&gt;与保存的进程ID比较,如果是,则处理
 
Yhhe,我问了一中午没答案。。。。<br>你继续吧,呵呵
 
通过一个父窗体的句柄,递归的枚举它的子窗体,我们可以最终找到需要的子窗体。<br><br>用法如下:<br><br>nParentHandle: HWnd; <br>nChildHandle: HWnd; <br><br>nParentHandle := FindWindow(nil, 'Notepad'); <br>if nParentHandle &lt;&gt; 0 then <br>nChildHandle := FindChildWindow(nParentHandle, 'SomeChildEditsClassName'); <br><br>------函数代码------ <br><br>var <br>hwndFindChildWindow : HWND; <br><br>function EnumWindowsForFindChildWindowProc(WHandle: HWND; lParam: LPARAM): BOOL; export; stdcall; <br>const <br>MAX_WINDOW_NAME_LEN = 80; <br>var <br>sTargetClassName: string; <br>nHandle: HWnd; <br>sCurrClassName: string; <br>bResult: Boolean; <br>begin <br>if (hwndFindChildWindow &lt;&gt; 0) then <br>exit; <br>sTargetClassName := PChar(lParam); <br>sCurrClassName := GetWindowClass(WHandle); <br>bResult := CompareText(sCurrClassName, sTargetClassName) = 0; <br>If (bResult) then <br>hwndFindChildWindow := WHandle <br>else <br>FindChildWindow(WHandle, PChar(lParam)); <br>end; <br><br>function FindChildWindow(hwndParent: HWnd; ClassName: PChar) : HWnd; <br>begin <br>try <br>EnumChildWindows(hwndParent, @EnumWindowsForFindChildWindowProc, LongInt(PChar(ClassName))); <br>Result := hwndFindChildWindow; <br>except <br>on Exception do <br>Result := 0; <br>end; <br>end; <br><br>//返回当前获得焦点的窗体<br>function GetFocusedWindowFromParent(ParentWnd:HWnd):HWnd; <br>var <br>OtherThread, <br>Buffer : DWord; <br>idCurrThread: DWord; <br>begin <br>OtherThread := GetWindowThreadProcessID(ParentWnd, @Buffer); <br>idCurrThread := GetCurrentThreadID; <br>if AttachThreadInput(idCurrThread, OtherThread, true) then begin <br>Result := GetFocus; <br>AttachThreadInput(idCurrThread, OtherThread, false); <br>end <br>else <br>Result:= GetFocus; <br>end; <br><br>//获得当前获得焦点的子窗体,即使它是其他应用程序的窗体<br>function GetFocusedChildWindow: HWnd; <br>begin <br>Result := GetFocusedWindowFromParent(GetForegroundWindow); <br>end; <br><br>//获得窗体的文本<br>function EIGetWinText(nHandle: Integer): string; <br>var <br>pcText: array[0..32768] of char; <br>begin <br>SendMessage(nHandle, WM_GETTEXT, 32768, LongInt(@pcText)); <br>Result := pcText; <br>end; <br><br>//设定窗体的文本<br>procedure EISetWinText(nHandle: Integer; const sNewText: string); <br>begin <br>SendMessage(nHandle, WM_SETTEXT, Length(sNewText), LongInt(PChar(Trim(sNewText)))); <br>end; <br><br>//返回窗体的类名<br>function EIGetWindowClass(const nHandle: HWnd): string; <br>var <br>szClassName: array[0..255] of char; <br>begin <br>GetClassName(nHandle, szClassName, 255); <br>Result := szClassName; <br>end; &nbsp;<br>&nbsp;<br>
 
请问如何通过进程的句柄获得该进程窗体的句柄?
 
请大家不要跑题
 
FindWindow
 
能说详细点吗?
 
获得主线程的句柄,然后调用下面的函数,可以获得某个线程的所有窗口对象<br>EnumThreadWindows<br>
 
配合下面的函数,就可以根据文件名找到主线程<br>但对于服务可能不行的<br>CreateToolhelp32Snapshot(
 
我的代码,可以完成楼主所说的功能,请大家多多指教!<br><br>unit Unit1;<br><br>interface<br><br>uses<br>&nbsp; Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,<br>&nbsp; Dialogs, StdCtrls;<br><br>type<br>&nbsp; TForm1 = class(TForm)<br>&nbsp; &nbsp; Button1: TButton;<br>&nbsp; &nbsp; Edit1: TEdit;<br>&nbsp; &nbsp; ListBox1: TListBox;<br>&nbsp; &nbsp; procedure Button1Click(Sender: TObject);<br>&nbsp; private<br>&nbsp; &nbsp; { Private declarations }<br>&nbsp; public<br>&nbsp; &nbsp; { Public declarations }<br>&nbsp; end;<br><br>var<br>&nbsp; Form1: TForm1;<br><br>implementation<br><br>{$R *.dfm}<br><br>procedure TForm1.Button1Click(Sender: TObject);<br>var<br>&nbsp; Sti: TStartupInfo;<br>&nbsp; Psi: TProcessInformation;<br>&nbsp; ThrdId: Cardinal;<br>&nbsp; function EnumProc(Handle: THandle; Param: Integer): Boolean; &nbsp;stdcall;<br>&nbsp; var<br>&nbsp; &nbsp; ClsName: String;<br>&nbsp; &nbsp; WndCapt: String;<br>&nbsp; begin<br>&nbsp; &nbsp; SetLength(ClsName, 250);<br>&nbsp; &nbsp; SetLength(WndCapt, 250);<br>&nbsp; &nbsp; GetWindowText(Handle, PChar(WndCapt), 250);<br>&nbsp; &nbsp; GetClassName(Handle, PChar(ClsName), 250);<br>&nbsp; &nbsp; TStrings(Param).Add('Handle: $' + IntToHex(Handle, 8) + ' &nbsp;' +<br>&nbsp; &nbsp; &nbsp; PChar(ClsName) + ':' + PChar(WndCapt));<br>&nbsp; &nbsp; Result := True;<br>&nbsp; end;<br>begin<br>&nbsp; ListBox1.Items.Clear;<br>&nbsp; FillMemory(@Sti, SizeOf(Sti), 0);<br>&nbsp; Sti.cb := SizeOf(Sti);<br>&nbsp; Sti.wShowWindow := SW_MINIMIZE; //SW_SHOW;<br>&nbsp; Sti.dwFlags := STARTF_USESHOWWINDOW or STARTF_USEFILLATTRIBUTE;<br>&nbsp; Sti.dwFillAttribute := FOREGROUND_INTENSITY or BACKGROUND_BLUE;<br>&nbsp; if CreateProcess(PChar(Edit1.Text), nil,<br>&nbsp; &nbsp; nil, nil, False,<br>&nbsp; &nbsp; 0, nil, PChar(ExtractFilePath(Edit1.Text)),<br>&nbsp; &nbsp; Sti, Psi) then<br>&nbsp; begin<br>&nbsp; &nbsp; ListBox1.Items.Add('Start Process: ' + Edit1.Text);<br>&nbsp; &nbsp; ListBox1.Items.Add('');<br>&nbsp; &nbsp; ThrdId := Psi.dwThreadId;<br>&nbsp; &nbsp; //等待程序启动完毕,最多等待10秒钟,<br>&nbsp; &nbsp; //如果不等待,有可能窗口还没有来得及创建呢<br>&nbsp; &nbsp; WaitForInputIdle(Psi.hProcess, 10*1000);<br>&nbsp; &nbsp; EnumThreadWindows(ThrdId, @EnumProc, Integer(ListBox1.Items));<br>&nbsp; end;<br>end;<br><br>end.<br>
 
楼主? test
 
LiChaoHui,好像DOS程序不行。
 
因为DOS程序根本就没有窗口啊,你也太吹毛求皮了吧,<br>DOS程序的那个窗口,是操作系统提供的虚拟机的一部分<br>DOS根本就没有Windows窗口,你不会连这个都不知道吧?<br><br>对于DOS程序,只能用以前,我给你说的方法来控制和捕捉程序的输入输出了
 
多人接受答案了。
 

Similar threads

回复
0
查看
560
不得闲
S
回复
0
查看
800
SUNSTONE的Delphi笔记
S
S
回复
0
查看
802
SUNSTONE的Delphi笔记
S
顶部