作者:Junhot
更新时间:2004-12-15
-------------------------------------------------------------------------------
总的流程描述图:
从具体控件看起,以鼠标点击Button控件的事件为例,Button控件代码包含在dxmutgui.cs文件中:
Button的Click事件的原型:
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(this, true);
}
}
break;
}
return false;
}
控件如何知道何时该触发Click事件:
在Dialog类中(Dialog类代码同样包含在dxmutgui.cs中)通过MessageProc捕获WindowMessage,然后调用Control的HandleKeyboard或者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;
}
}