skip to Main Content

I created a new Windows Forms App in Visual Studio and added the following code to it:

new Form1().Show();

By calling this code, the Process.MainWindowHandle of my process, reported by Process.GetProcessById(Environment.ProcessId).MainWindowHandle will be changed to the new Form.

But if I activate the first created form again, the MainWindowHandle will be reported with the initially created form. So, if I’m right, the Process.MainWindowHandle always reports the active form handle and not the initially created form.

I’ve also tried to use a ApplicationContext with defining its MainForm property, but this does not change anything.

How and I define a MainForm in .Net with C#, which handles will be reported by Process.MainWindowHandle always, independent if it’s active or hidden?

2

Answers


  1. Chosen as BEST ANSWER

    Inspired by the comments to my question, I found this solution to get the handle of my MainForm:

    With this code, I will find a windows handle of a process, which answers to a user defined Windows message:

    IntPtr mainFormHandle = IntPtr.Zero;
    foreach (ProcessThread thread in Process.GetProcessById(processId).Threads)
        EnumThreadWindows(
            (uint)thread.Id,
            (hWnd, lParam) =>
            {
                if (SendMessage(hWnd, WM_USER, 0, 0) == TRUE)
                    mainFormHandle = hWnd;
                return TRUE;
            },
            0);
    

    ... if the MainForm was found, the mainFormHandle is set to it's handle.

    To use this code, my MainForm has to answer the sent Windows message:

    protected override void WndProc(ref Message m)
    {
        if (m.Msg == WM_USER)
            m.Result = TRUE;
        else
            base.WndProc(ref m);
    }
    

  2. You could create a statically available Map between names and windows. So, if you want to perform something on a specific window, then you would be able to load that window by name from this Map. This of course means that whenever a window is created, it needs to be reflected into this Map and whenever a window is disposed of, then the Map needs to be adjusted as well.

    As about your actual question, look at this resource: https://learn.microsoft.com/en-us/dotnet/api/system.diagnostics.process.mainwindowhandle?view=net-8.0

    particularly this part:

    The main window is the window opened by the process that currently has the focus (the TopLevel form). You must use the Refresh method to refresh the Process object to get the most up to date main window handle if it has changed. In general, because the window handle is cached, use Refresh beforehand to guarantee that you’ll retrieve the current handle.

    So, whatever refreshes the TopLevel property by focusing the form, such as the Show method that you called will change the main window handle accordingly. If you expect something different to occur instead, then you will need to implement that logic yourself.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search