【问题标题】:Win32 textbox control alt keypress messageWin32 文本框控件 alt 按键消息
【发布时间】:2013-02-25 17:40:54
【问题描述】:

我需要在子窗口控件中连接 alt+alphanumberic 按键。

我编写了这个程序来测试它的功能。但它似乎对击键没有反应 像我的应用程序(键盘翻译器)所必需的 ALT+X 、 ALT+X 。

#include <windows.h>
#include <stdio.h>
#include <wchar.h>
#include <tchar.h>
#include <string.h>

#ifndef NULL
#define NULL 0
#endif

/* glaobal variables */
HWND hwndEdit = NULL;
HWND hwndWindow = NULL;
WCHAR* lpszClassName  = L"Vijesekara Keyboard Test Application";
WCHAR* lpszAppName = L"Vijesekara Keyboard Test Application";
int main_window_width = 0;
int main_window_height = 0;
WNDPROC edit_old_wndproc;

/*
  GWL_WNDPROC
*/
#ifndef GWL_WNDPROC 
#define GWL_WNDPROC (-4)
#endif

/* child window ID's */
#ifndef __CHILD_WINDOW_EDIT_ID__
#define __CHILD_WINDOW_EDIT_ID__
#define ID_EDIT     2000
// :TODO: more comes from here //
#endif 


/* constrains on child window positions */
#ifndef __CHILD_WINDOW_POSITION__
#define __CHILD_WINDOW_POSITION__
#define EDIT_CHILD_LEFT_PRECENTAGE 0.05
#define EDIT_CHILD_RIGHT_PRECENTAGE 0.05
#define EDIT_CHILD_TOP_PRECENTAGE 0.10
#define EDIT_CHILD_BOTTOM_PRECENTAGE 0.10
// :TODO: Other controls //
#endif

/* main window procedure */
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam,LPARAM lParam);
/* edit box procedure */
LRESULT CALLBACK EditBoxProc(HWND ,UINT , WPARAM , LPARAM );

/* resize child windows */
void ResizeChildWindows();

/* win main entry */
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
                    PSTR szCmdLine, int iCmdShow)
{

  WNDCLASS wndclass;

  wndclass.style = CS_HREDRAW |CS_VREDRAW ;
  wndclass.lpfnWndProc = WndProc;
  wndclass.cbClsExtra = 0;
  wndclass.hInstance = hInstance ;
  wndclass.hIcon = (HICON)LoadIcon(NULL,IDI_APPLICATION);
  wndclass.hCursor = (HCURSOR)LoadCursor(NULL,IDC_ARROW);
  wndclass.hbrBackground =(HBRUSH) GetStockObject( WHITE_BRUSH );
  wndclass.lpszMenuName = NULL ;
  wndclass.lpszClassName = lpszClassName ;

  /* Register class */
  int result ;
  result = RegisterClass( &wndclass) ;

  /* if failed to register window */
  if ( 0 == result )
  {
    MessageBox(NULL,L"Registering Window Have Been Failed" , lpszAppName, MB_OK);
    exit(0);  
  }

  /* Create the window */
  hwndWindow = CreateWindow(lpszAppName , lpszAppName ,WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT,\
                 CW_USEDEFAULT, CW_USEDEFAULT,NULL,NULL,hInstance,NULL);
  if(NULL == hwndWindow )
  {
    MessageBox(NULL,L"Window Creation have being failed", lpszAppName,MB_OK);
    exit(0); 
  }              
  ShowWindow(hwndWindow, iCmdShow);

  /* Enter message loop */
  MSG msg ;
  while(GetMessage(&msg,NULL, 0,0 ))
  {
    TranslateMessage(&msg);
    DispatchMessage(&msg); 
  } 
  return msg.wParam;
}

/* window procedure */
LRESULT CALLBACK WndProc (HWND hwnd, UINT message,WPARAM wParam,LPARAM lParam)
{
  switch(message)
  {
    case WM_CREATE:
     if( hwndEdit != NULL)
     {
        MessageBox(NULL,L"Edit control handle have already initialized",lpszAppName , MB_OK);
        exit(0);
     } 
     hwndEdit = CreateWindow( L"edit" ,NULL, WS_CHILD|WS_VISIBLE|WS_VSCROLL\
                              |WS_BORDER|ES_LEFT|ES_MULTILINE|ES_AUTOVSCROLL,0,0,0,0,hwnd,(HMENU)ID_EDIT\
                              ,GetModuleHandle(NULL),NULL);
     if( NULL == hwndEdit )
     {
       MessageBox(hwnd, L"Edit child window control creation failed", lpszAppName, MB_OK);
       exit(0);
     }   

    edit_old_wndproc = (WNDPROC)SetWindowLongPtr(hwndEdit,GWL_WNDPROC,(LONG_PTR)EditBoxProc );
      break;

    case WM_SIZE:
       main_window_height = HIWORD(lParam);
       main_window_width = LOWORD (lParam);
       ResizeChildWindows();
       return 0;
    case WM_COMMAND:

      /*:TODO:process */
      break; 

    case WM_DESTROY:

       PostQuitMessage(0);
       return 0; 
    default:
      return DefWindowProc(hwnd,message,wParam,lParam);
  }
  return DefWindowProc(hwnd,message,wParam,lParam);
}

