我用CreateProcedure调用了另外一个delphi程序,能够得到该程序的窗口handle??(200分)

  • 主题发起人 主题发起人 DingDang
  • 开始时间 开始时间
D

DingDang

Unregistered / Unconfirmed
GUEST, unregistred user!
我的主程序由于要调用((多个))子EXE程序,我想通过createprocess的process handle维护一个当前活动应用列表,并且通过主程序激活已经打开但是没有FOCUS的程序,苦于不知道如何得到窗口句柄,本人又不想通过查询所有窗口的办法得到!<br>&nbsp; 望大虾指教! &nbsp; &nbsp; hProcess ---&gt; hWnd
 
没有FOCUS的程序是什么意思?
 
对不起,表达不够准确<br>并且没有加回车<br>重述如下:<br>我的主程序由于要调用((多个))子EXE程序,我想通过createprocess的<br>processhandle 或者 ThreadHandle维护一个当前活动应用列表,<br>并且想通过主程序激活已经打开但是被切换在后台的程序,苦于不知道如何<br>得到窗口句柄,本人又不想通过查询所有窗口的办法得到!<br><br>望大虾指教! &nbsp; &nbsp; hProcess ---&gt; hWnd<br>
 
子EXE程序是你自己编的吗?
 
是的,但是很多 &gt; 100
 
