返回首页

目录{A}简介
大多数键盘和鼠标,出售这些天,超出标准的两个按钮和104键。与Windows Me和2000年开始,已建成的操作系统支持这些额外的硬件按钮与新的操作系统,支持更多的按钮,自然会给应用程序的一些功能有限的免费。例如,如果您按下"停止"按钮,当前的应用程序将收到按Escape键;滚动鼠标滚轮滚动的窗口具有焦点如果是滚动和点击端鼠标按钮浏览IE浏览器一样,后退和前进工具栏按钮。
应用程序可以处理这些按钮,如果他们想提供自己的特点。例如,媒体播放器应用可以处理的播放,暂停,和停止按钮,并执行相应的行动对当前歌曲。图形应用程序可以处理鼠标滚轮消息提供缩放功能。
示例项目是一个基于对话框的的应用程序,演示了如何处理由应用程序按钮产生的消息,它只是简单地打印它收到的所有消息的详细信息。
本文假定您熟悉与WTL的GUI编程。退房设立VC使用WTL的指示。硬件和驱动程序
由于我只用微软的键盘和鼠标,本文只讨论微软硬件。来自其他公司的硬件(希望)的行为从应用的角度来看,同样的,自通知窗口消息。
Microsoft自然临一排的功能键上方的蓝色按钮,如下所示:
{S0}
新的键盘使用的功能键,以及应用程序按钮。例如,自然键盘4000有这些额外的标签上的F1 - F5键:
键可与F Lock键的功能键和应用程序按钮之间切换。
老鼠有一个滚轮和两个额外的侧按钮(有时每边一个):
{S2}
的按钮,功能和生成命令是高度依赖你的操作系统和驱动程序版本。没有驱动程序的Windows 2000或以后将只能识别按钮(大多是浏览器的导航按钮和音量控制)的一个子集。只有一些按钮的功能,如果你安装的IntelliType或IntelliPoint驱动程序。例如,4000键盘上的组合按钮和收藏按钮无法正常的IntelliType在所有没有。
请记住,如果您的硬件按钮似乎没有工作 - 更新驱动程序!按钮标识
#在每个应用程序的按钮WINUSER.H定义。鼠标按钮被称为"X按钮",确定为XBUTTON1和XBUTTON2消息。按钮也有虚拟键代码:VK_XBUTTON1和VK_XBUTTON2。
{S3}
作为鼠标中键滚轮:
{S4}的
由于滚轮按钮不被视为一个X按钮,它会不会在这里介绍。鼠标滚轮本身不具备的ID或虚拟键代码,而是一个特殊的消息被发送时轮推出。
键盘按钮确定与APPCOMMAND_开始的常量,例如APPCOMMAND_BROWSER_BACKWARD和APPCOMMAND_VOLUME_MUTE。需要注意的是一些键盘按键有没有标识所有,如4000键盘的最爱按钮,:
{五}
调用这些按钮的功能完全由IntelliType软件的实施,并按下这些按钮时,应用程序不通知。
有些键盘有一个缩放滑块:
这种控制也处理完全由的IntelliType。当用户移动滑块的IntelliType活动的应用程序发送鼠标滚轮消息,它显示用户按下控制键的车轮轧。处理应用程序按钮
当用户按下鼠标或键盘的按钮,触发一个命令,它不是一个完全由驱动程序(如上面所述的按钮我的最爱)实施的按钮,当前的应用程序接收到一个WM_APPCOMMAND消息。 WM_APPCOMMAND发送信息的若干件包装成消息参数:窗口句柄的事件发生,命令(一个APPCOMMAND_ *常数),一个标志,指示命令是否是由键盘或鼠标触发,指示标志的ID也按下Shift键和鼠标按钮。
命令ID的名单很长,所以我不会在这里一一列举。 的完整列表。第二个标志可以FAPPCOMMAND_KEY如果命令是用键盘,FAPPCOMMAND_MOUSE触发,如果是用鼠标触发,或FAPPCOMMAND_OEM如果使用其他一些方法。您可以检查这个标志告诉,例如,如果APPCOMMAND_BROWSER_BACKWARD命令被调用使用键盘上的后退按钮,或鼠标的X按钮1。
您可以检查的旗帜最后告诉什么键或鼠标按钮被按下时生成的命令。其标志是:MK_CONTROL,MK_SHIFT,MK_LBUTTON,MK_MBUTTON,MK_RBUTTON,MK_XBUTTON1,MK_XBUTTON2。注意司机可能不会总是通过这些标志当前的应用程序,因此,如果用户按下"后退"按钮的同时按住Shift键,WM_APPCOMMAND消息发送的标志可能不包括MK_SHIFT。
需要注意的一件事是,WM_APPCOMMAND是不同于大多数其他消息,在该应用程序应返回TRUE(而不是零),如果它处理的消息。如果返回零,司机可能会执行默认的命令,无论您的应用程序除了。
在WTL消息映射宏MSG_WM_APPCOMMAND可用于处理WM_APPCOMMAND。您的处理程序应该有这个原型:

