Disabling Shortcut Keys in Full Screen mode

昨天和两个同学一起玩魔兽<?xml:namespace prefix = st1 ns = "urn:schemas-microsoft-com:office:smarttags" /><chmetcnv unitname="C" sourcevalue="3" hasspace="False" negative="False" numbertype="1" tcsc="0" w:st="on"><span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">3C</span></chmetcnv>的时候,由于很长时间我都是躲在练功房里砍木头人升级,而这种体力活不需要我监视英雄的举动,所以我就不断地切出游戏去上网,这种行为弄得两个哥们十分郁闷。呵呵,谁让我是主机呢,于是就不断地出现掉线的情况。<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

过后我就在想,那么如何在游戏中限制用户这种动作呢,使得他无法利用 WIN功能键不断地切进切出。

下面就是我给出的一个解决方案,原理是:利用一个底层的键盘钩子函数对待处理的键盘消息进行过滤。这个钩子即使在用户对窗口最小化或切换到另一个应用程序也是有效的。

None.gif // demo0.cpp:Definestheentrypointfortheapplication.
None.gif
// ******************************
None.gif
// Author:phinecos
None.gif
// Date:2008-4-17
None.gif
// *******************************
None.gif

None.gif#include
" stdafx.h "
None.gif#include
" demo0.h "
None.gif
None.gif
#define MAX_LOADSTRING100
None.gif
None.gif
// GlobalVariables:
None.gif
HINSTANCEhInst; // currentinstance
None.gif
HWNDhWnd = NULL; // 窗口句柄
None.gif
HHOOKg_hKeyboardHook;
None.gif
None.gif
None.gifTCHARszTitle[MAX_LOADSTRING];
// Thetitlebartext
None.gif
TCHARszWindowClass[MAX_LOADSTRING]; // themainwindowclassname
None.gif
BOOLisFullScreen = TRUE; // 是否全屏
None.gif
BOOLisActive = TRUE; // WindowActiveFlagSetToTRUEByDefault
None.gif
None.gif
// Forwarddeclarationsoffunctionsincludedinthiscodemodule:
None.gif
ATOMMyRegisterClass(HINSTANCEhInstance);
None.gifBOOLInitInstance(HINSTANCE,
int );
None.gifLRESULTCALLBACKWndProc(HWND,UINT,WPARAM,LPARAM);
None.gif
None.gif
None.gifLRESULTCALLBACKLowLevelKeyboardProc(
int nCode,WPARAMwParam,LPARAMlParam)
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif
if(nCode<0||nCode!=HC_ACTION)//donotprocessmessage
InBlock.gif
returnCallNextHookEx(g_hKeyboardHook,nCode,wParam,lParam);
InBlock.gif
InBlock.gif
boolbEatKeystroke=false;
InBlock.gifKBDLLHOOKSTRUCT
*p=(KBDLLHOOKSTRUCT*)lParam;
InBlock.gif
switch(wParam)
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gif
caseWM_KEYDOWN:
InBlock.gif
caseWM_KEYUP:
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gifbEatKeystroke
=(isFullScreen&&isActive&&((p->vkCode==VK_LWIN)||(p->vkCode==VK_RWIN)));
InBlock.gif
break;
ExpandedSubBlockEnd.gif}

ExpandedSubBlockEnd.gif}

InBlock.gif
InBlock.gif
if(bEatKeystroke)
InBlock.gif
return1;
InBlock.gif
else
InBlock.gif
returnCallNextHookEx(g_hKeyboardHook,nCode,wParam,lParam);
ExpandedBlockEnd.gif}

None.gif
None.gif
None.gif
None.gif
int APIENTRY_tWinMain(HINSTANCEhInstance,
None.gifHINSTANCEhPrevInstance,
None.gifLPTSTRlpCmdLine,
None.gif
int nCmdShow)
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gifUNREFERENCED_PARAMETER(hPrevInstance);
InBlock.gifUNREFERENCED_PARAMETER(lpCmdLine);
InBlock.gif
InBlock.gif
//TODO:Placecodehere.
InBlock.gif
MSGmsg;
InBlock.gifg_hKeyboardHook
=SetWindowsHookEx(WH_KEYBOARD_LL,LowLevelKeyboardProc,GetModuleHandle(NULL),0);//设置钩子
InBlock.gif

