北方站长站
客服热线:0632-5117766

窗口句柄的获得

[2007-12-09 00:00:00] 作者:Northz.com 来源:北方站长站

Tags:获得 窗口 // 函数 可以 得到 HWND 方法 这个 所有 然后

  

这篇文章是关于如何获取窗口句柄,以及有哪些函数可供使用的简单讨论!可适用于vc、bcb(其他的我没有试,估计可以),本人在bcb环境下试验。TuS北方站长站
首先我会罗列出一些获取句柄的win32 api 函数,然后简单说说他们的用途!最后说说我是怎么理解和应用的。见笑了!TuS北方站长站
可用的win32 api函数:TuS北方站长站
1.HWND FindWindow(LPCTSTR lpClassName, LPCTSTR lpWindowName) TuS北方站长站
   HWND FindWindowEx(HWND hwndParent, HWND hwndChildAfter,LPCTSTR lpClassName, LPCTSTR lpWindowName) TuS北方站长站
2.HWND WindowFromPoint(POINT& Point)TuS北方站长站
3.BOOL CALLBACK EnumChildProc(HWND hwnd,LPARAM lParam)TuS北方站长站
   BOOL CALLBACK EnumChildWindows(HWND hWndParent, WNDENUMPROC lpEnumFunc,LPARAM lParam)TuS北方站长站
   BOOL CALLBACK EnumWindows(WNDENUMPROC lpEnumFunc, LPARAM lParam)TuS北方站长站
   BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lParam)TuS北方站长站
一般用途:TuS北方站长站
       对于第一种,大家都很熟悉,是捕捉句柄的常规武器,FindWindow这两兄弟,可以接受捕捉对象的类名或者窗口标题之一,作为参数,返回一个HWND。可是对于一般群众,不一定知道所有的窗口(包括标题栏、按钮等等)的类名啊!棗可以简单举例,请问你知道桌面图标的窗口的类名吗?而对于窗口标题,有可能会出现相同的标题,有两个窗口棗指一个程序的两个进程,这又是个麻烦吧!好了,这个问题先放放,继续下一组。TuS北方站长站
       第二组,通过win32定义的POINT结构(typedef struct tagPOINT {   LONG x;TuS北方站长站
  LONG y;} POINT),来获得当前鼠标光标位置的窗口HWND,这是最直观的武器!常规操作如下:先得到Cursor的POINT(BOOL GetCursorPos(LPPOINT)函数),再用WindowFromPoint。这样,我们几乎可以获得任何打开的有窗口的函数的HWND了!然后通过获取类名的win32 api函数(int GetClassName(  HWND hWnd,   LPTSTR lpClassName,   int nMaxCount ))得到类名棗这里的lpClassName最好用字符数组地址,nMaxCount就是数组的size了,同时,这种方法解决了第一个问题的麻烦!棗我可以把鼠标放在任何地方!*^_^*TuS北方站长站
       第三组,这些是用来列举和处理任何窗口的超级武器!通过组合运用EnumWindows和EnumWindowsProc,EnumChildWindows与EnumChildProc,可以扫描桌面所有窗口并对之处理!TuS北方站长站
