tags:

views:

648

answers:

3

Got some C# forms/controls that can be called up either from a C# control on a Winform in a Winforms MDI app OR the same C# control used by a PowerBuilder MDI app via COM.

I've been using the WinAPI call SetParent to attach forms to the MDI.

  1. It works (or seemed to) in both environments.
  2. It lets the child window have its own WindowState (Normal, Maximised) instead of taking on that of the child windows already open (which was a real pain).

Say the control is called T. Code on control T calls up form D.

Control T is on form X.
Control T is also on form Y.

In .Net all is well, and form D stays within the MDI.

in PB:
Control T is on PB control PX. Control T is also on PB control PY.

For PX all is well.
For PY, however, there is a problem - form D does not seem to become an MDI child - it can go outside the app and has a taskbar icon. I stress that this is using same objects as the ones that do work. The SetParent is literally the same line of code.

Further research has revealed that SetParent doesn't really work for proper MDI childing - but that's OK(ish) cos we don't need to merge menus etc.

Interestingly, have found that though SetParent seems to 'work', you don't get the handle back if you try GetParent...

Form form = new MyForm();
WindowsMessageHelper.SetParent(form.Handle, MDIParentHandle); //passed down 
int parentHandle = WindowsMessageHelper.GetParent(form.Handle);

parentHandle will always be 0....

Is there any way of making form D behave under all circumstances? My own researches have not been promising. I don't really want to go back and rewrite my forms as controls and have PowerBuilder manage them - mainly becasue there can be multiple instances of each form and PowerBuilder would have to handle that (instead of the controller class/base class I've got doing it in the .net app).

Can I stress that there is NO problem within .Net, the problem only shows up in the PowerBuilder app

A: 

Your child needs to be a System.Windows.Forms.Form, and set its MdiParent property to the MDI Patent window (not its Parent).

The container needs to also follow a few rules.

A read through the MDI instructions on MSDN may help further.


Option two: you may not be able to do this with a single control. Instad consider composition of the core implementation in two wrappers. The first wrapper acts as a WinForms MDI child, the second as a COM wrapper for use under whatever GUI framework PowerBuilder works.

Richard
I have edited the question to hopefully make more clear why this answer does not suffice - your solution is a purely .Net solution, and there is no issue there.
kpollock
I have edited the question to hopefully make more clear why this answer does not suffice - your solution is a purely .Net solution, and there is no issue there.
kpollock
option two is what we have done for the other forms, but it means PB has to control them - anyway see my answer below...
kpollock
A: 

If the only problem you haven't solved yet is GetParent doesn't work you might be able to live with it.

EDIT: but asker has more problems.

There are a number of API pokes that have to be each done in turn to make this work. You will have an easier time making this a user control and placing it on a native MDI parent when using it VIA a COM interface or on a .NET MDI child when placing it in a .NET MDI parent.

There are different base window procedures (DefWindowProc vs DefMdiChildProc) that have to be used here and to make this work you end up implementing DefMdiChildProc.

If you used .NET reflector, you might be able to find a way to cause System.Windows.Forms.Form to call DefMdiChildProc for you.

Joshua
I have edited the question to hopefully make more clear why this answer does not suffice. The SetParent doesn't induce the expected behaviour for form D in the 2nd case.
kpollock
+1  A: 

In the end, we found that the difference was that PB was doing the equivalent of setting .MDIParent for the control PX (the one where calling up form D worked) but not for PY.

Once that was sorted then we were then getting the correct MDIParent handle and all is now well.

kpollock
You might want to accept your own answer.
Joshua
ah - apparently I have to wait 48 hours...
kpollock