InBlock.gif
if(MessageBox(NULL,L"是否以全屏模式运行?",L"信息?",MB_YESNO|MB_ICONQUESTION)==IDNO)
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gifisFullScreen
=FALSE;//WindowedMode
ExpandedSubBlockEnd.gif
}

InBlock.gif
//Initializeglobalstrings
InBlock.gif
LoadString(hInstance,IDS_APP_TITLE,szTitle,MAX_LOADSTRING);
InBlock.gifLoadString(hInstance,IDC_DEMO0,szWindowClass,MAX_LOADSTRING);
InBlock.gif
InBlock.gif
//Performapplicationinitialization:
InBlock.gif
if(!InitInstance(hInstance,nCmdShow))
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gif
returnFALSE;
ExpandedSubBlockEnd.gif}

InBlock.gif
InBlock.gif
//Mainmessageloop:
InBlock.gif
while(GetMessage(&msg,NULL,0,0))
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gif
InBlock.gifTranslateMessage(
&msg);
InBlock.gifDispatchMessage(
&msg);
ExpandedSubBlockEnd.gif}

InBlock.gifUnhookWindowsHookEx(g_hKeyboardHook);
//卸载钩子
InBlock.gif
return(int)msg.wParam;
ExpandedBlockEnd.gif}

None.gif
None.gif
None.gif
None.gif
//
None.gif
// FUNCTION:MyRegisterClass()
None.gif
//
None.gif
// PURPOSE:Registersthewindowclass.
None.gif
//
None.gif
// COMMENTS:
None.gif
//
None.gif
// Thisfunctionanditsusageareonlynecessaryifyouwantthiscode
None.gif
// tobecompatiblewithWin32systemspriortothe'RegisterClassEx'
None.gif
// functionthatwasaddedtoWindows95.Itisimportanttocallthisfunction
None.gif
// sothattheapplicationwillget'wellformed'smalliconsassociated
None.gif
// withit.
None.gif
//
None.gif
ATOMMyRegisterClass(HINSTANCEhInstance)
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gifWNDCLASSEXwcex;
InBlock.gif
InBlock.gifwcex.cbSize
=sizeof(WNDCLASSEX);
InBlock.gif
InBlock.gifwcex.style
=CS_HREDRAW|CS_VREDRAW;
InBlock.gifwcex.lpfnWndProc
=WndProc;
InBlock.gifwcex.cbClsExtra
=0;
InBlock.gifwcex.cbWndExtra
=0;
InBlock.gifwcex.hInstance
=hInstance;
InBlock.gifwcex.hIcon
=LoadIcon(hInstance,MAKEINTRESOURCE(IDI_DEMO0));
InBlock.gifwcex.hCursor
=LoadCursor(NULL,IDC_ARROW);
InBlock.gifwcex.hbrBackground
=(HBRUSH)(COLOR_WINDOW+1);
InBlock.gifwcex.lpszMenuName
=0;
InBlock.gifwcex.lpszClassName
=szWindowClass;
InBlock.gifwcex.hIconSm
=LoadIcon(wcex.hInstance,MAKEINTRESOURCE(IDI_SMALL));
InBlock.gif
InBlock.gif
returnRegisterClassEx(&wcex);
ExpandedBlockEnd.gif}

None.gif
None.gifVOIDKillWindow(VOID)
// ProperlyKillTheWindow
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif
if(isFullScreen)//AreWeInFullscreenMode?
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gifChangeDisplaySettings(NULL,
0);//IfSoSwitchBackToTheDesktop
InBlock.gif
ShowCursor(TRUE);//ShowMousePointer
ExpandedSubBlockEnd.gif
}

InBlock.gif
if(hWnd&&!DestroyWindow(hWnd))//AreWeAbleToDestroyTheWindow?
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gifMessageBox(NULL,L
"CouldNotReleasehWnd.",L"SHUTDOWNERROR",MB_OK|MB_ICONINFORMATION);
InBlock.gifhWnd
=NULL;//SethWndToNULL
ExpandedSubBlockEnd.gif
}

InBlock.gif
if(!UnregisterClass(szWindowClass,hInst))//AreWeAbleToUnregisterClass
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gifMessageBox(NULL,L
"CouldNotUnregisterClass.",L"SHUTDOWNERROR",MB_OK|MB_ICONINFORMATION);
InBlock.gifhInst
=NULL;//SethInstanceToNULL
ExpandedSubBlockEnd.gif
}

ExpandedBlockEnd.gif}

