转载自:http://blog.csdn.net/chenlycly/article/details/7657701
我们为解决某些特殊的问题时,可能会用到Windows非公开API接口,当我们把非公开的API写进代码后,编译器则会因为找不到函数定义的地方,报出未定义的错误。此时,我们可以通过显式的Load系统的user32.dll库,获得对应的函数接口指针,通过函数指针去调用对应的函数。下面通过两个实例来说明一下。
1、调用GetLastInputInfo函数,获取系统最后一次接收输入的时间,以实现类似QQ离开状态的自动检测
离开状态自动检测的原理:调用调用GetLastInputInfo函数,获取系统最后一次接收输入的时间,然后与当前时间做差值,再与设定的离开时间检测值,做比较以判断当前是否是离开状态。具体的,设定一个定时器去定时的获取系统最后一次接收输入的时间,进而实现离开状态的实时检测。当然也可以开一个线程来检测。相关代码如下所示。
- typedef struct tagLASTINPUTINFO {
- UINT cbSize;
- DWORD dwTime;
- } LASTINPUTINFO, * PLASTINPUTINFO;
- typedef BOOL (WINAPI* PGETLASTINPUTINFO)(PLASTINPUTINFO plii);
- PGETLASTINPUTINFO pfnGetLastInputInfo = NULL;
- pfnGetLastInputInfo = (PGETLASTINPUTINFO)GetProcAddress(hSysDll, "GetLastInputInfo"); // 获取GetLastInputInfo函数接口指针
- if( NULL == GetLastInputInfo )
- {
- FreeLibrary( hSysDll );
- }
- LASTINPUTINFO lpi;
- lpi.cbSize = sizeof(lpi);
- pfnGetLastInputInfo(&lpi);
- DWORD dwTime = lpi.dwTime;
- DWORD dwSec = GetTickCount() - lpi.dwTime;
- ......
2、调用ChangeWindowMessageFilter函数,放行WM_DROPFILES消息和WM_COPYGLOBALDATA消息,以解决Win7系统中文件拖放失效的问题
由于Win7的安全机制,导致与文件拖放的WM_DROPFILES消息和WM_COPYGLOBALDATA消息被系统拦截了,从而导致了文件拖放失效的问题。解决问题的办法就是,调用ChangeWindowMessageFilter函数,放行WM_DROPFILES消息和WM_COPYGLOBALDATA消息。相关代码如下所示。
- // 放行文件拖放相关事件消息,仅对win7有效,以解决win7中文件拖放失效的问题
- ChangeWndMessageFilter( WM_DROPFILES, TRUE );
- ChangeWndMessageFilter( 0x0049, TRUE ); // 0x0049 - WM_COPYGLOBALDATA
- BOOL CXXXApp::ChangeWndMessageFilter( UINT uMessage, BOOL bAllow )
- {
- typedef BOOL (WINAPI* ChangeWindowMessageFilterFn)( UINT, DWORD );
- HMODULE hUserMod = NULL;
- BOOL bResult = FALSE;
- hUserMod = LoadLibrary( "user32.dll" );
- if ( hUserMod == NULL )
- {
- return FALSE;
- }
- // 获取ChangeWindowMessageFilter函数接口指针
- ChangeWindowMessageFilterFn pfnChangeWindowMessageFilter = (ChangeWindowMessageFilterFn)GetProcAddress( hUserMod, "ChangeWindowMessageFilter" );
- if ( pfnChangeWindowMessageFilter == NULL )
- {
- FreeLibrary( hUserMod );
- return FALSE;
- }
- bResult = pfnChangeWindowMessageFilter( uMessage, bAllow?1:2 ); // 1-MSGFLT_ADD, 2-MSGFLT_REMOVE
- FreeLibrary( hUserMod );
- return bResult;
- }
遇到问题时,我们找不到直接的办法,可以通过间接的方法来解决或规避问题。