没时间仔细看VCL控件代码,自己重写了一个,与大家分享。
要是谁有更好的办法,麻烦通知一声,,自卑~~{
description:自定义SpeedButton,用于Active Form
     * Active Form上放置的控件不会触发CM_MOUSELEVEL事件。
author:CoolSlob
last update:2004/06/12 10:31
history:
  2004/06/12:
        1. 添加ActivForm属性,用于选择是否应用于Active Form
        2. 添加ParentControl属性,用于向所属parent的所有TMySpeedButton手动发送CM_MOUSELEVEL事件.}
unit MySpeedButton;interfaceuses
  SysUtils, Classes, Controls, Buttons, Messages, Dialogs, Forms,
  ExtCtrls, Windows;type
  TMySpeedButton = class(TSpeedButton)
  private
    { Private declarations }
    FActiveForm: Boolean;
    FParentControl: TWinControl;
  protected
    { Protected declarations }
  public
    { Public declarations }
  protected
    procedure CMMouseEnter(var Message: TMessage); message CM_MOUSEENTER;
  published
    { Published declarations }
    property ActiveForm: Boolean read FActiveForm write FActiveForm;
    property ParentControl: TWinControl read FParentControl write FParentControl;
  end;procedure Register;implementationprocedure Register;
begin
  RegisterComponents('Additional', [TMySpeedButton]);
end;{ TMySpeedButton }procedure TMySpeedButton.CMMouseEnter(var Message: TMessage);
var
  I: Integer;
begin
  if FActiveForm and (Assigned(FParentControl)) then
  begin
    for I := 0 to FParentControl.ControlCount - 1 do
    begin
      if FParentControl.Controls[I] is TMySpeedButton then
      begin
        if (FParentControl.Controls[I] as TMySpeedButton).MouseInControl then
          (FParentControl.Controls[I] as TMySpeedButton).Perform(CM_MOUSELEAVE, 0, 0);
      end;
    end;
  end;
  inherited;
end;end.

解决方案 »

  1.   

    CM_MOUSELEAVE、CM_MOUSEENTER消息都依赖于TApplication.DoMouseIdle的方法~~
    DLL中的Application是失效的,所以CM_MOUSELEAVE、CM_MOUSEENTER没发处理了~~function TApplication.DoMouseIdle: TControl;
    var
      CaptureControl: TControl;
      P: TPoint;
    begin
      GetCursorPos(P);
      Result := FindDragTarget(P, True);
      if (Result <> nil) and (csDesigning in Result.ComponentState) then
        Result := nil;
      CaptureControl := GetCaptureControl;
      if FMouseControl <> Result then
      begin
        if ((FMouseControl <> nil) and (CaptureControl = nil)) or
          ((CaptureControl <> nil) and (FMouseControl = CaptureControl)) then
          FMouseControl.Perform(CM_MOUSELEAVE, 0, 0);
        FMouseControl := Result;
        if ((FMouseControl <> nil) and (CaptureControl = nil)) or
          ((CaptureControl <> nil) and (FMouseControl = CaptureControl)) then
          FMouseControl.Perform(CM_MOUSEENTER, 0, 0);
      end;
    end;
      

  2.   

    //如果将Application的句柄传入,这就可以响应此消息了~~
    //参考如下代码~~
    procedure NewMyClass(mHandle: THandle); stdcall; export;
    begin
      if Assigned(FormTempLib) then Exit;
      FormTempLib := TFormTempLib.Create(nil);
      FormTempLib.Show;
      Application.Handle := mHandle;
    end;procedure FreeMyClass; export;
    begin
      if Assigned(FormTempLib) then FormTempLib.Free;
      Application.Handle := 0;
    end;procedure NewMyClass(mHandle: THandle); stdcall; external 'TempLib.dll';procedure TForm1.Button1Click(Sender: TObject);
    begin
      NewMyClass(Application.Handle);
    end;