Criando Controles em tempo de execução


Olhe bem para o formulário da figura 1.0. O que você esta vendo ? Somente o formulário e nada mais, certo ? Eu asseguro que não há nenhum controle escondido e que temos somente este formulário no projeto. Olhou bem ?

Agora olhe a figura 2.0 ; Este é o resultado da execução do projeto exibido na figura 1.0 . O que há de diferente ? Um botão de comando !!, pois bem . Como ele surgiu no formulário ? Será que é mesmo um botão de comando ? Clicando nele obtemos a figura 3.0 . É realmente um botão de comando que disparou uma mensagem ao ser clicado . Como ????

Fig 1.0 - O formulário do projeto  Fig 2.0 - O resultado do processamento

 

fig 3.0 - O resultado ao se clicar o botão de comando

 Vamos dar uma expiada no código do formulário. Vejamos:

Option Explicit
Private WithEvents btnObj As CommandButton

Private Sub btnObj_Click()
 
MsgBox "
Eu sou um botão incluido dinamicamento em tempo de execução...", vbInformation, "Botão Dinâmico"
End Sub

Private Sub Form_Load()
 
Set btnObj = Controls.Add("VB.CommandButton", "btnObj")
  Form1.Caption = "Criando controles"
  With btnObj
     .Visible = True
     .Width = 2000
     .Caption = "Olá Pessoal !!!"
     .Top = 500
     .Left = 1200
  End With
End Sub

Vejamos o que este código faz :

Ele declara uma variável objeto ( btnObj ) do tipo CommandButton usando a palavra chave WithEvents. Isto permite programar os eventos do controle.(No caso usamos somente o evento Click)

A variável objeto é definida para a referência retornada pelo método Add - ( Set btnObj = Controls.Add("VB.CommandButton", "btnObj")

O resto do código apenas dá título ao formulário e define as dimensões e a posição do controle commandbutton  no formulário.

Conclusão : - "Podemos facilmente criar controles em nossos projetos em tempo de execução ! ". Uauuu...

Não acredita ? Então insira o seguinte código na secção General Declarations do formulário :

Dim WithEvents ctlDynamic As VBControlExtender
Dim WithEvents ctlText As VB.TextBox
Dim WithEvents ctlcombo As VB.ComboBox

A seguir insira o seguinte código no evento Load do formulário:

Set ctlText = Controls.Add("VB.TextBox", "ctText")
Set ctlcombo = Controls.Add("VB.ComboBox", "ctlcombo")
Set ctllabel = Controls.Add("VB.Label", "ctllabel")

'cria controle textbox
With ctlText
   .Visible = True
   .Width = 3000
   .Text = " Caixa de texto criada"
   .Top = 1100
   .Left = 1200
End With

'cria controle combobox
With ctlcombo
   .Visible = True
   .Top = 1600
   .Left = 1200
   For i = 0 To 5
     .AddItem "texto " & i
   Next
   .ListIndex = 0
End With

'cria controle label
With ctllabel
   .Visible = True
   .Width = 3000
   .Caption = "Controles Criados em tempo de execução"
   .Top = 100
   .Left = 1200
End With

Ao executar o projeto vamos obter o seguinte resultado:

Criamos assim mais três controles: Label , TextBox e ComboBox em tempo de execução. A mágica é obtida usando-se o método Add  para incluir um controle a coleção Controls retornando a sua referência.

A sintaxe é:

objeto.Add (ProgID , Name , container)

Objeto  Uma variável objeto definida 
ProgID Uma string que identifica o controle. Para determinar o ProgID de muitos controles usamos o Object Browser.
Name Uma string que identifica o membro da coleção
container Uma referencia a um objeto que especifica o container do controle

O método Add permite a incluir controles em uma aplicação em tempo de execução. A adição de um controle pode ser usado para inserir uma funcionalidade de um controle a uma aplicação mesmo que a aplicação tenha sido compilada e montada. 

O método também  pode ser usado para incluir dinamicamente um controle que não esta referenciado em um projeto ( um controle não referenciado é um controle que não esta presente na caixa de ferramentas - Toolbox.) . Neste caso você vai ter que incluir a chave de licença do controle a coleção Licenses.

Assim para incluir um controle Treeview no nosso projeto , além de definir a variável objeto e usar o método Add para incluir o controle na coleção Controls devemos inserir a licença do controle a coleção Licenses. Veja código abaixo:

Dim i As Integer
Licenses.Add "MSComctlLib.TreeCtrl"

Set ctlDynamic = Controls.Add("MSComctlLib.TreeCtrl", "meuctl", Form1)

A sintaxe para inserir uma licença na coleção Licenses é:

objeto.Add ( ProgID , LicenseKey )

Objeto  Uma variável objeto definida 
ProgID Uma string que identifica o controle para o qual a licença vai ser incluida.
LicenseKey Uma string que determina a chave License.

O método Add é usado para inserir uma licença a um controle em tempo de execução quando este requerer uma chave de licença. 

Vejamos agora o código completo do projeto para incluir um controle TreeView em tempo de execução:

- Código da seção General Declarations do formulário padrão

Option Explicit
Dim WithEvents ctltree As VBControlExtender

- Código  do evento Load do formulário padrão

Private Sub Form_Load()
Dim i As Integer
Form1.Caption = "Criando um TreeView"

 
Licenses.Add "MSComctlLib.TreeCtrl"

 Set ctltree = Controls.Add("MSComctlLib.TreeCtrl", "meuctl", Form1)
 'define a localização e tamanho do controle no form
  ctltree.Move 200, 300, 2500, 2500
 'Adiciona alguns nós ao controle treeview
 For i = 1 To 5
      ctltree.object.nodes.Add Key:="Item" & Str(i), Text:="Item" & Str(i)
      ctltree.object.nodes.Add Relative:="Item" & Str(i), Relationship:=4, Text:="Item Filho" & Str(i)
 Next i
 ctltree.Visible = True
End Sub

Abaixo o resultado da execução do projeto:

Observe a linha de códigoDim WithEvents ctltree As VBControlExtender

A fim de programar os eventos para um controle não referenciado, devemos declarar uma variável objeto usando a chave WithEvents como um objeto VBControlExtender e definir a variável objeto pela referência retornada via método Add. A seguir devemos usar o evento ObjectEvent do objeto  VBControlExtender .

Assim para programar um evento do controle TreeView inserido devemos usar o seguinte código:(No caso estamos programando o evento Click )

Private Sub ctltree_objectEvent(info As EventInfo)
Select Case info
   Case
"Click"
       MsgBox "Voce clicou no controle "
End Select
End Sub

Você só não pode associar um controle intrinseco do VB á variável VBControlExtender pois ocorrerá um erro de tipo incompatível ( Mismatch error).

Obs: A técnica é util quando você precisa criar vários controles do mesmo tipo. Vamos supor que você precise criar 25 botoes de comando e associar a propriedade caption de cada um a uma letra do alfabeto. Daria trabalho fazer isto manualmente , veja o codigo para criar o memos efeito:

Option Explicit
Private WithEvents cmd As CommandButton 
Dim i As Integer
Dim x As Single
Dim y As Integer
x = 0
y = 65


For i = 0 To 25
  Set cmd = Controls.Add("VB.CommandButton", "cmd" & i, Me)
  cmd.Width = 255
  cmd.Height = 255
  cmd.Move 200 + x, 400
  cmd.Caption = Chr(65 + i)
  cmd.Visible = True
  x = x + 255
Next

O resulto será:

Inté...