子窗体始终位于主窗体上方

发布于 2024-11-05 16:06:34 字数 770 浏览 5 评论 0原文

我正在使用delphi 2007,每次我使用这样的代码创建一个新表单

var
  Child : TFrmChild;
begin
  Child:=TFrmChild.Create(Self);
  Child.Show();
end;

The child form is shown and displayed above all other forms ,这是可以的,但是当单击主表单时子窗体位于主窗体之上。所以我有两个问题,

  1. 为什么即使在主窗体中单击,子窗体仍保留在主窗体上方?
  2. 当我点击主窗体时,如何使主窗体保持在所有其他窗体之上?

谢谢

更新

这是子表单的 dfm

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

I'm using delphi 2007 and each time which I create a new form using a code like this

var
  Child : TFrmChild;
begin
  Child:=TFrmChild.Create(Self);
  Child.Show();
end;

The child form is shown and appears above all others forms , that is ok, but when a click in the main form the child form stays above of the main form. so i have two questions

  1. why the child form stay above of the main form even if a click in the main form?
  2. How i can make which the main form stay over all others forms when i click on it?

Thanks

UPDATE

this is the dfm of the child form

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

唠甜嗑 2024-11-12 16:06:34

您有两个顶层窗口。主窗体是子窗体的所有者。拥有的窗口总是显示在其所有者之上,这只是 Windows 的规则之一。

请注意,所有者我指的是 Windows 概念而不是 Delphi 概念。

Windows 功能主题介绍了规则。关键的说法是:

在 z 顺序中,拥有的窗口始终位于其所有者之上。

至于如何让你的应用程序表现不同,我不太确定。例如,如果您将子窗体设置为无主,那么它将有自己的任务栏按钮,并且当主窗体最小化时,它不会最小化。

You have two top level windows. The main form is the owner of the child form. Owned windows always appear above their owners, that's just one of the rules of Windows.

Note that by owner I am referring to the Windows concept rather than the Delphi concept.

The Windows Features topic explains the rules. The key statement is:

An owned window is always above its owner in the z-order.

As for how to make you app behave differently I'm not so sure. If you make your child form unowned then it will have its own taskbar button and it won't be minimised when the main form is minimised, for example.

梦过后 2024-11-12 16:06:34

此问题已报告给 QualityCentral。 进行设置

  Application.MainFormOnTaskbar := False;

简单的解决方法是在项目的 .dpr 文件中 。缺点是失去了一些 Vista 功能。

还有另一种解决方法,但它很笨拙并且存在其他问题(请参阅 QC 的链接)。

This has been reported to QualityCentral. The simple workaround is to set

  Application.MainFormOnTaskbar := False;

in your project's .dpr file. The downside is loss of some Vista functionality.

There is another workaround, but it is clumsy and has other problems (see the link to QC).

趴在窗边数星星i 2024-11-12 16:06:34

迟到的回答 - 我刚刚解决了这个问题。我们想要 Aero 风格的 ALT-TAB 和 WIN-TAB 功能,但 MainFormOnTaskBar 导致了第三方组件的一些问题。 (LMD 停靠 - 如果主窗体上有一个停靠站点,子窗体上有一个停靠站点,则拖动子窗体上的停靠项目会将主窗体带到前面)

解决方案是:

  • 在 CreateParams 中将 Params.WndParent 设置为 0
  • 使用 ITaskBarList 界面 管理任务栏选项卡。这还将窗口添加到 ALT-TAB 和 WIN-TAB 处理程序

TaskBarList.pas

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 检查 HRESULTS,因为我希望它在现场静默失败。

Late answer - I have just worked around this issue. We wanted the Aero style ALT-TAB and WIN-TAB funtionality, but MainFormOnTaskBar caused some issues with a third-party component. (LMD Docking - if there was a docksite on the main form and a docksite on a child, dragging a docked item on the child brought the main form to the front)

The solution to this was to:

  • Set Params.WndParent to 0 in CreateParams
  • use the ITaskBarList interface to manage the TaskBar tabs. This also adds the windows to the ALT-TAB and WIN-TAB handlers,

TaskBarList.pas

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.

NOTE: I haven't checked the HRESULTS using OleCheck as I would prefer it to fail silently in the field.

灰色世界里的红玫瑰 2024-11-12 16:06:34
  1. 你的子窗体可能是ALWAYS ON TOP FORM
  2. 你可以使用MDI Form(人窗体)和MDI Child form(子窗体)。或者您可以使用 MTI ,查看这篇文章 http://delphi.about.com/b/2010/02/23/tabbed-interface-mti-for-your-mdi-delphi-applications.htm
  1. Your child form may be ALWAYS ON TOP FORM
  2. U can use MDI Form (man form) and MDI Child form (child form). Or u can use MTI , check this article http://delphi.about.com/b/2010/02/23/tabbed-interface-mti-for-your-mdi-delphi-applications.htm
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文