简体   繁体   中英

Set focus to new popup winform

I have an app that runs in the system tray and when a user presses a combation of buttons it displays a WinForm to be filled out and sends an email. Everything works great but the part when the WinForm is displayed. It shows on top and the focus appears to be on the text box but the window is not active.

Code used to to call the Popup form.

My.Forms.frmpopup.ShowDialog()

Code on the Popup Form

Private Sub frmPopup_Shown(sender As Object, e As EventArgs) Handles Me.Shown
    Activate()
    BringToFront()
End Sub

Private Sub frmPopup_Load(sender As Object, e As EventArgs) Handles Me.Load
    TextBoxName.Focus()
End Sub

The real kick in the pants is that this works as long as the user is not currently focused on an Internet Explorer Window. If I find a solution I'll post it.


It appears merging the two Subs into a single sub fixes the issue, I'll continue to test.

Private Sub frmPopup_Shown(sender As Object, e As EventArgs) Handles Me.Shown Activate() BringToFront() TextBoxName.Focus() End Sub

Make sure your application has focus as well...

Include the following import...

<Runtime.InteropServices.DllImport("user32.dll", SetLastError:=True, CharSet:=Runtime.InteropServices.CharSet.Auto)> _
Private Shared Function SetForegroundWindow(ByVal hWnd As IntPtr) As Long
End Function

And before you call the pop-up, or from within the pop-up LOAD event, call

SetForegroundWindow(Me.Handle)

SendToTop(true) should bring the window to TopMost.

Private Const SWP_NOSIZE As Integer = &H1
Private Const SWP_NOMOVE As Integer = &H2

Private Shared ReadOnly HWND_TOPMOST As New IntPtr(-1)
Private Shared ReadOnly HWND_NOTOPMOST As New IntPtr(-2)
Public Declare Function SetWindowPos Lib "user32" (ByVal hWnd As IntPtr, ByVal hWndInsertAfter As IntPtr, ByVal X As Integer, ByVal Y As Integer, ByVal cx As Integer, ByVal cy As Integer, ByVal uFlags As Integer) As Boolean

Public Sub SendToTop(toTop As Boolean)
    If toTop Then
        SetWindowPos(Me.Handle, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE Or SWP_NOSIZE)
    Else
        SetWindowPos(Me.Handle, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOSIZE Or SWP_NOMOVE)
    End If
End Sub

just use Active(); on the popup load event

In my use-case* the following showed the desired result:

popup.Show();
popup.Activate();

where popup: Form . Not sure why you have to call the Activate() after the Show() method, but that proved to be working correctly.


Use-case

My use-case was showing popup along with the loader form. Both the popup and the loader are top level forms and are triggered with the ShowDialog() method. They are executed in separate threads with the idea that loader form is displayed while the popup form is fetching its data. Once the long operation (ie fetching) is completed, the loader form closes and the popup form is shown.

Everything was working as described, except that the popup was not focused after the loader closes.

The given two lines of code are solving my problem and now everything is working as expected.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM