如何获得窗口句柄以及WIN32+API参考大全
2013-11-26 16:08
363 查看
在Windows程序设计领域处于发展初期时,Windows程序员可使用的编程工具唯有API函数。这些函数在程序员手中犹如"积木块"一样,可搭建出各种界面丰富、功能灵活的应用程序。不过,由于这些函数结构复杂,所以往往难以理解,而且容易误用。
随着软件技术的不断发展,在Windows平台上出现了很多优秀的可视化编程环境,程序员可以采用"所见即所得"的编程方式来开发具有精美用户界面和功能的应用程序。这些可视化编程环境操作简便、界面友好,比如:Visual C++,Delphi,Visual Basic等等。在这些工具中提供了大量的类库和各种控件,它们替代了API的神秘功能。事实上,这些类库和控件都是构筑在Windows API的基础上的,但它们使用方便,加速了Windows应用程序的开发,所以受到程序员的普遍采用。有了这些类库和控件,程序员们便可以把主要精力放在整体功能的设计上,而不必过于关注具体细节。不过,这也导致了非常多的程序员在类库面前"固步自封",对下层API函数的强大功能一无所知。
实际上。程序员要想开发出更灵活、更实用、更具效率的应用程序,必然要涉及到直接使用API函数。虽然类库和控件使应用程序的开发容易得多,但它们只提供Microsoft Windows的一般功能,对于一些比较复杂和特殊的功能来说,单使用类库和控件是难以实现的,必须直接使用API函数来编写。API函数是构筑整个Windows框架的基石,只有充分理解和利用API函数,才能深入到Windows的内部,充分发挥各种32位平台的强大功能和灵活性,才能成功地扩展和突破类库、控件和可视开发环境的限制。
Win32 API即为Microsoft 32位平台的应用程序编程接口(Application Programming Interface)。所有在Win32平台上运行的应用程序都可以调用这些函数。
使用Win32 API,应用程序可以充分挖掘Windows的32位操作系统的潜力。 Mircrosoft的所有32位平台都支持统一的API,包括函数、结构、消息、宏及接口。使用 Win32 API不但可以开发出在各种平台上都能成功运行的应用程序,而且也可以充分利用每个平台特有的功能和属性。
在具体编程时,程序实现方式的差异依赖于相应平台的底层功能的不同。最显著的差异是某些函数只能在更强大的平台上实现其功能。例如,安全函数只能在Windows NT操作系统下使用。另外一些主要差别就是系统限制,比如值的范围约束,或函数可管理的项目个数等等。
标准Win32 API函数可以分为以下几类:
窗口管理
窗口通用控制
Shell特性
图形设备接口
系统服务
国际特性
网络服务
关于如何获取窗口句柄,以及有哪些函数可供使用的简单讨论!可适用于vc、bcb等。
首先我们一起熟悉一些获取句柄的win32 api 函数,然后简单说说他们的用途,最后介绍一下具体应用。
可用的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。可是对于刚接触编程的朋友,不一定知道所有的窗口(包括标题栏、按钮等等)的类名。可以简单举例,请问你知道Windows桌面窗口的类名吗?而对于窗口标题,有可能不同窗口会出现相同的标题。好了,这个问题先放放,继续下一组。
第二组,通过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,可以扫描桌面所有窗口并对之处理!
任务:得到所有的窗口的类名。
解决办法1:我们会先想到第三组,可以自桌面窗口开始(它是所有窗口的祖先),依次扫描,获取类名并存之。有点儿像Visual Studio的Spy++,或者Borland 的WinSight32,具体办法如下:(bcb中)
在主程序中,调用EnumWindows,传入YouEnumProc的函数地址作第一个参数,别忘了转换成WNDENUMPROC类型。第二参可NULL。::EnumWindows(reinterpret_cast YouEnumProc,NULL);
在YourEnumProc函数中,如果第一参HWND = = NULL,就跳离(return FALSE;),可以结束啦!
然后,把类名数组准备好,得到类名,存之。
返回真值,继续下一次扫描。
看起来并不复杂,是一种函数递归。
第二种解决方法:简单、直观
首先准备一个时钟,一种存类名方法(这里用TMemo)
在定时器处理函数中:
1、得到当前cursor的点位置
2、再用WindowFromPoint,
3、然后得到类名,放到TMemo里
这样可以用鼠标获得你想要的窗口(包括按钮等),只要鼠标在窗口放一会儿。
第三种方法:其实利用FindWindow和循环结构也应该可以
总结:其实得到HWND的方法很多,比如知道了窗口层次,依次向下扫。。。在说第三种呢!各位朋友自己可以根据需要选择一种最直接有效的方法。
欢迎大家与我一起讨论这个问题。对于API使用不清楚的地方,大家可以参照MSDN。
下面是来自微软的例子,这个枚举所有的窗口,然后向窗口发送关闭的消息。
[cpp] view
plaincopy
#include
BOOL CALLBACK EnumWindowsProc(
HWND hwnd,
DWORD lParam
);
//
// EnumWindowsProc must be called from a Windows
// application on Windows 95.
//
int WINAPI WinMain(
HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow
)
{
//
// Close all open applications.
//
EnumWindows(EnumWindowsProc, 0);
// Now do a regular logoff.
ExitWindowsEx(EWX_LOGOFF , 0);
}
BOOL CALLBACK EnumWindowsProc(
HWND hwnd,
DWORD lParam
)
{
DWORD pid = 0;
LRESULT lResult;
HANDLE hProcess;
DWORD dwResult;
lResult = SendMessageTimeout(
hwnd,
WM_QUERYENDSESSION,
0,
ENDSESSION_LOGOFF,
SMTO_ABORTIFHUNG,
2000,
&dwResult);
if( lResult )
{
//
// Application will terminate nicely, so let it.
//
lResult = SendMessageTimeout(
hwnd,
WM_ENDSESSION,
TRUE,
ENDSESSION_LOGOFF,
SMTO_ABORTIFHUNG,
2000,
&dwResult);
}
else // You have to take more forceful measures.
{
//
// Get the ProcessId for this window.
//
GetWindowThreadProcessId( hwnd, &pid );
//
// Open the process with all access.
//
hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
//
// Terminate the process.
//
TerminateProcess(hProcess, 0);
}
//
// Continue the enumeration.
//
return TRUE;
}
获取窗口的句柄我们就可以获取窗口的环境参数,这样就可以获取设备场景句柄,那么我们可以把图形输出到这个设备场景上。但是我们不可以在WINDOWS下开启这样一个进程,然后再获取另外一个进程窗口的句柄,然后由这个进程控制另外一个进程
随着软件技术的不断发展,在Windows平台上出现了很多优秀的可视化编程环境,程序员可以采用"所见即所得"的编程方式来开发具有精美用户界面和功能的应用程序。这些可视化编程环境操作简便、界面友好,比如:Visual C++,Delphi,Visual Basic等等。在这些工具中提供了大量的类库和各种控件,它们替代了API的神秘功能。事实上,这些类库和控件都是构筑在Windows API的基础上的,但它们使用方便,加速了Windows应用程序的开发,所以受到程序员的普遍采用。有了这些类库和控件,程序员们便可以把主要精力放在整体功能的设计上,而不必过于关注具体细节。不过,这也导致了非常多的程序员在类库面前"固步自封",对下层API函数的强大功能一无所知。
实际上。程序员要想开发出更灵活、更实用、更具效率的应用程序,必然要涉及到直接使用API函数。虽然类库和控件使应用程序的开发容易得多,但它们只提供Microsoft Windows的一般功能,对于一些比较复杂和特殊的功能来说,单使用类库和控件是难以实现的,必须直接使用API函数来编写。API函数是构筑整个Windows框架的基石,只有充分理解和利用API函数,才能深入到Windows的内部,充分发挥各种32位平台的强大功能和灵活性,才能成功地扩展和突破类库、控件和可视开发环境的限制。
Win32 API即为Microsoft 32位平台的应用程序编程接口(Application Programming Interface)。所有在Win32平台上运行的应用程序都可以调用这些函数。
使用Win32 API,应用程序可以充分挖掘Windows的32位操作系统的潜力。 Mircrosoft的所有32位平台都支持统一的API,包括函数、结构、消息、宏及接口。使用 Win32 API不但可以开发出在各种平台上都能成功运行的应用程序,而且也可以充分利用每个平台特有的功能和属性。
在具体编程时,程序实现方式的差异依赖于相应平台的底层功能的不同。最显著的差异是某些函数只能在更强大的平台上实现其功能。例如,安全函数只能在Windows NT操作系统下使用。另外一些主要差别就是系统限制,比如值的范围约束,或函数可管理的项目个数等等。
标准Win32 API函数可以分为以下几类:
窗口管理
窗口通用控制
Shell特性
图形设备接口
系统服务
国际特性
网络服务
关于如何获取窗口句柄,以及有哪些函数可供使用的简单讨论!可适用于vc、bcb等。
首先我们一起熟悉一些获取句柄的win32 api 函数,然后简单说说他们的用途,最后介绍一下具体应用。
可用的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。可是对于刚接触编程的朋友,不一定知道所有的窗口(包括标题栏、按钮等等)的类名。可以简单举例,请问你知道Windows桌面窗口的类名吗?而对于窗口标题,有可能不同窗口会出现相同的标题。好了,这个问题先放放,继续下一组。
第二组,通过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,可以扫描桌面所有窗口并对之处理!
任务:得到所有的窗口的类名。
解决办法1:我们会先想到第三组,可以自桌面窗口开始(它是所有窗口的祖先),依次扫描,获取类名并存之。有点儿像Visual Studio的Spy++,或者Borland 的WinSight32,具体办法如下:(bcb中)
在主程序中,调用EnumWindows,传入YouEnumProc的函数地址作第一个参数,别忘了转换成WNDENUMPROC类型。第二参可NULL。::EnumWindows(reinterpret_cast YouEnumProc,NULL);
在YourEnumProc函数中,如果第一参HWND = = NULL,就跳离(return FALSE;),可以结束啦!
然后,把类名数组准备好,得到类名,存之。
返回真值,继续下一次扫描。
看起来并不复杂,是一种函数递归。
第二种解决方法:简单、直观
首先准备一个时钟,一种存类名方法(这里用TMemo)
在定时器处理函数中:
1、得到当前cursor的点位置
2、再用WindowFromPoint,
3、然后得到类名,放到TMemo里
这样可以用鼠标获得你想要的窗口(包括按钮等),只要鼠标在窗口放一会儿。
第三种方法:其实利用FindWindow和循环结构也应该可以
总结:其实得到HWND的方法很多,比如知道了窗口层次,依次向下扫。。。在说第三种呢!各位朋友自己可以根据需要选择一种最直接有效的方法。
欢迎大家与我一起讨论这个问题。对于API使用不清楚的地方,大家可以参照MSDN。
下面是来自微软的例子,这个枚举所有的窗口,然后向窗口发送关闭的消息。
[cpp] view
plaincopy
#include
BOOL CALLBACK EnumWindowsProc(
HWND hwnd,
DWORD lParam
);
//
// EnumWindowsProc must be called from a Windows
// application on Windows 95.
//
int WINAPI WinMain(
HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow
)
{
//
// Close all open applications.
//
EnumWindows(EnumWindowsProc, 0);
// Now do a regular logoff.
ExitWindowsEx(EWX_LOGOFF , 0);
}
BOOL CALLBACK EnumWindowsProc(
HWND hwnd,
DWORD lParam
)
{
DWORD pid = 0;
LRESULT lResult;
HANDLE hProcess;
DWORD dwResult;
lResult = SendMessageTimeout(
hwnd,
WM_QUERYENDSESSION,
0,
ENDSESSION_LOGOFF,
SMTO_ABORTIFHUNG,
2000,
&dwResult);
if( lResult )
{
//
// Application will terminate nicely, so let it.
//
lResult = SendMessageTimeout(
hwnd,
WM_ENDSESSION,
TRUE,
ENDSESSION_LOGOFF,
SMTO_ABORTIFHUNG,
2000,
&dwResult);
}
else // You have to take more forceful measures.
{
//
// Get the ProcessId for this window.
//
GetWindowThreadProcessId( hwnd, &pid );
//
// Open the process with all access.
//
hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
//
// Terminate the process.
//
TerminateProcess(hProcess, 0);
}
//
// Continue the enumeration.
//
return TRUE;
}
获取窗口的句柄我们就可以获取窗口的环境参数,这样就可以获取设备场景句柄,那么我们可以把图形输出到这个设备场景上。但是我们不可以在WINDOWS下开启这样一个进程,然后再获取另外一个进程窗口的句柄,然后由这个进程控制另外一个进程
相关文章推荐
- 如何获得窗口句柄以及WIN32+API参考大全
- 如何获得窗口句柄(HWND )和改变窗口属性
- autoIt DllCall 如何获得句柄和对窗口操作
- js父子窗口传值以及当前页面在js前台如何获得url参数
- [VC++]如何利用this获得窗口句柄
- 如何获得窗口句柄(HWND )和改变窗口属性
- 已知IWebBrowser2接口,如何获得其Internet Explorer_Server窗口句柄?
- 在框架窗口中如何获得,视图类的指针以及文档,视图,框架窗口指针的获取与应用
- 如何获得窗口句柄(FindWindow函数的使用)
- dll中如何获得调用者的窗口?得到窗口句柄那么DC也就可以得到了!
- 如何通过窗口句柄来获得一个程序窗口的大小
- 多层窗口如何抓取句柄以及后台鼠标位置解决方案
- 如何从Internet Explorer_Server窗口句柄获得IHTMLDocument
- WPF窗口如何获得一个句柄?
- BCB如何获得当前所有可视窗口的窗口标题和窗口句柄
- 如何获得窗口句柄(HWND )和改变窗口属性
- 如何在其它程序窗口(已知窗口的句柄)加上一个按钮
- 通过进程号ID获得窗口的句柄
- 解析js中获得父窗口链接getParent方法以及各种打开窗口的方法
- 如何从窗口句柄得到窗口的指针