LRESULT OnAppCommand(HWND hwndCtrl, int nCommand, UINT uDevice, UINT uKeys);

如果消息处理函数应该返回TRUE。在7.5以前的WTL的版本中,MSG_WM_APPCOMMAND宏总是返回0,所以你需要重新界定它得到正确的行为:{C}
这是示例应用程序如何列出WM_APPCOMMAND按几个应用程序按钮后收到的消息:
{七}处理鼠标X按钮{A18}客户区消息
当用户点击X按钮,系统会发送鼠标消息鼠标光标下的窗口时间。当光标在应用程序的客户区,X按钮生成的消息WM_XBUTTONDOWN,WM_XBUTTONUP和WM_XBUTTONDBLCLK。 (当光标控制,WM_APPCOMMAND消息生成。)
X按钮鼠标消息的WPARAM发送两个信息:一个标志,指示shift键和鼠标按钮被按下的时候,和另一个号码,表示鼠标按钮生成消息(XBUTTON1或设置XBUTTON2)。 lParam包含鼠标光标的坐标,与其他鼠标消息。
在WTL中,有一个为每个消息的消息映射宏。例如,MSG_WM_XBUTTONDOWN处理WM_XBUTTONDOWN,有此原型的处理程序:
LRESULT OnXButtonDown(UINT uButton, UINT uKeys, CPoint pt);

与WM_APPCOMMAND,X按钮消息处理程序应返回TRUE,如果消息处理。 WTL的消息映射宏的所有返回零,所以你需要重新定义它们。例如,一个固定的MSG_WM_XBUTTONDOWN是:
#undef MSG_WM_XBUTTONDOWN

#define MSG_WM_XBUTTONDOWN(func) \

  if (uMsg == WM_XBUTTONDOWN) \

  { \

    SetMsgHandled(TRUE); \

    lResult = func(GET_XBUTTON_WPARAM(wParam), GET_KEYSTATE_WPARAM(wParam), \

              CPoint(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam))); \

    if(IsMsgHandled()) \

      return TRUE; \

  }

MSG_WM_XBUTTONUP和MSG_WM_XBUTTONDBLCLK需要类似的变化。这需要做的所有WTL的版本,自宏仍然在7.5版的不正确的。{A19}非客户区消息
当用户点击一个窗口的非客户区的X按钮,系统会发送鼠标消息,该窗口。的消息WM_NCXBUTTONDOWN,WM_NCXBUTTONUP,并WM_NCXBUTTONDBLCLK。这些消息发送两件的WPARAM信息:命中测试值,该值指示光标在非客户区的一部分,并XBUTTON *常量指示哪个按钮生成消息。 lParam包含光标的坐标。
WTL有这三个消息的消息映射宏,例如MSG_WM_NCXBUTTONDOWN处理WM_NCXBUTTONDOWN。处理程序应该有这个原型:
LRESULT OnNCXButtonDown(UINT uButton, int nHitTest, CPoint pt);

