Windows Develop Bookmark and Share   
 index > Windows Forms General > How to set owner of a form to a form in a different process
 

How to set owner of a form to a form in a different process

Hi,
I have a process that contains a form. This process creates another process that has its own form. I want to set the owner of the child process form to be the form of the parent process. Is it possible?
BTW, the reason I want to do it is that I want the second form to always be on top of the parent form. Is there any other way to guarantee this without setting the owner form (I don't want to use top-most windows...)?.
Thanks,
Alon.
Alonbo  Sunday, October 04, 2009 8:28 AM
You might want to try to SetParent function.

See pinvoke.net for a good example on how to platform invoke the SetParent function.
Geert van Horrik - CatenaLogic
Visit my blog: http://blog.catenalogic.com

Looking for a way to deploy your updates to all your clients? Try Updater!
Geert van Horrik  Sunday, October 04, 2009 9:47 AM
You might want to try to SetParent function.

See pinvoke.net for a good example on how to platform invoke the SetParent function.
Geert van Horrik - CatenaLogic
Visit my blog: http://blog.catenalogic.com

Looking for a way to deploy your updates to all your clients? Try Updater!
Geert van Horrik  Sunday, October 04, 2009 9:47 AM
What you are trying to do is strictly forbidden by the Windows SDK docs, the parent window must belong to the same process.  There are however app compat hacks in Windows that might make it work for you.  They were designed to support Windows 3.x programs where this wasn't a problem because 3.x didn't support multitasking.  Specifically Office programs are known to not support this.  You'll have to try.

Hans Passant.
nobugz  Sunday, October 04, 2009 12:41 PM
OK, so if it is forbidden, how can I assure that form A (created by process A) is always on top of Form B (created by process B) without using TopMost property?
Alonbo  Sunday, October 04, 2009 2:18 PM

As far as I know, using SetParent with handles from different processes is an undocumented feature and not allowed by Microsft.

Alonbo  Sunday, October 04, 2009 2:20 PM

Hi Alon,

Since you didn't say when the form created by the child process is on top of the "parent" form, should or should not the parent form being able to have input focus, here I assume what you want is something works like a modal dialog. The following code starts a Notepad process, and makes sure the Notepad window is always in front of the MainForm. The basic idea is to intercept the activate messages of the MainForm, insert the MainForm after the Notepad window in the Z order and set the Notepad window foreground.

public partial class MainForm : Form
{
    [DllImport("user32.dll")]
    private static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, uint uFlags);

    [DllImport("user32.dll")]
    private static extern bool SetForegroundWindow(IntPtr hWnd);

    [DllImport("user32.dll")]
    private static extern bool ReleaseCapture();

    private const uint SWP_NOSIZE = 0x0001;
    private const uint SWP_NOMOVE = 0x0002;

    private const int WM_ACTIVATE = 0x0006;
    private const int WM_MOUSEACTIVATE = 0x0021;
    private const int MA_NOACTIVATEANDEAT = 4;

    public MainForm()
    {
        InitializeComponent();
    }

    Process notepad = null;

    private void MainForm_Load(object sender, EventArgs e)
    {
        notepad = Process.Start("notepad.exe");
        notepad.WaitForInputIdle();
    }

    protected override void WndProc(ref Message m)
    {
        switch (m.Msg)
        {
            case WM_MOUSEACTIVATE:
                SetBehind();
                m.Result = new IntPtr(MA_NOACTIVATEANDEAT);
                return;

            case WM_ACTIVATE:
                SetBehind();
                m.Result = IntPtr.Zero;
                return;
        }

        base.WndProc(ref m);
    }

    private void SetBehind()
    {
        if (notepad != null &&
            !notepad.HasExited)
        {
            ReleaseCapture();
            SetWindowPos(this.Handle,
                notepad.MainWindowHandle,
                0, 0, 0, 0,
                SWP_NOSIZE | SWP_NOMOVE);
            SetForegroundWindow(notepad.MainWindowHandle);
        }
    }
}

Please let me know if this is what you want.

Regards,
Jie
MSDN Subscriber Support in Forum
If you have any feedback on our support, please contact msdnmg[at]microsoft.com


Please remember to mark the replies as answers if they help and unmark them if they provide no help.

If you have any feedback, please tell us.

