dawnsong请进,隐藏窗口仍然无法得到!:枚举桌面窗口的判断条件问题 ( 积分: 100 )

  • 主题发起人 主题发起人 YuZi
  • 开始时间 开始时间
Y

YuZi

Unregistered / Unconfirmed
GUEST, unregistred user!
以前讨论枚举桌面应用程序可视窗口的贴子已经很多了,但却没有一个是能真正解决问题的,枚举容易,但判断条件的设定却是最大的难点,很多人都是用<br>EnumWindowProc + if IsWindowVisible() and (一些Style判断)<br>但近日发现,这样做有一个非常大的问题就是函数过份依赖于IsWindowVisible(),使得某一窗口被一些工具隐藏后就无法枚举到列表了。<br>但我发现一个隐藏窗口工具HideHelper却能把隐藏的应用窗口枚举出来,请问它是如何实现的呢?
 
以前讨论枚举桌面应用程序可视窗口的贴子已经很多了,但却没有一个是能真正解决问题的,枚举容易,但判断条件的设定却是最大的难点,很多人都是用<br>EnumWindowProc + if IsWindowVisible() and (一些Style判断)<br>但近日发现,这样做有一个非常大的问题就是函数过份依赖于IsWindowVisible(),使得某一窗口被一些工具隐藏后就无法枚举到列表了。<br>但我发现一个隐藏窗口工具HideHelper却能把隐藏的应用窗口枚举出来,请问它是如何实现的呢?
 
不会吧,这么大的一个坛子没人知道?还是¥少了?
 
顶上去!!!!!
 
dfw怎么啦?人呢?
 
If the specified window, its parent window, its parent's parent window, and so forth, have the WS_VISIBLE style, the return value is nonzero. Otherwise, the return value is zero. <br>上面是IsWindowVisible说明,不用isWindowVisible过滤呗,隐藏的窗体用这个应该就被过滤掉了<br><br>或者用EnumThreadWindows
 
谢谢dawnsong,这次又只有你关注一下。我想判断的时候绝对不能用IsWindowVisible或者是WS_VISIBLE,<br>但只用复合的style和EXstyle条件判断,我试了很多,却始终没办法正确地枚举出所有的跟HideHelper一样结果的窗口(包含被隐藏的窗口)
 
GetWindowInfo能得到很多信息,是窗体的话,应该就有个Rect,那用WINDOWINFO structure判断一下这个Rect是否为nil,应该就能确定是否就是窗体吧,呵呵,我没试过,只是给点儿参考意见[:)]
 
1、thanks,EnumThreadWindows 会把其它一些窗口也列出来,比如:记事本窗口,枚举线程窗口后得到下面三个窗口:<br>无标题 - 记事本<br>M<br>Default IME<br><br>2、tagWINDOWINFO = packed record<br> &nbsp; &nbsp;cbSize: DWORD;<br> &nbsp; &nbsp;rcWindow: TRect;<br> &nbsp; &nbsp;rcClient: TRect;<br> &nbsp; &nbsp;dwStyle: DWORD;<br> &nbsp; &nbsp;dwExStyle: DWORD;<br> &nbsp; &nbsp;dwOtherStuff: DWORD;<br> &nbsp; &nbsp;cxWindowBorders: UINT;<br> &nbsp; &nbsp;cyWindowBorders: UINT;<br> &nbsp; &nbsp;atomWindowType: TAtom;<br> &nbsp; &nbsp;wCreatorVersion: WORD;<br> &nbsp;end;<br>rcClient和rcWindow对于不可见窗口好像返回的也是有效的TRect。另外不知道这个成员有什么用:dwOtherStuff,atomWindowType,wCreatorVersion。
 