None.gif
None.gif
None.gifBOOLMyCreateWindow(TCHAR
* title, int width, int height, int bits,BOOLfullscreenflag)
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gifDWORDdwExStyle;
//WindowExtendedStyle
InBlock.gif
DWORDdwStyle;//WindowStyle
InBlock.gif
RECTWindowRect;//GrabsRectangleUpperLeft/LowerRightValues
InBlock.gif
WindowRect.left=(long)0;//SetLeftValueTo0
InBlock.gif
WindowRect.right=(long)width;//SetRightValueToRequestedWidth
InBlock.gif
WindowRect.top=(long)0;//SetTopValueTo0
InBlock.gif
WindowRect.bottom=(long)height;//SetBottomValueToRequestedHeight
InBlock.gif

InBlock.gifisFullScreen
=fullscreenflag;//SetTheGlobalFullscreenFlag
InBlock.gif
if(isFullScreen)//AttemptFullscreenMode?
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gifDEVMODEdmScreenSettings;
//DeviceMode
InBlock.gif
memset(&dmScreenSettings,0,sizeof(dmScreenSettings));//MakesSureMemory'sCleared
InBlock.gif
dmScreenSettings.dmSize=sizeof(dmScreenSettings);//SizeOfTheDevmodeStructure
InBlock.gif
dmScreenSettings.dmPelsWidth=width;//SelectedScreenWidth
InBlock.gif
dmScreenSettings.dmPelsHeight=height;//SelectedScreenHeight
InBlock.gif
dmScreenSettings.dmBitsPerPel=bits;//SelectedBitsPerPixel
InBlock.gif
dmScreenSettings.dmFields=DM_BITSPERPEL|DM_PELSWIDTH|DM_PELSHEIGHT;
InBlock.gif
InBlock.gif
//TryToSetSelectedModeAndGetResults.NOTE:CDS_FULLSCREENGetsRidOfStartBar.
InBlock.gif
if(ChangeDisplaySettings(&dmScreenSettings,CDS_FULLSCREEN)!=DISP_CHANGE_SUCCESSFUL)
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gif
//IfTheModeFails,OfferTwoOptions.QuitOrUseWindowedMode.
InBlock.gif
if(MessageBox(NULL,L"TheRequestedFullscreenModeIsNotSupportedBy/nYourVideoCard.UseWindowedModeInstead?",L"Infomation",MB_YESNO|MB_ICONEXCLAMATION)==IDYES)
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gifisFullScreen
=FALSE;//WindowedModeSelected.Fullscreen=FALSE
ExpandedSubBlockEnd.gif
}

InBlock.gif
else
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gif
//PopUpAMessageBoxLettingUserKnowTheProgramIsClosing.
InBlock.gif
MessageBox(NULL,L"ProgramWillNowClose.",L"ERROR",MB_OK|MB_ICONSTOP);
InBlock.gif
returnFALSE;//ReturnFALSE
ExpandedSubBlockEnd.gif
}

ExpandedSubBlockEnd.gif}

ExpandedSubBlockEnd.gif}

InBlock.gif
InBlock.gif
if(isFullScreen)//AreWeStillInFullscreenMode?
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gifdwExStyle
=WS_EX_APPWINDOW;//WindowExtendedStyle
InBlock.gif
dwStyle=WS_POPUP;//WindowsStyle
InBlock.gif
ShowCursor(FALSE);//HideMousePointer
ExpandedSubBlockEnd.gif
}

InBlock.gif
else
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gifdwExStyle
=WS_EX_APPWINDOW|WS_EX_WINDOWEDGE;//WindowExtendedStyle
InBlock.gif
dwStyle=WS_OVERLAPPEDWINDOW;//WindowsStyle
ExpandedSubBlockEnd.gif
}

InBlock.gif
InBlock.gifAdjustWindowRectEx(
&WindowRect,dwStyle,FALSE,dwExStyle);//AdjustWindowToTrueRequestedSize
InBlock.gif
InBlock.gif
//CreateTheWindow
InBlock.gif
if(!(hWnd=CreateWindowEx(dwExStyle,//ExtendedStyleForTheWindow
InBlock.gif
szWindowClass,//ClassName
InBlock.gif
title,//WindowTitle
InBlock.gif
dwStyle|//DefinedWindowStyle
InBlock.gif
WS_CLIPSIBLINGS|//RequiredWindowStyle
InBlock.gif
WS_CLIPCHILDREN,//RequiredWindowStyle
InBlock.gif
0,0,//WindowPosition
InBlock.gif
WindowRect.right-WindowRect.left,//CalculateWindowWidth
InBlock.gif
WindowRect.bottom-WindowRect.top,//CalculateWindowHeight
InBlock.gif
NULL,//NoParentWindow
InBlock.gif
NULL,//NoMenu
InBlock.gif
hInst,//Instance
InBlock.gif
NULL)))//DontPassAnythingToWM_CREATE
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gifKillWindow();
//ResetTheDisplay
InBlock.gif
MessageBox(NULL,L"WindowCreationError.",L"ERROR",MB_OK|MB_ICONEXCLAMATION);
InBlock.gif
returnFALSE;//ReturnFALSE
ExpandedSubBlockEnd.gif
}

