找回密码
 立即注册

QQ登录

只需一步,快速开始

graper

高级会员

45

主题

63

帖子

1348

积分

高级会员

积分
1348

活字格认证

graper
高级会员   /  发表于:2009-12-11 15:33  /   查看:6874  /  回复:0
Post by gw0506", 09-28-2007, 11:04
-----------------------------------------------------

MS Button的Click比较特殊,Mouse 和 Space 以及Enter key都可以触发。但是mouse点击button过程中,MouseDown后发KeyDown、KeyUp(任意Key 除了 Space 和Enter)然后Click和MouseClick就不会发了,只有MouseUp。

    根据MSDN描述
        Standard Click Event Behavior:
        1.MouseDown event.
        2.Click event.
        3.MouseClick event.
        4.MouseUp event.
    Note
          If the user moves the pointer out of the toggle control while the mouse button is down (such as moving the mouse off the Button control while it is     pressed), the toggle control will paint in the raised state and only the MouseUp event occurs. The Click or MouseClick events will not occur in this     situation.

    所以,现在有两种Case,MS Button 的Click和MouseClick不会触发。但是我没有找到原因。向各位求助。

    跟了一下各种正常,非正常case下的事件和消息信息,如下所示:
/-- 正常状态--/

  1. MouseDown
  2. {msg=0xf (WM_PAINT) hwnd=0x4d0b08 wparam=0x0 lparam=0x0 result=0x0}
  3. Paint
  4. {msg=0x202 (WM_LBUTTONUP) hwnd=0x4d0b08 wparam=0x0 lparam=0xe002a result=0x0}
  5. {msg=0xf (WM_PAINT) hwnd=0x4d0b08 wparam=0x0 lparam=0x0 result=0x0}
  6. Paint
  7. {msg=0x84 (WM_NCHITTEST) hwnd=0x4d0b08 wparam=0x0 lparam=0x13e0260 result=0x0}
  8. Click
  9. MouseUp
复制代码

/-- MouseDown 后发KeyDown KeyUp 消息 然后 MouseUp (非space key) --/

  1. MouseDown
  2. {msg=0x87 (WM_GETDLGCODE) hwnd=0x4d0b08 wparam=0x0 lparam=0x0 result=0x0}
  3. {msg=0x87 (WM_GETDLGCODE) hwnd=0x4d0b08 wparam=0x0 lparam=0x0 result=0x0}
  4. {msg=0x100 (WM_KEYDOWN) hwnd=0x4d0b08 wparam=0x90 lparam=0x1450001 result=0x0}
  5. KeyDown
  6. {msg=0x101 (WM_KEYUP) hwnd=0x4d0b08 wparam=0x90 lparam=0xffffffffc1450001 result=0x0}
  7. {msg=0xf (WM_PAINT) hwnd=0x4d0b08 wparam=0x0 lparam=0x0 result=0x0}
  8. Paint
  9. KeyUp
  10. {msg=0x202 (WM_LBUTTONUP) hwnd=0x4d0b08 wparam=0x0 lparam=0xa0022 result=0x0}
  11. MouseUp
复制代码
/-- MouseDown 后发KeyDown KeyUp 消息 然后 MouseUp (space key)--/

  1. MouseDown
  2. {msg=0x87 (WM_GETDLGCODE) hwnd=0x4d0b08 wparam=0x0 lparam=0x0 result=0x0}
  3. {msg=0x87 (WM_GETDLGCODE) hwnd=0x4d0b08 wparam=0x0 lparam=0x0 result=0x0}
  4. {msg=0x100 (WM_KEYDOWN) hwnd=0x4d0b08 wparam=0x90 lparam=0x1450001 result=0x0}
  5. KeyDown
  6. {msg=0x101 (WM_KEYUP) hwnd=0x4d0b08 wparam=0x90 lparam=0xffffffffc1450001 result=0x0}
  7. {msg=0xf (WM_PAINT) hwnd=0x4d0b08 wparam=0x0 lparam=0x0 result=0x0}
  8. Paint
  9. KeyUp
  10. {msg=0x2a1 (WM_MOUSEHOVER) hwnd=0x4d0b08 wparam=0x1 lparam=0xd0031 result=0x0}
  11. {msg=0x87 (WM_GETDLGCODE) hwnd=0x4d0b08 wparam=0x0 lparam=0x0 result=0x0}
  12. {msg=0x87 (WM_GETDLGCODE) hwnd=0x4d0b08 wparam=0x0 lparam=0x0 result=0x0}
  13. {msg=0x100 (WM_KEYDOWN) hwnd=0x4d0b08 wparam=0x20 lparam=0x390001 result=0x0}
  14. KeyDown
  15. {msg=0x87 (WM_GETDLGCODE) hwnd=0x4d0b08 wparam=0x0 lparam=0x0 result=0x0}
  16. {msg=0x87 (WM_GETDLGCODE) hwnd=0x4d0b08 wparam=0x0 lparam=0x0 result=0x0}
  17. {msg=0x102 (WM_CHAR) hwnd=0x4d0b08 wparam=0x20 lparam=0x390001 result=0x0}
  18. {msg=0xf (WM_PAINT) hwnd=0x4d0b08 wparam=0x0 lparam=0x0 result=0x0}
  19. Paint
  20. {msg=0x101 (WM_KEYUP) hwnd=0x4d0b08 wparam=0x20 lparam=0xffffffffc0390001 result=0x0}
  21. {msg=0xf (WM_PAINT) hwnd=0x4d0b08 wparam=0x0 lparam=0x0 result=0x0}
  22. Paint
  23. Click
  24. KeyUp
  25. {msg=0x202 (WM_LBUTTONUP) hwnd=0x4d0b08 wparam=0x0 lparam=0xd0031 result=0x0}
  26. MouseUp
