Home > Software engineering >  Child form opened from external thread losing focus on start
Child form opened from external thread losing focus on start

Time:08-16

I have a form application that listenes a named pipeline. When message arrives from pipeline, it launches a new child form. But child form loses focus.

This is where i handle new message from named pipe:

private void OnMessage(CommunicationObject message)
    {
        switch (message.MessageType)
        {
            case MessageTypes.Pop:
                {
                    if (isLoginSessionActive) return;

                    StartSTATask(() =>
                    {
                        OpenLoginSession();
                    });

                    break;
                }
        }
    }

And this is OpenLoginSession method:

private void OpenLoginSession()
    {
        loginForm = new LoginForm(clientPipe);

        loginForm.FormClosing  = (ss, ee) =>
        {
            ee.Cancel = !loginSuccessful;
        };

        loginForm.FormClosed  = (ss, ee) =>
        {
            isLoginSessionActive = false;
            loginForm = null;
        };

        loginForm.Shown  = (ss, ee) =>
        {
            this.InvokeIfRequired(() =>
            {
                loginForm.WindowState = FormWindowState.Maximized;
                loginForm.Activate();
                loginForm.BringToFront();
                loginForm.Focus();
                loginForm.TxtUsername.Focus();
            });
        };

        loginForm.ShowDialog();
    }

This is StartSTATask method:

private Task StartSTATask(Action func)
    {
        var tcs = new TaskCompletionSource<object>();

        Thread thread = new Thread(() =>
        {
            func();
            tcs.SetResult(null);
        });

        thread.SetApartmentState(ApartmentState.STA);
        thread.Start();

        return tcs.Task;
    }

I tried many methods but no result.

Thanks.

CodePudding user response:

Ok i did it with mouse_event by clicking on textbox. Here is the code if anyone needs it.

  • First i get current cursor location,

  • Second i set cursor location to textbox pointtoscreen,

  • I simulate mouse click with

    [DllImport("user32.dll")] private static extern void mouse_event(int dwFlags, int dx, int dy, int dwData, int dwExtraInfo);

  • Then i set cursor location to previous location.

  • Related