WM_XBUTTON *消息的WM_NCXBUTTON *处理程序应该返回TRUE,如果消息处理。 WM_NCXBUTTON *所有返回零WTL的宏,所以你需要重新定义它们。例如,一个固定的MSG_WM_NCXBUTTONDOWN是:
MSG_WM_NCXBUTTONUP和MSG_WM_NCXBUTTONDBLCLK需要类似的变化。这需要做的所有WTL的版本,自宏仍然在7.5版的不正确的。
下面是一个鼠标点击X按钮后,收到消息的例子:
{S8}{A20}处理鼠标滚轮事件
有两种类型的滚轮。成离散的位置点击原始类型,因为它是旋转,而新型旋转顺利。智能浏览器4.0已经顺利滚动的车轮,这也是一个倾斜滚轮:
{S9}
倾斜功能是讨论在本节后面。平滑滚动和倾斜功能要求的IntelliPoint,没有它,车轮会发送消息,就好像它是一个旧式的点击轮。
当用户滚动的车轮,应用程序收到WM_MOUSEWHEEL消息。 wParam包含两个比特的信息:标志,指示Shift键或鼠标按钮被按下,和距离值。 LPARAM保存光标的坐标。
点击车轮的距离值的数量WHEEL_DELTA(定义为120)的倍数。这一价值的标志,告诉你哪个方向轮旋转:积极的手段向前(远离用户),负面手段落后(对用户)。例如,如果距离,WHEEL_DELTA,然后用户把对自己的车轮一次点击。如果距离是3 WHEEL_DELTA,那么他很快把方向盘即可。较大的距离值的平均值的应用程序应该做的较大的滚动或缩放操作。
下面是一个点击轮滚动时收到的消息的例子:
{S10}
顺利滚轮,距离值不会永远是WHEEL_DELTA倍数。它是应用程序的责任,保持多少距离已覆盖的轨道。如果车轮不动一个完整的WHEEL_DELTA距离,应用程序可以执行一个更小的滚动或缩放,或可以等到充分的WHEEL_DELTA多个遍历。
下面是一个使用平滑滚动的车轮时,收到的消息的例子:
{S11}
如果键盘上有一个缩放滑块的IntelliType与MK_CONTROL标志设置发送WM_MOUSEWHEEL消息。如果您的应用程序具有缩放功能,你应该响应此消息在执行缩放。上面的屏幕截图中的最后两个消息产生一个缩放滑块 - 通知,控制键被按下的消息表明,。 4000键盘上的缩放滑块是一个简单的数字交换机,因此,距离参数始终是WHEEL_DELTA。如果距离是积极的,应用程序应放大,或者如果它的负面,应用程序应该缩小。
注意,一些应用程序,尤其是IE和Firefox,变焦方向逆转。 4000的缩放滑块是标有 - 的迹象,这表明,推动滑块(这发出了一个积极的距离)会放大,并倒推将缩小。就个人而言,我将跟随滑块标记。此外,在办公室和Paint Shop Pro的变焦功能相匹配的滑块标记。希望有一天,所有程序将走到一起的和谐,并决定哪种方式来放大。
倾斜滚轮不支持任何的Windows航运版本本身,这样的IntelliPoint转换成横向的滚动消息的倾斜滚轮事件,以及应用程序不直接倾斜滚轮事件的通知。在Vista中,有一个新的消息,WM_MOUSEHWHEEL,方向盘倾斜时发送。 WM_MOUSEHWHEEL异常WM_MOUSEWHEEL相同的参数,距离参数表明,左/右的运动,而不是前进/后退。此外,为WM_MOUSEHWHEEL的处理程序应该返回TRUE,如果消息是处理一个WM_MOUSEWHEEL处理程序,而应返回零。
在WTL,你可以使用的MSG_WM_MOUSEWHEEL消息映射宏来处理WM_MOUSEWHEEL。处理程序应该有这个原型:
LRESULT OnMouseWheel(UINT uKeys, short nDistance, CPoint pt);

