鼠标移动时突出显示TPanel

时间:2013-05-26 16:46:25

标签: delphi delphi-xe2

我正在尝试让应用程序显示一些信息,它会创建Panels运行时并在其上放置信息,每个面板将像图片一样平坦,app也将使用运行时主题,所以我不能要在鼠标移动时更改面板bg颜色,我尝试在TSpeedButton上放置信息:v当它使用运行时主题时,它有平坦的高亮显示功能,但主要问题是当我移动时图像和标签不移动快速按钮,我需要这么多,他们只是留在那里..

我尝试编辑TCustomPanel.Paint以查看面板是否看起来像突出显示的按钮,最后添加代码:

PaintRect := ClientRect;
Details := StyleServices.GetElementDetails(ttbButtonHot);
StyleServices.DrawElement(Canvas.Handle, Details, PaintRect);

但没有成功..

在运行时链接一些自定义代码OnClick事件也很困难,例如:

ShowMessage('custom message on each panel');

我对如何做到这一点一无所知,希望有人会给我建议或给我一些例子。

顺便说一句,面板将以这种方式创建:

var
  P: TPanel;
begin
 P := TPanel.Create(Self);
 P.Left := 20;
 P.Top := 100;
 P.Width := 60;
 P.Height := 20;
 P.Visible := True;
 P.Parent := Self;
 @P.OnClick := @Showmessageproc; // somehow this way..
end;

App pic:

pic

如果我这样做:

procedure TMyPanel.MouseMove(Shift: TShiftState; X, Y: Integer);
var
  mEvnt: TTrackMouseEvent;
begin
  inherited;
  if not FMouseTracking then begin
    mEvnt.cbSize := SizeOf(mEvnt);
    mEvnt.dwFlags := TME_LEAVE;
    mEvnt.hwndTrack := Handle;
    TrackMouseEvent(mEvnt);
    FMouseTracking := True;
    showmessage('IN');
  end;
end;

procedure TMyPanel.WMMouseLeave(var Msg: TMessage);
begin
 if Msg.Msg = WM_MOUSELEAVE then showmessage('OUT');
  Msg.Result := 0;
  FMouseTracking := False;
  if Assigned(FOnMouseLeave) then
    FOnMouseLeave(Self);
end;

procedure G(Sender: TObject);
begin
showmessage('message');
end;

procedure TMainFrm.Button1Click(Sender: TObject);
var
  P: TMyPanel;
begin
 P := TMyPanel.Create(Self);
 P.Left := 20;
 I := I + 100;
 P.Top := I;
 P.Width := 200;
 P.Height := 80;
 P.Visible := True;
 P.Parent := Self;
 @P.OnClick := @g;
end;

当我在运行时创建的面板上移动鼠标时,出现2 msgbox,IN和OUT,“mousemove”工作正常,但“鼠标离开”不好,mainc问题仍然是实际的。问题是,我无法获得创建的面板画布。上面的例子可以通过更简单的方式实现:

 @P.OnMouseLeave := @onmouseleaveproc;
 @P.OnMouseMove  := @onmousemoveproc;

但是使用Canvas,一切都比较困难,在某些地方我读过画布在TCustomPanel中受到保护。

还有另一个问题:是否可以处理称为例如OnMouseMove的面板?因为可能会有30个(运行时创建的面板)

我试过这种方式:(并且它不起作用)

type
  TMyPanel = class(TPanel)
  public
   constructor Create(AOwner: TComponent); override;
  private
  //  FMouseTracking: Boolean;
  //  FOnMouseLeave: TNotifyEvent;
    procedure CMMouseEnter(var msg: TMessage); message CM_MOUSEENTER;
    procedure CMMouseLeave(var msg: TMessage); message CM_MOUSELEAVE;
  protected
  //  procedure MouseMove(Shift: TShiftState; X, Y: Integer); override;
  published
  //  property OnMouseLeave: TNotifyEvent read FOnMouseLeave write FOnMouseLeave;
  end;

    constructor TMyPanel.Create(AOwner: TComponent);
    begin
      ControlStyle := ControlStyle - [csParentBackground] + [csOpaque];
      inherited;
    end;


    procedure TMyPanel.CMMouseEnter(var msg: TMessage);
    begin
      inherited;
      Color := clBlue;
      { Do Whatever }
    end;

    procedure TMyPanel.CMMouseLeave(var msg: TMessage);
    begin
      inherited;
      Color := clRed;
      { Do Whatever }
    end;

简单地说,颜色不会改变。 (颜色随主题变化而变化)

2 个答案:

答案 0 :(得分:1)

对于Delphi 6来说,它基本上是explained here,但我认为这个概念相同。您想为面板定义自定义Windows消息处理程序。这将为您提供基本的鼠标输入/退出功能。然后,您可以从那里设置TPanel属性,以找到您喜欢的内容。例如,要模拟速度按钮,您可以只设置背景颜色并相应地更改边框斜角。如果这还不够,您可以在鼠标进入/退出时直接写入TPanel的Canvas(绘制您想要查看的行为),以获得您所追求的视觉行为。

答案 1 :(得分:0)

我在Delphi中创建了以下新组件并进行了安装。新的TColorPanel组件出现在IDE中的新MyComponents选项卡中。然后我使用它在新应用程序上放置TColorPanel,它对鼠标进入/离开事件做出了适当的响应,并根据需要更改颜色。我不确定您是如何将应用的面板设为TMyPanel而不是标准TPanel。这就是我尝试的方式。我按原样使用了您最新的消息处理代码。

unit ColorPanel;

interface

uses
  WinTypes, WinProcs, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  ExtCtrls;

type
  TColorPanel = class(TPanel)
  public
   constructor Create(AOwner: TComponent); override;
  private
    procedure CMMouseEnter(var msg: TMessage); message CM_MOUSEENTER;
    procedure CMMouseLeave(var msg: TMessage); message CM_MOUSELEAVE;
  protected
  //  procedure MouseMove(Shift: TShiftState; X, Y: Integer); override;
  published
  //  property OnMouseLeave: TNotifyEvent read FOnMouseLeave write FOnMouseLeave;
  end;

procedure Register;

implementation

procedure Register;
begin
  RegisterComponents('MyComponents', [TColorPanel]);
end;

constructor TColorPanel.Create(AOwner: TComponent);
begin
  ControlStyle := ControlStyle - [csParentBackground] + [csOpaque];
  inherited;
end;

procedure TColorPanel.CMMouseEnter(var msg: TMessage);
begin
  inherited;
  Color := clBlue;
  { Do Whatever }
end;

procedure TColorPanel.CMMouseLeave(var msg: TMessage);
begin
  inherited;
  Color := clRed;
  { Do Whatever }
end;

end.

我不确定为什么你的工作不起作用,除了确定你的应用程序面板如何宣布为TMyPanel