【问题标题】:WM_KEYDOWN - capturing keypress causing event [duplicate]WM_KEYDOWN - 捕获按键导致事件[重复]
【发布时间】:2011-09-14 00:17:44
【问题描述】:

我正在尝试做一个非常简单的任务 - 按下某个键时会发生一个事件 - 但在实现它时遇到了很多困难。

我正在使用 Win32 API。有人问我正在使用什么框架,但我不知道。我正在使用 Visual C++,该程序是一个 Windows 程序。

我只想在按下特定键时发生事件。对于这个例子,我使用's'键,事件是一个整数,要么设置为 1 要么设置为 0;在按键时未设置为哪个(我会使用 bool,但我还不知道它是如何工作的)。

有人告诉我使用GetKeyState(),然后告诉我这实际上不好。我也被告知要使用 WM_KEYDOWN 但无法弄清楚它是如何工作的......当然我所做的必须是绝对的基本编程(键盘输入>输出)但我无法清楚地解释它是如何工作的?!

我尝试使用以下方法,但没有成功:

int Flag;
if (GetKeyState(115) == 1 && Flag == 0) Flag = 1;
if (GetKeyState(115) == 1 && Flag == 1) Flag = 0;

我也试过用这个:

if (GetKeyState(115) & 0x8000 && Flag == 0) Flag = 1;
if (GetKeyState(115) & 0x8000 && Flag == 1) Flag = 0;

都不行。有谁知道我如何实现 WM_KEYDOWN?

我正在使用 Windows 消息循环

【问题讨论】:

  • 您使用的是 Windows 消息循环 (en.wikipedia.org/wiki/Message_loop_in_Microsoft_Windows) 吗?
  • 请阅读 Petzold 的书,Windows 编程。您不可能在一夜之间学习 Windows GUI 编程。这不是微不足道的。你需要先走路才能跑。
  • @SirDarius 是的,我想我是。我的 WinMain 函数以 (HINSTANCE hThisInstance, HINSTANCE hPrevInstance, LPSTR lpszArgument, int nFunsterStil) 开头。是这个意思吗?
  • 是 MFC 还是普通 Win32?如果是 MFC,则可以使用消息映射进行处理。否则你需要查看 Window Proc
  • @CaptainProg 按下按钮时是否有一个窗口/对话框?是用 DialogBox 还是 CreateWindow 创建的?

标签: c++ winapi keypress


【解决方案1】:

有几种方法可以解决这个问题。这些都不会为您提供“纳秒级”的精度,但它们就在这里。

如果您希望按键被活动窗口或对话框接收,您即使在对话框/窗口的 WINPROC 中也可以处理 WM_KEYDOWN。

void InSomePlace()
{
  WNDCLASS wndClass
  ZeroMemory( &wndClass, sizeof(wndClass) );

  // Initialize wndClass members here
  wndClass.lpszClassName = _T("MyWindow");
  wndClass.lpfnWndProc = &MyWndProcHandler; // 

  RegisterClass( &wndClass );
  HWND hWnd = CreateWindow( _T("MyWindow", /* lots of other parameters */ );

  MSG msg;
  BOOL bRet;
  while ( (bRet = GetMessage( &msg, hWnd, 0, 0 )) != 0 )
  {
    if (bRet == -1)
    {
      // handle the error and possibly exit
    }
    else
    {
      TranslateMessage(&msg); 
      DispatchMessage(&msg); 
    }
  }
}

LRESULT CALLBACK MyWndProcHandler( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
{
  switch ( uMsg )
  {
    // Lots of case statements, in particular you want a WM_KEYDOWN case
    case WM_KEYDOWN:
      if ( wParam == 'S' )
      {
        // Do something here
        return 0L;
      }
      break;
  }

  return DefWindowProc( hwnd, uMsg, wParam, lParam );
}

对于非常相似的 DialogBox,您仍然会有一个 DLGPROC,它作为最后一个参数传递给 DialogBox/CreateDialog

void InSomePlace( HINSTANCE hInstance, HWND hParentWindow )
{
  DialogBox( hInstance, _T("MyDialogTemplate"), hParentWindow, &MyDialogProc );
}

INT_PTR CALLBACK MyDialogProc( HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam )
{
  case ( uMsg )
  {
    // Lots of case statements, in particular you want a WM_KEYDOWN case
    case WM_KEYDOWN:
      if ( wParam == 'S' )
      {
        // Do something here
        SetWindowLong(hwndDlg, DWL_MSGRESULT, 0L);
        return TRUE;
      }
      break;
  }
  return FALSE;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-09-19
    • 1970-01-01
    • 1970-01-01
    • 2011-05-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多