首页 > 代码库 > C++捕获组合键

C++捕获组合键

vc视图类程序可以接收OnKeyDown消息,但在对话框上却需要PreTranslateMessage处理按键消息,

而且系统按键Alt,F10也需要特殊处理。

 

还是直接上代码:

 


BOOL CTestDlg::PreTranslateMessage(MSG* pMsg)
{
 // TODO: Add your specialized code here and/or call the base class
 CString str;
 CString strMsg;
 int valid_down=0;
 
 static int SHIFT=0;
 int CAPITAL=0;
 static int CTRL=0;

 static int ALT=0;
 static int F10=0;
 short key_down=0;
 short alt_down=0;
 short f10_down=0;
 short ctrl_down=0;

//通过检测消息知道,这些键的按键状态如下:
//第1次按下为 0xFFFFFF81 ,弹起却为 1
//第2次按下为 0xFFFFFF80 ,弹起却为 0
//以后重复上述逻辑过程
//所以,最低位0x0f不容易判定,要判定高位才可


  key_down = GetKeyState(VK_MENU) & 0xff00;//81 80
  if (key_down) ALT=1;
  else ALT=0;


  key_down = GetKeyState(VK_SHIFT)& 0xff00;//81 80
  if (key_down) SHIFT=1;
  else SHIFT=0;

  key_down = GetKeyState(VK_CONTROL)& 0xff00;//81 80
  if (key_down) CTRL=1;
  else CTRL=0;

//F10 2次点击
  key_down = GetKeyState(VK_F10) & 0xff00;//81 80
  if (key_down) F10=1;
  else F10=0;

  str.Format("%0x,m=%d,w=%d,l=%ld",key_down,pMsg->message,pMsg->wParam,pMsg->lParam);//pMsg->wParam);
  SetWindowText(str);

//因为在按下Alt键后,再按其它键,就没有KEYDOWN消息,仍然是WM_SYSKEYDOWN,只不过 pMsg->wParam是按键的码制
//为了简单,这里记住ALT F10等系统键的按下后,如果仍然有其它按键,则通过pMsg->wParam来判别
//没有系统按键,就检测WM_KEYDOWN,所以三者是并行关系

 if  (  CTRL || ALT || SHIFT )
 {
  if ( pMsg->message==260 ) return TRUE;//有其它键按键按下,直接返回,等待弹起再处理
  if (  CTRL )
  {//Ctrl键按下时,不是一般键,或者F10键弹起,就直接返回
   if (  (pMsg->message!=257 && pMsg->message!=261)  ) return TRUE;//有其它键按键按下,直接返回,等待弹起再处理
  }

 }

 if (pMsg->message==WM_KEYUP || CTRL || ALT || SHIFT || F10)//检测按键弹起
 {   

 // if  (0x8000 & GetKeyState(VK_SHIFT) )  SHIFT=1;
 // if  (0x8000 & GetKeyState(VK_CONTROL) )  CTRL=1;
 // if  (0x0080 & GetKeyState(VK_MENU) )  ALT=1;
  if  (GetKeyState(VK_CAPITAL)!=0)  CAPITAL=1;
//F1-F24 
  if (pMsg->wParam>=0x70 && pMsg->wParam<=0x87)
  {
   if (pMsg->wParam>=0x70 && pMsg->wParam<=0x78)//F1-F9
    str.Format("F%c",pMsg->wParam-0x70+‘1‘);
   else if (pMsg->wParam>=0x79 && pMsg->wParam<=0x7B)//F10-F12
    str.Format("F1%c",pMsg->wParam-0x79+‘0‘);
   else if (pMsg->wParam>=0x7C && pMsg->wParam<=0x84)//F13-F21
    str.Format("F2%c",pMsg->wParam-0x7C+‘3‘);
   else if (pMsg->wParam>=0x85 && pMsg->wParam<=0x87)//F22-F24
    str.Format("F2%c",pMsg->wParam-0x85+‘2‘);
          
   valid_down=1;
  }
//A-Z
  if (pMsg->wParam>=‘A‘ && pMsg->wParam<=‘Z‘)
  {
   if ( SHIFT || CAPITAL )
    str.Format("%c",pMsg->wParam);
   else
    str.Format("%c",pMsg->wParam-‘A‘+‘a‘);
   valid_down=1;

  }
//0-9
  if (pMsg->wParam>=‘0‘ && pMsg->wParam<=‘9‘)
  {//正常数字键盘
    str.Format("%c",pMsg->wParam-‘0‘+48);
   valid_down=1;
  }
//0-9
  if (pMsg->wParam>=0x60 && pMsg->wParam<=0x69)
  {//小键盘上的数字键
    str.Format("%c",pMsg->wParam-0x60+48);
   valid_down=1;
  }


  switch(pMsg->wParam)
  {
  case VK_RETURN :
   str="回车";
   valid_down=1;
   break;
  case VK_BACK:
            str="back";
   valid_down=1;
//……
   
  }
  if (valid_down==1)  //有效按键
  {
 //  if  (CAPITAL)  str="CapsLock + "+str;
   if  (SHIFT )  str="Shift + "+str;
   if  (ALT )  str="Alt + "+str;
   if  (CTRL )  str="Ctrl + "+str;
   GetDlgItem(IDC_BUTTON1)->SetWindowText(str);

  }
  
 }
 return CDialog::PreTranslateMessage(pMsg);
}

C++捕获组合键