type<br> &nbsp;pStringList=^TStringList;<br><br>function &nbsp;ListAllWindows(AHandle:THandle;AList:pStringList):Boolean;stdcall;<br>var<br> &nbsp;theCaption :array[0..255] of Char;<br> &nbsp;theExe &nbsp; &nbsp; :array[0..2055] of char;<br> &nbsp;str :string;<br> &nbsp;winInfo :TWindowInfo;<br>begin<br><br> &nbsp;if GetWindowText(Ahandle,theCaption,SizeOf(theCaption)-1)&lt;&gt;0 then<br> &nbsp;begin<br> &nbsp; &nbsp;GetWindowModuleFileName(AHandle,theExe,SizeOf(theExe)-1);<br> &nbsp; &nbsp;str :=Format('%.10d---%s---%s',[AHandle,theCaption,theExe]);<br> &nbsp; &nbsp;if IsWindowVisible(AHandle) then<br> &nbsp; &nbsp;begin<br> &nbsp; &nbsp; &nbsp;str :=Format('%s---%s',['可见',str]);<br> &nbsp; &nbsp; &nbsp;AList^.Insert(0,str);<br> &nbsp; &nbsp;end<br> &nbsp; &nbsp;else begin<br> &nbsp; &nbsp; &nbsp;ZeroMemory(@winInfo,SizeOf(winInfo));<br> &nbsp; &nbsp; &nbsp;winInfo.cbSize :=SizeOf(winInfo);<br> &nbsp; &nbsp; &nbsp;GetWindowInfo(AHandle,winInfo);<br> &nbsp; &nbsp; &nbsp;{dwWindowStatus<br> &nbsp; &nbsp; &nbsp;The window status. If this member is WS_ACTIVECAPTION, the window is active. Otherwise, this member is zero.<br> &nbsp; &nbsp; &nbsp;}//此处如此判断,得到的结果就和HideHelper非常接近了<br> &nbsp; &nbsp; &nbsp;//这么还会有两种多余的Window也能够出现,一个是ProgramManager,<br> &nbsp; &nbsp; &nbsp;//一个就是在TrayIcon上而不在任务栏里的。那样自己再判断过滤一下就Ok了<br> &nbsp; &nbsp; &nbsp;if winInfo.dwOtherStuff&lt;&gt;0 then begin<br> &nbsp; &nbsp; &nbsp; &nbsp;str :=Format('%s---%s',['隐藏',str]);<br> &nbsp; &nbsp; &nbsp; &nbsp;AList^.Insert(0,str);<br> &nbsp; &nbsp; &nbsp;end;<br> &nbsp; &nbsp;end;<br> &nbsp;end;<br> &nbsp;//theCaption :=<br> &nbsp;Result :=true;<br>end;<br><br>procedure TfrmMain.btnEnumWindowsClick(Sender: TObject);<br>begin<br> &nbsp;ListBoxWindows.Clear;<br> &nbsp;EnumWindows(@ListAllWindows,Integer(@(ListBoxWindows.Items)));<br>end;
 
楼主试一下上面的代码,接近要求否?
 
这100分是dawnsong的了!主要是感谢dawnsong对本人问题的关心!<br>问题继续,望高手指点更好的办法,一定另开贴出分(200)!
 
很感谢dawnsong,您其实是帮助了很多像我这样的人,这又岂是100个虚拟分所能相等价的呢!<br>晚上结束此贴,谢谢!
 
dawnsong的判断其实就是:<br>Result := IsWindowVisible(WND) or (winInfo.dwOtherStuff&lt;&gt;0);<br>粗一看好像正确,但隐藏窗口仍然无法得到。
 
现在比较了一下,通过IsWindowVisible对同一个程序窗口得到两部分,一部分即是所看到的在桌面上的,一部分在任务栏上面,如果在TrayIcon也有的话,那同样也会得到那里的一个Handle,如果那里的隐藏了, IsWindowVisible(WND) or (winInfo.dwOtherStuff&lt;&gt;0);确实是会把它过滤掉
 
这个Window Style很多,组合起来判断确实很烦人,关键的几个组合还是得慢慢试
 
我是这样考虑的,可能要分三种情况判断:标准窗口、对话框、小标题工具窗口。<br>然后把三种情况 or连起来。<br>但是分析后发现,几个隐藏的系统窗口,除了隐藏外,其它风格几乎与标准窗口一样,比如<br>conime.exe进程的Debug窗口。<br>我已经可以判断工具窗口了,但是其它两种,组合风格实在很难跟一些隐藏系统窗口区别开来,所以,我有点怀疑HideHelper是不是通过Style和Extyle来判断的?
 
什么都得靠自己了。。。
 
楼主问个提外话。为什么你说的那个HideHelper软件,安装后,会在C:/temp/Explorer~tmp/svchost.exe有个文件。还要访问网络?文件有200多K哦~~
 
的确如此,我刚下载的也发现了这个问题,由文件名如此伪装便可知它不是什么善类,你可以去问问软件作者,不过我不认识他,想来应该不是作者所为,我以前有装过一次,但很快就反安装了,没注意这个问题。这个软件用Shell Hook隐藏托盘(可能是很多C代码中写的那种),消耗资源太厉害了,而且XP下常常会使Explorer.exe出错,不好使,我正在自己尝试做一个跟它一样的隐藏软件,而且不用HOOK隐藏托盘图标,可惜的是dfw愿意帮助人的高人越来越少了,唉。。。。
 
后退
顶部