MDI Child window z-order

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.
LVL 1
PhilipRaymentAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

kretzschmarCommented:
this is not possible,

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

meikl ;-)
0
PhilipRaymentAuthor Commented:
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
kretzschmarCommented:
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

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
PhilipRaymentAuthor Commented:
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
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Delphi

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.