WTL的不支持为WM_MOUSEHWHEEL但为它创建消息映射宏是简单的:
#define WM_MOUSEHWHEEL 0x020E

#define MSG_WM_MOUSEHWHEEL(func) \

  if (uMsg == WM_MOUSEHWHEEL) \

  { \

    SetMsgHandled(TRUE); \

    lResult = func((UINT)LOWORD(wParam), (short)HIWORD(wParam), \

              CPoint(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam))); \

    if(IsMsgHandled()) \

      return TRUE; \

  }

WM_MOUSEHWHEEL处理程序应具有相同的原型为OnMouseWheel()以上。请注意,我还没有尝试过在Vista上的示例代码,但希望将所有的工作!{A21}版权和许可
这篇文章是受版权保护的材料,??006迈克尔邓恩。我知道这是不是要停止复制,围绕"净人,但我不得不说也无妨。如果你是在做翻译了这篇文章感兴趣,请给我发电子邮件,让我知道。我不预见拒绝任何人的许可,做翻译,我想知道翻译,这样我就可以在这里张贴一个链接。
本文附带的演示代码发布到公共领域。我释放它的代码,这种方式使所有人受益。 (我不使文章本身的公共领域,因为只有在CodeProject上的文章,有利于自己的知名度和在CodeProject网站。)如果您使用自己的应用程序的演示代码,电子邮件,让我知道,将不胜感激(只是为了满足我的好奇心,关于是否乡亲是从我的代码中获益),但不要求。在自己的源代码的归属也表示赞赏,但不是必需的。{A22}修订历史记录
2006年5月4:文章首次发表。

回答

评论会员:t800g 时间:2011/12/06
我想向在WTL一个简单的图像浏览器(我的新手业余尝试{S12}),没有工具栏或命令栏,菜单视图,
视图窗口继承CScrollWindowImpl,我发现,当我把OnMouseWheel成员,并在CMainFrame
MESSAGE_HANDLER(WM_MOUSEWHEEL,OnMouseWheel)
BEGIN_MSG_MAP (...)循环,唯一的CMainFrame得到
WM_MOUSEWHEEL消息时,我正在运行的程序KatMouse
(套,而不是keybrd鼠标焦点),"原因很显然,直接发送WM_MOUSEWHEEL到CMainFrame中,当我将鼠标悬停在视图区的鼠标不
当我尝试把在视图类的成员,我得到这个错误:

C:\程序文件\ Microsoft Platform SDK中的Windows Server 2003 R2 \ \ CRT \ xtree(56):错误C2976:"STD::_Bidit":太少模板参数

C:\程序文件\ Microsoft Platform SDK中的Windows Server 2003 R2 \ \ CRT \ xtree(56):错误C2955:"STD::_Bidit":使用类模板需要模板参数列表

C:\程序文件\ Microsoft Platform SDK中的Windows Server 2003 R2 \ \ CRT \ xtree(56):错误C2976:"STD::_Bidit":太少模板参数

C:\程序文件\ Microsoft Platform SDK中的Windows Server 2003 R2 \ \ CRT \ xtree(56):错误C2955:"STD::_Bidit":使用类模板需要模板参数列表

("宣言... ..."的东西)

我怎样才能处理WM_MOUSEWHEEL我自己/重写这个成员函数?(车轮向上/向下,而不是默认的滚动)
由于这只是我的爱好,在正确的方向任何帮助/微调赞赏{S13}
评论会员:ZuikWay 时间:2011/12/06
我VS8,WTL的最新更新的解决方案和运行。我看不到鼠标滚轮的消息处理,即使间谍表示WM_MOUSEWHEEL消息发送。我看到的唯一的反应是前进和后退的按键,的。
如何检测鼠标滚轮或任何提示,我失踪。

韦恩

