Delphi面板和自定义组件Z顺序问题

4
我正在做一个个人项目,最近遇到了很多问题,有很多问题需要问,但是嘿,这就是SO的作用,对吧? ;)
不管怎样,我尝试制作了一个透明的TPanel,通过制作一个自定义组件实现。我的应用程序是关于魔兽世界的,我做了一个类似于官方网站的天赋计算器,但是在Windows应用程序中。天赋是法术/技能,每个天赋都有信息,显示在工具提示中。
所以我有一个带有信息的工具提示,
我有一个天赋网格,当我将鼠标悬停在天赋上时,我想看到信息。 除此之外,我希望信息显示在鼠标指针的位置附近。
几乎可以实现。定位可以正常工作,并显示正确的信息,但是问题在这里。
看一下这张图片: Talent screen 黑色半透明面板是我的工具提示。 你看到的天赋(那个小的4x6网格)位于称为pnlTalents的深灰色面板中 该面板的父级是覆盖整个表单的较浅灰色面板,称为Panel1。 名为TooltipTalent的工具提示也具有父级Panel1。 我尝试将pnlTalents发送到后面,并将TooltipTalent带到前面,但是这完全没有任何区别。 我甚至尝试在位置改变的时候使用TooltipTalent.BringToFront; 注意,工具提示在屏幕顶部带有速度按钮的较暗灰色面板上没有任何问题。 我比较了两个面板(顶部的一个和包含天赋的一个),并找不到属性上的任何区别。 我真的没有什么想法了。我不知道是什么原因导致了这个问题,也不知道该如何解决它。
作为最后的资源,我尝试放下另一个覆盖整个表单的透明面板,看看是否有所帮助,但问题仍然存在。
我也可以发布我的自定义组件代码,但那会很多。 如果您想查看代码,请告诉我,我会找到一种方法来显示它 :)
有人能帮帮我吗? 此致敬礼

1
TToolWindowTHintWindow继承自TWinControl,应该可以正常显示。你的工具提示是从TControl/TGraphicControl派生的自定义控件吗?在这种情况下,网格将始终位于顶部。 - NGLN
使用所有这些混合技术,也许你真的应该尝试基于FireMonkey(FMX)库而不是VCL来构建你的程序? - Arioch 'The
@NGLN 这个网格是由 TPanels 组成的,而我的自定义控件也是基于 TPanel 的。 - Teun Pronk
我敢打赌,工具提示可能在Z顺序树的某个地方有“始终置顶”标志。使用类似WinSight、Spy++(我个人使用带有Process Manager插件的TotalCommander)的东西来遍历Windows窗口的层次结构。阅读VCL,了解TCustomForm.FormStyle = fsStayOnTop是如何实现的。另请参见WS_EX_TOPMOST - Arioch 'The
1个回答

3
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上也无法重现问题:

在这里输入图片描述


这个有点起作用了。现在它会在顶部,但我失去了透明度。 - Teun Pronk
这很奇怪,因为在设计视图中它显示为透明,但在运行时却不是。 - Teun Pronk
可能是不同的Windows窗口Z顺序树,或者在其中有不同的标志(请检查),或者在Delphi exe和您的exe中有不同的XP MAINFEST。 - Arioch 'The
我应该寻找什么?当我想要做这件事时,我从未想过它会如此深奥,哈哈。所以说实话,现在我不知道我在寻找什么。 - Teun Pronk
问题现在已经解决了,尽管我用的方法可能是有史以来最糟糕和最恶心的!我注意到如果工具提示与天赋技能具有相同的父级,则不会出现问题。但是我将被限制在那个深灰色块中。因此,我现在有两个工具提示,其中一个与天赋技能具有相同的父级,使得该工具提示与第一个工具提示具有相同的位置,这样您只能看到其他工具提示隐藏的部分。我想这是重叠吧。 - Teun Pronk
虽然我一开始就听从了您的建议,但是我还是要感谢您,因为我通过您的建议取得了很大的进展 :) - Teun Pronk

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接