zl程序教程

您现在的位置是:首页 >  系统

当前栏目

Windows非公开API函数的调用办法

WindowsAPI 函数 调用 办法 公开
2023-09-14 09:10:49 时间

        我们为解决某些特殊的问题时,可能会用到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;
}


         遇到问题时,我们找不到直接的办法,可以通过间接的方法来解决或规避问题。