InBlock.gifShowWindow(hWnd,SW_SHOW);
//ShowTheWindow
InBlock.gif
SetForegroundWindow(hWnd);//SlightlyHigherPriority
InBlock.gif
SetFocus(hWnd);//SetsKeyboardFocusToTheWindow
InBlock.gif

InBlock.gif
returnTRUE;//Success
ExpandedBlockEnd.gif
}

None.gif
//
None.gif
// FUNCTION:InitInstance(HINSTANCE,int)
None.gif
//
None.gif
// PURPOSE:Savesinstancehandleandcreatesmainwindow
None.gif
//
None.gif
// COMMENTS:
None.gif
//
None.gif
// Inthisfunction,wesavetheinstancehandleinaglobalvariableand
None.gif
// createanddisplaythemainprogramwindow.
None.gif
//
None.gif
BOOLInitInstance(HINSTANCEhInstance, int nCmdShow)
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gifMyRegisterClass(hInstance);
InBlock.gifhInst
=hInstance;//Storeinstancehandleinourglobalvariable
InBlock.gif
MyCreateWindow(szTitle,640,480,16,isFullScreen);
InBlock.gif
InBlock.gif
if(!hWnd)
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gif
returnFALSE;
ExpandedSubBlockEnd.gif}

InBlock.gif
InBlock.gifShowWindow(hWnd,nCmdShow);
InBlock.gifUpdateWindow(hWnd);
InBlock.gif
InBlock.gif
returnTRUE;
ExpandedBlockEnd.gif}

None.gif
None.gif
//
None.gif
// FUNCTION:WndProc(HWND,UINT,WPARAM,LPARAM)
None.gif
//
None.gif
// PURPOSE:Processesmessagesforthemainwindow.
None.gif
//
None.gif
// WM_COMMAND-processtheapplicationmenu
None.gif
// WM_PAINT-Paintthemainwindow
None.gif
// WM_DESTROY-postaquitmessageandreturn
None.gif
//
None.gif
//
None.gif
LRESULTCALLBACKWndProc(HWNDhWnd,UINTmessage,WPARAMwParam,LPARAMlParam)
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gifPAINTSTRUCTps;
InBlock.gifHDChdc;
InBlock.gif
InBlock.gif
switch(message)
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gif
caseWM_PAINT:
InBlock.gifhdc
=BeginPaint(hWnd,&ps);
InBlock.gif
//TODO:Addanydrawingcodeheredot.gif
InBlock.gif
EndPaint(hWnd,&ps);
InBlock.gif
break;
InBlock.gif
caseWM_DESTROY:
InBlock.gifPostQuitMessage(
0);
InBlock.gif
break;
InBlock.gif
caseWM_ACTIVATEAPP:
InBlock.gif
//g_bWindowActiveisusedtocontroliftheWindowskeyisfilteredbythekeyboardhookornot.
InBlock.gif
if(wParam==TRUE)
InBlock.gifisActive
=TRUE;
InBlock.gif
else
InBlock.gifisActive
=FALSE;
InBlock.gif
break;
InBlock.gif
InBlock.gif
caseWM_KEYDOWN:
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gif
if(wParam==VK_ESCAPE)
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{//退出
InBlock.gif
KillWindow();//KillOurCurrentWindow
ExpandedSubBlockEnd.gif
}

ExpandedSubBlockEnd.gif}

InBlock.gif
break;
InBlock.gif
default:
InBlock.gif
returnDefWindowProc(hWnd,message,wParam,lParam);
ExpandedSubBlockEnd.gif}

InBlock.gif
return0;
ExpandedBlockEnd.gif}

None.gif


参考资料:

1, Disabling Shortcut Keys in Games

2, Nehe OpenGL tutorial

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值