thunderxframe ou thunderDframeComment savoir si ce Handle est celui d'un UserForm ou pas ? Par le ClassName ? Autre ?
Public Declare Function GetForegroundWindow Lib "user32" _
Alias "GetForegroundWindow" () As Long
Public Declare Function GetWindowText Lib "user32" _
Alias "GetWindowTextA" (ByVal hwnd As Long, _
ByVal lpString As String, ByVal cch As Long) As Long
Sub RecupNomActiveWindow()
Dim WinText As String
Dim HWnd As Long
Dim L As Long
HWnd = GetForegroundWindow()
WinText = String(255, vbNullChar)
L = GetWindowText(HWnd, WinText, 255)
WinText = Left(WinText, InStr(1, WinText, vbNullChar) - 1)
Debug.Print L, WinText
End Sub
thunderxframe ou thunderDframeComment savoir si ce Handle est celui d'un UserForm ou pas ? Par le ClassName ? Autre ?
Le but est assez complexe, il s'agit, pour un utilitaire utilisant lui-même un UserForm de savoir, lorsqu'il est demandé d'exclure des interactions extérieures quand il est affiché, s'il doit se placer en vbModeless + Interactive = False car appelé directement ou en vbModal sur un UserForm vbModeles qui l'appelle, sachant que sur un UserForm vbModal il ne peut se placer lui-même qu'en vbModal. Alors il faut que je sache qui l'appelle car que je veux privilégier le vbModeless qui me permet de faire des choses comme boucler pour faire un timer ou capter des sélections sur feuille alors que le UserForm est affiché.
Option Explicit
Public QUI
Public Function ShowX(parmoi, Optional ByVal vbmode = 1)
With UserForm1
Set .QUI = parmoi
.Show vbmode
End With
End Function
Private Sub UserForm_Activate()
MsgBox "Hallo!!! c'est " & QUI.Name & " qui appelle"
End Sub
Private Sub CommandButton1_Click()
UserForm1.ShowX Me, 1
End Sub
Private Declare PtrSafe Function GetActiveWindow Lib "user32.dll" () As LongPtr
Private Declare PtrSafe Function GetClassName Lib "user32" Alias "GetClassNameA" (ByVal hWnd As LongPtr, ByVal lpClassName As String, ByVal nMaxCount As Long) As Long
'--------------------------------------------------
'Retourne True si le Handle est celui d'un UserForm
'--------------------------------------------------
Function CallerIsUserForm(Optional ByVal hWndCaller As LongPtr = 0) As Boolean
Dim Class As String
If hWndCaller = 0 Then hWndCaller = GetActiveWindow
Class = Space$(255)
Call GetClassName(hWndCaller, Class, Len(Class))
Class = UCase(Left(Class, InStr(Class, Chr(0)) - 1))
If Class = "THUNDERDFRAME" Or Class = "THUNDERXFRAME" Then
'Return value
CallerIsUserForm = True
End If
End Function
Private Declare PtrSafe Function GetActiveWindow Lib "user32.dll" () As LongPtr
Private Declare PtrSafe Function GetClassName Lib "user32" Alias "GetClassNameA" (ByVal hWnd As LongPtr, ByVal lpClassName As String, ByVal nMaxCount As Long) As Long
Private AppelantEstUserForm As Boolean
Public Sub Display(Optional ByVal ShowMode As Integer = vbModal)
AppelantEstUserForm = CallerIsUserForm
Me.Show ShowMode
End Sub
reEt à toutes fins utiles, une petite fonction pour terminer...
VB:Private Declare PtrSafe Function GetActiveWindow Lib "user32.dll" () As LongPtr Private Declare PtrSafe Function GetClassName Lib "user32" Alias "GetClassNameA" (ByVal hWnd As LongPtr, ByVal lpClassName As String, ByVal nMaxCount As Long) As Long '-------------------------------------------------- 'Retourne True si le Handle est celui d'un UserForm '-------------------------------------------------- Function CallerIsUserForm(Optional ByVal hWndCaller As LongPtr = 0) As Boolean Dim Class As String If hWndCaller = 0 Then hWndCaller = GetActiveWindow Class = Space$(255) Call GetClassName(hWndCaller, Class, Len(Class)) Class = UCase(Left(Class, InStr(Class, Chr(0)) - 1)) If Class = "THUNDERDFRAME" Or Class = "THUNDERXFRAME" Then 'Return value CallerIsUserForm = True End If End Function
Edit: Et comme le précise @patricktoulon dans le message suivant, si on appelle cette fonction d'un UserForm pour savoir qui veut l'afficher, il faut intercepter le Handle de l'appelant AVANT le UserForm_Activate() car Excel ne donnera pas un UserForm appelant comme Parent du UserForm appelé, ce qui exclut de le retrouver avec l'API GetParent() !
Ce qui revient à devoir écrire une procédure Public dans le UserForm de type:
Et au lieu de faire UserForm1.Show, faire UserForm1.Display (avec le paramètre Mode éventuel)VB:Private Declare PtrSafe Function GetActiveWindow Lib "user32.dll" () As LongPtr Private Declare PtrSafe Function GetClassName Lib "user32" Alias "GetClassNameA" (ByVal hWnd As LongPtr, ByVal lpClassName As String, ByVal nMaxCount As Long) As Long Private AppelantEstUserForm As Boolean Public Sub Display(Optional ByVal ShowMode As Integer = vbModal) AppelantEstUserForm = CallerIsUserForm Me.Show ShowMode End Sub