Solved

MDI Child window z-order

Posted on 2003-11-30
4
1,609 Views
Last Modified: 2010-04-05
If I create an MDI form and place, say, a TPanel on it, then open an MDI Child form, the MDI child form appears *behind* the panel.

Is there a way around this, i.e. so that the panel appears behind the MDI child form? I have had a bit of a fiddle with SetWindowPos() but no luck so far.
0
Comment
Question by:PhilipRayment
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 2
  • 2
4 Comments
 
LVL 27

Expert Comment

by:kretzschmar
ID: 9848615
this is not possible,

mdi-Childs can only showed in the uncovered
client-area of the mdi-mainform

meikl ;-)
0
 
LVL 1

Author Comment

by:PhilipRayment
ID: 9849944
meikl wrote:
>>mdi-Childs can only showed in the uncovered client-area of the mdi-mainform<<

Thanks for responding, but could you please explain/elaborate on this?

I know that MDI Child forms can only be shown on the client area of the MDI main form, but what do you mean by the "uncovered" client area?  I can "cover" part of the MDI main form with a non-windows control (e.g. TLabel) and the MDI Child window will show in front of it.  I can also "cover" part of the MDI main form with a windowed control (e.g. TPanel) and show an MDI Child window there, it's just that the TPanel shows in front of the MDI Child window.

I realise that there is a difference between windowed and non-windowed controls, in that the former have a windows handle.  But so do MDI Child windows, so I would have thought that I could manipulate the relative order of the two.
0
 
LVL 27

Accepted Solution

by:
kretzschmar earned 100 total points
ID: 9856651
let me explain it as metapher

a mdi-mainform is like a car-truck
(a truck (main) loaded with cars (childs))

usual by this kind of truck the loading area is open
(any people can look and touch the cars on the loading area)

you will now cover this loading area, and you will have
now the problem that no people can
look and touch the cars on the loading area.

and because of this, you will now place the cars on the
cover, which is impossible, because the cars will
fall down from the cover.

so far the matapher, back to the os.

simplified explaination

mdi is a special os-gui, which has defined rules,
and specialized messages to keep care of the
organization of this kind of gui. these special messages
are only sent to the main-window, which dispatches it to the
its childs, if needed.

a panel cannot do this job (it will never receives these messages),
because it is not the main-window of the app.

but well, there is a workaround,
a pseudo mdi-like app
(formstyle is allways fsNormal)

-----  mainform
unit mdi_child_on_panel_main_u;

interface

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

type
  TForm1 = class(TForm)
    Panel1: TPanel;
    Panel2: TPanel;
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

uses
  mdi_child_on_panel_child_u; //where the child is defined

procedure TForm1.Button1Click(Sender: TObject);
begin
  with tform2.create(self) do
  begin
    parent := panel2;
    show;
    PostMessage(Handle, WM_NCACTIVATE, 1, 0);  //get the caption activated of the child
  end;
end;

end.

------ the child

unit mdi_child_on_panel_child_u;

interface

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

type
  TForm2 = class(TForm)
    Button1: TButton;
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
    procedure CMMouseEnter(var Msg: TMessage); message CM_MOUSEENTER;
  public
    { Public declarations }
  end;

var
  Form2: TForm2;

implementation

{$R *.dfm}

procedure TForm2.CMMouseEnter(var Msg: TMessage);
begin
  PostMessage(Handle, WM_NCACTIVATE, 1, 0);
end;

procedure TForm2.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  action := caFree;
end;

procedure TForm2.Button1Click(Sender: TObject);
begin
  close;
end;

end.

------- end paste

you may notice, that there are some fallbacks by doing so,
which causes in additional codings, to get the original mdi-bahaviour
implemented.


hope this clarifies a bit

meikl ;-)
0
 
LVL 1

Author Comment

by:PhilipRayment
ID: 9888330
Thanks for your help meikl.  I have experimented a bit more, including trying out your workaround.  I might use it, or I might use a non-windowed control and add some functionality to that.

I am now figuring that the problem is that Windows maintains the MDI child window z-order stack to be immediately in front of the MDI form.  That is, the child window behind all other child windows must always have a z-order placing it immediately in front of the MDI form itself.  What I was wanting was a panel to be placed between the MDI form and the MDI child, and it seems Windows just doesn't allow for that.  Non-windowed controls are different in that Delphi simply paints the image of them directly onto the MDI form's canvas; they are not really separate entities, as far as Windows is concerned.
0

Featured Post

Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
find a node in VST 2 89
Breakpoint doesn't stop in my variable 3 45
How to Get Images From Server to Client using App Tethering 1 53
Delphi Seattle StructureView color 1 30
The uses clause is one of those things that just tends to grow and grow. Most of the time this is in the main form, as it's from this form that all others are called. If you have a big application (including many forms), the uses clause in the in…
Introduction The parallel port is a very commonly known port, it was widely used to connect a printer to the PC, if you look at the back of your computer, for those who don't have newer computers, there will be a port with 25 pins and a small print…
I've attached the XLSM Excel spreadsheet I used in the video and also text files containing the macros used below. https://filedb.experts-exchange.com/incoming/2017/03_w12/1151775/Permutations.txt https://filedb.experts-exchange.com/incoming/201…
Attackers love to prey on accounts that have privileges. Reducing privileged accounts and protecting privileged accounts therefore is paramount. Users, groups, and service accounts need to be protected to help protect the entire Active Directory …

738 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question