ExcelVBA技 ユーザーフォーム E13U010

E13U010 (Excel2000~2013)
複数ウィンドウを親子の関係にする

複数ウィンドウを親子の関係とは?
エクセルでユーザーフォームをモードレスで表示した場合の、エクセル本体ウィンドウとユーザーフォームウィンドウの関係が該当します。 親と子のウィンドウをそれぞれ切替えて操作出来て子ウィンドウは常に親ウィンドウの前面に表示されます。親ウィンドウを閉じると子ウィンドウも連携して自動的に閉じられます。
複数のモードレスユーザーフォームを表示した場合に親子の関係にする例を示します。

'標準モジュール
Option Explicit

'kParentChild関数の使用例 ユーザーフォームを表示
'UserForm1とUserForm2を配置、UserForm1にCommandButton1を配置
Sub example_e13u010()
  UserForm1.Show vbModeless
End Sub
'フォーム モジュール
Option Explicit
#If VBA7 And Win64 Then
Private Declare PtrSafe Function WindowFromObject Lib "oleacc" Alias "WindowFromAccessibleObject" _
  (ByVal pacc As Object, phwnd As LongPtr) As LongPtr
Private Declare PtrSafe Function SetWindowLong Lib "user32" Alias "SetWindowLongPtrA" _
  (ByVal hwnd As LongPtr, ByVal nIndex As Long, ByVal dwNewLong As LongPtr) As LongPtr
#Else
Private Declare Function WindowFromObject Lib "oleacc" Alias "WindowFromAccessibleObject" _
  (ByVal pacc As Object, phwnd As Long) As Long
Private Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" _
  (ByVal hwnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
  #End If
Const GWL_HWNDPARENT = (-8)

'kParentChild関数
'2つのウィンドウを親子の関係にする
Function kParentChild(Parent As Object, Child As Object) As Long
  Dim wnd1, wnd2
  WindowFromObject Parent, wnd1
  WindowFromObject Child, wnd2
  'wnd2をwnd1の子にする
  SetWindowLong wnd2, GWL_HWNDPARENT, wnd1
End Function

'kParentChild関数の使用例
'UserForm1とUserForm2を配置、UserForm1にCommandButton1を配置
Private Sub CommandButton1_Click()
  Dim Child As New UserForm2 '子とするUserForm
  With Child '子UserFormの位置設定例
    .StartUpPosition = 0
    .Top = Top + 50
    .Left = Left + 50
    .Show vbModeless
  End With
  'UserForm2をMeの子にする
  kParentChild Me, Child
End Sub