/* resize window procedure */
void ResizeChildWindows()
{
  MoveWindow(hwndEdit,main_window_width*EDIT_CHILD_LEFT_PRECENTAGE , main_window_height* EDIT_CHILD_TOP_PRECENTAGE , \
    main_window_width * (1- EDIT_CHILD_LEFT_PRECENTAGE - EDIT_CHILD_RIGHT_PRECENTAGE)          ,// height 
    main_window_height * (1- EDIT_CHILD_TOP_PRECENTAGE - EDIT_CHILD_BOTTOM_PRECENTAGE), TRUE   // width 
 );  
}
static int alt=0;
static int ctl=0;
static int sys =0;
WCHAR buffer[1024];

LRESULT CALLBACK EditBoxProc(HWND hwnd, UINT message, WPARAM wParam , LPARAM lParam)
{
  switch ( message)
  {

    case WM_SYSCHAR:
      sys =1;
      if( lParam && (1<<29) ) { alt= 1;}
      else { 
        alt=0;
      }

    case WM_KEYPRESS:
      wsprintf( buffer,TEXT("KeyCode is :%d"), wParam);
      MessageBox( NULL,buffer, TEXT("Vijesekara Keyboard"), MB_OK);
      SetFocus(hwnd);
      /* keyboard procedure */


    alt =0;
    if ( sys==1)
    {
      sys=0;
      break;
      }

    return 0;

    default:
      break;
  }
  return CallWindowProc(edit_old_wndproc ,hwndEdit,message,wParam,
           lParam);
}


// end of vijesekara_keyboard.cpp

注意:在子类文本框内,WM_CHAR 消息不适用于 alt 击键,我可以 没有发送 WM_CHAR 消息并按下 alt 键到 for AlT+keystokes。所以我使用 spy++ 记录所有消息 然后我发现已发送 WM_SYSCHAR 而不是 WM_CHAR 用于编辑框子项中的那些消息 窗口。

知道我该怎么做吗?

--提前致谢--

【问题讨论】:

  • 如果有人按下 ALT+X,你会得到 WM_SYSCHAR 而不是 WM_CHAR。所以处理 WM_SYSCHAR。有什么问题?
  • 不,当我像其他字符一样按 ALT+C 时,我得到 WM_SYSCHAR,它不适用于 Alt+A Alt+X,就像几个键一样。我的问题不清楚吗?我会努力改进它,同时如果您愿意,请尝试编辑它。
  • 一旦我解决了 WM_KEYPRESS 不存在等问题,我就运行了您的示例代码。我得到了 ALT+C、ALT+A 和 ALT+X 的 WM_SYSCHAR。您是否在示例代码或其他应用程序中遇到此问题?如果是另一个应用程序,它是否具有吞噬 ALT+X 的菜单或加速器或快捷键?
  • 不,我说的是同一个应用程序,你的意思是它确实显示了带有键码的消息框?
  • 说真的,在声明 wndclass 之后,我如上所述对其进行初始化。我注释掉了 WM_KEYPRESS。而已。代码在其他方面是相同的。如果您仍然没有获得 ALT+A 的 WM_SYSCHAR,请运行 spy++,查看您收到了哪些消息以及正在处理它们的内容。

标签: winapi unicode keyboard editbox


【解决方案1】:

好吧,这很奇怪, 这是我的 Alt+A 键的 spy+ 输出。

那么我已经挂钩了 WM_SYSKEYUP 消息,Fixup 就是这个,

case WM_SYSKEYUP:
  if( lParam && (1<<29) ) {alt=1;}else{break;}
  if( wParam == 'A' || wParam=='Z'|| wParam =='X' || wParam== 'W' || wParam == 'Y' ){}else{break;}

case WM_SYSCHAR:
  sys =1;
  if( lParam && (1<<29) ) { alt=1; }
  else { 
    alt=0;
    break;
  }

 case WM_CHAR:
  wsprintf( buffer,TEXT("KeyCode is :%d"), wParam);
  MessageBox( NULL,buffer, TEXT("Vijesekara Keyboard"), MB_OK);
  SetFocus(hwnd);
  /* keyboard procedure */


  alt =0;


  return 0;

当我在 WM_SYSKEYU 上中断(调用默认窗口过程)时,它会发出令人讨厌的叮咚声 在 Windows 里面。我已经返回它然后声音消失了。

arx 的说法很奇怪。是的,我弄错了 WM_KEYPRESS,没有叫做 WM_KEYPRESS 的东西。 并且应该更正为 WM_CHAR。据他说没有这些机会 MessageBox 出现。那是 很奇怪。 @Arx,您可以发布您的答案,以便其他挖掘它的人受益,并且 我也可以给你一些学分。并挖掘为什么会发生这种情况,然后我们可以接受 并且此答案将保留为替代答案(未解决问题,但已修复 应用程序)。

【讨论】:

  • 请注意,这并不能回答问题,但这会解决问题。为了发现相同错误的人的利益。
猜你喜欢
  • 1970-01-01
  • 2011-03-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-11-08
  • 1970-01-01
  • 1970-01-01
  • 2011-12-12
相关资源
最近更新 更多