Oui, c'est vrai, avec plusieurs boutons ça ne marche pas

C'est possible de contourner le problème avec du subclassing (pour empêcher VB de recevoir l'événement LostFocus). Rajoute un module standard avec ce code :
Private Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
Private Declare Function GetProp Lib "user32" Alias "GetPropA" (ByVal hwnd As Long, ByVal lpString As String) As Long
Private Declare Function SetProp Lib "user32" Alias "SetPropA" (ByVal hwnd As Long, ByVal lpString As String, ByVal hData As Long) As Long
Private Declare Function RemoveProp Lib "user32" Alias "RemovePropA" (ByVal hwnd As Long, ByVal lpString As String) As Long
Private Declare Function CallWindowProc Lib "user32" Alias "CallWindowProcA" (ByVal lpPrevWndFunc As Long, ByVal hwnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Const GWL_WNDPROC = -4, WM_DESTROY = &H2, WM_SETFOCUS = &H7
Public Sub Subclass(hwnd As Long)
Dim OldProc As Long
'Capture tous les événements reçus par le bouton
OldProc = SetWindowLong(hwnd, GWL_WNDPROC, AddressOf WinProc)
SetProp hwnd, "OLDWPROC", OldProc
End Sub
Private Function WinProc(ByVal hwnd As Long, ByVal uMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Dim OldProc As Long
OldProc = GetProp(hwnd, "OLDWPROC")
If uMsg = WM_DESTROY Then 'Fait le ménage avant la fermeture
SetWindowLong hwnd, GWL_WNDPROC, OldProc
RemoveProp hwnd, "OLDWPROC"
End If
'Tous les événements sont transmis à vb sauf WM_SETFOCUS
If uMsg <> WM_SETFOCUS Then WinProc = CallWindowProc(OldProc, hwnd, uMsg, wParam, lParam)
End Function
Puis dans le code de création du bouton
With ButModif
...
Subclass .hwnd End With
Bon, finalement, la solution de Kristof_Koder avec les groupes de contrôles était beaucoup plus simple...