0

我正在尝试让应用程序显示一些信息,它将创建面板运行时并在其上放置信息,每个面板都将像图片一样平坦,应用程序也将使用运行时主题,所以我无法更改面板鼠标移动时的 bg 颜色,我试图在 TSpeedButton 上放置信息:v Oo 当应用程序使用运行时主题时它是平坦的,它具有美妙的突出显示功能,但主要问题是当我移动速度按钮时图像和标签没有移动,我需要这么多,他们就呆在那里..

我尝试编辑 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,IN 和 OUT,“mousemove”工作正常但“鼠标离开”不好,mainc 问题仍然是实际的。问题是我无法获得创建面板的画布来绘制。上面的例子可以用更简单的方法来实现:

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

但是对于 Canvas,一切都变得更加困难,在某处我读到 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;

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

4

2 回答 2

1

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

于 2013-05-26T17:02:12.523 回答
0

我在 Delphi 中创建了以下新组件并安装了它。一个新TColorPanel组件出现在MyComponentsIDE 的新选项卡中。然后我用它来放置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.

于 2013-05-27T14:37:25.760 回答