作者:Junhot
更新时间:2004-12-15

-------------------------------------------------------------------------------
总的流程描述图:


从具体控件看起,以鼠标点击
Button控件的事件为例,Button控件代码包含在dxmutgui.cs文件中:

 

ButtonClick事件的原型:

Button中声明了如下的事件Click及事件触发方法RaiseClickEvent
        Event code

Button内部如何触发Click事件:

HandleMouse这个方法调用RaiseClickEvent方法从而导致Click事件的触发,另外还有如HandleKeyboard方法等,同样也是事件触发的方法之一。


        
/// <summary>
        
/// Handle mouse messages from the buttons
        
/// </summary>

        public override bool HandleMouse(NativeMethods.WindowMessage msg, System.Drawing.Point pt, IntPtr wParam, IntPtr lParam)
        
{
            
if (!IsEnabled || !IsVisible)
                
return false;

            
switch(msg)
            
{
                
case NativeMethods.WindowMessage.LeftButtonDoubleClick:
                
case NativeMethods.WindowMessage.LeftButtonDown:
                
{
                    
if (ContainsPoint(pt))
                    
{
                        
// Pressed while inside the control
                        isPressed = true;
                        NativeMethods.SetCapture(Parent.SampleFramework.Window);
                        
if (!hasFocus)
                            Dialog.RequestFocus(
this);

                        
return true;
                    }

                }

                    
break;
                
case NativeMethods.WindowMessage.LeftButtonUp:
                
{
                    
if (isPressed)
                    
{
                        isPressed 
= false;
                        NativeMethods.ReleaseCapture();
                        
if (!parentDialog.IsUsingKeyboardInput)
                            Dialog.ClearFocus();

                        
// Button click
                        if (ContainsPoint(pt))
                            RaiseClickEvent(
thistrue);
                    }

                }

                    
break;
            }


            
return false;
        }

控件如何知道何时该触发Click事件:

Dialog类中(Dialog类代码同样包含在dxmutgui.cs中)通过MessageProc捕获WindowMessage,然后调用ControlHandleKeyboard或者HandleMouse方法,下面是调用HandleMouse方法的代码:


                
// Mouse messages
                case NativeMethods.WindowMessage.MouseMove:
                
case NativeMethods.WindowMessage.MouseWheel:
                
case NativeMethods.WindowMessage.LeftButtonUp:
                
case NativeMethods.WindowMessage.LeftButtonDown:
                
case NativeMethods.WindowMessage.LeftButtonDoubleClick:
                
case NativeMethods.WindowMessage.RightButtonUp:
                
case NativeMethods.WindowMessage.RightButtonDown:
                
case NativeMethods.WindowMessage.RightButtonDoubleClick:
                
case NativeMethods.WindowMessage.MiddleButtonUp:
                
case NativeMethods.WindowMessage.MiddleButtonDown:
                
case NativeMethods.WindowMessage.MiddleButtonDoubleClick:
                
case NativeMethods.WindowMessage.XButtonUp:
                
case NativeMethods.WindowMessage.XButtonDown:
                
case NativeMethods.WindowMessage.XButtonDoubleClick:
                
{
                    
// If not accepting mouse input, return false to indicate the message should still 
                    
// be handled by the application (usually to move the camera).
                    if (!usingMouseInput)
                        
return false;

                    
// Current mouse position
                    short mouseX = NativeMethods.LoWord((uint)lParam.ToInt32());
                    
short mouseY = NativeMethods.HiWord((uint)lParam.ToInt32());
                    System.Drawing.Point mousePoint 
= new System.Drawing.Point(mouseX, mouseY);
                    
// Offset mouse point
                    mousePoint.X -= dialogX;
                    mousePoint.Y 
-= dialogY;

                    
// If caption is enabled, offset the Y coordinate by the negative of its height.
                    if (hasCaption)
                        mousePoint.Y 
-= captionHeight;

                    
// If a control is in focus, it belongs to this dialog, and it's enabled, then give
                    
// it the first chance at handling the message.
                    if (controlFocus != null && 
                        controlFocus.Parent 
== this && 
                        controlFocus.IsEnabled)
                    
{
                        
// If the control MsgProc handles it, then we don't.
                        if (controlFocus.HandleMouse(msg, mousePoint, wParam, lParam))
                            
return true;
                    }


                    
// Not yet handled, see if the mouse is over any controls
                    Control control = GetControlAtPoint(mousePoint);
                    
if ((control != null&& (control.IsEnabled))
                    
{
                        
// Let the control handle the mouse if it wants (and return true if it handles it)
                        if (control.HandleMouse(msg, mousePoint, wParam, lParam))
                            
return true;
                    }

                    
else
                    
{
                        
// Mouse not over any controls in this dialog, if there was a control
                        
// which had focus it just lost it
                        if (msg == NativeMethods.WindowMessage.LeftButtonDown &&
                            controlFocus 
!= null &&
                            controlFocus.Parent 
== this)
                        
{
                            controlFocus.OnFocusOut();
                            controlFocus 
= null;
                        }

                    }