ボタンButton1
を押すと、_frm
次のように新しいフォームが開きます。
Protected _frm As Form
[...]
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
_frm = New Form()
AddHandler _frm.Deactivate, AddressOf OnFormDeactivated
AddHandler _frm.FormClosed, AddressOf OnFormClosed
With _frm
.Location = PointToScreen(New Point(0, Height))
.Text = "_frm"
.Show(Me.FindForm)
End With
End Sub
そして、のハンドラDeactivate
とFormClosed
、次のようにイベントが定義されています。
Private Sub OnFormDeactivated(sender As Object, e As EventArgs)
_frm.Close()
End Sub
Private Sub OnFormClosed(sender As Object, e As FormClosedEventArgs)
Me.FindForm.RemoveOwnedForm(_frm)
RemoveHandler _frm.Deactivate, AddressOf OnFormDeactivated
RemoveHandler _frm.FormClosed, AddressOf OnFormClosed
_frm.Dispose()
_frm = Nothing
WindowUtil.ShowWindow(Process.GetCurrentProcess) 'call to user32.dll ShowWindow
WindowUtil.ToForeground(Process.GetCurrentProcess) 'call to user32.dll SetForegroundWindow
End Sub
子フォームを閉じると、親フォームにフォーカスが戻ります。別のアプリケーションを選択した場合も同じことが言えます。これは、目的の動作です。
ただし、親フォーム内の任意の場所をクリックすると、子フォームは正しく表示されなくなりますが、親フォーム(したがってアプリケーション全体)はフォーカスを失います。
編集
WindowUtil.vb
方法:
<DllImport("user32.dll", EntryPoint:="SetForegroundWindow",
CallingConvention:=CallingConvention.StdCall,
CharSet:=CharSet.Unicode, SetLastError:=True)>
Private Shared Function SetForegroundWindow(ByVal handle As IntPtr) As Boolean
End Function
Public Shared Sub ToForeground(proc As Process)
Dim ForegroundReturn As Boolean = SetForegroundWindow(proc.MainWindowHandle)
End Sub
<DllImport("user32.dll", EntryPoint:="ShowWindow",
CallingConvention:=CallingConvention.StdCall,
CharSet:=CharSet.Unicode, SetLastError:=True)>
Private Shared Function ShowWindow(ByVal handle As IntPtr, ByVal nCmd As Int32) As Boolean
End Function
Public Shared Sub ShowWindow(proc As Process)
Dim ShowReturn As Boolean = ShowWindow(proc.MainWindowHandle, 1)
End Sub
BringToFront()
/Activate()
メソッドの呼び出しとForm.Close()
所有されているフォームを閉じる呼び出しの間に遅延を追加することをお勧めします。所有者フォームをクリックしたときと別のアプリケーションに属するウィンドウをクリックしたときの両方の状況でより安定した結果が得られるはずです。
注として:
そのため、PInvokingは必要ありません(つまり、フレームワークはすでにこれを行っています)。
Form.Close()
所有者フォームのアクティブ化後に呼び出されます。これにより、ActiveControl
このプロパティを明示的に設定せずに、マウスアクションを受け取るコントロール(所有者フォーム内)がになります。
►フォーム15
の性質(フォームの作成方法と含まれるコントロールの数)が閉じる必要のある時間に影響を与える可能性があるため、ミリ秒の遅延は微調整できます(OwnerForm.Activate()
asyncActivateForm()
メソッドから戻る直前に呼び出されてフォームがオンになるため)トップは直後に閉じられます)。これにより、よりスムーズな遷移が生成されますが、別のプロセスに属するウィンドウをクリックしたときに所有者フォームが点滅する場合もあります。
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
' someForm is clearly a made-up class name :) Set it to actual the class name.
Dim frm As New someForm()
AddHandler frm.Deactivate, AddressOf OnFormDeactivated
With frm
' Whatever this means to you
.Location = PointToScreen(New Point(0, Height))
.Text = "frm"
.Show(Me)
End With
End Sub
Private Async Sub OnFormDeactivated(sender As Object, e As EventArgs)
Dim frm = DirectCast(sender, Form)
RemoveHandler frm.Deactivate, AddressOf OnFormDeactivated
Await ActivateForm(Me)
frm.Close()
End Sub
Private Async Function ActivateForm(frm As Form) As Task
Await Task.Delay(15)
frm.BringToFront()
Await Task.Delay(15)
frm.Activate()
End Function
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加