The CodeFx Project
My Blog (in Simplified Chinese)
Wang, Jie  Monday, October 05, 2009 7:43 AM
What you are trying to do is strictly forbidden by the Windows SDK docs, the parent window must belong to the same process.  There are however app compat hacks in Windows that might make it work for you.  They were designed to support Windows 3.x programs where this wasn't a problem because 3.x didn't support multitasking.  Specifically Office programs are known to not support this.  You'll have to try.

Hans Passant.

Then shall we unmark Geert's SetParent solution as an answer?
Please remember to mark the replies as answers if they help and unmark them if they provide no help.

If you have any feedback, please tell us.

The CodeFx Project
My Blog (in Simplified Chinese)
Wang, Jie  Monday, October 05, 2009 7:45 AM

Hi Jie,

Thanks for your reply. I like your solution but I think something is still missing in my case-

I know that there are more messages for activating the window (other than the two you've mentioned in your code).

Do you know where can I find more information on these missing messages?

Thanks in advance,

Alon.

 

Alonbo  Tuesday, October 06, 2009 9:11 AM
Hi Alon,

Another message I can think of is WM_ACTIVATEAPP.

Yes, I've only tested the sample code with mouse and keyboard, not 100% sure if it works fine with other input devices (pen? touch?).

You may also want to check the description of WM_ACTIVATE and WM_MOUSEACTIVATE, making sure they covers your requirements or not.

The links to the MSDN Library online contains all the messages and you can find out more from there.

Hope this helps.

Regards,
Jie
MSDN Subscriber Support in Forum
If you have any feedback on our support, please contact msdnmg[at]microsoft.com
Please remember to mark the replies as answers if they help and unmark them if they provide no help.

If you have any feedback, please tell us.

The CodeFx Project
My Blog (in Simplified Chinese)
Wang, Jie  Tuesday, October 06, 2009 10:29 AM
Hi Jie,
I found a problem with your suggestion:
When FormA is the real parent of FormB (this was my intention from the first place) - they are always 'attached', meanning nothing can come between them.
The following scenario (using your suggestion) cause a third form to come between the first two:
1. run the sample (both form and notepad are opened)
2. run windows explorer
3. put windows explorer on top of the first two forms.
4. switch to notepad
  -->windows explorer is located between the two forms

I need that the form and notepad to always come together and if notepad is selected - the original form jumps (in Z order) to be behind notepad.

any suggestion?
Thanks,
Alon.


Alonbo  Tuesday, October 06, 2009 3:04 PM

Hi Alon,

Yes, I'm aware of that. If we were working on a native C/C++ project, then we can use hooks to monitor the child process and make sure the two windows stick together. However, we can't do that in .NET because we don't want to inject CLR into other processes.

I can't think of a better solution right now. Althought the word "Timer" is hopping up and down somewhere in my mind, I don't want to do that ugly workaround - periodically check the Z order and fix it if some other window is inserted between our windows.

Or if you have control over the child application, maybe making some changes to the child app code so it will be aware of the parent app can also solve the problem.

Regards,
Jie
MSDN Subscriber Support in Forum
If you have any feedback on our support, please contact msdnmg[at]microsoft.com


Please remember to mark the replies as answers if they help and unmark them if they provide no help.

If you have any feedback, please tell us.

The CodeFx Project
My Blog (in Simplified Chinese)
Wang, Jie  Wednesday, October 07, 2009 9:11 AM
Hi,
Does SetWindowPos ensures that when it sets Z order of a window - it is right beneath the other window? if so, I can (as you said) - create a C/C++ 'server' that ensures the Z order of the windows (hooks to the applications and 'listens' to WM_ACTIVATEAPP or something like this).
Thanks,
Alon.

Alonbo  20 hours 3 minutes ago

You can use google to search for other answers

Custom Search

More Threads

• HelpProvider relation by topic
• UI types
• Toggle from excel to windows form not wokring
• deploying vb.net class library for VB6 application
• Property Grid Custom Tab Focus.
• Strange RichTextBox.Select(0,x) Problem / Bug?
• Deleting projects from visual studio's start page
• Interact with Windows forms (.net 2.0) from Access 2003
• Tab Control in c# using ado.net
• PROBLEM why will a one click vb.net app work on one computer but not completly on another