【问题标题】:Delphi Panels and custom component Z order issueDelphi Panels 和自定义组件 Z 顺序问题
【发布时间】:2012-12-24 15:01:52
【问题描述】:

我正在从事一个个人项目,最近遇到了很多问题,导致很多问题,但是,嘿,这就是 SO 的用途吗? ;)

无论如何,我尝试制作一个透明的 TPanel,这是通过制作自定义组件来实现的。 我制作的应用程序是关于魔兽世界的,我在官方网站上制作了一个天赋计算器,但在 Windows 应用程序中。 天赋是法术/技能,每个天赋都有显示在工具提示中的信息。

所以我有一个带有信息的工具提示,

我有一个天赋网格,当我将鼠标悬停在天赋上时,我想查看信息。 除此之外,我希望信息显示在光标位置附近。

几乎可以工作。定位有效,它显示了正确的信息但是!这就是问题所在。 看看这张图片:

黑色半透明面板是我的工具提示。 您会看到位于名为 pnlTalents 的深灰色面板中的人才(那个小 4x6 网格) 该面板的父面板是覆盖整个表单的浅灰色面板,称为Panel1。 名为TooltipTalent 的工具提示也有父Panel1。 我尝试将pnlTalents 发送到后面并将TooltipTalent 发送到前面,但这根本没有区别。 我什至在位置改变的那一刻尝试了TooltipTalent.BringToFront;。 请注意,工具提示在屏幕顶部带有速度按钮的深灰色面板上没有问题。 我比较了两个面板(顶部的一个和天赋的一个),发现属性没有区别。 我在这里严重用尽了想法。我不知道是什么原因造成的,也不知道如何解决这个问题。

作为最后的手段,我尝试删除另一个覆盖整个表单的透明面板,看看是否有帮助,但问题仍然存在。

我也可以发布我的自定义组件的代码,但这会很多。 如果您想查看代码,请告诉我,我会找到一种方法来显示它:)

谁能帮我解决这个问题? 亲切的问候

【问题讨论】:

  • TToolWindowTHintWindow 继承自 TWinControl 并且应该显示得很好。您的工具提示是来自TControl/TGraphicControl 的自定义控件吗?在这种情况下,网格将始终位于顶部。
  • 使用所有这些混合,也许您真的会尝试将您的程序基于 FireMonkey (FMX) 库而不是 VCL?
  • @NGLN 网格由 TPanel 组成,我的自定义控件也基于 TPanel。
  • 我敢打赌,工具提示可能在 Z 顺序树的某处具有“始终在顶部”标志。使用某些东西来遍历 Windows 窗口的层次结构。像 WinSight、Spy++(我个人使用 TotalCommander 和 Process MANager 插件)。阅读 VCL 如何实现TCustomForm.FormStyle = fsStayOnTop。另见WS_EX_TOPMOST

标签: delphi z-order delphi-xe3 tpanel


【解决方案1】:
procedure TMyPanel.CreateParams(var params: TCreateParams);
begin
  params.ExStyle := params.ExStyle or WS_EX_TRANSPARENT or WS_EX_TOPMOST ;
  inherited CreateParams(params);    
end;

使用 Quickhackcode 我得到了这个结果

例如,Image1 包含一个半透明的 png:

unit Unit4;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ExtCtrls, StdCtrls, dxGDIPlusClasses;

type

  TMyPanel=Class(TPanel)
     procedure CreateParams(var params: TCreateParams); override;
     procedure WMEraseBkGnd(var msg: TWMEraseBkGnd); message WM_ERASEBKGND;
  End;


  TForm4 = class(TForm)
    Panel1: TPanel;
    Button1: TButton;
    Image1: TImage;
    Button2: TButton;
    CheckBox1: TCheckBox;
    Panel2: TPanel;
    Button3: TButton;
    Label1: TLabel;
    procedure Button1Click(Sender: TObject);
    procedure Button3Click(Sender: TObject);
  private
    { Private-Deklarationen }

   Fmp:TMyPanel;
   fisInPaint:Boolean;
  public
    { Public-Deklarationen }
  end;

var
  Form4: TForm4;

implementation

{$R *.dfm}

{ TMyPanel }

procedure TMyPanel.CreateParams(var params: TCreateParams);
begin
  params.ExStyle := params.ExStyle or WS_EX_TRANSPARENT or WS_EX_TOPMOST ;
  inherited CreateParams(params);
end;



procedure TMyPanel.WMEraseBkGnd(var msg: TWMEraseBkGnd);
begin
  SetBkMode (msg.DC, TRANSPARENT);
  msg.result := 1;
end;

procedure TForm4.Button1Click(Sender: TObject);
begin

  Fmp := TMyPanel.Create(self);
  With Fmp do
    begin
      Parent := self;
      left:= Panel1.Left -100;
      top:= Panel1.top -100;
      width := 300;
      Height := 300;
    end;
   image1.Parent := Fmp;
   Image1.Align := alClient;
   Image1.Stretch := true;
   Fmp.BringToFront;
   Label1.Parent := FMP;
   label1.Transparent := true;
   Label1.Left := 100;
   Label1.Left := 100;
end;

procedure TForm4.Button3Click(Sender: TObject);
begin
   Fmp.Left := fmp.Left + 10;
end;

end.

也无法重现 XP 的问题:

【讨论】:

  • 嗯,这种伎俩。现在它会在顶部,但我失去了透明度
  • 这很奇怪,因为在设计视图中它显示为透明但在运行时却不显示
  • 可能不同的 Windows 窗口 Z 顺序树或沿途不同的标志(检查),或者可能在 Delphi exe 和您的 exe 中不同的 XP MAINFEST。
  • 我到底应该寻找什么?当我想这样做时,我从未想过它会如此深刻,哈哈。所以说实话,现在我不知道我在寻找什么
  • 好吧,现在问题已经解决了,尽管我以一种可能是有史以来最糟糕和最讨厌的方式来解决问题!我注意到如果工具提示与天赋具有相同的父级,我没有问题。但是,我将仅限于那个深灰色块。所以我现在有 2 个工具提示,其中一个与天赋具有相同的父级,赋予该工具提示与第一个相同的位置,这使得您只能看到为另一个隐藏的部分。我猜有点重叠。
猜你喜欢
  • 1970-01-01
  • 2010-09-23
  • 2016-12-14
  • 1970-01-01
  • 2014-04-29
  • 2012-04-28
  • 2019-05-18
  • 2011-05-02
  • 1970-01-01
相关资源
最近更新 更多