Delphi 鼠标移动时高亮显示TPanel

Delphi 鼠标移动时高亮显示TPanel,delphi,delphi-xe2,Delphi,Delphi Xe2,我正在尝试让应用程序显示一些信息,它会在运行时创建面板并在上面放置信息,每个面板都会像图片一样平坦,而且应用程序会使用运行时主题,所以我无法在鼠标移动时更改面板背景颜色,我试着在TSpeedButton上放置信息:v O.O当应用程序使用运行时主题时,当它是平面时,它有奇妙的突出显示功能,但主要的问题是,当我移动speedbutton时,图像和标签没有移动,我需要这么多,它们只是停留在那里 我试图编辑TCustomPanel.Paint以查看面板是否像高亮显示的按钮,并在末尾添加代码: Pain

我正在尝试让应用程序显示一些信息,它会在运行时创建面板并在上面放置信息,每个面板都会像图片一样平坦,而且应用程序会使用运行时主题,所以我无法在鼠标移动时更改面板背景颜色,我试着在TSpeedButton上放置信息:v O.O当应用程序使用运行时主题时,当它是平面时,它有奇妙的突出显示功能,但主要的问题是,当我移动speedbutton时,图像和标签没有移动,我需要这么多,它们只是停留在那里

我试图编辑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;
应用图片:

如果我这样做:

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,进进出出,“mousemove”工作正常,但“mouse leave”不好,而且主要问题仍然存在。问题是,我无法在已创建面板的画布上绘制。上述示例可以通过更简单的方式实现:

 @P.OnMouseLeave := @onmouseleaveproc;
 @P.OnMouseMove  := @onmousemoveproc;
但对于Canvas,一切都更加困难,我在某个地方读到过,Canvas在TCustomPanel中受到保护

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

我试过这样做:(但不起作用)


简单地说,颜色不会改变。(主题关闭时颜色会发生变化)

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

我在Delphi中创建了以下新组件并安装了它。一个新的
t颜色面板
组件出现在IDE的一个新的
MyComponents
选项卡中。然后我用它在一个新的应用程序上放置了一个
t颜色面板
,它正确地响应了鼠标进入/离开事件,并根据需要更改颜色。我不知道您是如何将应用程序面板设置为
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

我可以像SpeedButton那样突出显示面板吗?你可以根据你想要编写的自定义代码的多少来处理它。捕获鼠标事件后,可以使用设置TPanel属性的标准Delphi方法。如果这些与您想要的不一致,您可以在TPanel画布上进行自定义绘制以完成您喜欢的操作。这不是答案。仅链接的答案还不够好。我部分同意David Heffernan的观点,但我担心如果我这样写的话,我会被删掉,我的帖子也会被删除。我一直在努力为OP提供帮助,但没有写出完整的答案。我加入了这个链接,因为它在很大程度上描述了答案的一个重要部分。我在回答中阐述了一点,并在评论中进一步阐述。我的理解是,在这个论坛上,我们将提供帮助,但不一定要做每个人的家庭作业。在Dave的评论之后,我随后在评论的答案中添加了更多的内容。如果需要,我很乐意进一步帮助。英国不是一个国家。你是说“英国人”。是的,我很着急。顺便说一句,英语不是我的母语。你的英语学得很好。:)你的TMyPanel课程是什么样子的?具体来说,我希望看到message Handler.edited的声明,在关闭主题的情况下更改颜色,但我希望在dxe2:)中在运行时主题上使用runtime themeTurn
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.