Delphi 子窗体始终位于主窗体的上方
我使用的是Delphi2007,每次我都使用这样的代码创建一个新表单Delphi 子窗体始终位于主窗体的上方,delphi,delphi-2007,Delphi,Delphi 2007,我使用的是Delphi2007,每次我都使用这样的代码创建一个新表单 var Child : TFrmChild; begin Child:=TFrmChild.Create(Self); Child.Show(); end; 子窗体将显示并显示在所有其他窗体的上方,这是可以的,但单击主窗体时,子窗体将停留在主窗体的上方。所以我有两个问题 为什么即使单击主窗体,子窗体仍位于主窗体上方 当我点击主窗体时,如何使它保持在所有其他窗体之上 谢谢 更新 这是子窗体的dfm object F
var
Child : TFrmChild;
begin
Child:=TFrmChild.Create(Self);
Child.Show();
end;
子窗体将显示并显示在所有其他窗体的上方,这是可以的,但单击主窗体时,子窗体将停留在主窗体的上方。所以我有两个问题
object FrmChild: TFrmChild
Left = 549
Top = 308
Caption = 'FrmChild'
ClientHeight = 228
ClientWidth = 213
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'Tahoma'
Font.Style = []
OldCreateOrder = False
PixelsPerInch = 96
TextHeight = 13
end
Application.MainFormOnTaskbar := False;
在项目的.dpr文件中。缺点是失去了一些Vista功能
还有另一种解决方法,但它很笨拙,并且还有其他问题(请参见QC的链接)。您有两个顶级窗口。主窗体是子窗体的所有者。拥有的窗口总是出现在其所有者的上方,这只是windows的规则之一 请注意,我指的是Windows概念,而不是Delphi概念 本主题解释了规则。关键的声明是: 拥有的窗口在z顺序中始终高于其所有者
至于如何让你的应用程序表现不同,我不太确定。如果您将您的子窗体设为无主窗体,则它将有自己的任务栏按钮,并且当主窗体最小化时,它不会被最小化。例如。后期回答-我刚刚解决了这个问题。我们想要Aero风格的ALT-TAB和WIN-TAB功能,但MainFormOnTaskBar导致第三方组件出现一些问题。(LMD停靠-如果主窗体上有停靠站点,子窗体上有停靠站点,则拖动子窗体上的停靠项会将主窗体带到前面) 解决办法是:
- 在CreateParams中将Params.WndParent设置为0
- 使用管理任务栏选项卡。这还会将窗口添加到ALT-TAB和WIN-TAB处理程序中
unit TaskbarList;
interface
uses
Windows, Messages,
CommCtrl,
ShlObj,
SysUtils, Classes, ComCtrls;
const
SID_ITaskbarList = '{56FDF342-FD6D-11D0-958A-006097C9A090}';
SID_ITaskbarList2 = '{602D4995-B13A-429B-A66E-1935E44F4317}';
SID_ITaskbarList3 = '{EA1AFB91-9E28-4B86-90E9-9E9F8A5EEFAF}';
SID_ITaskbarList4 = '{C43DC798-95D1-4BEA-9030-BB99E2983A1A}';
CLSID_TaskbarList: TGUID = '{56FDF344-FD6D-11d0-958A-006097C9A090}';
type
ITaskbarList = interface(IUnknown)
[SID_ITaskbarList]
function HrInit: HRESULT; stdcall;
function AddTab(hwnd: HWND): HRESULT; stdcall;
function DeleteTab(hwnd: HWND): HRESULT; stdcall;
function ActivateTab(hwnd: HWND): HRESULT; stdcall;
function SetActiveAlt(hwnd: HWND): HRESULT; stdcall;
end;
ITaskbarList2 = interface(ITaskbarList)
[SID_ITaskbarList2]
function MarkFullscreenWindow(hwnd: HWND; fFullscreen: BOOL): HRESULT; stdcall;
end;
type
THUMBBUTTON = record
dwMask: DWORD;
iId: UINT;
iBitmap: UINT;
hIcon: HICON;
szTip: packed array[0..259] of WCHAR;
dwFlags: DWORD;
end;
tagTHUMBBUTTON = THUMBBUTTON;
TThumbButton = THUMBBUTTON;
PThumbButton = ^TThumbButton;
// THUMBBUTTON flags
const
THBF_ENABLED = $0000;
THBF_DISABLED = $0001;
THBF_DISMISSONCLICK = $0002;
THBF_NOBACKGROUND = $0004;
THBF_HIDDEN = $0008;
THBF_NONINTERACTIVE = $10;
// THUMBBUTTON mask
THB_BITMAP = $0001;
THB_ICON = $0002;
THB_TOOLTIP = $0004;
THB_FLAGS = $0008;
THBN_CLICKED = $1800;
const
TBPF_NOPROGRESS = 0;
TBPF_INDETERMINATE = $1;
TBPF_NORMAL = $2;
TBPF_ERROR = $4;
TBPF_PAUSED = $8;
TBATF_USEMDITHUMBNAIL = $1;
TBATF_USEMDILIVEPREVIEW = $2;
const
STPF_NONE = $00000000;
STPF_USEAPPTHUMBNAILALWAYS = $00000001;
STPF_USEAPPTHUMBNAILWHENACTIVE = $00000002;
STPF_USEAPPPEEKALWAYS = $00000004;
STPF_USEAPPPEEKWHENACTIVE = $00000008;
type
ITaskbarList3 = interface(ITaskbarList2)
[SID_ITaskbarList3]
function SetProgressValue(hwnd: HWND; ullCompleted: ULONGLONG;
ullTotal: ULONGLONG): HRESULT; stdcall;
function SetProgressState(hwnd: HWND; tbpFlags: Integer): HRESULT; stdcall;
function RegisterTab(hwndTab: HWND; hwndMDI: HWND): HRESULT; stdcall;
function UnregisterTab(hwndTab: HWND): HRESULT; stdcall;
function SetTabOrder(hwndTab: HWND; hwndInsertBefore: HWND): HRESULT; stdcall;
function SetTabActive(hwndTab: HWND; hwndMDI: HWND;
tbatFlags: Integer): HRESULT; stdcall;
function ThumbBarAddButtons(hwnd: HWND; cButtons: UINT;
pButton: PThumbButton): HRESULT; stdcall;
function ThumbBarUpdateButtons(hwnd: HWND; cButtons: UINT;
pButton: PThumbButton): HRESULT; stdcall;
function ThumbBarSetImageList(hwnd: HWND; himl: HIMAGELIST): HRESULT; stdcall;
function SetOverlayIcon(hwnd: HWND; hIcon: HICON;
pszDescription: LPCWSTR): HRESULT; stdcall;
function SetThumbnailTooltip(hwnd: HWND; pszTip: LPCWSTR): HRESULT; stdcall;
function SetThumbnailClip(hwnd: HWND; var prcClip: TRect): HRESULT; stdcall;
end;
ITaskbarList4 = interface(ITaskbarList3)
[SID_ITaskbarList4]
function SetTabProperties (hwnd: HWND; stpFlags: Integer): HRESULT; stdcall;
end;
implementation
end.
BaseForm.pas:
unit BaseForm;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls,
TaskBarList;
type
TBaseForm = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
class var FTaskBarList: ITaskbarList;
protected
class function TaskBarList: ITaskbarList;
procedure DoShow;override;
procedure DoHide;override;
procedure Activate;override;
procedure CreateParams(var Params: TCreateParams); override;
public
constructor Create(AOwner: TComponent); override;
end;
var
BaseForm: TBaseForm;
implementation
uses
ComObj;
{$R *.dfm}
{ TBaseForm }
procedure TBaseForm.Activate;
begin
inherited;
TaskBarList.ActivateTab(Handle);
end;
procedure TBaseForm.Button1Click(Sender: TObject);
begin
TBaseForm.Create(Self).Show;
end;
constructor TBaseForm.Create(AOwner: TComponent);
begin
inherited;
// remove taskbar button for Application.Handle
TaskBarList.DeleteTab(Application.Handle);
end;
procedure TBaseForm.CreateParams(var Params: TCreateParams);
begin
inherited;
if (Parent = nil) and (ParentWindow = 0) then // don't use on docked Windows
Params.WndParent := 0;
end;
procedure TBaseForm.DoHide;
begin
inherited;
TaskBarList.DeleteTab(Handle);
end;
procedure TBaseForm.DoShow;
begin
inherited;
TaskBarList.AddTab(Handle);
end;
class function TBaseForm.TaskBarList: ITaskbarList;
var
pIntF: IInterface;
begin
if not assigned(FTaskBarList) then
begin
pIntF := CreateComObject(CLSID_TaskbarList);
pIntF.QueryInterface(ITaskBarList, FTaskBarList);
FTaskBarList.HrInit;
end;
Result := FTaskBarList;
end;
end.
注意:我没有使用OleCheck检查HRESULT,因为我希望它在字段中以静默方式失败。谢谢,但是我的子窗体的
formstyle
属性设置为fsNormal
,我也不想使用MDI接口。您不需要始终处于顶部的窗体来实现这一点。您只需将子窗体归主窗体所有(在windows意义上)。感谢该链接,如果我将应用程序设置为,则windows Vista功能可能会丢失。MainFormOnTaskbar
为false
?虽然您已向QC报告了这一点,但您是正确的,您应该注意到,它已被关闭,原因是其行为符合设计要求。@DelphiNewbie-我不使用Vista,所以我不知道,但我相信它与应用程序在任务栏上的显示方式有关。@DelphiNewbie-其中有对MainFormOnTaskbar的描述,它可能位于QualityCentral(bug db)上,但这不是一个bug,这是预期的Windows平台行为。