复制代码
/-- mousedown -> move out of control -> mouse up (MSDN situation)--/

  1. MouseDown
  2. {msg=0xf (WM_PAINT) hwnd=0x4d0b08 wparam=0x0 lparam=0x0 result=0x0}
  3. Paint
  4. {msg=0x200 (WM_MOUSEMOVE) hwnd=0x4d0b08 wparam=0x1 lparam=0xd003b result=0x0}
  5. {msg=0x200 (WM_MOUSEMOVE) hwnd=0x4d0b08 wparam=0x1 lparam=0xd003c result=0x0}
  6. ......
  7. {msg=0xf (WM_PAINT) hwnd=0x4d0b08 wparam=0x0 lparam=0x0 result=0x0}
  8. Paint
  9. {msg=0x202 (WM_LBUTTONUP) hwnd=0x4d0b08 wparam=0x0 lparam=0x3700a5 result=0x0}
  10. {msg=0xf (WM_PAINT) hwnd=0x4d0b08 wparam=0x0 lparam=0x0 result=0x0}
  11. Paint
  12. MouseUp
复制代码
Reply by "KevinShan",  09-28-2007, 11:11
-----------------------------------------------------

在ButtonBase类的OnKeyUp这里,^_^

  1. protected override void OnKeyUp(KeyEventArgs kevent)
  2. {
  3.     if (this.GetFlag(2) && !base.ValidationCancelled)
  4.     {
  5.         if (this.OwnerDraw)
  6.         {
  7.             this.ResetFlagsandPaint();
  8.         }
  9.         else
  10.         {
  11.             this.SetFlag(4, false);
  12.             this.SetFlag(2, false);
  13.             base.SendMessage(0xf3, 0, 0);
  14.         }
  15.         if ((kevent.KeyCode == Keys.Return) || (kevent.KeyCode == Keys.Space))
  16.         {
  17.             this.OnClick(EventArgs.Empty);
  18.         }
  19.         kevent.Handled = true;
  20.     }
  21.     base.OnKeyUp(kevent);
  22. }
复制代码
Reply by "winking",  10-04-2007, 13:49
-----------------------------------------------------

Kevin好歹也给解释清楚嘛!!

其实Kevin给出了问题的关键所在,在ButtonBase类上处理KeyUp时清楚了一个内部标志,而发Click事件恰好需要验证它:

  1. protected override void OnKeyUp(KeyEventArgs kevent)
  2. {
  3.     if (this.GetFlag(2) && !base.ValidationCancelled)
  4.     {
  5.         if (this.OwnerDraw)
  6.         {
  7.             this.ResetFlagsandPaint();
  8.         }
  9.         else
  10.         {
  11.             this.SetFlag(4, false);
  12.             this.SetFlag(2, false); //关键在就在这里,所有Key消息处理时,清除Flag(2)这个标志
  13.             base.SendMessage(0xf3, 0, 0);
  14.         }
  15.         if ((kevent.KeyCode == Keys.Return) || (kevent.KeyCode == Keys.Space))
  16.       {
  17.            this.OnClick(EventArgs.Empty);
  18.         }
  19.         kevent.Handled = true;
  20.     }
  21.     base.OnKeyUp(kevent);
  22. }
复制代码
而在Button类上override了OnMouseUp:

  1. protected override void OnMouseUp(MouseEventArgs mevent)
  2. {
  3.    if ((mevent.Button == MouseButtons.Left) && base.MouseIsPressed)
  4.    {
  5.       bool mouseIsDown = base.MouseIsDown; // 此处取了MouseIsDown,
  6.         if (base.GetStyle(ControlStyles.UserPaint))
  7.         {
  8.             base.ResetFlagsandPaint();
  9.         }
  10.         if (mouseIsDown) //这里验证了MouseIsDown,只有它为True才会走里面逻辑,发Click和MouseClick事件。
  11.         {
  12.             Point point = base.PointToScreen(new Point(mevent.X, mevent.Y));
  13.             if ((UnsafeNativeMethods.WindowFromPoint(point.X, point.Y) == base.Handle) && !base.ValidationCancelled)
  14.             {
  15.                 if (base.GetStyle(ControlStyles.UserPaint))
  16.                 {
  17.                     this.OnClick(mevent);
  18.                 }
  19.                 this.OnMouseClick(mevent);
  20.             }
  21.         }
  22.     }
  23.     base.OnMouseUp(mevent);
  24. }
复制代码
很显然你想问那MouseIsDown里又是什么东西,这个是ButtonBase上的属性,定义如下:

  1. internal bool MouseIsDown
  2. {
  3.     get
  4.     {
  5.         return this.GetFlag(2);
  6.     }
  7. }
复制代码

0 个回复

您需要登录后才可以回帖 登录 | 立即注册
返回顶部