我的理解:(这部分用任务驱动式教学方法棗谁让小弟是老师呢!xi xi)TuS北方站长站
任务:得到所有的窗口的类名。TuS北方站长站
解决办法1:我们会先想到第三组,可以自桌面窗口开始(它是所有窗口的祖先),依次扫描,获取类名并存之。有点儿像Visual Stdio的Spy++,或者Borland 的WinSight32,具体办法如下:(bcb中)TuS北方站长站
在主程序中,调用EnumWindows,传入YouEnumProc的函数地址作第一个参数,别忘了转换成WNDENUMPROC类型。第二参可NULL。::EnumWindows(reinterpret_cast YouEnumProc,NULL);TuS北方站长站
在YouEnumProc函数中,如果第一参HWND = = NULL,就跳离(return FALSE;),可以结束啦!TuS北方站长站
然后,把类名数组准备好,得到类名,存之。TuS北方站长站
返回真值,继续下一次扫描。TuS北方站长站
看起来并不复杂,是一种函数递归。但是我可会解释!面啊!: pTuS北方站长站
第二种解决方法:简单、直观棗自己想出来的,颇得意TuS北方站长站
首先准备一个时钟,一种存类名方法(我用TMemo)TuS北方站长站
在定时器处理函数中:TuS北方站长站
1、得到当前cursor的点位置TuS北方站长站
2、再用WindowFromPoint,TuS北方站长站
3、然后得到类名,放到TMemo里TuS北方站长站
这样可以用鼠标获得你想要的窗口(包括按钮等),只要鼠标在窗口放一会儿。。。哈哈TuS北方站长站
第三种方法:其实利用FindWindow和循环结构也应该可以TuS北方站长站
总结:其实得到HWND的方法很多,比如知道了窗口层次,依次向下扫。。。在说第三种呢!但我觉得,我的方法最直接有效,你说呢?TuS北方站长站
欢迎大家与我联系,并讨论这个问题!有关这个问题我还有许多疑问,比如HWND与ID的转换,在如IE页面中的表单控件的HWND或ID,还是其他的东东,总之是能识别他的东西。。。这个我很困惑,没办法!TuS北方站长站
不清楚地方,大家要参照MSDN啊!(好东西呀!)TuS北方站长站
  下面是来自微软的例子,这个枚举所有的窗口,然后向窗口发送关闭的消息。 TuS北方站长站
     #include  TuS北方站长站
     TuS北方站长站
     BOOL CALLBACK EnumWindowsProc( TuS北方站长站
     HWND hwnd, TuS北方站长站
     DWORD lParam TuS北方站长站
     ); TuS北方站长站
     TuS北方站长站
     // TuS北方站长站
     // EnumWindowsProc must be called from a Windows TuS北方站长站
     // application on Windows 95. TuS北方站长站
     // TuS北方站长站
     int WINAPI WinMain( TuS北方站长站
     HINSTANCE hInstance, TuS北方站长站
     HINSTANCE hPrevInstance, TuS北方站长站
     LPSTR lpCmdLine, TuS北方站长站
     int nCmdShow TuS北方站长站
     ) TuS北方站长站
     { TuS北方站长站
     // TuS北方站长站
     // Close all open applications. TuS北方站长站
     // TuS北方站长站
     EnumWindows(EnumWindowsProc, 0); TuS北方站长站
     TuS北方站长站
     // Now do a regular logoff. TuS北方站长站
     ExitWindowsEx(EWX_LOGOFF , 0); TuS北方站长站
     TuS北方站长站
     } TuS北方站长站
     TuS北方站长站
     BOOL CALLBACK EnumWindowsProc( TuS北方站长站
     HWND hwnd, TuS北方站长站
     DWORD lParam TuS北方站长站
     ) TuS北方站长站
     { TuS北方站长站
     DWORD pid = 0; TuS北方站长站
     LRESULT lResult; TuS北方站长站
     HANDLE hProcess; TuS北方站长站
     DWORD dwResult; TuS北方站长站
     TuS北方站长站
     lResult = SendMessageTimeout( TuS北方站长站
     hwnd, TuS北方站长站
     WM_QUERYENDSESSION, TuS北方站长站
     0, TuS北方站长站
     ENDSESSION_LOGOFF, TuS北方站长站
     SMTO_ABORTIFHUNG, TuS北方站长站
    日期: 2000, TuS北方站长站
     &dwResult); TuS北方站长站
     TuS北方站长站
     if( lResult ) TuS北方站长站
     { TuS北方站长站
     // TuS北方站长站
     // Application will terminate nicely, so let it. TuS北方站长站
     // TuS北方站长站
     lResult = SendMessageTimeout( TuS北方站长站
     hwnd, TuS北方站长站
     WM_ENDSESSION, TuS北方站长站
     TRUE, TuS北方站长站
     ENDSESSION_LOGOFF, TuS北方站长站
     SMTO_ABORTIFHUNG, TuS北方站长站
    日期: 2000, TuS北方站长站
     &dwResult); TuS北方站长站
     TuS北方站长站
     } TuS北方站长站
     else // You have to take more forceful measures. TuS北方站长站
     { TuS北方站长站
     // TuS北方站长站
     // Get the ProcessId for this window. TuS北方站长站
     // TuS北方站长站
     GetWindowThreadProcessId( hwnd, &pid ); TuS北方站长站
     // TuS北方站长站
     // Open the process with all access. TuS北方站长站
     // TuS北方站长站
     hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid); TuS北方站长站
     // TuS北方站长站
     // Terminate the process. TuS北方站长站
     // TuS北方站长站
     TerminateProcess(hProcess, 0); TuS北方站长站
     TuS北方站长站
     } TuS北方站长站
     // TuS北方站长站
     // Continue the enumeration. TuS北方站长站
     // TuS北方站长站
     return TRUE; TuS北方站长站
     } TuS北方站长站
TuS北方站长站

 

News

 

info

 

down

出售手机裁听器,手机跟踪定位系统    企业网站,网城,购物网,都市导购,校园网    网上书店系统    上海电信机房服务器托管,双线主机托管    美女图片馆    15G 高清晰图片资源 无水印    室内装潢材料新产品杰威尔艺术漆    收一万ip的美女图片    大量收购个人网址导航网站    出售网址站PR=4alexa=119,764    

下一篇链接:用Visual C++ 6.0设计媒体播放器

上一篇链接:在Visual C++中使用fopen()函数来读写文件

评论】 【打印】 【加入收藏】 【关闭→论坛 →博客 →数据中心

 共有 0 位网友发表了评论 此处只显示部分留言 点击查看完整评论页面