Uso de API SetParen...
 
Notifications
Clear all

Uso de API SetParent da Dll User32

4 Posts
2 Usuários
0 Reactions
1,080 Visualizações
(@mikel-silveira-fraga)
Posts: 41
Trusted Member
Topic starter
 

Bom dia moçada, blz.

Estou quebrando a cabeça na tentativa de utilizar a API SetParent, da dll User32, entre dois UserForms.

Estou necessitando abrir um formulário (UserForm1) com um subformulário (UserForm2), da mesma forma que ocorre dentro do Access.

Já vi este tipo de operação ser realizada dentro do Delphi, mas não estou conseguindo utilizá-la nos UserForms do Excel/VBA.

Alguém tem conhecimento mais acirrado sobre API´s, de forma que possa me dar uma força?

Segue o link de um modelo ao qual estou tentando adaptar, conforme descrição acima:
http://www.cpearson.com/excel/SetParent.aspx

Aguardo o retorno.

Abraço a todos.

 
Postado : 19/02/2014 6:43 am
(@fernandofernandes)
Posts: 43750
Illustrious Member
 

O uso de APIs não é minha praia, mas pelo que vi do código referenciado, o mesmo vota-se para form vs aplicação e não form vs form.
O uso de formulários e subformulários no Access e Delphi são "controlados" pelas funcionalidades da própria aplicação (Access ou Delphi), e não manipulação(pelo menos explicita) de APIs do sistema operacional.
No Excel VBA não tem (até onde sei) essa funcionalidade. Porem dependendo do que deseja; pode ser que seja possível uma adaptação.

 
Postado : 19/02/2014 7:57 am
(@mikel-silveira-fraga)
Posts: 41
Trusted Member
Topic starter
 

Ronaldo, obrigado pelo retorno.

Lhe agradeci mais cedo, mas somente agora pude lhe responder, mais valeu a pena. Consegui resolver o problema.

No modelo em anexo, eu criei dois UserForms.

No Userform1, criei um evento ao inicializar, para que o UserForm2 também fosse aberto:

Private Sub UserForm_Initialize()
    UserForm2.Show vbModeless
End Sub

Já no UserForm2, adicionei o código do link acima, mas fiz algumas modificações, de forma que ficou resumida:

Private Declare Function SetParent Lib "user32" ( _
    ByVal hWndChild As Long, _
    ByVal hWndNewParent As Long) As Long

Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" _
    (ByVal lpClassName As String, _
    ByVal lpWindowName As String) As Long
    
Private Sub UserForm_Initialize()

    Const C_VBA6_USERFORM_CLASSNAME = "ThunderDFrame"
    Dim MeHWnd As Long
    Dim OrHWnd As Long
    Dim Res As Long
    
    ' get the window handle of the userform
    MeHWnd = FindWindow(C_VBA6_USERFORM_CLASSNAME, Me.Caption)
    OrHWnd = FindWindow(C_VBA6_USERFORM_CLASSNAME, UserForm1.Caption)
    
    If (MeHWnd > 0) And (OrHWnd > 0) Then
         ' make the userform a child window of the ActiveWindow
         Res = SetParent(MeHWnd, OrHWnd)
         If Res = 0 Then
             ''''''''''''''''''''
             ' an error occurred.
             ''''''''''''''''''''
             MsgBox "The call to SetParent failed."
         End If
    End If

End Sub

Como pode ser observado, foi mantida as declarações das API´s, FindWindow e SetParent.
Pelo que percebi, a FindWindow captura um identificador para os formulários, aplicativos e janelas, em geral.

Também mantive as variáveis C_VBA6_USERFORM_CLASSNAME,MeHWnd e Res, além de adicionar a variável OrHWnd.
No caso, a variável C_VBA6_USERFORM_CLASSNAME vai identificar que o tipo de aplicativo que será lido pelo FindWindow. Neste caso, ele informa que é um UserForm do VBA6.
As variáveis MeHWnd e OrHWnd, irão capturar as identificações (valores) dos formulários, através da API FindWindow, conforme abaixo:

    MeHWnd = FindWindow(C_VBA6_USERFORM_CLASSNAME, Me.Caption) 'Valor do UserForm2.
    OrHWnd = FindWindow(C_VBA6_USERFORM_CLASSNAME, UserForm1.Caption) 'Valor do UserForm1.

Após estas duas variáveis serem preenchidas, a variável Res irá receber o valor do comando SetParent, que é gerado a partir das variáveis MeHWnd e OrHWnd. Como resultado, o UserForm2 é aberto dentro do UserForm1, conforme pode ser visto do anexo.

Não sei se a explicação ficou muito clara, mas espero que este tópico possa ajudar quem se interessar pelo assunto.

Obrigado Ronaldo e a todos do fórum.

 
Postado : 19/02/2014 9:47 am
(@fernandofernandes)
Posts: 43750
Illustrious Member
 

Caso seja necessário reabrir o tópico, o autor poderá enviar uma MP para um dos moderadores solicitando o desbloqueio.

 
Postado : 19/02/2014 10:00 am