怎样用findwindow找到application.message弹出的对话框的句柄?(50分)

  • 主题发起人 一个过客
  • 开始时间
呵呵,messagebox就是起提示做用的,你都不要人工干涉了还用messagebox做什么?<br>用个boolean变量判断一下不是更有效么?<br>》》.........................................
 
为什么不用名称查找呢?
 
ZYDFY真是小人之心啊,不想理你这种货色。<br><br>我之所以有这个需求,是因为我有一个程序,有一些自动的功能。 客户要求支持完全自动,无人职守。但是又要求有人的时候照常弹出对话框,以供用户甄别是否需要手工处理。<br><br>因此我的解决方案就是弹出对话框,显示10秒之后自动消失,这样既兼顾了无人职守,也照顾到手工干预的情况。<br><br>formality说详细一点,怎么判断?<br>MrMengyi,就是找不到呀
 
好象就是application.handle,你看看这个函数的代码。
 
楼上我试过了,把wm_close消息postmessage给dialog让他关闭。如果用application.handle的话,整个程序就关闭了
 
不好意思我记错了,十分对不起,可以用HOOK吗:<br><br>unit Unit1;<br><br>interface<br><br>uses<br> &nbsp;Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,<br> &nbsp;Dialogs, StdCtrls, ExtCtrls;<br><br>type<br> &nbsp;TForm1 = class(TForm)<br> &nbsp; &nbsp;btnAppMsgBox: TButton;<br> &nbsp; &nbsp;Memo1: TMemo;<br> &nbsp; &nbsp;OpenDialog: TOpenDialog;<br> &nbsp; &nbsp;btnMsgBox: TButton;<br> &nbsp; &nbsp;procedure btnAppMsgBoxClick(Sender: TObject);<br> &nbsp; &nbsp;procedure FormCreate(Sender: TObject);<br> &nbsp; &nbsp;procedure FormDestroy(Sender: TObject);<br> &nbsp; &nbsp;procedure btnMsgBoxClick(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 HookMessageBox(code: integer; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall;<br><br>var<br> &nbsp;Form1: TForm1;<br> &nbsp;HookMsgBox: DWORD = 0;<br><br>implementation<br><br>{$R *.dfm}<br><br>function GetWindowClassName(H:Thandle):string;<br>var<br> &nbsp;buf: array[0..255] of char;<br>begin<br> &nbsp;GetClassName(H, buf, SizeOf(buf));<br> &nbsp;result:=buf;<br>end;<br><br>function HookMessageBox(code: integer; wParam: WPARAM; lParam: LPARAM): LRESULT;<br>var<br> &nbsp;H: Thandle;<br> &nbsp;PCW: ^CBT_CREATEWND;<br>begin<br> &nbsp;if (code&gt;=0) and (code=HCBT_CREATEWND) then<br> &nbsp;begin<br> &nbsp; &nbsp;H := Thandle(wParam);<br> &nbsp; &nbsp;PCW:=Pointer(lparam);<br> &nbsp; &nbsp;if (GetWindowClassName(H)='#32770')<br> &nbsp; &nbsp; &nbsp; and ((GetWindowLong(H, GWL_STYLE) and WS_SIZEBOX) = 0) &nbsp;//边框不可以缩放<br> &nbsp; &nbsp; &nbsp; and (PCW^.lpcs^.hwndParent=Application.Handle) //检查是不是 Application.MessageBox<br> &nbsp; &nbsp;then Form1.Memo1.Lines.Add(GetWindowClassName(H));<br> &nbsp;end;<br> &nbsp;Result:=CallNextHookEx(HookMsgBox, Code, wParam, lParam);<br>end;<br><br>procedure TForm1.btnAppMsgBoxClick(Sender: TObject);<br>begin<br> &nbsp;Application.MessageBox('test', 'test');<br>end;<br><br>procedure TForm1.FormCreate(Sender: TObject);<br>begin<br> &nbsp;HookMsgBox:=SetWindowsHookEx(WH_CBT,HookMessageBox,0, GetCurrentThreadID);<br>end;<br><br>procedure TForm1.FormDestroy(Sender: TObject);<br>begin<br> &nbsp;if HookMsgBox&lt;&gt;0 then UnhookWindowsHookEx(HookMsgBox);<br>end;<br><br>procedure TForm1.btnMsgBoxClick(Sender: TObject);<br>begin<br> &nbsp;MessageBox(Handle, 'test', 'test', 0);<br>end;<br><br>end.
 
晕哦~~~~这么麻烦? 我现在窗口类名,窗口标题都知道,直接findwindow为什么不行?我很奇怪
 
unit Unit1;<br><br>interface<br><br>uses<br> &nbsp;Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,<br> &nbsp;Dialogs, StdCtrls, ExtCtrls;<br><br>type<br> &nbsp;TForm1 = class(TForm)<br> &nbsp; &nbsp;Button1: TButton;<br> &nbsp; &nbsp;Timer1: TTimer;<br> &nbsp; &nbsp;procedure Button1Click(Sender: TObject);<br> &nbsp; &nbsp;procedure Timer1Timer(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>begin<br> &nbsp;Timer1.Enabled:=True;<br> &nbsp;application.MessageBox('对话框', '对话框 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ', 0);<br>end;<br><br>procedure TForm1.Timer1Timer(Sender: TObject);<br>var<br> &nbsp;H,H1:THandle;<br> &nbsp;ClassName: array[0..255] of Char;<br>begin<br> &nbsp;ClassName:='#32770';<br> &nbsp;H:=FindWindow(ClassName,nil);<br> &nbsp;H1:=GetParent(H);<br> &nbsp;GetClassName(H1,ClassName,255);<br> &nbsp;if (ClassName=#84+#65+#112+#112+#108+#105+#99+#97+#116+#105+#111+#110)<br> &nbsp; &nbsp; &nbsp;and(H1=Application.Handle) then<br> &nbsp;begin<br> &nbsp; &nbsp;ClassName:=#199+#235+#194+#165+#214+#247+#190+#161+#191+#236+#189+#225+#204<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; +#249+#183+#197+#183+#214;<br> &nbsp; &nbsp;SetWindowText(H,ClassName);<br> &nbsp; &nbsp;Timer1.Enabled:=False;<br> &nbsp;end;<br>end;<br><br>end.
 
ZYDFY 废话真多自己解决不了就算了还要挖苦别人一下~~鄙视!!绝对的鄙视!<br> &nbsp; 有没有用那是别人的事,自己懂的 提供解决方法就OK了~~<br>不知道用 GetWindow 可以不可以<br>这个可以查子窗体的~~findwindow好象不可以的吧
 
楼上的这个办法的确找到了那个dialog,不错。<br><br>但是有一点小问题,你的原理是先找一个#32770的窗口,然后看他的父亲是不是application,如果是,就关闭。 那么如果不是呢?怎样找下一个匹配的?
 
补充,我刚才说的楼上指的是kinneng朋友 <br><br>老大,救我!你的意思是说,用getwindow来查application的子窗口吗?
 
我刚才试验了一下,getwindow(application.handle,GW_CHILD) 查不到
 
试试TOpenDialog, 也是这个类名的.还有其它windows标准对话框都是<br><br>to 一个过客<br>我还以为不知道标题呢
 
[h3][red]windows标准对话框的类名是 #32770 [/red][/h3]
 
EnumWindows ???
 
哦,这样简单:<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><br> &nbsp; &nbsp;procedure Button1Click(Sender: TObject);<br> &nbsp; &nbsp;procedure Button2Click(Sender: TObject);<br> &nbsp;private<br> &nbsp; &nbsp;{ Private declarations }<br> &nbsp;public<br> &nbsp; &nbsp;{ Public declarations }<br> &nbsp;end;<br><br> type<br> Tmyclose=class(Tthread)<br> public<br> procedure Execute;override;<br> end;<br>var<br> &nbsp;Form1: TForm1;<br><br>implementation<br><br>{$R *.dfm}<br><br>procedure TForm1.Button1Click(Sender: TObject);<br>var<br>uname:pchar;<br>len:dword;<br>myclose:Tmyclose;<br>begin<br>myclose:=Tmyclose.Create(false);<br>application.MessageBox(pchar('hoho'),pchar('heihei'),mb_ok);<br>end;<br><br>{ Tmyclose }<br><br>procedure Tmyclose.Execute;<br>var<br>hd:Thandle;<br>begin<br> &nbsp; sleep(1000);<br> &nbsp; hd:=findwindow(nil,'heihei');//你知道窗口标题了吧 我这里标题是heihei<br> &nbsp; sendmessage(hd,wm_close,0,0);//建议还是不要用类名,万一找错了怎么办。<br> &nbsp; self.Terminate;<br>end;<br><br>procedure TForm1.Button2Click(Sender: TObject);//这个没用<br>var<br>myclose:Tmyclose;<br>begin<br> myclose:=Tmyclose.Create(false);<br>end;<br><br>end.<br>==============================<br>form上一个按钮,然后copy, xp 下 ok<br>看看行不行
 
此外,配合类名称和Caption,findwindow应该能定位了吧<br>我用findwindow('#32770',nil)是能找到的~~
 
自己定义一个提示窗口.最简单!
 
to 一个过客<br>那就历遍所有窗口,也没有什么难度<br>只要符合类名= #32770,父窗口的句柄=本程序Application的句柄,那就是要找的对话框,<br>这来项缺一不可。
 
to kinneng<br>但是OpenDialog等标准的Windows对话框父窗口的句柄也是application.handle<br>所以还应该检查窗口样式,参见我上面的HOOK,当然还可以再检查其它的样式.
 
顶部