Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1810949
  • 博文数量: 272
  • 博客积分: 1272
  • 博客等级: 少尉
  • 技术积分: 1866
  • 用 户 组: 普通用户
  • 注册时间: 2011-03-09 15:51
文章分类

全部博文(272)

文章存档

2016年(16)

2015年(28)

2014年(97)

2013年(59)

2012年(25)

2011年(47)

分类: WINDOWS

2014-02-28 14:32:23

句柄(HANDLE)是Windows程序中一个重要的概念,使用也非常频繁。在Windows程序中,有各种各样的资源(窗口、图标、光标等),系统在创建这些资源时会为它们分配内存,并返回标识这些资源的标识号,即句柄。


窗口句柄是windows句柄的一种,且是重要的一种句柄。在Windows应用程序中,窗口是通过窗口句柄(HWND)来标识的。我们要对某个窗口进行操作,首先就要得到这个窗口的句柄。


窗口句柄的概念比较抽象,简单说窗口句柄就是一个窗口(window)的代表。我们通过几个例子来认识它。


1.LRESULT CALLBACK WndProc(HWND hWnd, UINT message,
WPARAM wParam, LPARAM lParam);


windows窗口处理函数,windows消息机制说的是,每当某个窗口发生变化(比如改变大小,移动),windows系统都会发相应的消息(wm_size,wm_move)给这个窗口。即调用函数
SendMessage(HWND hWnd,UINT Msg,WPARAM wParam,LPARAM
lParam);注意这里WndProc和SendMessage的第一个参数都是HWND,窗口句柄代表这个窗口。


2. hWnd = CreateWindow(szWindowClass, szTitle,
WS_OVERLAPPEDWINDOW,


      CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL,
NULL, hInstance, NULL);


这里说的是窗口句柄的产生,可以把hWnd想象成指针,CreateWindow想象成c++里的new,创建一个window,系统要为这个window对象分配一些资源,可以想象,window是由一个大的结构构成的。同时窗口句柄用来标识这个窗口。


3.有个窗口的句柄,则你就可以操控这个窗口的一切。


大量管理window的win32 api都是以hwnd做为参数。下面列举一些:


BringWindowToTop


FindWindowEx


GetParent


SetWindowPos


GetWindowRect


等等。


4.不仅窗口,窗口上的控件,象按钮,编辑框等也有窗口句柄,因为它们也是一种特殊的窗口,上面操作窗口的api大部分对这些控件窗口也适用。


获取句柄的方法:


这篇文章是关于如何获取窗口句柄,以及有哪些函数可供使用的简单讨论!可适用于vc、bcb(其他的我没有试,估计可以),本人在bcb环境下试验。


首先我会罗列出一些获取句柄的win32 api 函数,然后简单说说他们的用途!最后说说我是怎么理解和应用的。见笑了!


可用的win32 api函数:


1.HWND FindWindow(LPCTSTR lpClassName, LPCTSTR lpWindowName)


   HWND FindWindowEx(HWND hwndParent, HWND hwndChildAfter,LPCTSTR
lpClassName, LPCTSTR lpWindowName)


2.HWND WindowFromPoint(POINT& Point)


3.BOOL CALLBACK EnumChildProc(HWND hwnd,LPARAM lParam)


   BOOL CALLBACK EnumChildWindows(HWND hWndParent, WNDENUMPROC
lpEnumFunc,LPARAM lParam)


   BOOL CALLBACK EnumWindows(WNDENUMPROC lpEnumFunc, LPARAM lParam)


   BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lParam)


一般用途:


      
对于第一种,大家都很熟悉,是捕捉句柄的常规武器,FindWindow这两兄弟,可以接受捕捉对象的类名或者窗口标题之一,作为参数,返回一个HWND。可是对于一般群众,不一定知道所有的窗口(包括标题栏、按钮等等)的类名啊!--可以简单举例,请问你知道桌面图标的窗口的类名吗?而对于窗口标题,有可能会出现相同的标题,有两个窗口--指一个程序的两个进程,这又是个麻烦吧!好了,这个问题先放放,继续下一组。


       第二组,通过win32定义的POINT结构(typedef struct tagPOINT {   LONG x;
  LONG
y;} POINT),来获得当前鼠标光标位置的窗口HWND,这是最直观的武器!常规操作如下:先得到Cursor的POINT(BOOL
GetCursorPos(LPPOINT)函数),再用WindowFromPoint。这样,我们几乎可以获得任何打开的有窗口的函数的HWND了!然后通过获取类名的win32
api函数(int GetClassName(  HWND hWnd,   LPTSTR lpClassName,   int nMaxCount
))得到类名--这里的lpClassName最好用字符数组地址,nMaxCount就是数组的size了,同时,这种方法解决了第一个问题的麻烦!--我可以把鼠标放在任何地方!*^_^*


      
第三组,这些是用来列举和处理任何窗口的超级武器!通过组合运用EnumWindows和EnumWindowsProc,EnumChildWindows与EnumChildProc,可以扫描桌面所有窗口并对之处理!


我的理解:(这部分用任务驱动式教学方法--谁让小弟是老师呢!xi xi)


任务:得到所有的窗口的类名。


解决办法1:我们会先想到第三组,可以自桌面窗口开始(它是所有窗口的祖先),依次扫描,获取类名并存之。有点儿像Visual
Stdio的Spy++,或者Borland 的WinSight32,具体办法如下:(bcb中)


在主程序中,调用EnumWindows,传入YouEnumProc的函数地址作第一个参数,别忘了转换成WNDENUMPROC类型。第二参可NULL。::EnumWindows(reinterpret_cast
YouEnumProc,NULL);


在YouEnumProc函数中,如果第一参HWND = = NULL,就跳离(return FALSE;),可以结束啦!


然后,把类名数组准备好,得到类名,存之。


返回真值,继续下一次扫描。


看起来并不复杂,是一种函数递归。但是我可会解释!面啊!: p


第二种解决方法:简单、直观--自己想出来的,颇得意


首先准备一个时钟,一种存类名方法(我用TMemo)


在定时器处理函数中:


1、得到当前cursor的点位置


2、再用WindowFromPoint,


3、然后得到类名,放到TMemo里


这样可以用鼠标获得你想要的窗口(包括按钮等),只要鼠标在窗口放一会儿。。。哈哈


第三种方法:其实利用FindWindow和循环结构也应该可以


总结:其实得到HWND的方法很多,比如知道了窗口层次,依次向下扫。。。在说第三种呢!但我觉得,我的方法最直接有效,你说呢?


欢迎大家与我联系,并讨论这个问题!有关这个问题我还有许多疑问,比如HWND与ID的转换,在如IE页面中的表单控件的HWND或ID,还是其他的东东,总之是能识别他的东西。。。这个我很困惑,没办法!


不清楚地方,大家要参照MSDN啊


其它获取句柄的方法:


1.根据id获取窗口句柄
  Hwnd hwnd =
GetDlgItem(hwndParent,id).
2.根据窗口句柄,获取id
    id =
GetWindowLong(hwndChild,GWL_ID)
    id =
GetDlgCtrlID(hwndchild).
3.获取实例句柄的若干方法
    hInst =
GetWindowLong(hwnd,GWL_HINSTANCE)
    把HINSTANCE
作为全局变量保存.
    当建立窗口时,参数lparam指向了一个建立结构的地址.
    可以这样获取实例句柄
    hInst =
((LPCREATESTRUCT)lParam)->hInstance.

阅读(1945) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~