评论会员:Thrack 时间:2011/12/06
我需要为我的程序,除了我用的是DEV - C编译器。有一个版本,编译器?
如果不是,可能我得到我需要,我使用的编译器的代码?
评论会员:迈克尔邓恩 时间:2011/12/06
我不知道,我从来没有使用DEV - C

- 迈克 -
的Visual C MVP {S14}
链接〜! {A23}

我的工作为凯泽S#246;泽
评论会员:麦克空间 时间:2011/12/06
我很好奇其他方向。我有一个应用程序,我想创造我自己的"放大"像微软键盘上的按钮(目前我使用OSK类型的应用程序来模拟)。我发送的控制键,鼠标滚轮的消息,但它不工作。在我看来,父窗口可能不被通过的消息。我有点新的这个东西,有没有人遇到此之前呢?我的代码为按钮的回调函数:

私人无效button9_Click(对象发件人,EventArgs的发送)
 60; {
HWND的IntPtr = WindowsAPIs.GetForegroundWindow()
& #160; INT的wParam = 0,LPARAM = 0;
wParam参数=(120 LT,LT; 16)(INT)WindowsAPIs.MK_CONTROL;
WindowsAPIs.SendMessage(HWND,(INT)WindowsAPIs.WM_MOUSEWHEEL,WPARAM,LPARAM)
& #160; }

我可以看到越来越间谍父窗口的消息。就像我说的,它像父窗口需要通过它。我做我的测试使用IE6.0。另一个有趣的事情,更何况 - 当我用一个实际的鼠标滚轮控制按钮,消息没有出现在父窗口的间谍,但我看到放大/缩小

感谢您的帮助。
麦克
评论会员:迈克尔邓恩 时间:2011/12/06
我发送消息,而不是尝试SendInput(),因为SendInput()实际上是模拟输入,这是更复杂的不仅仅是一个消息。

- 迈克 -
的Visual C MVP {S14}
链接〜! {A23}

我的工作为凯泽S#246;泽
评论会员:麦克空间 时间:2011/12/06
我想我开始用SendInput(),但不知道如何得到控制的关键。重新审视后,我得到了它的工作在我发送的结构键盘和鼠标输入的组合。

感谢您的帮助。
麦克


评论会员:king_vincy 时间:2011/12/06
您好,
证明你的应用程序,第4和第5的按钮,可以通过XBUTTON1和XBUTTON2信息处理

我与7个按键的鼠标。
你有任何信息/想到如何处理/检测按钮的信息,在应用程序级别的第6和第7按钮,

任何帮助是极大的赞赏。


谢谢!
维诺德
评论会员:迈克尔邓恩 时间:2011/12/06
AFAIK只有两个按钮(MS的小鼠的按钮)为他们定义的常量。你有窥​​探消息,看看其他值使用额外的按钮?他们可能只是XBUTTON2 1和2。
评论会员:paski2222 时间:2011/12/06
我要捕获所有鼠标左键点击,这样我就可以看看会发生什么,当我点击applictions按钮,在我编写的程序,并重新创建这些事件,但我坚持呢?可以帮助吗?

迈克尔帕斯科
评论会员:迈克尔邓恩 时间:2011/12/06
一个按钮控件点击时WM_COMMAND消息发送到它的父。
评论会员:DN哈里斯 时间:2011/12/06
有用的功能

感谢

大卫
评论会员:弗林Arrowstarr 时间:2011/12/06
好文章。我在想,如果有可能延长该计划,以检查其他设备上的按键,的吗?例如,我有一个触摸功能的硬盘驱动器的情况下。我想捕捉到按下按钮,并把它重定向到一个我选择的备份方案,而不是案发蹩脚的工具,。任何帮助将不胜感激。感谢。 =)

弗林
评论会员:迈克尔邓恩 时间:2011/12/06
这听起来像一个驱动程序做了一些事,看一些数据表明按钮被按下通过USB或FW巴士。

- 迈克 -
的Visual C MVP {S14}