今天在网上查挂机锁的原理,其中有人提到了一个函数LockWorkStation。

查看SDK,其原型如下:

BOOL WINAPI LockWorkStation(void);

看似很简单的函数,真正用起来却不是那么容易。贴下代码:

#include <windows.h>

int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
{
 if(IDOK == MessageBox(NULL, TEXT("您确定要锁定计算机吗?"), TEXT("锁定计算机"), MB_OKCANCEL | MB_ICONQUESTION))
 {
  if(!LockWorkStation())
  {
   TCHAR* szError = {0};
   wsprintf(szError, "LockWorkStation failed with %d\n", GetLastError());
   MessageBox(NULL, szError, "Error", MB_OK | MB_ICONSTOP);
  }
 }
 return 0;
}

编译,却不能通过。错误竟然是'LockWorkStation' was not declared in this scope!看SDK,“Declared in Winuser.h; include Windows.h.”没错,“Requires Windows Vista, Windows XP, or Windows 2000 Professional.”没错,lib和dll都没错。到底怎么回事呢?跳至LockWorkStation的定义,发现:

#if (_WIN32_WINNT >= 0x0500)
WINUSERAPI BOOL WINAPI LockWorkStation(void);
#endif

原来要求_WIN32_WINNT 的宏大于等于 0x0500。于是在#include <windows.h>后加上#define _WIN32_WINNT 0x0500,编译,还是出错!还加上了_WIN32_WINNT重复定义的错了。

求助百度和谷歌,发现不少人遇到这个问题,有人说加上#define就能成功了,有人说要加在stdafx.h中……不过,全是在MFC里的解决方法。泄气,只能自己继续。查找_WIN32_WINNT结果发现:

#ifndef WINVER
#define WINVER 0x0400
/*
 * If you need Win32 API features newer the Win95 and WinNT then you must
 * define WINVER before including windows.h or any other method of including
 * the windef.h header.
 */
#endif
#ifndef _WIN32_WINNT
#define _WIN32_WINNT WINVER
/*
 * There may be the need to define _WIN32_WINNT to a value different from
 * the value of WINVER.  I don't have any example of why you would do that.
 * However, if you must then define _WIN32_WINNT to the value required before
 * including windows.h or any other method of including the windef.h header.
 */
#endif

明白了。原来_WIN32_WINNT被定义为WINVER,而WINVER又被定义为0x0400,而且要改变两个的值需要在#include <windows.h>之前。把#define WINVER 0x0500(或者#define _WIN32_WINNT 0x0500)放在最前面,编译,问题解决。(建议使用#define WINVER 0x0500,因为_WIN32_WINNT的说明中要求尽量保持和WINVER的一致。)