Keyboard Interface

zlxadhkust 2009-05-30 01:32:53
仿造《Programming Windows 》一书中例子,给一个无模式对话框的窗口处理函数添加如下代码,通过插入MessageBeep (0)函数试验,结果我发现这个窗口其实从来没收到WM_KWYDOWN消息,书中的例子是模式对话框的,我这里用在了无模式对话框,难道两者在接收WM_KWYDOWN消息上有不同的地方?



case WM_KEYDOWN:
switch (wParam)
{
case VK_HOME:
SendMessage (hwnd, WM_VSCROLL, SB_TOP, 0) ;
break ;

case VK_END:
SendMessage (hwnd, WM_VSCROLL, SB_BOTTOM, 0) ;
break ;

case VK_PRIOR:
SendMessage (hwnd, WM_VSCROLL, SB_PAGEUP, 0) ;
break ;

case VK_NEXT:
SendMessage (hwnd, WM_VSCROLL, SB_PAGEDOWN, 0) ;
break ;

case VK_UP:
SendMessage (hwnd, WM_VSCROLL, SB_LINEUP, 0) ;
break ;

case VK_DOWN:
SendMessage (hwnd, WM_VSCROLL, SB_LINEDOWN, 0) ;
break ;

case VK_LEFT:
SendMessage (hwnd, WM_HSCROLL, SB_PAGEUP, 0) ;
break ;

case VK_RIGHT:
SendMessage (hwnd, WM_HSCROLL, SB_PAGEDOWN, 0) ;
break ;
}
return 0 ;

...全文
121 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
zlxadhkust 2009-06-01
  • 打赏
  • 举报
回复
又及:

Windows SDK->User Interface Services->Windows User Interface->Windowing->Messages and Message Queues->Message Handling->Message Loop

A thread's message loop must include TranslateMessage if the thread is to receive character input from the keyboard. The system generates virtual-key messages (WM_KEYDOWN and WM_KEYUP) each time the user presses a key. A virtual-key message contains a virtual-key code that identifies which key was pressed, but not its character value. To retrieve this value, the message loop must contain TranslateMessage, which translates the virtual-key message into a character message (WM_CHAR) and places it back into the application message queue. The character message can then be removed upon a subsequent iteration of the message loop and dispatched to a window procedure.

...

If a thread uses a modeless dialog box, the message loop must include the IsDialogMessage function so that the dialog box can receive keyboard input.



没人回答这个问题,只好自己来顶了,慢慢研究吧···

zlxadhkust 2009-06-01
  • 打赏
  • 举报
回复
整理一下目前收集的信息(摘自MSDN):


Windows SDK->User Interface Services->Windows User Interface->Windowing->Dialog Boxes->About Dialog Boxes->Modeless Dialog Boxes:

The application is responsible for retrieving and dispatching input messages to the dialog box. Most applications use the main message loop for this. To permit the user to move to and select controls by using the keyboard, however, the application must call the IsDialogMessage function. For more information about this function, see Dialog Box Keyboard Interface.

Windows SDK->User Interface Services->Windows User Interface->Windowing->Dialog Boxes->Dialog Boxes Reference->Dialog Box Functions->IsDialogMessage

When IsDialogMessage processes a message, it checks for keyboard messages and converts them into selections for the corresponding dialog box. For example, the TAB key, when pressed, selects the next control or group of controls, and the DOWN ARROW key, when pressed, selects the next control in a group.

Because the IsDialogMessage function performs all necessary translating and dispatching of messages, a message processed by IsDialogMessage must not be passed to the TranslateMessage or DispatchMessage function.


Windows SDK->User Interface Services->Windows User Interface->Windowing->Dialog Boxes->About Dialog Boxes->Dialog Box Keyboard Interface

The system automatically provides the keyboard interface for all modal dialog boxes. It does not provide the interface for modeless dialog boxes unless the application calls the IsDialogMessage function to filter messages in its main message loop. This means that the application must pass the message to IsDialogMessage immediately after retrieving the message from the message queue. The function processes the messages if it is for the dialog box and returns a nonzero value to indicate that the message has been processed and must not be passed to the TranslateMessage or DispatchMessage function.

Because the dialog box keyboard interface uses direction keys to move between controls in a dialog box, an application cannot use these keys to scroll the contents of any modal dialog box or any modeless dialog box for which IsDialogMessage is called. When a dialog box has scroll bars, the application must provide an alternate keyboard interface for the scroll bars. Note that the mouse interface for scrolling is available when the system includes a mouse.


上面这些介绍总结起来,梗概是:如果想处理无模式对话框的键盘消息的话,就必须在消息循环里加IsDialogMessage函数来处理,这样就能接收WM_KEYDOWN消息了,可是因为方向键是用来专门处理在不同控件之间切换的,所以不能用来滚动窗口里的内容。

我的程序的相应关码如下:

main函数内:

hDMlesGraph = CreateDialog (hInstance, TEXT ("Graphics"),
hwnd, GraphDlgProc) ;

while (GetMessage (&msg, NULL, 0, 0))
{
if (hDMlesGraph == 0 || !IsDialogMessage (hDMlesGraph, &msg))
{
TranslateMessage (&msg) ;
DispatchMessage (&msg) ;
}
}


GraphDlgProc函数内:


...
switch (message)
{
.....

case WM_KEYDOWN:

switch (wParam)
{
case VK_HOME:
SendMessage (hDlg, WM_VSCROLL, SB_TOP, 0) ;
break ;

case VK_END:
SendMessage (hDlg, WM_VSCROLL, SB_BOTTOM, 0) ;
break ;

case VK_PRIOR:
SendMessage (hDlg, WM_VSCROLL, SB_PAGEUP, 0) ;
break ;

case VK_NEXT:
SendMessage (hDlg, WM_VSCROLL, SB_PAGEDOWN, 0) ;
break ;

case VK_UP:
MessageBeep (0) ;
SendMessage (hDlg, WM_VSCROLL, SB_LINEUP, 0) ;
break ;

case VK_DOWN:
MessageBeep (0) ;
SendMessage (hDlg, WM_VSCROLL, SB_LINEDOWN, 0) ;
break ;

case VK_LEFT:
SendMessage (hDlg, WM_HSCROLL, SB_PAGEUP, 0) ;
break ;

case VK_RIGHT:
SendMessage (hDlg, WM_HSCROLL, SB_PAGEDOWN, 0) ;
break ;
}

return TRUE;



问题是,程序其实从来就没有进入过这一个switch的代码块里。

fairchild811 2009-05-30
  • 打赏
  • 举报
回复
没有ctrl的直接按那个字母就行了
Sou2012 2009-05-30
  • 打赏
  • 举报
回复
up!!!
zlxadhkust 2009-05-30
  • 打赏
  • 举报
回复
顺便还想问个关于快捷键(Keyboard Accelerators)的问题, 在大多数程序里,几乎菜单的每个item的名字都会有一个字符是加下划线的,来标记快捷键,可是除了后边跟有‘Ctrl + ...’ 提示的那些item以外,我也没见到哪个是能用的,貌似很少数的程序做到了所有的item都实现了相应的快捷键?
《Programming Windows 》对此也说的不详细,书中的例子也只是实现了文本编辑时剪切拷贝的那几个快捷键而已。我想问的是如果真的要实现应该怎么做呢?比如菜单里的Save键,如何让它与S关联。

65,211

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