既然是自己的程序,给你想一个笨办法:<br>每个子程序(*.exe)执行后,把自己的processhandle,windowhandle都发给<br>主程序,发送方法可以是sendmessage,wm_copydata等.<br><br>或者你干脆不要保存process列表,而是保存windowhandle列表,得到handle<br>的方法是: createprocess之后,用findwindow(classname)--你自己的程序<br>classname当然应该知道.<br>这也是一个笨办法,........ &nbsp;:-(<br>
 
ProcessHandle是个伪句柄,应该用ProcessID维护列表。<br><br>小EXE启动后,向主调窗体wnd发消息。<br><br>SendMessage(wnd,WM_USER+1,Handle,GetCurrentProcessID);<br><br>wnd就可得到ProcessID与HWND的一一对应表。<br>这个ProcessID就是CreateProcess的TProcessInfomation中的dwProcessId。
 
大家的想法给我很多启示,我无意中发现一条消息 WM_ACTIVEAPP<br>我想是否可以通过 ThreadID 直接发消息,但是不会用.
 
DingDang下面的代码或许对你有所帮助<br>unit Unit1;<br><br>interface<br><br>uses<br>&nbsp; Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,<br>&nbsp; StdCtrls;<br><br>type<br>&nbsp; EnumThreadWndProc=function(hw:HWND;lP:LPARAM):boolean;<br><br>type<br>&nbsp; TForm1 = class(TForm)<br>&nbsp; &nbsp; ListBox1: TListBox;<br>&nbsp; &nbsp; Button1: TButton;<br>&nbsp; &nbsp; Button2: TButton;<br>&nbsp; &nbsp; procedure Button1Click(Sender: TObject);<br>&nbsp; &nbsp; procedure Button2Click(Sender: TObject);<br>&nbsp; &nbsp; procedure ListBox1DblClick(Sender: TObject);<br>&nbsp; private<br>&nbsp; &nbsp; { Private declarations }<br>&nbsp; public<br>&nbsp; &nbsp; { Public declarations }<br>&nbsp; end;<br><br>&nbsp; function Enum(hw:HWND;lP:LPARAM):boolean;stdcall;<br><br>var<br>&nbsp; Form1: TForm1;<br>&nbsp; st:TStartUpInfo;<br>&nbsp; pp:array[1..3] of TProcessInformation;<br>&nbsp; ppp:Thandle;<br>&nbsp; pppp:TProcessInformation;<br><br>implementation<br><br>{$R *.DFM}<br><br>function Enum(hw:HWND;lP:LPARAM):boolean;<br>var<br>&nbsp; Buffer:Array[0..255] of Char;<br>begin<br>&nbsp; GetWindowText(hw,buffer,256);<br>&nbsp; TListBox(lp).items.addobject(buffer,Tobject(hw));<br>&nbsp; Result:=true;<br>end;<br><br><br><br>procedure TForm1.Button1Click(Sender: TObject);<br>var<br>&nbsp; proc:EnumThreadWndProc;<br>&nbsp; i:integer;<br>begin<br>&nbsp; proc:=@Enum;<br>for i:=1 to 3 do<br>&nbsp; EnumThreadWindows(pp.dwThreadId,@proc,lparam(listbox1));<br>end;<br><br>procedure TForm1.Button2Click(Sender: TObject);<br>begin<br>FillChar(st,sizeof(st),#0);<br>with st do<br>begin<br>&nbsp; cb:=sizeof(st);<br>&nbsp; dwFlags:=StartF_UsesTDHandles or STARTF_USESHOWWINDOW;<br>&nbsp; lptitle:=nil;<br>&nbsp; wShowWindow:=SW_HIDE;<br>end;<br>CreateProcess(PChar('c:/program files/microsoft office/office/winword.exe'),<br>&nbsp; &nbsp; &nbsp; nil,nil,nil,true,DETACHED_PROCESS,nil,nil,st,pp[1]);<br>CreateProcess(PChar('c:/program files/microsoft office/office/Excel.exe'),<br>&nbsp; &nbsp; &nbsp; nil,nil,nil,true,DETACHED_PROCESS,nil,nil,st,pp[2]);<br>CreateProcess(PChar('c:/program files/microsoft office/office/MSACCESS.exe'),<br>&nbsp; &nbsp; &nbsp; nil,nil,nil,true,DETACHED_PROCESS,nil,nil,st,pp[3]);<br>// &nbsp;ppp:=OpenProcess(PROCESS_ALL_ACCESS, FALSE,pp.dwProcessId );<br>// &nbsp;TerminateProcess(ppp,0);<br>end;<br><br>procedure TForm1.ListBox1DblClick(Sender: TObject);<br>begin<br>&nbsp; ppp:=Thandle(Listbox1.Items.Objects[Listbox1.ItemIndex]);<br>&nbsp; showwindow(ppp,sw_show);<br>end;<br><br>end.
 
Liu JZX: 人家说了"本人又不想通过查询所有窗口的办法得到",<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;如果可以用枚举就简单了.
 
看来通过 findwindow 或 Enum 的方法还是可行<br>接下来又出现一个问题:<br>&nbsp; 我的子程序中有 SHOWMODAL 的几重窗口,当我用<br>SETFOREGROUNDWINDOW 时,不能确定哪个窗口句柄才是<br>该程序最前面的窗口, 有时会把SHOWMODAL的父窗口<br>显示出来,但是又点不动.
 
DingDang将回调过程函数改为下面形式在试一试,如何<br>function Enum(hw:HWND;lP:LPARAM):boolean;<br>var<br>&nbsp; Buffer:Array[0..255] of Char;<br>&nbsp; hh:HWND;<br>begin<br>&nbsp; GetWindowText(hw,buffer,256);<br>&nbsp; if GetTopWindow(hw)&lt;&gt;0 then<br>&nbsp; begin<br>&nbsp; tt:=String(buffer);<br>&nbsp; TListBox(lp).items.addobject(buffer,Tobject(hw));<br>&nbsp; end;<br>&nbsp; Result:=true;<br>end;<br>
 
上面代码忘了删掉tt:=String(buffer);
 
unit Unit1;<br><br>interface<br><br>uses<br>&nbsp; Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,StdCtrls;<br><br>type<br>&nbsp; EnumThreadWndProc=function(hw:HWND;lP:LPARAM):boolean;<br><br>type<br>&nbsp; TForm1 = class(TForm)<br>&nbsp; &nbsp; ListBox1: TListBox;<br>&nbsp; &nbsp; Button1: TButton;<br>&nbsp; &nbsp; Button2: TButton;<br>&nbsp; &nbsp; procedure Button1Click(Sender: TObject);<br>&nbsp; &nbsp; procedure Button2Click(Sender: TObject);<br>&nbsp; &nbsp; procedure ListBox1DblClick(Sender: TObject);<br>&nbsp; private<br>&nbsp; &nbsp; { Private declarations }<br>&nbsp; public<br>&nbsp; &nbsp; { Public declarations }<br>&nbsp; end;<br><br>&nbsp; function Enum(hw:HWND;lP:LPARAM):boolean;stdcall;<br><br>var<br>&nbsp; Form1: TForm1;<br>&nbsp; st:TStartUpInfo;<br>&nbsp; pp:array[1..3] of TProcessInformation;<br>&nbsp; ppp:Thandle;<br><br>implementation<br><br>{$R *.DFM}<br><br>function Enum(hw:HWND;lP:LPARAM):boolean;<br>var<br>&nbsp; Buffer:Array[0..255] of Char;<br>begin<br>&nbsp; if GetTopWindow(hw)&lt;&gt;0 then<br>&nbsp; begin<br>&nbsp; &nbsp; GetWindowText(hw,buffer,256);<br>&nbsp; &nbsp; TListBox(lp).items.addobject(buffer,Tobject(hw));<br>&nbsp; end;<br>&nbsp; Result:=true;<br>end;<br><br><br><br>procedure TForm1.Button1Click(Sender: TObject);<br>var<br>&nbsp; proc:EnumThreadWndProc;<br>&nbsp; i:integer;<br>begin<br>&nbsp; proc:=@Enum;<br>for i:=1 to 2 do<br>&nbsp; EnumThreadWindows(pp.dwThreadId,@proc,lparam(listbox1));<br>end;<br><br>procedure TForm1.Button2Click(Sender: TObject);<br>begin<br>FillChar(st,sizeof(st),#0);<br>with st do<br>begin<br>&nbsp; cb:=sizeof(st);<br>&nbsp; dwFlags:=StartF_UsesTDHandles or STARTF_USESHOWWINDOW;<br>&nbsp; lptitle:=nil;<br>&nbsp; wShowWindow:=SW_HIDE;<br>end;<br>CreateProcess(PChar('c:/program files/microsoft office/office/winword.exe'),<br>&nbsp; &nbsp; &nbsp; nil,nil,nil,true,DETACHED_PROCESS,nil,nil,st,pp[1]);<br>CreateProcess(PChar('c:/program files/microsoft office/office/Excel.exe'),<br>&nbsp; &nbsp; &nbsp; nil,nil,nil,true,DETACHED_PROCESS,nil,nil,st,pp[2]);<br>end;<br><br>procedure TForm1.ListBox1DblClick(Sender: TObject);<br>begin<br>&nbsp; ppp:=Thandle(Listbox1.Items.Objects[Listbox1.ItemIndex]);<br>&nbsp; if IsWindowVisible(ppp) then<br>&nbsp; &nbsp; BringWindowToTop(ppp)<br>&nbsp; else<br>&nbsp; &nbsp; showwindow(ppp,sw_show);<br>end;<br><br>end.
 
Liu JZX:<br>&nbsp; GetTopWindow能够过滤去很多不用的窗口,但是还是存在一个问题!<br>例如,打开 word 后,再打开 FILEOPEN 对话框,于是会出现找到两个<br>窗口,此时,如果还是双击 word 连接的话,还是只有word窗口被激活,<br>而不是最前面的open对话框.word 还好,它的灰化的open窗口还在前面.<br>更惨的是我的程序,一个窗口showmodal另外一个窗口后,后面的窗口<br>被show到前面了,但是不能响应事件,而前面的窗口不见了.
 
DingDang:<br>&nbsp; 我不太明白你的要求<br>此时双击 Open 连接 ,open窗口就会被激活
 
将下面代码写入,双击 Open 连接 ,open窗口就会被激活,在双击 word 连接的话<br>open窗口就会被激活,我也不知道为什么,试一试<br>function Enum(hw:HWND;lP:LPARAM):boolean;<br>var<br>&nbsp; Buffer:Array[0..255] of Char;<br>&nbsp; tt:Thandle;<br>&nbsp; tc:Thandle;<br>begin<br>&nbsp; tt:=GetTopWindow(hw);<br>&nbsp; tc:=GetWindow(tt,GW_Child);<br>&nbsp; if tc&lt;&gt;0 then<br>&nbsp; begin<br>&nbsp; &nbsp; GetWindowText(hw,buffer,256);<br>&nbsp; &nbsp; TListBox(lp).items.addobject(buffer,Tobject(tc));<br>&nbsp; end;<br>&nbsp; Result:=true;<br>end;<br>
 
后退
顶部