------------------------------------------------------------------
###@@@$$$&&&***!!!+++???~~~~|||^^^^)))%%%///```(((''']]]---\\\####
####@@@$$$&&&***!!!+++???~~~~|||^^^^)))%%%///```(((''']]]---\\\###
###      D I C A S     D E     V I S U A L     B A S I C       ###
###      D I C A S     D E     V I S U A L     B A S I C       ###
###      D I C A S     D E     V I S U A L     B A S I C       ###
###      D I C A S     D E     V I S U A L     B A S I C       ###
###@@@$$$&&&***!!!+++???~~~~|||^^^^)))%%%///```(((''']]]---\\\####
####@@@$$$&&&***!!!+++???~~~~|||^^^^)))%%%///```(((''']]]---\\\###
-------------------------------------------------------------------

1)Internet     

  
Podes querer ligar-te, dentro de um programa em Visual Basic, a um determinado URL (Unic Resource Located) da Web e navegar de seguida. Para isso  fcil, quando podemos utilizar uma API do Windows, a funo ShellExecute().

Na (General) / (Declaration), de um Form coloca a seguinte linha de cdigo.
 
  
Private Declare Function ShellExecute Lib _
"shell32.dll" Alias "ShellExecuteA" _
(ByVal hWnd As Long, ByVal lpOperation _
As String, ByVal lpFile As String, ByVal _
lpParameters As String, ByVal lpDirectory _
As String, ByVal nShowCmd As Long) As Long
 
  
Utiliza uma caixa de texto com a propriedade Name = ligacao, e um boto com a propriedade Name = cmdligacao.

Na caixa de texto escreves o URL pretendido, e quando clicares no botao, que tem o evento click() com o cdigo que se segue, vers o que acontece.
 
  
Private Sub cmdligacao_Click() 
ShellExecute 0&, vbNullString, ligacao.Text, vbNullString, _
vbNullString, SW_SHOWNORMAL

End Sub
  
Nota : Esta dica s funciona, se tiveres o acesso  rede ligado. 




2) Erros de comparao de variveis em textbox    
 
  
Quando recebes um valor numrico de uma Textbox, podes querer compar-lo com outro valor predefinido. Considera o seguinte cdigo: 
 

Select Case Text1.Text
   Case 1 to 12
      MsgBox "Valor Aceite"
   Case Else
      MsgBox "Valor Incorrecto"
End Select

Podes pensar que este cdigo compara correctamente os valores introduzidos entre 1 e 12, mas no  assim. Sero correctos os valores 1, 10, 11, e 12, mas incorrectos por exemplo os valores de 2 a 9, e isto porque o campo retormna uma string e compara-as exactamente dessa forma.

Para resolver esta situao "inesperada", usaremos a funo Val(), para converter os valores texto em numeros. Assim o cdigo correcto seria: 

Select Case Val(Text1.Text)
   Case 1 to 12
      MsgBox "Valor Aceite"
   Case Else
      MsgBox "Valor Incorrecto"
End Select

 
 
3) Os ficheiros .INI    
 
  
Os ficheiros .ini, so ficheiros de texto usados para guardar informaes, que devem ser "lembradas" pelo programa da prxima vez que for executado.

Alguns exemplos so

Preferncias do utilizador 
Posicionamento e comprimento de ecrans 
Ficheiros usados mais recentemente 
O caminho / nome das base de dados 
O caminho dos relatrios

 
A estrutura de um ficheiro INI est dividida em 3 partes:

[nome_da_seco] 
Nome_da_chave 
Valor_da_chave 
O Nome_da_chave est separado do Valor_da_chave por um sinal de igual(=).

Exemplo :

[caminho]
bdados=c:\tutoriais\dados
mapas=c:\tutoriais\mapas


[tabelas]
001=amigos.mdb 



 
Para utilizarmos este tipo de ficheiros em programa criamos um Modulo.bas, onde vamos aplicar API's do Windows (falaremos do que so API's mais adiante), como o exemplo que a seguir descrevemos:

Declare Function GetPrivateProfileString Lib _
"kernel32" Alias "GetPrivateProfileStringA" _
(ByVal lpApplicationname As String, ByVal _
lpKeyName As String, ByVal lpDefault As _
String, ByVal lpReturnedString As String, _
ByVal nSize As Long, ByVal lpFileName As _
String) As Long

Global caminho As String
Global bdados As String
Global strfilename As String
Global lngresult As Long
Global strresult As String * 50
Global nfirma As String
Global percurso As String
Global basedados As String
Global variavel As String




 
 
Private Sub MDIForm_Load()

Dim digito As Long
caminho = "caminho"
nfirma = "bdados"
strfilename = App.Path & "\amigos.ini" 

lngresult = GetPrivateProfileString(caminho, nfirma, strfilename, strresult, Len(strresult), strfilename)
percurso = Left(strresult, lngresult)

caminho = "tabela"
nfirma = "001"
lngresult = GetPrivateProfileString(caminho, nfirma, strfilename, strresult, Len(strresult), strfilename)
basedados = Left(strresult, lngresult)


End Sub
 
 
 
   
Para escrever em Runtime basta criar uma funo em que em vez de GetPrivateProfileString dever aparecer WritePrivateProfileString. 
 


4) Aceitar s numeros num campo de texto    
 
 
 
  
Muitas vezes  necessrio validar a introduo de dados pelo utilizador, neste caso pretendemos somente a introduo de caracteres numricos. O evento Change() da textbox,  o melhor local para o fazer. Contudo se usarmos, somente a funo IsNumeric(), poderemos comenter um erro. Por exemplo atenta no seguinte cdigo:

Private Sub Text1_Change()
If Not IsNumeric(Text1.Text) Then
    Text1.Text = ""
End If

Nesta circunstncias se o utilizador introduzir um numero negativo (-123), o controlo no o aceita , porque o 1 caracter no  um numero.

Para resolver a situao atenta ao seguinte cdigo:


Private Sub Text1_Change()
If Not ValidateNumeric(Text1.Text) Then
    Text1.Text = ""
End If
End Sub

Private Function ValidateNumeric(strText As String) _
    As Boolean
ValidateNumeric = CBool(strText = "" _
    Or strText = "-" _
    Or strText = "-." _
    Or strText = "." _
    Or IsNumeric(strText))
End Function



5) No percas o focus no UserControls    
 
  
Normalmente, para determinar quando um UserControl, recebe ou perde o focus, podes pensar que usando os eventos standard GotFocus e LostFocus, so uma atitude correcta. No entanto h situaes onde o controlo perde o focus sem "passar" pelo evento LostFocus. Por exemplo, quando se faz (Alt+Tab) para outra aplicao. Assim a tua melhor aposta para controlar o focus  inserir o cdigo nos eventos EnterFocus e ExitFocus.


6) Esconder o cursor do rato numa aplicao VB     
 
 
 
  
A funo API "ShowCursor" permite uma forma rpida de esconder o cursor do rato. Insere e seguinte declarao 

Private Declare Function ShowCursor Lib "user32" _ (ByVal bShow As Long) As Long 

Quando digitares 0 para o argumento bShow, o cursor do rato desaparece. Com -1, o cursor volta a aparecer.  preciso um certo cuidado ao usar esta funo, porque apesar do cursor do rato se encontrar escondido, no significa que no esteja activo. Para comprovares o que acabmos de dizer, insere o cdigo seguinte a um Form.

 

Dim blnShow As Boolean


Private Sub Form_Click()
blnShow = Not bln
ShowShowCursor blnShow
End Sub


Private Sub Form_Load()
blnShow = True
End Sub


Private Sub Form_QueryUnload(Cancel As Integer, UnloadMode As Integer)
If Not blnShow Then ShowCursor TrueEnd 
SubNow, run the project.  

 
  
Quando fazes click no Form, o Visual Basic torna o cursor invisivel. Clica novamente no Form e o cursor reaparece. Agora volta novamente a fazer dezaparecer o cursor do rato, e move-o em direco  barra de menus. Apesar de invisivel, o cursor quando passa por cima de cada boto, fica pronto a ser clicado. 


7) Manter a largura das colunas em runtime do DBGrid    
 
 
 
  
O DBgrid  a melhor forma de mostrar dados de uma forma "familiar". Contudo se alterares a largura de uma coluna em runtime, o Visual Basic no utiliza esta nova largura da prxima vez que correres a aplicao. Felizmente o procedimento seguinte manter a largura das colunas.



Sub DBGridLayout(Operation As String)
'save width of columnsDim lWidth As Long
Dim clm As Column
Dim lDefWidth As Long  l

DefWidth = DBGrid1.DefColWidth
For Each clm In DBGrid1.Columns
  With clm
    Select Case LCase(Operation)
      Case "save"
        lWidth = .Width
        SaveSetting App.Title, "Cols", CStr(.ColIndex), _
          lWidth
      Case "load"
        lWidth = GetSetting(App.Title, "Cols", _
          CStr(.ColIndex), lDefWidth)
        .Width = lWidth
    End Select
  End With
Next clm

End Sub

Como podes ver, este procedimento usa as funes SaveSetting e GetSetting para armazenar os valores da largura corrente. Para usar o procedimento, chama-a do Form Load pai e unload evento. Depois indica que operao queres que o procedimento execute.

Private Sub Form_Load()
DBGridLayout "Load"
End Sub

Private Sub Form_Unload(Cancel As Integer)
DBGridLayout "Save"
End Sub
 


8) Alarme    
 
 
 
  
Option Explicit
Dim AlarmTime
Const conMinimized = 1


Private Sub Form_Click()
AlarmTime = InputBox("Digite a hora", "VB Alarme", Hora de Alarme)
If AlarmTime = "" Then Exit Sub
If Not IsDate(AlarmTime) Then
     MsgBox "Valor digitado invlido"
Else ' String vlida,
     AlarmTime = CDate(AlarmTime) ' Guarda o valor da hora em AlarmTime.
End If
End Sub

Private Sub Form_Load()
AlarmTime = ""
End Sub

Private Sub Form_Resize()
If WindowState = conMinimized Then ' Se o Form for minimizado mostra a hora em caption.
     SetCaptionTime
Else
     Caption = "Alarme"
End If
End Sub

Private Sub SetCaptionTime()
Caption = Format(Time, "Medium Time") ' Mostra a hora usando o formato medium time.
End Sub

Private Sub Timer1_Timer()
Static AlarmSounded As Integer
If lblTime.Caption <> CStr(Time) Then
'  um segundo diferente do que aquele que  mostrado.
If Time >= AlarmTime And Not AlarmSounded Then
     Beep 5000
     MsgBox "Alarme s" & Time
     AlarmSounded = True
ElseIf Time < AlarmTime Then
     AlarmSounded = False
End If
If WindowState = conMinimized Then
' Se minimizado, ento actualiza o Caption do Form a cada minuto.
If Minute(CDate(Caption)) <> Minute(Time) Then SetCaptionTime
Else
' Seno, actualiza a label Caption do form cada segundo.
     lblTime.Caption = Time
End If
End If
End Sub
 


9) Calculadora    
 
 
 
  
Option Explicit
Dim Op1, Op2 ' Operando previamente introduzido .
Dim DecimalFlag As Integer ' Ponto decimal j presente ?
Dim NumOps As Integer ' Numero de operandos.
Dim LastInput ' Indicata o tipo da ultimo keypress evento.
Dim OpFlag ' Indica a operao pendente.
Dim TempReadout

' O evento Click para o procedimento C (cancel).
' Limpa o mostrador e inicializa variaveis.


Private Sub Cancel_Click()
Readout = Format(0, "0.")
Op1 = 0
Op2 = 0
Form_Load


' O evento Click para o procedimento CE (cancelar entrada).


Private Sub CancelEntry_Click()
Readout = Format(0, "0.")
DecimalFlag = False
LastInput = "CE"
End Sub

' O evento Click para o procedimento do ponto decimal.
' Se a ultima tecla for um operador, inicializa
' readout to "0." Seno, adiciona um ponto decimal
' ao mostrador.


Private Sub Decimal_Click()
If LastInput = "NEG" Then
Readout = Format(0, "-0.")
ElseIf LastInput <> "NUMS" Then
Readout = Format(0, "0.")
End If
DecimalFlag = True
LastInput = "NUMS"
End Sub

' Rotina de inicializao para o Form.
' Inicializa as variveis.


Private Sub Form_Load()
DecimalFlag = False
NumOps = 0
LastInput = "NONE"
OpFlag = " "
Readout = Format(0, "0.")
'Decimal.Caption = Format(0, ".")
End Sub

' O evento Click para o procedimento de numeros de (0-9).
' Junta um novo numero ao apresentado no mostrador.


Private Sub Number_Click(Index As Integer)
If LastInput <> "NUMS" Then
Readout = Format(0, ".")
DecimalFlag = False
End If
If DecimalFlag Then
Readout = Readout + Number(Index).Caption
Else
Readout = Left(Readout, InStr(Readout, Format(0, ".")) - 1) + Number(Index).Caption + Format(0, ".")
End If
If LastInput = "NEG" Then Readout = "-" & Readout
LastInput = "NUMS"
End Sub

' O evento Click para os operadores (+, -, x, /, =).


Private Sub Operator_Click(Index As Integer)
TempReadout = Readout
If LastInput = "NUMS" Then
NumOps = NumOps + 1
End If
Select Case NumOps
Case 0
If Operator(Index).Caption = "-" And LastInput <> "NEG" Then
Readout = "-" & Readout
LastInput = "NEG"
End If
Case 1
Op1 = Readout
If Operator(Index).Caption = "-" And LastInput <> "NUMS" And OpFlag <> "=" Then
Readout = "-"
LastInput = "NEG"
End If
Case 2
Op2 = TempReadout
Select Case OpFlag
Case "+"
Op1 = CDbl(Op1) + CDbl(Op2)
Case "-"
Op1 = CDbl(Op1) - CDbl(Op2)
Case "X"
Op1 = CDbl(Op1) * CDbl(Op2)
Case "/"
If Op2 = 0 Then
MsgBox "Can't divide by zero", 48, "Calculator"
Else
Op1 = CDbl(Op1) / CDbl(Op2)
End If
Case "="
Op1 = CDbl(Op2)
Case "%"
Op1 = CDbl(Op1) * CDbl(Op2)
End Select
Readout = Op1
NumOps = 1
End Select
If LastInput <> "NEG" Then
LastInput = "OPS"
OpFlag = Operator(Index).Caption
End If
End Sub

' O evento Click para o procedimento percentagem (%).
' Mostra a percentagem do 1 operando.


Private Sub Percent_Click()
Readout = Readout / 100
LastInput = "Ops"
OpFlag = "%"
NumOps = NumOps + 1
DecimalFlag = True
End Sub
 


10) Utilizao do DBGrid    
 
 
 
  
Option Explicit

Private Sub Command1_Click()
List1.Clear ' Limpa a listbox
End Sub

Private Sub Command2_Click()
Unload Form1
End ' Finaliza a seco
End Sub


Private Sub Data1_Reposition()
' Liga o ttulo  propriedade caption 
Data1.Caption = Data1.Recordset("Title")
End Sub

Private Sub DBGrid1_DblClick()
' Adiciona um titulo  lista
List1.AddItem Data1.Recordset("Title")
End Sub

Private Sub Form_Load()

End Sub


 
11) Cpias de Segurana    
 
 
 
   
As cpias de segurana dos nossos dados so de uma importncia enorme. Infelizmente poucas so as empresas/pessoas que cumprem aquilo que  o mnimo exigido.

No exemplo que se segue, crimos um Form onde inserimos um objecto em Project/Components chamado "Microsoft Common Dialog Control 6.0", para ele aparecer na Toolbox.

Utilizmos 3 objectos: 

DriveListBox 
DirListBox 
FileListBox 
 
Option Explicit
Dim selectedfile As String
Dim destino As String 

Private Sub cmdiniciar_Click()
On Error Resume Next
Screen.MousePointer = 11 ' o boto do rato toma a forma de ampulheta
Call fechar ' fechamos a base de dados
destino = Drive2.Drive & "\" & File1.filename
MsgBox "INSIRA DISQUETE NO DRIVE", , "COPIA DE SEGURANA"
FileCopy selectedfile, destino
Screen.MousePointer = 0 ' o boto do rato volta  sua forma normal
Call abrir ' voltamos a abrir a base de dados 
End Sub


Private Sub cmdsair_Click()
Unload Me
End Sub


Private Sub Dir1_Change()
File1.Path = Dir1.Path
End Sub

Private Sub Drive1_Change()
Dir1.Path = Drive1.Drive
End Sub

Private Sub File1_Click()
selectedfile = File1.Path & "\" & File1.filename
End Sub


Private Sub Form_Load() ' Posisionamente e dimenses do Form
Me.Height = 4620
Me.Left = 2745
Me.Top = 1740
Me.Width = 7065
End Sub 


 
12) Aspectos do rato    
 
 
 
  
Contante Valor
 Descrio 
  
vbDefault           0  Defeito

vbArrow             1  Seta

vbCrosshair         2  Cruz

vbIbeam             3  Viga vertical

vbIconPointer       4  Icon

vbSizePointer       5  Cruz com setas na ponta

vbSizeNESW          6  Setas direco NE / SW

vbSizeNS            7  Setas direco N / S

vbSizeNWSE          8  Setas direco NW / SW

vbSizeWE            9  Setas direco W / E

vbUpArrow          10  Seta para cima

vbHourglass        11  Ampulheta

vbNoDrop           12  Circulo com diagonal

vbArrowHourglass   13  Seta + Ampulheta

vbArrowQuestion    14  Seta + Ponto Interrogao

vbSizeAll          15  Seta para todos os lados (N / S / W / E)

vbCustom           99  Do utilizador



 
13) Shape    

  
Valores assumidos pela propriedade Shape do objecto Shape 
 
 
0 Rectngulo

1 Quandrado

2 Oval

3 Crculo

4 Rectangulo c/ cantos redondos

5 Quandrado c/ cantos redondos


 
14) VScrollBar / HScrollBar    
 
 
 
  
As barras de deslocamento Vertical e Horizontal, permitem uma navegao fcil atraves de uma longa lista de item's ou de informao. Pode ser indicado para mostrar a velocidade ou o volume, etc,.

Algumas das propriedades importantes que convem referenciar:

LargeChange - indica a quantidade de deslocamento quando se clica no meio da barra. 
SmallChange - indica a quantidade de deslocamento quando se clica nas setas no fim da barra 
Value - indica o valor do deslocamento e pode variar entre 0 e 32.767 
Max - Valor mximo do controlo 
Min - Valor minimo do controlo 
Funo RGB() - retorna um valor numrico longo e indica a composio da cor no formato que se segue:

cor=RGB(RED, GREEN, BLUE) 

No exemplo que se segue, crimos um Form com 3 objectos VScrollBar e uma Label cuja funo  mostrar a cor atravs do deslocamento de qualquer das barras verticais.
 
  
Private Sub cor_Change(Index As Integer)
Const red = 0, green = 1, blue = 2
Dim corfinal As Long
corfinal = RGB(cor(red).Value, cor(green).Value, cor(blue).Value)
Label1.BackColor = corfinal
End Sub 
Private Sub cor_Scroll(Index As Integer)
cor_Change (Index)
End Sub

Private Sub Form_Load()
Dim i As Integer
For i = 0 To 2
     cor(i).Value = 0
     cor(i).Max = 0
     cor(i).Min = 255
     cor(i).LargeChange = 10
     cor(i).SmallChange = 1
Next i
End Sub


Private Sub cor_Change(Index As Integer)
Const red = 0, green = 1, blue = 2
Dim corfinal As Long
corfinal = RGB(cor(red).Value, cor(green).Value, cor(blue).Value)
Label1.BackColor = corfinal
Label5.Caption = corfinal
End Sub 
Private Sub cor_Scroll(Index As Integer)
cor_Change (Index)
End Sub

Private Sub Form_Load()
Dim i As Integer
For i = 0 To 2
cor(i).Value = 0
cor(i).Max = 0
cor(i).Min = 255
cor(i).LargeChange = 10
cor(i).SmallChange = 1
Next i
End Sub
 
 

 
15) Comando With    
 
  
Este comando executa uma srie de comandos para o mesmo objecto sem ter que reescrever o nome do objecto.

Sintaxe:

With objecto
     .comando1
     .comando2
     .comando3
End With

Onde o "objecto"  o nome de um objecto definido pelo utilizador, comando1, comando2 e comando3, os comandos a serem executados.
 
  
Por exemplo dimensionar e colocar um Form no ecran, com a propriedade Name = frmjanela:

With frmjanela
     .Left = 150
     .Top = 500
     .Height = 1500
     .Width = 2300
     .Caption = "Esta  a minha janela principal"
End With

 

16) Prevenir problemas com o DataReport do VB 6.0     
 
 
 
  
O Visual Basic 6.0 tem integrado um gerador de relatrios "DataReport". Quando usas esta ferramenta podes ter problemas durante a execuo do projecto compilado. 

Isto pode ocorrer se fizeres o Unload do Form, sem teres feito o Unload do DataReport, porque o Visual Basic inicializa o objecto DataReport, mas nunca lhe faz o Unload enquando ele est a ser impresso.

Para ultrapassar este problema utilizamos o Evento Unload() do Form como o exemplo que se segue:

Private Sub Form_Unload(Cancel As Integer)
Unload DataReport1
End Sub
 
 

 
17) Usar VBound() e UBound() quando usas arrays    
 
 
 
  
Quando usas o comando For...Next, para navegar num array, podes estar condicionado aos valores dos contadores inicial e final.

Por exemplo, supes que criaste o seguinte array:

TipoMusicas = Array("Blues", "Classic Rock", "Country", _ "Dance", "Disco", "Funk", "Grunge", "Hip -Hop", _ "Jazz", "Metal", "New Age", "Oldies", "Other")

Podes navegar atravs do array da seguinte forma:

For x = 0 To 12
Debug.Print TipoMusicas(x)
Next x

Contudo, e porque podes querer adicionar mais item's ao array,  melhor utilizar as funes LBound() e UBound(), para delimitar as "fronteiras" dos contadores, alterando o cdigo do exemplo anterior no seguinte:
 
  
For x = LBound(MusicGenres) To UBound(MusicGenres)
Debug.Print TipoMusicas(x)
Next x


 
18) Preencher todas as TextBox    
 
 
 
  
Imagine um Form com vrios objecto TextBox, e que obrigatriamente todas devero ter informao. 

Para completar esta dica, adicionamos ao Form um objecto CommandButton, com a propriedade Caption = "Gravar" e Name = "botao".

Na propriedade KeyPreview do Form colocamo-la = True

No evento Load() colocamos o boto.enabled = False

No evento KeyUP do Form digitamos o seguinte cdigo: 

 
 
Private Sub Form_KeyUp(KeyCode As Integer, Shift As Integer)
' Coloca o botao enabled somente se todas as TextBox do Form
' forem preenchidas
Dim curControl As Control
For Each curControl In Controls 'Faz um Loop a todos os controlos do form.
If TypeOf curControl Is TextBox Then
If curControl.Text = "" Then 'A TextBox corrente est vazia
botao.Enabled = False 'Torna o botao disabled
Exit Sub
End If
End If
Next
' Todas as TextBox tm informao
botao.Enabled = True
End Sub
 
 

 
19) Debug    
 
 
 
  
O Visual Basic permite fazer uma anlise interactiva durante a fase de desenvolvimento de um projecto, para encontrar possiveis erros de run-time ou de lgica.

Eis algumas instrues e a sua explicao :

Toggle Breakpoint - Provoca a paragem do projecto na linha de cdigo assinalada. Pode-se fazer isto de trs formas: fazer click atrs da linha, no painel esquerdo, com a tecla F9, ou atravs da barra de tarefas em Debud/Toggle Breakpoint 
Step Into - (F8) Executa uma linha de comando de cada vez. Se o comando for um Call para um Procedimento, o prximo comando mostrado,  o primeiro comando do procedimento. 
Step Over - (SHIFT+F8) Semelhante ao Step Into, executa de uma s vez um procedimento Call, e a prxima linha de comando mostrada,  a linha a seguir no procedimento corrente. 
Step Out - (CTRL+SHIFT+F8) Executa as restantes linhas da funo, onde est inserida a paragem corrente. O prximo comando mostrado,  o comando seguinte ao procedimento Call. 
Add Watch - Este comando mostra uma caixa de dilogo, na qual podemos inserir uma expresso (qualquer expresso vlida em Visual Baisc). 
Quick Watch - (SHIFT+F9) Mostra uma caixa de dilogo com o valor corrente da expresso seleccionada. 
Clear All Breakpoints - (CTRL+SHIFT+F9) - Remove todos os Breakpoints.  
 


20) Format    
 
 
 
  
Este comando existente no menu ToolBar,  simples e facilita a vida ao programador. Vale a pena uma chamada de ateno para ele.

Para seleccionar vrios comandos de um Form, clicamos neles com a tecla SHIFT premida. ou clicamos e arrastamos o rato por cima deles. Isto provoca o aparecimento de 8 pontos em torno de cada objecto.

Divises do comando Format:

Align :

Left - Alinhamento pala esquerda 
Centers - Ao centro 
Right - Pala direita 
Tops - Em cima 
Middles - Ao centro 
Bottoms - Em baixo 
To Grid - Pela grelha 
Make Same Size :

Width - Com o mesmo comprimento 
Height - Com a mesma altura 
Both - Com o mesmo comprimento e altura 
Horizontal / Vertical Spaccing :

Make Equal - O mesmo espao 
Increase - Aumenta 
Decrease - Diminui 
Remove - Remove 
Center in Form :

Horizontally - No sentido horizontal 
Vertically - No sentido vertical 
Order :

Bring to Front - Coloca o objecto  frente 
Send to Back - Coloca o objecto atrs
 
 


21) Apagar todos os registos de uma tabela    
 
 
 
  
Algumas linguagens de programao tm uma instruo que permite apagar todos os registos de uma tabela. Digamos que pretendemos que a mesma se torne "vazia". (Se no estou errado, a instruo "Zap" do clipper e do FoxPro)

O Visual basic infelizmente no tem uma instruo assim to linear. Temos duas formas de o fazer. A 1  utilizar um ciclo For....Next e executar uma instruo de Delete por cada registo lido. A 2 que me parece mais fcil e lgica  utilizar uma instruo SQL, como o exemplo a seguir documenta.

Utilizamos a nossa Base de Dados "Amigos" dos tutoriais para fazer o teste. No Form "frmpessoal", acrescenta um boto com a linha de cdigo que se segue:

 
 
Dim strSQL As String


strSQL = "DELETE FROM pessoal WHERE codigo <> 0 "
DBenc.Execute strSQL

 
  
Pessoal  o nome da tabela na base de dados.

Codigo  a chave principal, nica sem duplicao, e por opo nunca ser igual a 0 (zero). Por isso nesta instruo dissemos-lhe para "DELETE" apagar todos os registos cujo codigo fosse diferente de zero.

DBenc,  a Base de Dados.
 
 

 
22) Client/Server VS. File Server    
 
 
 
  
Client/Server, refere-se a pelo menos duas entidades separadas, um Cliente e o Servidor. O Client,  um computador com o qual o utilizador interage, o Server,  o computador que aceita os pedidos de um ou mais clientes e envia respostas. Tudo isto no  nem mais nem menos que comunicao.

File/Server, refere-se ao conjunto de um ou mais computadores que partilham recusrsos de um computador central chamado File Server. Por exemplo, se abrires um documento residente no disco do servidor, o cliente abre o documento, carrega-o para a sua memria e mostra-o ao utilizador. Todo o trabalho ocorre no cliente.

Operando uma aplicao de Base de Dados num File/Server

O Microsoft Jet abre a Base de Dados de uma forma simples em termos de tempo e recursos 
O Microsoft Jet DLL corre na tua estao de trabalho e recolhe informaes das tabelas da mesma 
O Microsoft Jet l os detalhes da tabela para a memria da tua estao de trabalho, como numero de campos,tipo, indices disponiveis e informao acerca da posio da 1 pgina de dados 
Uma cpia do Microsoft Jet l para a tua estao de trabalho um registo tornando-o acessivel para a tua aplicao. 
Operando uma aplicao de Base de Dados num Client/Server

Como nos pontos 1 e 2 o Microsoft Jet abre as Bases de Dados, recolhe alguma informao dela e fixa a sua estrutura na memria da estao de trabalho local. 
Quando o Microsoft l a tabela, v que h um Link e tenta criar uma coneco com o servidor. Esta operao pose ser demorada. 
Quando o Servidor recebe o pedido de coneco, reserva memria e outros recursos e prepara-se para subsquentes pedidos 
O Microsoft Jet emite um pedido patra o servidor 
O Servidor retorna o pedido do Microsoft Jet tornando-o acessivel para a aplicao do cliente. 
 
 
As vantagens do Client/Server

Operaes mais robustas e fidedignas, porque uma nica Base de Dados servidora interage, em vez de multiplas cpias 
Melhor escalabilidade 
Melhora de operaes, especialmente se as estaes de trabalho so computadores com pouca memria e lentos 
Reduo do trfico na rede 
Reduo das misses criticas como backups, recuperaes, etc.  
 

 
23) Centrar um Form no ecran    
 
 
 
  
Aproveitando o nosso projecto de amigos, codificmos o evento Load() da seguinte forma: 

 
 
Private Sub Form_Load()
Dim iLeft As Integer
Dim iTop As Integer
iLeft = (Screen.Width / 2) - (frmamigos.Width / 2)
iTop = (Screen.Height / 2) - (frmamigos.Height / 2)
frmamigos.Move
End Sub
 
  
Desta maneira simples, sempre que o Form  carregado, ele fica sempre centrado no ecran, independentemente da resoluo. 
  
Mas se quizermos que a nossa cdigo de cima possa ser aplicado a todas as situaes, evitando assim escrever linhas de cdigo, fazendo somente Copy e Paste para o evento Load() de todos os Form's, utilizamos o cdigo que se segue. 
  
With Me
     iLeft = (Screen.Width / 2) - (.Width / 2)
     iTop = (Screen.Height / 2) - (.Height / 2)
     .Move iLeft, iTop
End With
 
 

 
24) Bookmark    
 
 
 
  
Se pretendes, no decurso de um determinado projecto, marcar um registo de uma tabela, usas a instruo seguinte:

No (General) (Declarations) do Form, crias uma variavel tipo string da seguinte forma:

Dim marca As String

marca = tblami.Bookmark


 
 
Quando pretenderes situares-te no referido registo basta fazeres: 
  
tblami.Bookmark = marca
Call mostrarBD


O registo marcado aparece no Form
 
 

 
25) API's    
 
 
 
  
API, significa Application Programming Interface, e tem para cima de 1000 funes que podem ser usadas pelo Visual Basic ou por qualquer outra linguagem de programao que corra em Windows.

Apesar de haver muitos funes que podes utilizar, somente algumas delas so verdadeiramente uteis. 

Os componentes que afectam o sistema operativo de 32 Bits, so 3 DLL's, que suportam inteiramente todo o sistema operativo.

User32.dll - Sistemas de menus, interface com o urilizador e a maioria dos componentes visuais 
Kernel32.dll - Memria e gesto de recursos 
GDI32.dll - Painting, grficos, desenhos, etc. 
A primeira coisa a fazer se pretendes utilizar funes API,  declar-las em Visual Basic. Fazes isto, utilizando o comando Declare. Eis 2 exemplos

Declare Function GetWinFlags Lib "Kernel" () As Long 
Declare Sub UpdateWindow Lib "User" (ByVal hWnd As Integer) 
As declaraes podem ser colocadas em ficheiros .BAS.

A funo Declare informa o Visual Basic em que DLL particular se encontram as funes que necessitamos, que tipo de parmetros so necessrios.

A diferena entre um procedimento Function e Sub,  que o primeiro retorna um valor, ao contrrio do segundo. 

A seguir ao Declare Function, vem o nome da funo, seguido do comando Lib que indica ao Visual Basic em que ficheiro DLL ou EXE se encontra a funo. Finalmente o tipo de valores retornados a seguir  palavra AS.

Para chamar uma API dentro de um programa Visual Basic, basta faz-lo com se se tratasse de uma funo normal. 

 
 
Para usar o API Text Viewer, seleccionas Add-Ins, Api-Viewer. Seleccionas API Text Viewer.

Aparece-te uma caixa de texto e clicas em File/Load Text File do menu. Esxolhes WIN32API.TXT.

Depois de ser carregado este ficheiro de texto, tens acesso de uma enorme lista de API's do Windows disponveis. Podes seleccionar um ou mais destes Item's e eles sero passados para uma janela inferior. Quando terminares fazer Copy (para o Clipboard), e Paste ou simplesmente inserir directamente para um ficheiro .BAS.
 
 


26) Procurar uma string numa ListBox    
 
 
 
  
Vamos comear um novo projecto "Standard.EXE". No Form, inserimos uma ListBox com a propriedade Name=lstcapitais 

Criamos um procedimento capitais.

No evento Form_Load(), fazemos o Call capitais, para adicionar os respectivos itme's  ListBox.

Criamos um Modulo .Bas, ao qual adicionamos uma funo API, chamada SendMessage, e uma varivel constante LB_FINDSTRING com valor inicial em hexadecimal 399.

 
 
Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long


Public Const LB_FINDSTRING = &H18F

 
  
Private Sub capitais()
With lstcapitais
   .AddItem "Lisboa"
   .AddItem "Porto"
   .AddItem "Coimbra"
   .AddItem "Santarem"
   .AddItem "Guimaraes"
   .AddItem "Guarda"
   .AddItem "Faro"
   .AddItem "Beja"
   .AddItem "Evora"
   .AddItem "Braga"
   .AddItem "Funchal"
End With
End Sub
 
  
Adicioamos um objecto CommandButton com a propriedade Name=cmdProcura e Caption=Procurar, ao qual adicionmos o seguinte cdigo ao evento Click:

 
 
Private Sub cmdProcura_Click()


Dim strSearch As String
Dim intPos As Integer 

strSearch = InputBox$("Digite a String:", "Procurar")

With lstStates
If strSearch = "" Then
            .ListIndex = 0
Else
             intPos = SendMessage(.hwnd, _
                          LB_FINDSTRING, _
                          -1, _
                          ByVal strSearch)
             If intPos >= 0 Then
                          .ListIndex = intPos
             End If
End If
End With
End Sub

 
  
Clicando no boto procurar, digitamos a String, que pretendemos e ser assinalada a string igual ou maior ao que digitmos. 
 

 
27) Adicionat Tabs a uma ListBox    
 
 
 
  
O Objecto ListBox Standard que vem com o Visual Basic, no contempla colunas. Podemos no entanto ultrapassar o problema utilizando a mesma funo API do Windows, que utilizmos na dica anterior "SendMessage()".

No modulo .Bas adicionamos outra varivel constante:
Public Const LB_SETTABSTOPS = &H192


 
 
No evento Form_Load() digitamos o seguinte cdigo:

Private Sub Form_Load()
Dim lngRet As Long

LngRet = SendMessage(lstcapitais.hwnd, LB_SETTABSTOPS, 1, 40&)

Call Capitais

End Sub

Private Sub capitais()
     With lstcapitais
            .AddItem "Lisboa" & vbTab & "Estremadura"
            .AddItem "Porto" & vbTab & "Douro"
            .AddItem "Santarem" & vbTab & "Ribatejo"
            .AddItem "Faro" & vbTab & "Algarve"
     End With
End Sub

 
 

 
28) Funo GetDriveType32    
 
 
 
  
Considero esta funo com uma enorme importncia, pois chama a ateno para as seguranas dos dados que se devem fazer com regularidade e que poucos utilizadores fazem.

Criamos um objecto ComboBox com a propriedade Name=cboDrive, e uma TextBox com a propriedade Name=txtDriveType

No evento FormLoad() fazemos o Call ao procedimento cboDriveLoad().

 
 
Private Sub cboDriveLoad()
Dim intLoop As Integer

For intLoop = 65 To 90 ' As letras do alfabeto adicionadas  ComboBox
     cboDrive.AddItem Chr$(intLoop)
Next intLoop
End Sub
 
  
Private Sub cboDrive_Click()
Dim lngType As Long


lngType = GetDriveType32(cboDrive.Text & ":\")

Select Case lngType

Case DRIVE_REMOVABLE
     txtDriveType = "Disco Removivel"
Case DRIVE_FIXED
     txtDriveType = "Disco Duro"
Case DRIVE_CD_ROM
     txtDriveType = "CD-ROM "
Case Else
     txtDriveType = "Desconhecido, ou No Existente "
End Select
End Sub
 
 

 
29) ActiveX Control    
 
 
  
A imagem que mostramos em cima e que vamos chamar de "Spinner",  uma "juno" de dois objectos, uma caixa de texto e uma barra de deslocamento vertical. O objectivo  incrementar ou decrementar valores numricos que vo aparecer na caixa de texto, usando o rato em vez do teclado. 
  
Comecemos por criar um novo projecto "Standard.EXE", para nos aparecer um Form vazio. De seguida clicamos em File / Add Project / ActiveX Control.

Nesta altura ficamos com dois projectos abertos e umas novas imagens cinzentas que nos aparecem na TollBox.

Adicionamos uma TextBox cujo nome por defeito  Text1, e um ScroolBar vertical dentro da TextBox.

Fazemos Duplo-Click no ScroolBar vertical para introduzirmos no Evento_Change() a seguinte linha de cdigo:
 
  
text1.text = vscroll1.value 
  
Fechamos o 2 projecto, e passamos a ter acesso s imagens que estavem "esbatidas" na ToolBox.

Se clicarmos no objecto "UserControl1" e o desenharmos no Form do 1 projecto. obteremos uma imagem semelhante  de cima.
 
  
Pressiona F5 para correr o projecto e com o rato faz click nas setas inferior e superior do spinner.

Acabaste de criar o teu 1 controlo ActiveX. 
 
 


30) Instrues SQL 		
		
SQl significa, Structured Query Language. No  uma linguagem de programao, mas antes uma linguagem que pode ser utilizada em diversas linguagens como forma de obter determinado tipo de informao de Base de Dados, de uma ou mais tabelas.  Iremos basear os nossos exemplos na base de dados BIBLIO.MDB, que acompanha o CD-ROM do Visual Basic 5.0 Para um melhor entendimento iremos usar as palavras reservadas das instrues SQL em letras MAIUSCULAS, no que o Visual Basic o obrigue, mas porque  um bom hbito de programao. A instruo mais comum  SELECT_FROM, e contm duas partes: A seleo de colunas de uma ou mais tabelas  A lista de uma ou mais tabelas que contm as colunas pretendidas  Eis alguns exemplos de queries. Mas antes de executares estes exemplos, deves acrescentar um campo tipo date  tabela "Publishers", e preencheres esse campo com diferentes datas do ano 2001.		
Private Sub Command1_Click() Dim str As String Dim dyna As Recordset  str = "SELECT * FROM authors WHERE [Year Born] > 1954"  str = "SELECT * FROM publishers WHERE dtconst < #01/02/2001#" 'mm/dd/aaaa  str = "SELECT * FROM publishers WHERE month(dtconst) < 05" 'mm  Set dyna = DBEnc.OpenRecordset(str, dbOpenDynaset)  dyna.Filter = "name like '*AMS*'"  Set dyna = dyna.OpenRecordset(dbOpenDynaset)  dyna.Filter = "name > 'a' And name < 'B'"  Set dyna = dyna.OpenRecordset(dbOpenDynaset)  dyna.Sort = "name DESC"  Set dyna = dyna.OpenRecordset(dbOpenDynaset)  dyna.MoveFirst Do Until dyna.EOF Print dyna![Name] dyna.MoveNext Loop  End Sub 		
Da tabela de Authors, selecciona todos os registos onde o campo Year Born seja superior ao ano 1954. Repara como deves escrever o nome do campo.  Da tabela Publishers, selecciona todos os registo onde o campo dtconst seja menor que: Mes=2, Dia=1 Ano=2001  Da tabela Publishers, selecciona todos os registos onde o Ms do campo Dtconst seja menor que 5.  Cria uma nova tabela tipo Dynaset a partir da tabela Publishers  Coloca um filtro na nova tabela, para seleccionar somente os registos onde conste no campo Name a palavra AMS  Cria uma nova tabela tipo Dynaset a partir da tabela dyna  Coloca outro filtro na tabela criada de modo que s apaream registos cujo campo Name comece por uma letra superior a "a" e inferior a "B".  Cria uma nova tabela tipo Dynaset a partir da tabela dyna  Ordena os registo por ordem Descendente do campo Name. O inverso seria ASC.  Cria uma nova tabela tipo Dynaset a partir da tabela dyna  Por fim uma pequena rotina para mostrar os registos finais seleccionados.		
		
CRITICA Para que serviu tudo aquilo que acabmos de fazer? Para nada, a menos que quando desenvolveres o teu projecto facilites o mesmo ao teu cliente, para que de cada vez que os valores sejam alterados, ele possa "mexer" no projecto, criar um novo executvel e voltar a corr-lo. Ento h que transformar os valores fixos em valores variveis que sero introduzidos no decorrer do programa.  o que a seguir iremos fazer, atravs de uma varivel que crimos e que chammos: varSQL Dim varSQL As Date, ou As Integer, ou As String, dependendo da situao.		
varSQL = Trim(varSQL) str = "SELECT * FROM authors WHERE [Year Born] >" & varSQL & "" varSQL = CDate(varSQL) str = "SELECT * FROM publishers WHERE dtconst < # " & varSQL & "#" str = "SELECT * FROM publishers WHERE month(dtconst) <" & varSQL & "" varSQL = "*" & varSQL & "*" dyna.Filter = "name like '" & varSQL & "'" Set dyna = dyna.OpenRecordset(dbOpenDynaset) 		
Estes quatro exemplos refletem os de cima, mas de uma forma a que se possa operar segundo as indicaes do utilizador.		



31) CommitTrans, BeginTrans, RollBack		
	
Imagina que o teu chefe, patro, director de pessoal, te manda fazer om projecto em que pretende a alterao do vencimento de todos os funcionrios em +50% (???). Utilizando este processo, podes executar a tarefa sem problemas, em virtude das mesmas s produzirem efeito aps uma confirmao final dada pelo utilizador. BeginTrans - D inicio ao processamento CommitTrans - Conclui a transaco RollBack - Repe a situao anterior, ou melhor, no executa a transaco.		
Sub begintrans() wrk.BeginTrans  With tblpes Do Until .EOF .Edit tbltit![VenciBas] = tbltit![VenciBas] * 1.5 .Update .MoveNext Loop  If MsgBox("Confirma Alteraes ?", vbYesNo) = vbYes Then wrk.CommitTrans Else wrk.Rollback End If End With End Sub		


 
32) Table, Dynaset, Snapshot		
		
 		
		
Table -  o tipo de tabela no seu conceito mais "puro", pois permite-te criar indices, para acederes directamente a um determinado registo, atravs do mtodo SEEK, e num ambiente de trabalho multiposto, sempre que actualizares, apagares ou criares um novo registo, todos os utilizadores tm acesso imediato a essas alteraes Neste tipo de tabelas no podes usar o comando SELECT, nem podes agrupar tabelas de modo a criar uma unica. No podes usar BOOKMARKs, criar filtros ou mesmo ordenar a tabela.		
Dynaset - Criada a partir de uma Table, no pode fazer uso de indices, por isso no se pode usar o mtodo SEEK, para localizao imediata de um registo, podes no entanto usar os mtodos FindFirst, FindLast, FindNext e FindPrevios, para "navegar" . Podes usar o comando SELECT, criar filtros ordenar campos, e isto como resultado do conjunto de uma ou mais tabelas (tables).		
		
Snapshot - Semelhante ao Dynaset em termos de comportamento e propriedades, no entanto tem a particularidade de ser utilizada unicamente como forma de leitura (Read Only), no podes actualizar/modificar os registos da mesma, ao contrrio da Dynaset, e isto porque os Snapshots so uma cpia da tabela que  criada na memria da tua estao de trabalho.		


 
33) StatusBar

Form1.StatusBar1.Panels(1) = "MENSAGEM QUE QUERO TRANSMITIR"

 
34) Multiacesso 		
 
Uma base de dados criada em Microsoft Access,  por "defeito" criada em modo de partilha, isto , permite que numa situao de rede ser acedida por mais que um computador ao mesmo tempo.  Para abertura das tabelas, sero usados determinados parmentros que iremos de fenir de seguida de modo a permitir esta situao:
Set db = ws.OpenDatabase(App.Path & "\basedados.mdb") Set tblpart = db.OpenRecordset("Tabela", , dbOptimistic)

Na 1 linha abrimos a nossa Base de dados, indicando o respectivo caminho, ou localizao. Na 2 linha, definimos e abrimos a tabela de nome "Tabela", cuja sintaxe  a seguinte, e que iremos explicar de seguida. Set recordset = Objecto(OpenRecordset(Tabela, Tipo, Opes, lockedit)

Tipo: dbOpenTable - Abre um objecto tipo Recordset  dbOpenDynamic - Abre um objecto tipo dinamico semelhante ao ODBC dynamic cursor  dbOpenDynaset - Abre um objecto tipo Dynaset  dbOpenSnapShot - Abre um objecto tipo Snapshot  dbOpenForwardOnly - Abre um objecto tipo forward  Opes: dbAppendOnly - Permite somente adicionar novos registos  dbSQLPassPhrough - Passa uma instruo SQL para o Microsoft Jet-connected ODBA  dbSeeChanges - Gera uma rotina de erro se houver uma tentativa de alterar um registo editado por outro utilizador  dbDenyWrite - Evita que outros utilizadores modifiquem ou editem registos  dbDenyRead - Evita que outros utilizadores leiam registos da tabela  dbForwardOnly - Impede consultas a registos anteriores  dbReadOnly - Impede os utilizadores de alterar registos  dbRunAsync - Corre uma query assincrono  dbExecuteDirect - Corre uma query "saltando" o SQLprepare, e chamando directamente o SQLExecDirect  dbInconsistent - Permite actualizaes inconsistentes, somente em Dynaset e SnapShot  dbConsistent - Permite somente actualizaes consistentes para a mesma situao anterior  Lockedit: dbPessimistic - Determina um bloqueio ao registo assim que o mtodo Edit, ocorre  dbOptimistic - A pgina que contem o registo s  bloqueda quando  utilizado o mtodo Update 
Nas propriedaedes do LockEdit, podemos saber que tipo de bloquieo  utilizado, conforme o valor boleano que retorna: Se for True, ser um bloqueio Pessimistic Se for False, ser do tipo Optimistic


35) Como fazer para colocar mais de uma linha em uma MsgBox?

---------------------------------------------------------------------------------


Quebre as vrias linhas colocando um CHR$(13) no final de cada linha:
Mens$ = "Linha nmero 1" + chr$(13)
Mens$ = Mens$ + "Linha nmero 2" + chr$(13)
MsgBox Mens$

36) Como fazer uma funo de Pausa por alguns segundos?

---------------------------------------------------------------------------------

'Para chamar a rotina use:
'      Espere (120)

Public Sub Espere(ByVal QtdSegundos As Long)
   Static Incio As Variant
   If Incio = 0 Then Incio = Time

   While DateDiff("s", Incio, Time) < QtdSegundos

       DoEvents   'faa outras coisas enquanto espera
      ' se cruzar a meia-noite, volte um dia (86400 segundos)
      If DateDiff("s", Incio, Time) < 0 Then Incio = DateAdd("s", -86400, Incio) 
   Wend
   Incio = 0
End Sub




VISUAL BASIC

FUNES IMPORTANTES


ALTERANDO PAPEL DE PAREDE
'Crie esta parte do programa em General / Declarations
Private Declare Function SystemParametersInfo Lib "user32" Alias "SystemParametersInfoA" (ByVal uAction As Long, ByVal uParam As Long, ByVal lpvParam As String, ByVal fuWinIni As Long) As Long
Const SPIF_UPDATEINIFILE =1
Const SPI_SETDESKWALLPAPER = 20
Const SPIF_SENDWININICHANGE =2

' Crie esta parte em um boto 

Dim Arquivo as String
Arquivo = "C:\Windows\Bolhas.bmp"
Call SystemParametersInfo(SPI_SETDESKWALLPAPER, 0&, Arquivo, SPIF_UPDATEINIFILE Or SPIF_SENDWININICHANGE)

CHAMANDO TELAS DO PAINEL DE CONTROLE
Para chamar a tela principal do Painel de Controle
Call Shell("rundll32.exe shell32.dll,Control_RunDLL", vbNormalFocus)
Adicionar / Remover Programas
Instalar/Desinstalar
Call Shell("rundll32.exe shell32.dll,Control_RunDLL appwiz.cpl,,1", vbNormalFocus)

Instalao do Windows
Call Shell("rundll32.exe shell32.dll,Control_RunDLL appwiz.cpl,,2", vbNormalFocus)

Disco de Inicializao
Call Shell("rundll32.exe shell32.dll,Control_RunDLL appwiz.cpl,,3", vbNormalFocus)

Vdeo
Segundo Plano
Call Shell("rundll32.exe shell32.dll,Control_RunDLL desk.cpl,,0", vbNormalFocus)

Proteo de Tela
Call Shell("rundll32.exe shell32.dll,Control_RunDLL desk.cpl,,1", vbNormalFocus)

Aparncia
Call Shell("rundll32.exe shell32.dll,Control_RunDLL desk.cpl,,2", vbNormalFocus)

Configurao
Call Shell("rundll32.exe shell32.dll,Control_RunDLL desk.cpl,,3", vbNormalFocus)

Configuraes Regionais
Configuraes Regionais
Call Shell("rundll32.exe shell32.dll,Control_RunDLL intl.cpl,,0", vbNormalFocus)

Nmero
Call Shell("rundll32.exe shell32.dll,Control_RunDLL intl.cpl,,1", vbNormalFocus)

Moeda
Call Shell("rundll32.exe shell32.dll,Control_RunDLL intl.cpl,,2", vbNormalFocus)

Hora
Call Shell("rundll32.exe shell32.dll,Control_RunDLL intl.cpl,,3", vbNormalFocus)

Data
Call Shell("rundll32.exe shell32.dll,Control_RunDLL intl.cpl,,4", vbNormalFocus)

Joystick 
Call Shell("rundll32.exe shell32.dll,Control_RunDLL joy.cpl", vbNormalFocus)

Mouse
Call Shell("rundll32.exe shell32.dll,Control_RunDLL main.cpl @0", vbNormalFocus)

Teclado
Call Shell("rundll32.exe shell32.dll,Control_RunDLL main.cpl @1", vbNormalFocus)

Impressoras
Call Shell("rundll32.exe shell32.dll,Control_RunDLL main.cpl @2", vbNormalFocus)

Fontes
Call Shell("rundll32.exe shell32.dll,Control_RunDLL main.cpl @3", vbNormalFocus)

Mail e Fax
Call Shell("rundll32.exe shell32.dll,Control_RunDLL mlcfg32.cpl", vbNormalFocus)

Multimdia
Audio
Call Shell("rundll32.exe shell32.dll,Control_RunDLL mmsys.cpl,,0", vbNormalFocus)

Vdeo
Call Shell("rundll32.exe shell32.dll,Control_RunDLL mmsys.cpl,,1", vbNormalFocus)

MIDI
Call Shell("rundll32.exe shell32.dll,Control_RunDLL mmsys.cpl,,2", vbNormalFocus)

CD
Call Shell("rundll32.exe shell32.dll,Control_RunDLL mmsys.cpl,,3", vbNormalFocus)

Avanado
Call Shell("rundll32.exe shell32.dll,Control_RunDLL mmsys.cpl,,4", vbNormalFocus)

Som
Call Shell("rundll32.exe shell32.dll,Control_RunDLL mmsys.cpl @1", vbNormalFocus)

Modem
Call Shell("rundll32.exe shell32.dll,Control_RunDLL modem.cpl", vbNormalFocus)

Rede
Call Shell("rundll32.exe shell32.dll,Control_RunDLL netcpl.cpl", vbNormalFocus)

Senha
Call Shell("rundll32.exe shell32.dll,Control_RunDLL password.cpl", vbNormalFocus)

Sistema
Geral
Call Shell("rundll32.exe shell32.dll,Control_RunDLL sysdm.cpl,,0", vbNormalFocus)

Gerenciador de Dispositivos
Call Shell("rundll32.exe shell32.dll,Control_RunDLL sysdm.cpl,,1", vbNormalFocus)

Perfis de Hardware
Call Shell("rundll32.exe shell32.dll,Control_RunDLL sysdm.cpl,,2", vbNormalFocus)

Performance
Call Shell("rundll32.exe shell32.dll,Control_RunDLL sysdm.cpl,,3", vbNormalFocus)

Opes de Acessibilidade
Teclado
Call Shell("rundll32.exe shell32.dll,Control_RunDLL access.cpl,,1", vbNormalFocus)

Som
Call Shell("rundll32.exe shell32.dll,Control_RunDLL access.cpl,,2", vbNormalFocus)

Exibir
Call Shell("rundll32.exe shell32.dll,Control_RunDLL access.cpl,,3", vbNormalFocus)

Mouse
Call Shell("rundll32.exe shell32.dll,Control_RunDLL access.cpl,,4", vbNormalFocus)

Geral
Call Shell("rundll32.exe shell32.dll,Control_RunDLL access.cpl,,5", vbNormalFocus)

Assistente (Adicionar novo Hardware)
Call Shell("rundll32.exe shell32.dll,Control_RunDLL sysdm.cpl @1", vbNormalFocus)

Data e Hora
Call Shell("rundll32.exe shell32.dll,Control_RunDLL timedate.cpl", vbNormalFocus)

DiskCopy
Call Shell("rundll32 diskcopy.dll,DiskCopyRunDll", vbNormalFocus)


---------------------------------------------------------------------------------

DESABILITANDO CTRL+ALB+DEL, CTRL+ESQ E ALT+TAB
'Digite esta linha em General / Declarations
Private Declare Function SystemParametersInfo Lib "user32" Alias "SystemParametersInfoA" (ByVal uAction As Long, ByVal uParam As Long, ByVal lpvParam As Any, ByVal fuWinIni As Long) As Long 

Sub CtrlAltDel(Desabilita As Boolean)
Call SystemParametersInfo(97, bDisabled, "1", 0)
End Sub

'Para desabilitar basta chamar o sub 
CtrlAltDel True
'Para reabilitar basta chamar o sub 
CtrlAltDel False


---------------------------------------------------------------------------------

EXIBINDO/OCULTANDO BARRA DE TAREFAS

'Digite as seguintes linhas em General.Declarations
Private Declare Function SetWindowPos Lib "user32" (ByVal hwnd As Long, ByVal hWndInsertAfter As Long, ByVal x As Long, ByVal y As Long, ByVal cx As Long, ByVal cy As Long, ByVal wFlags As Long) As Long

Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Const SWP_HIDEWINDOW = &H80
Const SWP_SHOWWINDOW = &H40

Sub TaskBar(Stat As Boolean)
Dim Thwnd As Long
Thwnd = FindWindow("Shell_traywnd", "")
If Stat Then
Call SetWindowPos(Thwnd, 0, 0, 0, 0, 0, SWP_SHOWWINDOW)
Else
Call SetWindowPos(Thwnd, 0, 0, 0, 0, 0, SWP_HIDEWINDOW)

End If
End Sub


---------------------------------------------------------------------------------

CHAMANDO O BROWSER DA INTERNET

Private Declare Function ShellExecute Lib "shell32.dll" Alias "ShellExecuteA" (ByVal hWnd As Long, ByVal lpOperation As String, ByVal lpFile As String, ByVal lpParameters As String, ByVal lpDirectory As String, ByVal nShowCmd As Long) As Long

'Para executar a API use o seguinte comando:

Call ShellExecute(0&, vbNullString, "http://vbbrasil.com", vbNullString, vbNullString, vbNormalFocus)
'Onde "http://vbbrasil.com"  o endereo da URL desejada


---------------------------------------------------------------------------------

CHAMANDO PROGRAMA DE E-MAIL

Private Declare Function ShellExecute Lib "shell32.dll" Alias "ShellExecuteA" (ByVal hWnd As Long, ByVal lpOperation As String, ByVal lpFile As String, ByVal lpParameters As String, ByVal lpDirectory As String, ByVal nShowCmd As Long) As Long

'E use o seguinte comando para enviar

Call ShellExecute(0&, vbNullString, "mailto: rom_soft@hotmail.com", vbNullString, "c:\", vbMaximizedFocus)
'Onde mailto: rom_soft@hotmail.com  o endereo para onde voc deseja mandar o E-mail.


---------------------------------------------------------------------------------

COLOCANDO BARRA DE ROLAGEM EM LISTBOXES

'Em General / Declarations , digite:
Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long

Const LB_SETHORIZONTALEXTENT = &H400 + 21


'No evento Form_Load , digite:
Call SendMessage(List1.hwnd, LB_SETHORIZONTALEXTENT, 300, 0&)
List1.Additem "Exemplo de uma linha muito comprida para ser exibida em um listbox pequeno"
'Onde List1  o ListBox que ter a Barra de Rolagem Horizontal.


---------------------------------------------------------------------------------

IMPRIMINDO TEXTO DIAGONAL

Digite o seguinte Programa em General / Declarations

'APIs para criar a fonte
Private Declare Function CreateFontIndirect Lib "gdi32" Alias "CreateFontIndirectA" (lpLogFont As LOGFONT) As Long
Private Declare Function SelectObject Lib "gdi32" (ByVal hdc As Long, ByVal hObject As Long) As Long
Private Declare Function DeleteObject Lib "gdi32" (ByVal hObject As Long) As Long
Const PROOF_QUALITY = 2
Const FW_NORMAL = 400

'Estrutura para configurar a fonte
Private Type LOGFONT
lfHeight As Long
lfWidth As Long
lfEscapement As Long
lfOrientation As Long

lfWeight As Long
lfItalic As Byte
lfUnderline As Byte
lfStrikeOut As Byte
lfCharSet As Byte
lfOutPrecision As Byte
lfClipPrecision As Byte
lfQuality As Byte
lfPitchAndFamily As Byte
lfFaceName As String * 32
End Type

'Sub criado para facilitar a criao da fonte
'Onde:
' OBJHDC -  a propriedade HDC do Objeto que ter a fonte

' Nome Fonte -  o nome propriamente dito - Ex: "Arial"
' Largura - Largura independente do objeto 
' Altura - Altura independente do objeto - Se a Largura for diferente da altura a fonte pode ficar achatada ou comprida
' Angulo - ngulo em graus que a fonte ser rotacionada
Sub CriaFonte(OBJHdc As Long, NomeFonte As String, Largura As Byte, Altura As Byte, Angulo As Integer)
Dim hfont As Integer, Fonte As LOGFONT
Fonte.lfHeight = Altura

Fonte.lfWidth = Largura
Fonte.lfEscapement = Angulo * 10
Fonte.lfOrientation = Angulo * 10
Fonte.lfWeight = 400
Fonte.lfItalic = 0
Fonte.lfUnderline = 0
Fonte.lfStrikeOut = 0
Fonte.lfCharSet = 0
Fonte.lfOutPrecision = 0
Fonte.lfClipPrecision = 0
Fonte.lfQuality = 2
Fonte.lfPitchAndFamily = 33
Fonte.lfFaceName = NomeFonte + Chr$(0)

hfont = CreateFontIndirect(Fonte)
Call SelectObject(OBJHdc, hfont)
DeleteObject hfont
End Sub


'No evento Click de Picture1 a impresso  feita
Private Sub Picture1_Click()

CriaFonte Picture1.hdc, "Times New Roman", 10, 150, 45
Picture1.CurrentX = 0
Picture1.CurrentY = 3000
Picture1.Print "Exemplo de um Texto de 45 Graus"

End Sub


---------------------------------------------------------------------------------

MOVENDO UM FORMULRIO SEM BARRA DE TTULOS

' Em General / Declarations, digite:
Const WM_SYSCOMMAND = &H112
Const SC_MOVE = &HF012
Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long
Private Declare Sub ReleaseCapture Lib "user32" ()

'No evento MouseDown do formulrio ( ou outro objeto que possa servir de barra de ttulo ), digite.

Private Sub Form_MouseDown(Button As Integer, Shift As Integer, X As Single, Y As Single)
If Button = 1 Then
ReleaseCapture
SendMessage Me.hwnd, WM_SYSCOMMAND, SC_MOVE, 0
End If
End Sub
'Nesse caso, verificou-se se o boto esquerdo foi pressionado (Button=1)
'ReleaseCapture - Fora a liberao do boto esquerdo
'SendMessage - Simulou a ao de mover o objeto (no caso ME, o prprio Form)

'OBS: Essa dica  para mover formulrios, porm pode-se usar para mover qualquer outro objeto que possua a propriedade hwnd
bastando mudar de Me.hwnd para Objeto.hwnd.


---------------------------------------------------------------------------------

TORNANDO UM FORMULRIO SEMPRE VISVEL 

'Em General / Declarations, digite:
Const SWP_FLAGS = 3
Const SWP_HWND_TOPMOST = -1

Const SWP_HWND_NOTOPMOST = -2
Private Declare Function SetWindowPos Lib "user32" (ByVal hwnd%, ByVal hb%, ByVal x%, ByVal y%, ByVal cx%, ByVal cy%, ByVal f%) As Integer

'Sub responsvel pela janela Sempre Visvel 
Sub OnTop(FormHwnd, Flutua As Boolean)
If Flutua = True Then
Call SetWindowPos(FormHwnd, SWP_HWND_TOPMOST, 0, 0, 0, 0, SWP_FLAGS)
Else
Call SetWindowPos(FormHwnd, SWP_HWND_NOTOPMOST, 0, 0, 0, 0, SWP_FLAGS)

End If
End Sub

'No evento Load do formulrio, digite:
Private Sub Form_Load()

OnTop Me.hwnd, True

End Sub

'Onde OnTop  a sub que foi criada

'Me.Hwnd  o identificador do formulrio em que deseja tornar sempre visvel

'True indica sempre visvel, False que dizer Normal


---------------------------------------------------------------------------------

FAZENDO PISCAR BARRA DE TTULO E O CONE DA BARRA DE TAREFAS

'E General/Declarations, digite:
Private Declare Function FlashWindow Lib "user32" (ByVal hWnd%, ByVal bInvert%) As Integer

'No Evento Timer
Private Sub Timer1_Timer()
FlashWindow Me.hWnd, 1
End Sub
'Para cancelar, desabilite o Timer e use o seguinte comando FlashWindow Me.hWnd, 0


---------------------------------------------------------------------------------

LIMITANDO A REA DE MOVIMENTO DO MOUSE

'Em General Declarations, digite:
Private Declare Function ClipCursor Lib "user32" (lpRect As Any) As Long
Private Type RECT
Left As Long
Top As Long
Right As Long
Bottom As Long
End Type

Public Function LimitaMouse(Optional X1 As Integer, Optional Y1 As Integer, Optional X2 As Integer, Optional Y2 As Integer) As Variant
Dim retangulo As RECT
retangulo.Left = X1
retangulo.Top = Y1
retangulo.Right = X2
retangulo.Bottom = Y2
ClipCursor retangulo
End Function

'No evento form_Load, digite a seguinte Linha
Private Sub Form_Load()

LimitaMouse 50,100, 300,200

End Sub

'No evento form_Unload, digite a seguinte Linha

Private Sub Form_Unload(Cancel As Integer)

LimitaMouse 0, 0, Screen.Width / Screen.TwipsPerPixelX, Screen.Height / Screen.TwipsPerPixelY 'Volta ao estado Normal

End Sub

'Onde 50  a posio X inicial do limite

'100  a posio Y inicial

'300  o X final

'200  o Y final

'Todos os valores so determinados em Pixel

'Cuidado com as coordenadas pois poder no ter mais o controle do mouse, dendo assim que usar o teclado para finalizar o programa.


---------------------------------------------------------------------------------

CRIANDO FORMULRIO DIFERENTE I

Crie um boto chamado Command1

'Em General/Declarations
Private Declare Function CreateEllipticRgn Lib "gdi32" (ByVal X1 As Long, ByVal Y1 As Long, ByVal X2 As Long, ByVal Y2 As Long) As Long

Private Declare Function SetWindowRgn Lib "user32" (ByVal hwnd As Long, ByVal hRgn As Long, ByVal bRedraw As Boolean) As Long

Sub Eliptico(Objeto)
Dim RGN As Long
RGN = CreateEllipticRgn(0, 0, Objeto.Width / Screen.TwipsPerPixelX, Objeto.Height / Screen.TwipsPerPixelY)
SetWindowRgn Objeto.hwnd, RGN, True
End Sub
'Onde Objeto  o Formulrio ou controle a ser modificado

'No evento click do boto

Private Sub Command1_Click()
Me.BackColor = QBColor(8) 'Apenas para destacar a cor
Eliptico Me 'O formulrio fica Elptico
Eliptico Command1 'O boto fica Elptico
End Sub


---------------------------------------------------------------------------------

CRIANDO FORMULRIO DIFERENTE II

'Crie um boto Chamado Command1
'Em General/Declarations, digite:

Private Declare Function CreateRoundRectRgn Lib "gdi32" (ByVal X1 As Long, ByVal Y1 As Long, ByVal X2 As Long, ByVal Y2 As Long, ByVal X3 As Long, ByVal Y3 As Long) As Long
Private Declare Function SetWindowRgn Lib "user32" (ByVal hwnd As Long, ByVal hRgn As Long, ByVal bRedraw As Boolean) As Long

Sub Retangulo(Objeto, Fator As Byte)
Dim RGN As Long
RGN = CreateRoundRectRgn(0, 0, Objeto.Width / Screen.TwipsPerPixelX, Objeto.Height / Screen.TwipsPerPixelY, Fator, Fator)

SetWindowRgn Objeto.hwnd, RGN, True
End Sub
'Onde Objeto  o Formulrio ou controle a ser modificado
'Fator  a distncia da curvatura do canto arredondado

'No evento Click do Command1
Private Sub Command1_Click()
Me.BackColor = QBColor(8) 'Apenas para destacar a cor
Retangulo Me, 80 'Coloca o formulrio com os cantos arredondados e fator 80 de rea
Retangulo Command1, 30

End Sub


---------------------------------------------------------------------------------

CRIANDO FORMULRIO DIFERENTE III

Essa API possibilita a criao de um formulrio de qualquer forma poligonal. At hoje eu s vi o 4 programas com formulrios diferentes: O Vibe MP3player 3D, Norton CrashGuard, Norton Utilities 3 e o RomSoft Photo Collection 10000. O uso de polgonos  mais complexo que os outros mtodos de criao de formulrios citados anteriormente. Veja o Exemplo, que cria um formulrio na forma de uma estrela de quatro pontas:

'Em General / Declarations, digite:

Option Base 1
Private Declare Function CreatePolygonRgn Lib "gdi32" (lpPoint As POINTAPI, ByVal nCount As Long, ByVal nPolyFillMode As Long) As Long
Private Declare Function SetWindowRgn Lib "user32" (ByVal hwnd As Long, ByVal hRgn As Long, ByVal bRedraw As Boolean) As Long
Private Type POINTAPI
x As Long
y As Long
End Type

'No evento Form_Load
Private Sub Form_Load()
Dim Pontos(8) As POINTAPI 'Cria uma matriz de 8 Pontos
Dim RGN As Long
Me.Width = 1500
Me.Height = 1500
Pontos(1).x = 0 'Determina as oito coordenadas de uma estrela de quatro pontas (em Pixel)
Pontos(1).y = 0
Pontos(2).x = 50
Pontos(2).y = 25
Pontos(3).x = 100
Pontos(3).y = 0
Pontos(4).x = 75
Pontos(4).y = 50
Pontos(5).x = 100
Pontos(5).y = 100
Pontos(6).x = 50
Pontos(6).y = 75
Pontos(7).x = 0
Pontos(7).y = 100
Pontos(8).x = 25
Pontos(8).y = 50
RGN = CreatePolygonRgn(Pontos(1), 8, 0)
SetWindowRgn Me.hwnd, RGN, True
End Sub

'A API CreatePolygonRgn possui os seguintes parmetros

'Pontos(1), Primeiro elemento da matriz

'8 - Nmero de vrtices do polgono (Elementos da matriz)

'0 - Como ficaria o polgono se as suas linhas se sobrepossem (0 ou 1)



---------------------------------------------------------------------------------

COMBINANDO FORMULRIOS PARA CRIAR TELAS DIFERENTES

Private Declare Function CreateEllipticRgn Lib "gdi32" (ByVal X1 As Long, ByVal Y1 As Long, ByVal X2 As Long, ByVal Y2 As Long) As Long
Private Declare Function SetWindowRgn Lib "user32" (ByVal hwnd As Long, ByVal hRgn As Long, ByVal bRedraw As Boolean) As Long
Private Declare Function CombineRgn Lib "gdi32" (ByVal hDestRgn As Long, ByVal hSrcRgn1 As Long, ByVal hSrcRgn2 As Long, ByVal nCombineMode As Long) As Long

Private Declare Function CreateRectRgn Lib "gdi32" (ByVal X1 As Long, ByVal Y1 As Long, ByVal X2 As Long, ByVal Y2 As Long) As Long
Const RGN_AND = 1
Const RGN_OR = 2
Const RGN_XOR = 3
Const RGN_DIFF = 4

Private Sub Form_Load()
Dim RGNFim As Long, RGN1 As Long
RGNFim = CreateEllipticRgn(0, 0, 200, 200)
RGN1 = CreateEllipticRgn(25, 110, 175, 180)
Call CombineRgn(RGNFim, RGNFim, RGN1, RGN_XOR)

RGN1 = CreateEllipticRgn(25, 100, 175, 170)
Call CombineRgn(RGNFim, RGNFim, RGN1, RGN_OR)
RGN1 = CreateEllipticRgn(50, 50, 80, 80)
Call CombineRgn(RGNFim, RGNFim, RGN1, RGN_XOR)
RGN1 = CreateEllipticRgn(150, 50, 120, 80)
Call CombineRgn(RGNFim, RGNFim, RGN1, RGN_XOR)
RGN1 = CreateEllipticRgn(50, 190, 150, 300)
Call CombineRgn(RGNFim, RGNFim, RGN1, RGN_OR)
SetWindowRgn Me.hwnd, RGNFim, True

End Sub






90 Dicas de Visual Basic




---------------------------------------------------------------------------------

90 Dicas de Visual Basic
1 - VB4 - Atalhos para VB no Windows 95
2 - VB3/VB4 - Criando um procedimento de pausa
3 - VB3/VB4 - No v embora sem avisar
4 - VB3/VB4 - Programando de forma diferente em tempo de desenho e execuo
5 - VB4 - Novas funes de Registry
6 - VB3 - Carregando forms do VB4 no VB3
7 - VB3/VB4 - Como calcular as coordenadas (x,y) de qualquer posio de um crculo
8 - VB3/VB4 - Procurando por nulos retornados por chamadas DLL
9 - VB4 - Erros de Licena
10 - VB3/VB4 - Valores de retorno no requeridos
11 - VB4 - Atualizando Bound Controls por uma List Box
12 - VB4 - Destacando uma linha em um DBGrid
13 - VB3/VB4 - Objetos vazios?
14 - VB3/VB4 - Livre-se dos zeros inteis
15 - VB3/VB4 - Campos na peneira
16 - VB3/VB4 - Convertendo Identificadores em Rtulos e Cabealhos
17 - VB3/VB4 - Alteraes com Mid
18 - VB3/VB4 - Quando usar SendKeys
19 - VB3/VB4 - Resoluo do Monitor
20 - VB3/VB4 - Fechando todos os forms
21 - VB4 - Subclasse para ChDir
22 - VB3/VB4 - Graduando Cores
23 - VB3/VB4 - Arquivo Existe?
24 - VB3/VB4 - Tenha uma linha 3D entre um menu pulldown e uma barra de ferramentas
25 - VB4/VB3 - Providenciando menus especficos de contexto para seus objetos de interface
26 - VB4 - Use seus prprios menus popup
27 - VB3/VB4 - Criando mltiplos nveis de diretrios
28 - VB3/VB4 - Mova e redimensione controles com preciso
29 - VB4 - GetModuleUsage em 32 bits
30 - VB3/VB4 - Melhorando as declaraes API (I)
31 - VB3/VB4 - Melhorando as declaraes API (II - a volta do SendMessage)
32 - VB3/VB4 - Simplificando chamadas API atravs de funes prprias
33 - VB4 - Criando senhas para banco de dados
34 - VB4 - Abrindo bases de dados com senha
35 - VB4 - Posicionando uma Common Dialog
36 - VB3/VB4 - Economize memria com uma picture box
37 - VB3/VB4 - Lembra-se do SWAP?
38 - VB3/VB4 - Uma histria de trs beeps
39 - VB3/VB4 - Converso de Nulos
40 - VB4 - Determinando a classe de qualquer objeto
41 - VB4 - Identificando um controle genrico
42 - VB3/VB4 - Removendo o move
43 VB4 - Otimizando consultas no Jet 3
44 - VB3/VB4 - Piscar ou no piscar
45 - VB3/VB4 - Travou tudo?
46 - VB3/VB4 - Painel de Percentual
47 - VB3/VB4 - Painel de Percentual com SQL Count
48 - VB3 - Mantendo constantes
49 - VB3/VB4 - Inconsistncia no caminho da aplicao (app.path)
50 - VB3/VB4 - Bloqueando funes Copiar e Colar em caixas de texto
51 - VB3/VB4 - Digitao em Grid
52 - VB3/VB4 - O Caracter ENTER 2
53 - VB3/VB4 - Limpando Combos Read-Only
54 - VB3/VB4 - Brancos no controle Masked Edit Box
55 - VB3/VB4 - Forando caracteres maisculos
56 - VB3/VB4 - Pinte meu mundo ... nas cores padro!
57 - VB3 - Desmarcar todos os itens de uma lista
58 - VB4 - Ordenando Colunas da ListView
59 - VB4 - Problemas com o Print
60 - VB4 - Use o Code Profiler para depurao (debug)
61 - VB3/VB4 - Onde est o Beep?
62 - VB3/VB4 - TAB automtico para o prximo campo
63 - VB3/VB4 - Simplificando a condio de um IF
64 - VB3/VB4 - Eliminando o IF quando possvel
65 - VB4 - Forms redimensionveis sem barra de ttulo
66 - VB3/VB4 - Adicionando segurana a uma base de dados Jet
67 - VB3/VB4 - Passe nothing aos forms com cautela
68 - VB3/VB4 - Prevenindo interao do usurio, via MousePointer e Enabled
69 - VB4 - Depure simultaneamente o servidor  OLE e a aplicao
70 - VB4 - Identificando uma unidade de CD em Rede
71 - VB4 - Soluo para bug no DBGrid
72 - VB4 - Propriedade Count, de Control Array, no documentada
73 - VB4 - Determinando se um objeto foi definido (Set)
74 - VB3/VB4 - Criando Inner Joins (SQL) numa base Access (Jet)
75 - VB4 - O desafio de criar Add-ins
76 - VB4 - Evitando Erros de Atualizao em Bases Access
77 - VB4 - Descarregando DLLs fora de controle
78 - VB3/VB4 - Movendo itens em uma list box
79 - VB3/VB4 - Sub Main, iniciando um projeto sem interface
80 - VB3/VB4 - Capturando parmetros
81 - VB3/VB4 - Onde est o fim?
82 - VB3/VB4 - F1 e o Help de Contexto
83 - VB3/VB4 - Validando CGC e CPF
84 - VB3/VB4 - Performance com a SQL Passthrough
85 - VB4 - Listas erradas de API
86 - VB3/VB4 - Centralizando Forms (I)
87 - VB4 - Centralizando Forms (II - A verso)
88 - VB3 - Menu Colar Alternativo
89 - VB3/VB4 - J estou no ar?
90 - VB3/VB4 - Seja Feliz



---------------------------------------------------------------------------------

 
 


INTRODUO
90 Dicas de Visual Basic 
Suplemento Especial - As figurinhas que faltavam
 Bafo! Gritou o garotinho de oito anos, ao trocar uma figurinha com o colega.
No meu lbum falta a nmero trinta, voc tem?. Anos depois, continuamos a trocar figurinhas. Por exemplo: Voc sabe como criar um servidor OLE?, Como acesso um banco ODBC no VB?, e outras figurinhas. Nesta edio, trazemos algumas delas.
Conveno: VB3/VB4 = verso aplicvel  dica. Por = autor. Aperf. = adaptado e aperfeioado por. 

  


---------------------------------------------------------------------------------

1 - VB4 - Atalhos para VB no Windows 95
Com a verso quatro do Visual Basic e o novo ambiente de sistema operacional de 32 bits, eu usava trs verses do VB. Alguns de meus clientes no aceitavam aplicaes construdas em VB4. E alguns no migraram para 32 bits. Aps instalar ambas as verses 16 e 32 bits em minha mquina com Windows 95, descobri que qualquer projeto com extenso .VBP pode ser aberto no VB 32 bits. Este  o melhor caminho para executar a correta verso do VB:
1) Salve todos os arquivos de um projeto na mesma pasta.
2) Crie um atalho para o VB, na edio que voc usa.
3) Arraste o projeto (VBP) para o topo do atalho e (tcham); o projeto ser aberto por esta verso.
Por  Joe Sytniak*

---------------------------------------------------------------------------------

2 - VB3/VB4 - Criando um procedimento de pausa
Falta um comando do VB para provocar uma pausa (wait, dalay, pause etc.) no processamento? Basta implementar uma pequena rotina, em um mdulo (.BAS):
Function FU_Delay (Quanto As Double, PermiteDoEvents As Integer) As Double
'executa uma pausa na aplicao
    'quanto = tempo da pausa (em segundos)
    '    pode ter fraes de segundos
    'PermiteDoEvents  true ou false
    '     DoEvents permite realizar outras tasks do Windows
    'Timer  uma funo do VB que retorna
    '    o nr. de segundos desde meia noite
    ' RETORNO: o tempo de looping
    '    que devido a impreciso e multitask, pode ser
    '    diferente do valor pedido
    Dim Inicio As Double
    Dim Check  As Double
    Dim Contador As Double
    Contador = Timer
    Inicio = Timer
    Do Until Check >= (Inicio + Quanto)
        Check = Timer
        If PermiteDoEvents Then DoEvents
    Loop
    'o VB d uma boa preciso em 1/10 de segundo
    'a 1/100 a preciso j  parcialmente comprometida
    'a 1/100 a preciso se perde
    FU_Delay = (Timer - Contador)
End Function
Note que no foi necessrio inserir um controle Timer no form para executar esta pausa.
Para acessar a rotina basta citar o nome e passar o nmero de segundos. O segundo parmetro informa se deve ser usado DoEvents.
vPausa = FU_Delay (4.5, False) 'pausa de 4 segundos e meio
O valor de vPausa poder no ser 4.5 (uma subtrao poder servir de teste). O Windows executa vrias tarefas ao mesmo tempo. Assim, uma tarefa poder no ser executada duas vezes com o mesmo tempo. A chamada ao DoEvents provoca uma melhoria na distribuio de tarefas, para que a pausa no atrapalhe os demais programas.
Se desejar criar um procedimento de pausa mais simples, sem tanta preocupao com a preciso, a funo poder ser chamada por outra rotina, do tipo sub. Abaixo, esta rotina toma o DoEvents como ativado e simplifica a sintaxe.
SU_Delay 4.5 'chamada a uma pausa, como se fosse um comando
Sub SU_Delay (quanto As Double)
 Dim ret As Double
 ret = FU_Delay(quanto - .01, true)
End Sub 
Por Charles A. Mller.



---------------------------------------------------------------------------------

3 - VB3/VB4 - No v embora sem avisar
Usurios podem, por descuido, sair da sua aplicao atravs da Lista de Tarefas ou Barra de Tarefas, ou ainda, saindo do Windows. Adicione um procedimento ao evento QueryUnload do form principal para prevenir o problema.
Este evento possui um parmetro, o UnloadMode, que permite detectar como o fechamento do form foi invocado. Se o valor for 1, representa que o fechamento ocorreu via cdigo (comando Unload). Se o valor do parmetro cancel for alterado para true, o fechamento do form  cancelado. Veja QueryUnload e Using MDI Features no Help do VB para maiores detalhes.
Private Sub Form_QueryUnload (Cancel As Integer, UnloadMode As Integer)
 If UnloadMode <> 1 Then
  If 7 = MsgBox("Deseja realmente sair do sistema?", 32 + 4) Then
    'respondeu no
   Cancel = True
  End If
 End If
End Sub
O cdigo acima (VB4) tambm se aplica ao VB3.
Por Jiyang Keven Luo*, aperf. por Charles A. Mller

---------------------------------------------------------------------------------

 
 
4 - VB3/VB4 - Programando de forma diferente em tempo de desenho e execuo
Este cdigo habilita ou desabilita funes durante o desenho e teste. O cdigo poder permanecer durante o desenvolvimento, sem afetar o usurio final. Verifique se o caminho procurado  o caminho do seu projeto e no o diretrio final de sua aplicao.
If InsStr(App.Path, "VB") Then
 'execute os processos prprios
 'de debug e no de sistema executvel
End IF
Uma variao :
If InsStr(App.Path, "VB") Then Stop
Voc pode inserir este cdigo para depurao (debug); se voc esquecer, isto no causar - repetimos - problemas ao usurio.
Por John Bailey *

---------------------------------------------------------------------------------

5 - VB4 - Novas funes de Registry
H uma lista de novas funes do VB4 para trabalhar com entradas do Registry (ou INI, em plataformas Windows de 16 bits): GetSetting, GetAllSettings, SaveSetting e DeleteSetting. Estas novas funes eliminam a necessidade de chamadas API. Veja no VB Help maiores detalhes procurando "Additional Information on VBA Registry Functions".
Por Denis Basaric e Norbert Steinhoefel-Carqueville*

---------------------------------------------------------------------------------

6 - VB3 - Carregando forms do VB4 no VB3
Voc no poder ler um form do VB4 diretamente no VB3. A definio do form deve ser alterada em um editor de texto (ASCII).
VERSION 4.00
Begin VB.Form Form1
 Caption = "Form1"
 ClientHeight = 5940
 'demais propriedades
 '...
End
Attribute VB_Name = "Form1"
Attribute VB_Creatable = False
Attribute VB_Exposed = False
Option Explicit
Private Sub Form_Load()
 '...
End Sub
Mude a verso 4.00 para VERSION 2.00, remova todos os sufixos VB. no comando Begin Form, remova todas as declaraes Attribute. Remova tambm a clusula Private de algumas rotinas (eventos). Salve o arquivo e abra-o no VB3.
Por Saji Varghese*, aperf. por Charles A. Mller

---------------------------------------------------------------------------------

7 - VB3/VB4 - Como calcular as coordenadas (x,y) de qualquer posio de um crculo
A rotina abaixo (parte da biblioteca CodeBank) calcula as coordenadas de qualquer ponto, medida em graus, numa circunferncia, num crculo ou numa elipse. Como voc  pode notar,  uma rotina simples, mas extremamente til no desenho de grficos ou movimentao de objetos.
Public Sub DegreesToXY(CenterX as Long, CenterY as Long, _
 Degree as Double,  RadiusX as Long, RadiusY as Long, _
 X as Long, Y as Long)
 Dim Convert As Double
 Convert = 3.141593 /180 ' PI/180
 X = CenterX - (Sin(-Degree * Convert) * RadiusX)
 Y = CenterY - (Sin((90 + Degree) * Convert) * RadiusX)
End Sub
Por Ward Hitt, autor do Visual Components Inc.'s CodeBank*

---------------------------------------------------------------------------------

8 - VB3/VB4 - Procurando por nulos retornados por chamadas DLL
Aps uma chamada a DLL (API), o valor retornado pode conter um nulo. Um dos meios de eliminar este nulo  procurar o caracter Chr$(0), como neste exemplo.
'yourstring  a string retornada pela API, e pode conter um nulo
Dim CheckForNull As Integer
CheckForNull = Instr(YourString, Chr$(0))
If CheckForNull > 0 Then Left$(YourString, CheckForNull - 1)
Por Marc Mercuri*

---------------------------------------------------------------------------------

9 - VB4 - Erros de Licena
Enfrentei um interessante problema tentando instalar a edio Enterprise do VB4 no Windows 3.1. A nova verso do VB usa o Registry, que no Windows 3.1  limitada a 64Kb. Como consultor de uma grande empresa, tenho muitos softwares instalados no meu laptop para trabalhar em vrios ambientes de cliente. J havia instalado MS Office, MS Project e Lotus Suite Standart. O arquivo REG.DAT j estava cheio.
Quando instalei o VB4, no foram indicados erros de instalao. Mas, ao tentar us-lo, juntamente com alguns controles, surgiram erros de "licena".
Liguei para a Microsoft e recebi a seguinte orientao:
1. Remover manualmente o VB4.
2. Remover manualmente todos os OCXs e OCAs do diretrio Windows/System.
3. Remover manualmente a OC25.DLL do Windows/System.
4. Renomear REG.DAT para REG.OLD.
5. Remover todos os itens do grupo Start Up (Iniciar).
6. Remover as entradas Load e Run em WIN.INI.
7. Remover  todos os TSRs de AUTOEXEC.BAT.
8. Se voc utiliza um drive compactado, libere 6MB de espao em um volume no compactado.
9. "Resete" o micro.
10.  Reinicie o Windows e reinstale o VB4.
11.  Redefina as opes de sistema.
Nota do VBPJ*: Se estes erros de licena ocorrerem no Windows 95, remova e reinstale o VB4 para corrigir o problema.
Por Jim Gilligan*

---------------------------------------------------------------------------------

10 - VB3/VB4 - Valores de retorno no requeridos
Voc no precisa retornar valores em todas as funes. Mas,  uma implementao um pouco perigosa.
Private Sub Form_Load( )
 dice
End Sub
Function dice ( ) As Integer
 dice = Int(Rnd * 6) + 1
 MsgBox "Esta  uma rotina que no retorna valor"
End Function
Nota da Redao: Esta implementao apenas  til em empresas que padronizam todo o cdigo para funes. Recomendamos o uso de sub e no de function, para um procedimento que no retorna valor (Charles A. Mller).
Dica de Andy Rosa*

---------------------------------------------------------------------------------

11 - VB4 - Atualizando Bound Controls por uma List Box
Quando voc desejar que os Bound Controls (controles associados a dados) sejam atualizados em eventos de listas ou combos, adicione este cdigo no evento click (ou double-click) da lista ou combo:
Data1.RecordSet.Bookmark = DBCombo1.SelectedItem
Como resultado, seu registro corrente passar a ser o registro com a chave indicada na lista ou combo. Todos os Bound Controls so atualizados automaticamente.  necessrio definir apenas as propriedades RowSource e ListField. Assim, economiza-se tempo que seria gasto em converses de dados e atualizao de campos.
Por Peter Klein*

---------------------------------------------------------------------------------

12 - VB4 - Destacando uma linha em um DBGrid
Para destacar uma linha no controle DBGrid, adicione o registro corrente  SellBookmarks Collection:
Private Sub DBGrid_RowColChange _
 (LatRow As Variant, ByVal LasRow As Integer)
 If Data1.RecordSet.RecordCount Then
  DBGrid.SelBookmarks.Add _
   Data1.RecordSet.Bookmark
 End If
End Sub
Por Peter Chyan*

---------------------------------------------------------------------------------

13 - VB3/VB4 - Objetos vazios?
No se pode usar a funo IsEmpty para determinar se uma varivel-objeto (como Form ou qualquer controle) possui valor.  possvel, entretanto, usar a implementao abaixo para determinar se uma varivel de form (ou outro objeto) est vazia.
If Not frmChild Is Nothing Then
 Unload frmChild
End If
Por Arn Cota*

---------------------------------------------------------------------------------

14 - VB3/VB4 - Livre-se dos zeros inteis
Vamos retirar os zeros inteis da varivel mystring (que contm "00030"). Abaixo, um interessante caminho para isto.
Mystring = CStr(CInt(mystring))
Outro caminho :
Mystring = Str(Val(mystring))
Por Brad Herbert* aperf.  por Charles A. Mller

---------------------------------------------------------------------------------

15 - VB3/VB4 - Campos na peneira
Muitas vezes, utiliza-se um campo formatado para exibio, e se grava um valor "peneirado", ou seja, de um formato especfico. As funes abaixo "limpam" strings de nmeros ou alfabticos. Esta  uma alternativa ao controle Masked Edit.
Function FU_LimpaNumero (campo As String) As String
    'recebe string numrica
    'retorna string numrica sem pontos, vrgulas etc.
    'exemplo FU_LimpaNumero("1.245,90") = "1234590"
    Dim VA_Posicao As Integer
    Dim VA_Caracter As String * 1
    Dim VA_Resultado As String
    VA_Resultado = ""
    VA_Posicao = 1
    Do While VA_Posicao <= Len(campo)
        VA_Caracter = Mid$(campo, VA_Posicao, 1)
        If IsNumeric(VA_Caracter) Then
            VA_Resultado = VA_Resultado & VA_Caracter
        End If
        VA_Posicao = VA_Posicao + 1
    Loop
    FU_LimpaNumero = VA_Resultado
End Function
Function FU_LimpaAlfa (campo As String) As String
    'recebe string alfanumrica
    'retorna string de letras maisculas  sem pontos, vrgulas, nmeros etc.
    'exemplo FU_LimpaNumero("Adq-7465") = "ADQ"
    Dim VA_Posicao As Integer
    Dim VA_Caracter As String * 1
    Dim VA_Resultado As String
    VA_Resultado = ""
    VA_Posicao = 1
    campo = UCase(campo)
    Do While VA_Posicao <= Len(campo)
        VA_Caracter = Mid$(campo, VA_Posicao, 1)
        If Asc(VA_Caracter) > 64 And Asc(VA_Caracter) < 91 Then
            VA_Resultado = VA_Resultado & VA_Caracter
        End If
        VA_Posicao = VA_Posicao + 1
    Loop
    FU_LimpaAlfa = VA_Resultado
End Function
Por Charles A. Mller

---------------------------------------------------------------------------------

16 - VB3/VB4 - Convertendo Identificadores em Rtulos e Cabealhos
Programadores possuem o hbito de criar identificadores (nomes de variveis, por exemplo) por fuso de palavras como SobreNome ou CargoAnterior.  possvel usar alguns destes nomes para se criar labels (rtulos) e descries diversas. A funo abaixo insere espaos, "quebrando" os identificadores a cada inicial maiscula. Assim, CargoAnterior ser convertido para Cargo  Anterior.
Function SpaceName (src As String) As String
 Dim i as Integer, tgt As String
 tgt = Left$(src,1)
 For i = 2 To Len(src)
  Select Case Mid$(src, i-1, 1)
   Case "a" To "z"
    Select Case Mid$ (src, i, 1)
     Case "A" To "Z"
       tgt = tgt & " "
    End Select
  End Select
  tgt = tgt & Mid$(src, i, 1)
 Next i
 SpaceName = tgt
End Function
Por Pat Dooley*

---------------------------------------------------------------------------------

17 - VB3/VB4 - Alteraes com Mid
Voc provavelmente j conhece a funo e o comando Mid, que retorna uma substring com um nmero especfico de caracteres, ou seja, uma parte da string usada como parmetro. Mas, voc sabe como usar o Mid para substituir caracteres no meio de uma string? O Mid  uma pequena excentricidade do VB, pois, altera um de seus prprios argumentos. Mas, isto economiza uma srie de instrues de concatenao, observe:
Dim mystring As String
mystring = "SOME STRING"
If Mid(mystring, 2, 1) = "O" Then
 Mid(mystring, 2, 1) = "A" ' substituindo caracter
End If
Por William Storage*

---------------------------------------------------------------------------------

18 - VB3/VB4 - Quando usar SendKeys
A funo SendKeys (que simula o aperto de teclas) adiciona timos recursos de "interveno" do programador na operao do sistema. As teclas podem ser enviadas para um form ou controle (neste caso o controle dever ter o foco). A rotina abaixo simplifica o processo.
Sub SendKeyTo(KeyValue As String, cCnt As Control)
 If cCnt.Enabled Then cCnt.SetFocus
 SendKeys KeyValue
End Sub
Por Saji Varghese, aperf. por Charles A. Mller

---------------------------------------------------------------------------------

19 - VB3/VB4 - Resoluo do Monitor
H uma forma simples de se obter a resoluo de um monitor de vdeo usando uma API.
'declarations
Declare Function GetSystemMetrics Lib "User" (ByVal nIndex As Integer) As Integer
'...
Sub Form_Resize( )
 dim xRes As Integer
 dim yRes As Integer
 xRes = GetSystemMetrics(0)
 yRes = GetSystemMetrics(1) 
 If  xRes < 1024 And yRes < 768 Then
  'adicione seu cdigo de controle de dimenses
 End If
End Sub
Por Sanjay Mawalkar*



---------------------------------------------------------------------------------

20 - VB3/VB4 - Fechando todos os forms
Sub UnloadAll()
 Dim f As Integer
 f = Forms.Count
 Do While f > 0
  Unload Forms(f - 1)
  If f = Forms.Count Then Exit Do
  f = f - 1
 Loop
End Sub
Por Denis Basaric*

---------------------------------------------------------------------------------

21 - VB4 - Subclasse para ChDir
Se o seu diretrio de aplicao  D:\OldDir, a chamada ChDir(C:\NewDir) ir alterar o drive corrente para o diretrio NewDir. Mas o diretrio da aplicao continuar sendo D:\OldDir. Causa: o ChDir altera o diretrio na unidade diferente citada e no muda o da aplicao. Esta rotina, de classe subdefinida (subclassed), melhora a alterao de drives:
Sub ChDir(Path As String)
 Dim TargetDrive As String
 If Mid(Path, 2, 2) = ":\" Then
  TargetDrive = Left(Path, 3)
  If TargetDrive <> Left(CurDir, 3) Then
   ChDrive TargetDrive
  End If
 End If
 'chama a funo ChDir do VB
 VBA.ChDir Path
End Sub
Por Bruce Hamilton, Centric Development*

---------------------------------------------------------------------------------

22 - VB3/VB4 - Graduando Cores
Este  um meio fcil para pintar o fundo de um form, com efeito de uma "cortina degrad", isto , da cor mais clara no topo, para a cor mais escura na base. Para especificar a cor usada passe valores true ou false para os parmetros Vermelho, Verde ou Azul. Combinaes de cores (true) formam outras cores como roxo, amarelo, cinza etc.
O cdigo abaixo cria o efeito com a cor azul.
FadeForm Me, False, False, True
    'qualform, vermelho?,verde?, azul?
J este cria o efeito com a cor ciano (mistura do azul com verde)
FadeForm Me, False, True, True
    'qualform, vermelho?,verde?, azul?
O cdigo da rotina segue abaixo
Sub FadeForm(frm As Form, pRed As Integer, pGreen As Integer, pBlue As Integer)
    Dim SaveScale As Integer, SaveStyle As Integer, SaveDraw As Integer
    Dim y As Long, x As Long, i As Long, J As Long, pixels As Long
    'salvar as configuraes atuais do form
    SaveScale = frm.ScaleMode
    SaveStyle = frm.DrawStyle
    SaveDraw = frm.AutoRedraw
    'pintar a tela
    frm.ScaleMode = 3
    pixels = Screen.Height / Screen.TwipsPerPixelY
    x = pixels / 64 + 0.5
    frm.DrawStyle = 5
    frm.AutoRedraw = True
    For J = 0 To pixels Step x
        y = 240 - 245 * J / pixels
        If y < 0 Then y = 0
        frm.Line (-2, J - 2)-(Screen.Width + 2, J + x + 3), RGB(-pRed * y, -pGreen * y, -pBlue * y), BF
    Next J
    'restaura configuraes do form
    frm.ScaleMode = SaveScale
    frm.DrawStyle = SaveStyle
    frm.AutoRedraw = SaveDraw
End Sub
Por Timothy L. Birch*

---------------------------------------------------------------------------------

23 - VB3/VB4 - Arquivo Existe?
Uma das formas de testar se um arquivo especfico existe  utilizando a funo Dir$, com a identificao completa do caminho do arquivo. Dir$ ir retornar o exato nome do arquivo (se existir) ou um nulo, se no existir. Por exemplo:
If Dir$("C:\MYDIR\MYFILE.TXT") <> "" Then
 'o arquivo existe
Else
 'arquivo no encontrado
End If
Por Chuong Van Huynh*

---------------------------------------------------------------------------------

24 - VB3/VB4 - Tenha uma linha 3D entre um menu pulldown e uma barra de ferramentas
Desenhe um 3DPanel com um tamanho (height) de 30. Este tamanho no  fcil de ser desenhado manualmente. Apague a Caption, mude o BevelOuter para 1 (inset), border para 1 e Align para Top. Desenhe a barra de ferramentas e o menu.
Por Mrio Manuel Mouro Coelho*

---------------------------------------------------------------------------------

25 - VB4/VB3 - Providenciando menus especficos de contexto para seus objetos de interface
Muito da facilidade do Windows 95 inicia com o fato de que a interface de seus objetos possui seus prprios menus de contexto, acessados por um simples click no boto direito do mouse. Voc, desenvolvedor, poder criar seus prprios menus de contexto tambm . O exemplo abaixo mostra como isto funciona numa list box chamada lstSample:
1. Defina o menu de contexto, assim como se define qualquer outro menu, como o menu de help, com seus submenus. Diferente do menu de help, entretanto, este menu de contexto dever ter a propriedade visible = false, para que nunca seja visto pelo usurio na barra de menus pull-down. A caption nunca ser vista pelo usurio, mas, dever ser algo compreensvel para o programador como Context Menu de lstSample. O nome, neste exemplo, ser mnu_lstSample. Agora, basta definir os submenus, que iro aparecer sobre o objeto com o click do boto direito do mouse. Por exemplo, crie menus como &Remover Item, Remover &Todos, &Adicionar Item etc.
2. No evento MouseMove do objeto desejado (neste caso, lstSample), invoque o mtodo PopupMenu.
 Private Sub lstSample_MouseDown (button As Integer, Shift As Integer, _
  X As Single, Y As Single)
  Const vbRightButton = 2 'constante VB4
  If button And vbRightButton Then
   PopupMenu mnu_lstSample
  End If
 End Sub
3. Deve, obviamente, ser adicionado o cdigo de cada evento menu_click. Veja no help do VB mais detalhes sobre o mtodo PopupMenu.
Por Hassan Davis*, MicroHelp Inc
Nota da redao: segundo o autor*, esta  uma dica de VB4, mas, j existe menu de contexto (mtodo popup) no VB3, que funciona no Windows 3.1x (e parcialmente no Windows 3.0). A diferena  que, o mtodo possui menos recursos que no VB4. H um exemplo no VB3 (SAMPLES/CALLDLLS) que mostra como desenvolver Popup menus atravs da API TrackPopupMenu (biblioteca User);  um exemplo do VB2 que no deveria estar na verso 3. No VB3, a constante vbRightButton chama-se RIGHT_BUTTON. (Charles A. Mller)

---------------------------------------------------------------------------------

26 - VB4 - Use seus prprios menus popup
Em VB4, se voc quiser mostrar um menu popup para um texto, um menu de sistema (default) ser mostrado primeiro e o seu menu s aparecer quando o menu default for fechado. Para contornar este problema:
Private Sub Text1_MouseDown(Button As Integer, _
  Shift As Integer, X  As Single, Y As Single)
 If Button = 2 Then
  Text1.Enabled = False
  PopupMenu myMenu
  Text1.Enabled = False
 End If
End Sub
Por Mrio Coelho*

---------------------------------------------------------------------------------

27 - VB3/VB4 - Criando mltiplos nveis de diretrios
Programas de instalao ou outras aplicaes podem solicitar ao usurio para que informe onde deseja instalar arquivos ou efetuar alguma operao. Se o diretrio no existir, ser criado. Mas, o usurio poder informar vrios subnveis de diretrios inexistentes que devem ser criados. A rotina abaixo cria qualquer diretrio, em todos os nveis. Basta informar o drive (como C:) e o caminho (como \MYAPP\MYDIR\SUBDIR) a ser criado (se no existir). Podem ser criados diretrios de nomes longos em VB4 32 bits, mas, em 16 bits (inclusive VB3), os nomes sero truncados para a conveno 8.3. Voc poder adicionar seu prprio cdigo de manipulao de erros, conforme sua necessidade.
Abaixo temos um exemplo simples da criao de vrios nveis de diretrios:
Sub CreateLongDir(sDrive as String, sDir as String)
 Dim sBuild As String
 While Instr(2, sDir, "\") > 1
  sBuild = sBuild & Left(sDir, Instr(2, sDir, "\") - 1)
  sDir = Mid$(sDir, InStr (2, sDir, "\")
  If Dir$(sDrive & Sbuild, 16) = "" Then MkDir sDrive & sBuild
 Wend
End Sub
Sub Test( )
 Call CreateLongDir ("C:", "Test\MyApp\MyDir\Long Directory Name\")
End Sub
Por Jeffrey Renton*

---------------------------------------------------------------------------------

28 - VB3/VB4 - Mova e redimensione controles com preciso
Ao desenhar um form, voc pode utilizar mouse e teclado para obter melhor preciso. Esta dica serve tambm para Access 2 e 7 (95).
A - Quando  voc desejar alterar o tamanho de um controle:
1. Selecione-o
2. Pressione SHIFT e use as teclas de navegao para alterar o tamanho.
B - Quando voc desejar mover um controle:
1. Selecione-o
2. Pressione CTRL e use as teclas de navegao para alterar a posio.
Por Chris Kunicki, repassada por John Chmela (VB Developer's Network)*
Nota da Redao: Os autores informam que a dica (A e B) se aplica ao VB3, mas, no funciona. Acrescentamos, ainda, alguns dados abaixo.
C - Evitando acidentes
1. O VB4 possui o recurso de trava (lock) de tamanho e posio em tempo de desenho. Selecione o(s) controle(s) e clique no boto "cadeado", na barra de ferramentas.
2. O VB3 no possui o recurso de "cadeado", mas,  possvel mover ou selecionar os controles com maior cuidado (para alterar vrias propriedades ao mesmo tempo, por exemplo). Basta selecionar, passando o mouse no form, uma rea em volta dos controles. Isto no se aplica a controles contidos em outros objetos (como painis, frames e picture boxes).
D - Maior preciso
Use os valores numricos de tamanho e posio: left, top, height e width - correspondentes a  x, y' (eixo y do topo para baixo) , h (altura) e b (base), respectivamente - na Janela de Propriedades ou Janela de Cdigo. Esta tarefa  um pouco rdua, ento, desenhe o controle com medidas aproximadas para depois, ajustar, via digitao de valores.
Aperf. por Charles A. Mller

---------------------------------------------------------------------------------

29 - VB4 - GetModuleUsage em 32 bits
Encontrei uma soluo para o problema, da API GetModuleUsage no trabalhar em VB4 a 32 bits. A TaskID retornada pela funo Shell pode ser usada por AppActivate. Assim:
TaskID = Shell("DOSAPP.exe", vbNormalFocus)
On Error GoTo finished
While True
 DoEvents
 AppActivate TaskID
Wend
Finished:
 On Error GoTo 0
Por John Muiri, repassada por John Chmela (VB Developer's Network)*

---------------------------------------------------------------------------------

30 - VB3/VB4 - Melhorando as declaraes API (I)
Muitas rotinas API so declaradas como funo, mas, o valor de retorno no  sempre utilizado. A funo SendMessage, por exemplo, depende  da mensagem enviada, no importando o valor de retorno. Outro exemplo  a funo Shell (se o objetivo for chamar e no monitorar um programa externo, o retorno no ser utilizado).
Ocorrem chamadas assim:
Dim dummy As Integer
dummy = SendMessage(Text1.hWnd, WM_PASTE, 0, 0&)
A varivel s foi necessria por causa da declarao. Uma alternativa,  declarar a funo como Sub e usar um alias (apelido).
Declare Sub SUB_SendMessage Lib "User" Alias "SendMessage" (byVal hWnd as _  Integer , byVal msg as Integer, byVal wParam as Any, byVal lParam As Any)
Agora, chame pelo nome declarado e no pelo original:
SUB_SendMessage Text1.hWnd, WM_PASTE, 0, 0&
 Observe que, seu cdigo ficou mais produtivo de ser mantido.
Por Francesco Baleno* (texto revisado por Charles A. Mller)

---------------------------------------------------------------------------------

31 - VB3/VB4 - Melhorando as declaraes API (II - a volta do SendMessage)
Quando falava de SendMessage (veja dica anterior), lembrei de um outro truque que pode ser interessante para ser includo em seus hbitos de programao.  Quando uso algumas mensagens em particular, o argumento lParam , na verdade, considerado uma combinao de dois valores (words) . A mensagem EM_LINESCROLL pode rolar uma text box multilinha; a primeira word (low word) contm o nmero de linhas para rolar verticalmente e a segunda (hight word), contm o nmero de linhas para rolar horizontalmente.
'rola uma caixa de texto em "HO" linhas
'horizontalmente e "VE" linhas verticalmente
'obs.: isto no funciona corretamente
longValue& = HO * 65536 + VE
...
SUB_SendMessage Text1.hWnd, EM_LINESCROLL, 0, longValue
O cdigo acima no trabalha corretamente se HO for positivo e VE for negativo.
A soluo  dividir o nmero long de lParam em dois, na declarao
Declare Sub SUB_SendMessage2 Lib "User" Alias "SendMessage" (byVal hWnd as _  Integer , byVal msg as Integer, byVal wParam as Any, byVal lParam1%,_  lParam2)
A chamada passa a ser:
SUB_SendMessage2 Text1.hWnd, EM_LINESCROLL, 0, HO, VE
Este truque funciona, pois um valor long integer na "pilha" corresponde a combinao de dois valores word combinados.
Por Francesco Balena*

---------------------------------------------------------------------------------

32 - VB3/VB4 - Simplificando chamadas API atravs de funes prprias
Algumas chamadas  funo API (DLL) so bastante complexas. Uma dica  criar uma funo de cdigo VB que chama a API. Assim, a complexidade da API s ir aparecer uma vez.
Por exemplo, a funo GetPrivateProfileString que, captura uma configurao de arquivo INI.
Declare Function GetPrivateProfileString Lib "Kernel" (ByVal _
 lpApplicationName As String, ByVal lpKeyName As Any, ByVal lpDefault _
 As String, ByVal lpReturnedString As String, ByVal nSize As Integer, _
 ByVal lpFileName As String) As Integer
A chamada da funo ficaria assim:
Global Const Ini_File = App.path & "\Myapp.INI)
'...
Dim VA_LastUser
'chamada a API para capturar o contedo de "lastuser" na seo "options"
On Error GoTo Erro_INI
Dim VL_Sec As String, VL_Key As String, VL_Size As Integer
Dim VL_Return As String, VL_FileName As String
Dim VL_SizeHandle As Integer, VL_Valid As Integer
Dim Va_Msg As String
Const CL_Default = "" 'retorno no caso de no encontrar
VL_Sec = "options"
VL_Key = "lastuser"
VL_Size = 30
VL_Return = Space$(VL_Size) 'string  a retornar
VL_SizeHandle = Len(VL_Return) 'tamanho da string de retorno
VL_FileName = Ini_File 'arquivo no formato INI
VL_Valid = GetPrivateProfileString(VL_Sec, VL_Key, CL_Default, _
 VL_Return, VL_SizeHandle, VL_FileName)
 VA_LastUser = Left$(VL_Return, VL_Valid)
    Exit Function 'ou Exit Sub
Erro_LeMeuINI:
 VA_LastUser = CL_Default
Nota-se uma complexa e grande quantidade de cdigo. A API no retorna a string procurada e sim um buffer. O contedo  retornado por um argumento (!) e precisa ser formatado com o tamanho do buffer (funo left). Para eliminar todo este cdigo a cada necessidade (cada campo INI) foi implementada uma chamada assim:
Global Const Ini_File = App.path & "\Myapp.INI)
'...
Dim VA_LastUser
'chamada a API para capturar o contedo de "lastuser" na seo "options"
Global Const Ini_File = "MYAPP.INI"
...
VA_LastUser = FU_Le_MeuINI ("options", "lastuser", 30)
Abaixo, um exemplo de funo "tradutora" de API:
Function FU_Le_MeuIni (VL_Sec As String, VL_Key As String, VL_Size As Integer) As String
    'recebe nome da seo e do pargrafo e tamanho da string de retorno
    'retorna valor encontrado (string) ou ""
    'usa a constante Ini_File e
    'a API (Windows 3.1 Kernel) GetPrivateProfileString
    On Error GoTo Erro_LeMeuINI
    Dim VL_Return As String, VL_FileName As String
    Dim VL_SizeHandle As Integer, VL_Valid As Integer
    Dim Va_Msg As String
    Const CL_Default = "" 'retorno no caso de no encontrar
    VL_Return = Space$(VL_Size) 'string  a retornar
    VL_SizeHandle = Len(VL_Return) 'tamanho da string de retorno
    VL_FileName = Ini_File 'arquivo no formato INI
    VL_Valid = GetPrivateProfileString(VL_Sec, VL_Key, CL_Default, _
  VL_Return , VL_SizeHandle, VL_FileName)
    FU_Le_MeuIni = Left$(VL_Return, VL_Valid)
    Exit Function
Erro_LeMeuINI:
    FU_Le_MeuIni = CL_Default
    Resume Next
End Function
A funo usada como exemplo  do VB3, podendo ser usada em VB4 se sua aplicao for em 16 bits. Mas, o conceito de criar funes "traduzidas" ou "facilitadas" de API  aplicvel a qualquer verso do Visual Basic.
Por Charles A. Mller

---------------------------------------------------------------------------------

33 - VB4 - Criando senhas para banco de dados
O Jet Engine 3 (exclusivo32 bits) inclui um novo sistema de segurana baseado em senhas de BD mais complexas e mais seguras que o antigo modelo de grupos. Este sistema disponibiliza uma senha para abertura da base de dados . Este sistema  mais simples de ser utilizado mas   facilmente comprometido, pois, todos os usurios possuem a mesma senha. Entretanto, voc poder usar tanto o recurso de DB Password (senha de BD) como o de workgroup (grupos), ao mesmo tempo (isto , que dar mais segurana).
Manipule uma DB Password no VB, usando o novo mtodo NewPassword (database object), com cdigos como este:
Dim wrk As Workspace
Dim db As Database
Set wrk = DBEngine.Workspace(0)
Set db = wrk.OpenDatabase("MYDB.MDB",true)
'note que a base deve ser aberta como exclusiva
'alterando a senha atual (em branco) para "NewPass"
db.NewPassword "","NewPass
Por Paul Litwin*

---------------------------------------------------------------------------------

34 - VB4 - Abrindo bases de dados com senha
Na dica anterior mostrei a definio de senhas para bancos Jet 3 (32 bits). Para abrir o banco  necessrio passar a senha no parmetro Connect. No exemplo abaixo, a senha  "bobo".
Dim wrk As Workspace
Dim db As Database
Set wrk = DBEngine. Workspace(0)
Set db = wrk.OpenDatabase("MYDB.MDB", false, false, ";PWD=bobo")
O parmetro Connect (4o parmetro)  case sensitive (diferencia A de a) e - ao contrrio do que diz a documentao do VB - os parmetros exclusive e read-only (2o e 3o parmetros) devem ser falsos.
Por Paul Litwin*

---------------------------------------------------------------------------------

35 - VB4 - Posicionando uma Common Dialog
Ficou triste ao ler a documentao do VB, que dizia "Note: you cannot specify where a common dialog is displayed" (voc no poder especificar onde  mostrada uma common dialog)? Ento tente isto:
Inicie um novo form (que ser usado apenas para isto)  em vez de chamar a abertura do dilogo diretamente do form principal.
(FrmDummy_OpenSaveAs.Hide)
Defina as propriedades Left e Top conforme desejar e inicie a common dialog deste form. No Windows 95 (VB 4-32 bits) , a common dialog ir aparecer na posio do form que a chamou. Como o form hide (oculto), isto  imperceptvel para o usurio.
Por Reinhard Salchner*

---------------------------------------------------------------------------------

36 - VB3/VB4 - Economize memria com uma picture box
Mudar a propriedade AutoRedraw para true consiste em redesenhar forms rapidamente e desperdiar alguma memria. Se seu form  redimensionvel, o desperdcio pode ser bem maior, pois, o bitmap persistente criado pelo AutoRedraw  to grande quanto as dimenses mximas do form para revelar a sada oculta, quando o usurio maximiza ou minimiza a janela. Se o grfico a ser redimensionado (mantido) for pequeno em relao ao form, voc economizar memria se utilizar uma picture box com AutoRedraw = True e BorderStyle = 0, enquanto o AutoRedraw do form ser desativado (False).
Por Francesco Balena*

---------------------------------------------------------------------------------

37 - VB3/VB4 - Lembra-se do SWAP?
Fiquei surpreso quando notei que no Visual Basic, o comando SWAP do Qbasic no havia sido implementado. Na rotina abaixo, que usei para ordenar um arquivo, o SWAP  simulado com strings, mas funciona com outros tipos de dado.
Private Sub Form_Load( )
 Dim a,b As String * 4
 Dim c As String * 4 ' varivel para alternao (Swap)
 a = "Joo"
 b = "Francisco"
 Debug.Print "Antes do swap: " & a & " " & b
 c = a
 a = b
 b = c
 Debug.Print "Aps o swap: " & a & " " & b
End Sub
Por David Ferber*

---------------------------------------------------------------------------------

38 - VB3/VB4 - Uma histria de trs beeps
Seus programas no esto executando instrues em VB4 como executavam em VB3? Tente isto , em Qbasic, VB3 e VB4.
BEEP: BEEP: BEEP
Ao depurar com passo (F8), este mui complexo cdigo, voc ir ouvir trs Beeps, exceto no VB4. No VB4, palavras reservadas seguidas de dois pontos (:) so consideradas labels (rtulos de desvio).
Assim funciona:
Beep
Beep
Beep
E voc ouvir os to esperados trs beeps.
Por David Ferber*

---------------------------------------------------------------------------------

39 - VB3/VB4 - Converso de Nulos
Em consultas a bancos de dados, o retorno de uma varivel, quando nula, poder no ser 0 (numrico) ou "" (string). Geralmente se resolve assim:
If Not IsNull(myrecordset.myfield) Then
 myvar = myrecordset.myfield
Else
 myvar = ""
 'myvar = 0, no caso de numricos
End If
Uma forma mais simples -
myvar = "" & myrecordset.myfield
Ou
myvar = val(0 & myrecordset.myfield) ' para numricos
Por Garold Minkin* aperf. por Charles A. Mller

---------------------------------------------------------------------------------

40 - VB4 - Determinando a classe de qualquer objeto
No VB4, o comando TypeOf trabalha com qualquer objeto vlido. Exemplo:
'Esta rotina imprime informaes especficas de objetos
Public Sub PrintObjectInfo (YourObject As Object)
 If TypeOf YourObject Is CDesk Then
  Print "Object Type: Mesa"
  Print "Nmero de pernas: " & YourObject.NumberOfLegs
 ElseIf TypeOf YourObject Is CHouse Then
  Print "Object Type: Casa"
  Print "Nmero de portas: " & YourObject.NumberOfDoors
 End If
 'impresso das propriedades de mesmo nome
 Print "Data de Venda: " & YourObject.Date
 Print "Preo de Venda: " & YourObject.Price
 '...
End Sub
Por Hassan Davis*, MicroHelp Inc

---------------------------------------------------------------------------------

41 - VB4 - Identificando um controle genrico
Quando uma rotina pode trabalhar com muitos tipos de controles diferentes, a funo TypeOF pode detectar o tipo de controle em tempo de execuo:
Function MyFunc (ctl As Control)
 If TypeOf ctl Is TextBox Then
  '...
 ElseIf TypeOf ctl Is CommandButton Then
  '...
 '...
 End If
End Function
Este cdigo funciona em VB3 e VB4. A diferena  que no VB4, alm de controles e forms, qualquer objeto vlido pode ser identificado. O VB4 adiciona ainda, a funo TypeName que indica (numa string) o nome da classe do objeto:
Function MyFunc (ctl as Control)
 Dim sClassType As String
 'typeName  novidade do VB4
 sClassType = TypeName(ctl)
 Select Case sClassType
  Case "TextBox"
   '...
  Case "CommandButton"
   '...
  'case ...
 End Select
End Function
Os nomes das classes de controle, no ambiente do VB, aparecem na Properties Window (janela de propriedades, ao lado do nome do controle).
Por Senthil Shanmugham*

---------------------------------------------------------------------------------

42 - VB3/VB4 - Removendo o move
Em alguns casos,  interessante impedir o usurio de mover um form. No VB isto pode ser implementado com APIs:
Declare Function GetMenu% Lib "User" (ByVal hWnd%)
Declare Function RemoveMenu% Lib "User" (ByVal hWnd%, ByVal nPosition%, ByVal wFlags%)
'...
Dim Res%
Res = RemoveMenu(GetMenu(Form.hWnd), SC_MOVE, MF_BYPOSITION)
Por Phil Parsons*

---------------------------------------------------------------------------------

43 VB4 - Otimizando consultas no Jet 3
Se voc precisa analisar a performance de uma query (consulta) no Jet Engine 3.0 (banco .MDB), atravs de um plano de execuo de consultas, voc deve adicionar esta chave de Registry e execut-la no RegEdit.
\\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Jet\3.0\Engines\Debug
Para a nova chave Debug, adicione o nome JETSHOWPLAN (tudo maisculo) e valor ON. O Jet ir gerar um arquivo chamado SHOWPLAN.OUT, que ir mostrar  planos de execuo de queries associados com sua aplicao. Como estes arquivos podem se tornar muito grandes rapidamente, no se esquea de alterar o valor para OFF ao terminar.
Queries e bases de dados bem definidas iro gerar planos que, indicaro o uso de ndices e/ou a tecnologia Rushmore. Bases e consultas mal definidas exibem apenas uma leitura de tabela.
Por Rob Karatzas*

---------------------------------------------------------------------------------

44 - VB3/VB4 - Piscar ou no piscar
Geralmente, ao criar uma ajuda de barra de situao (status bar help), voc ir adicionar cdigo no evento MouseMove de controles e forms. A barra de status poder ser uma picture box com um label, um controle statusbar (VB4-32 bits) ou - como mais usado - um painel 3D. O problema  que o mouse se movimenta vrias vezes no mesmo controle, fazendo a barra de status "piscar". Para resolver este problema, basta verificar se a frase atual  diferente da frase nova. Criamos ainda uma funo que controla a barra de status.
Global Const CG_EXPLICAPADRAO = "Pressione F1 para obter ajuda."
'...
Sub SU_Explica (oque As String)
     'rotina em VB3, usa um painel 3D
   oque = Trim(oque)
    If oque = "" Then oque = CG_EXPLICAPADRAO
    If Len(oque) > 1 And Right$(oque, 1) <> "." Then
        oque = oque & "." 'acrescenta ponto final
    End If
   'muda a inicial para maiscula
    If Len(oque) > 1 Then
        oque = UCase(Left(oque, 1)) & Right(oque, Len(oque) - 1)
    Else
        oque = UCase(oque)
    End If
    'altera a barra se o novo contedo for diferente
    If MainForm.PA_Status.Caption <> oque Then
        MainForm.PA_Status.FloodShowPct = False
        MainForm.PA_Status.FloodType = 0
        MainForm.PA_Status.Caption = oque
    End If
End Sub
A funo usa uma constante (CG_EXPLICAPADRAO) que, contm uma frase genrica, para quando no houver o que explicar sobre um form ou objeto.
Para chamar a funo:
Sub CmdOK_MouseMove(Button As Integer, Shift As Integer, X As Single, _
 Y As Single)
 SU_Explica "Grava as alteraes no banco de dados."
End Sub
Pode ser utilizado tambm o evento GotFocus (para resposta ao teclado). Neste caso, o LostFocus dever limpar a barra de status (como a frase genrica).
Sub txtNome_LostFocus ( )
 SU_Emplica ""
End Sub
Por Dave Robins*, aperf.  por Charles A. Mller

---------------------------------------------------------------------------------

 
 

As trs prximas dicas se referem ao que mostrar para os usurios em processos demorados:

45 - VB3/VB4 - Travou tudo?
Em alguns processos demorados, como consultas a bancos de dados, o usurio tem a impresso de que o sistema "travou". No Windows 3.1x, esta sensao  maior (pois o controle de tarefas  mais rudimentar). Para minimizar o problema, estes loops (laos de repetio de cdigo) demorados devem conter uma instruo DoEvents. Para no assustar o usurio,  alterada a propriedade MousePointer do Form para ampulheta (hourglass) ou aparece uma mensagem (ou percentuais) na barra de status.
Para mudar o ponteiro do mouse:
'antes
Me.MousePointer = 11 'hourglass (ampulheta)
ExecutarProcessoDemorado
'depois
Me.MousePointer = 0 'padro
Neste caso, se o sistema operacional for o Windows 95 (ou outro Win32), o usurio poder definir um cone animado nas suas configuraes.
Outra forma  utilizar um 3D Panel como barra de progresso percentual, usando as propriedades FloodPercent, FloodShowPct e  FloodType (detalhes no help do VB).
Estes so os recursos mais comuns. Mas, se a barra de status j estiver sendo utilizada como contador percentual, onde exibirei uma mensagem de "aguarde processando..."? E se eu desejar algo com maior destaque que um simples ponteiro de mouse?
No  possvel utilizar um form para isto ou uma caixa de mensagem, pois, eles esperariam uma ao do usurio - o que interromperia o processamento.
A soluo  incluir, no MDI Form (form principal), uma "faixa de aguarde". Assim:
1) No MDI Form de sua aplicao (aqui chamado de F00), insira uma picture box, que ser chamada PI_Aguarde. Esta picture box ser como uma barra de ferramentas. A propriedade Align dever ser 1 (Align Top). Esta  a "faixa de aguarde". Atribua false para a propriedade Visible.
2) Na PI_Aguarde, insira um rtulo (label), chamado LB_MsgAguarde. Use um tamanho e formato de fonte que d bastante destaque ao texto.
3) Voc poder inserir ainda, ao lado do label, uma outra picture (pequena e para enfeite), contendo um desenho que remeta  idia de espera. Este desenho, poder ser um cone de um semforo.
4) Em um mdulo (.BAS), insira a rotina SU_Aguarde, para manipular a faixa.
Eis o cdigo da rotina:
Sub SU_Aguarde (VA_Liga As Integer, VA_Msg As String)
    'recebe VA_Liga (true/false)
    'mostra a picture de aguarde com VA_Msg ou padro
  If VA_Liga Then
        F00.PI_Aguarde.Visible = True
        screen.MousePointer = 11 'hourglass
        VA_Msg = Trim$(VA_Msg)
        If Len(VA_Msg) = 0 Then
     'mensagem padro
            VA_Msg = "Por favor, aguarde: processando..."
        End If
        F00.LB_MsgAguarde.Caption = VA_Msg
    Else 'desliga
   F00.LB_MsgAguarde.Caption = ""
   F00.PI_Aguarde.Visible = False
        screen.MousePointer = 0 'default
    End If
End Sub
Esta rotina pblica passa mensagens para a faixa, que ficar ativa durante o processo demorado. O primeiro parmetro (true/false) liga ou desliga a barra. O segundo passa uma frase. No caso de frase vazia (""),  usada uma frase padro.
Para chamar a rotina:
'antes
SU_Aguarde True, "Por favor, aguarde: consultando tabela de Clientes..."
ExecutarConsultaGrid_Cliente
'depois
SU_Aguarde False, ""
Por Charles A. Mller

---------------------------------------------------------------------------------

46 - VB3/VB4 - Painel de Percentual
Na dica anterior, citei a barra de progresso percentual como uma forma de mostrar ao usurio como est um processo demorado (assim ele no pensar que o programa "travou"). Para mostrar um percentual,  preciso conhecer o tempo (ou tamanho) total da operao e a que ponto se est em dado momento de um loop (lao de repetio). Num programa de instalao, por exemplo, se conhece o tamanho total dos arquivos (ou quantidade de arquivos) a serem instalados e qual o arquivo atual (no loop). Com isto, o usurio v X% da instalao completa.
Para usar um 3D Panel como barra de percentual, siga estes passos:
1) Insira um 3D Panel, com nome PA_Status, no MDIForm (aqui chamado de F00). Atribua Align = Alig Botton.
2) Insira em um mdulo (.BAS) a rotina SU_BarraPerc.
Sub SU_BarraPerc (Perc As Integer, Acum As Integer)
  'recebe perc, um nmero de 0 a 100
    '100 = "desliga" a barra
    'Acum = boolean, acumula o anterior ou no (true/false) 
    Static VA_Vez
    Static VA_SaveCor As Long 

    If Acum Then
        Perc = Perc + F00.PA_Status.FloodPercent
    End If
    If Perc > 100 Or Perc < -1 Then
        MsgBox "Perc deve estar entre -1 e 100", 16, "Erro de parmetro _
      em SU_BarraPerc"
        Exit Sub
    End If
    If IsEmpty(VA_Vez) Or VA_Vez = 1 Then
        'liga barra - altera o painel
   F00.PA_Status.Caption = ""
   F00.PA_Status.FloodShowPct = True
        VA_SaveCor = F00.PA_Status.ForeColor
        F00.PA_Status.ForeColor = RGB(0, 0, 0)'preto
   F00.PA_Status.BevelOuter = 2 'raised
        F00.PA_Status.BevelWidth = 3
        F00.PA_Status.BorderWidth = 1
        F00.PA_Status.FloodType = 1 'left to right
        F00.PA_Status.FontSize = 9.75
    End If
    If Perc < 100 Then
        If Perc > 48 Then
            F00.PA_Status.ForeColor = RGB(255, 255, 255)'branco
        End If
        'mostra perc
        F00.PA_Status.FloodPercent = Perc
        VA_Vez = 2 'ou mais
    Else
        'desliga barra - reestrutura painel
   F00.PA_Status.BevelOuter = 1 'inset
        F00.PA_Status.BevelWidth = 1
        F00.PA_Status.BorderWidth = 3
        F00.PA_Status.FloodType = 0 'none
        F00.PA_Status.FontSize = 8.25
        F00.PA_Status.ForeColor = VA_SaveCor
        F00.PA_Status.FloodShowPct = False
   VA_Vez = 1
    End If
End Sub
Para chamar a rotina, basta passar o valor atual do percentual. O segundo parmetro, indicar se o percentual anterior ser acumulado com este. No exemplo abaixo, a barra  preenchida de 10% em 10%.
'teste da barra de percentual
 Dim i As Integer
 For i = 1 To 10
     SU_BarraPerc (i * 10), False
  MsgBox "Clique em OK para continuar"
 Next i
 SU_BarraPerc (100), False 'desliga a barra
Por Charles A. Mller



---------------------------------------------------------------------------------

47 - VB3/VB4 - Painel de Percentual com SQL Count
Complementando a dica anterior: Em uma operao de consulta a um banco de dados (tpica de desenvolvimento comercial), deveremos conhecer o tamanho do retorno da consulta. O nmero de linhas que ir retornar  calculado por um Select Count (instruo SQL para contador) igual ao Select que, posteriormente, ser usado para a consulta. O Count  uma operao rpida, principalmente em bancos Client Server (onde o clculo  executado no servidor). O retorno do Select Count  um nmero, contendo o total de linhas que seria trazido pela consulta. Com o Count, podero ser impedidas consultas longas demais, por exemplo.
Para o percentual, j temos o total. O "registro corrente"  obtido dentro do loop. No exemplo abaixo, carregamos um Grid simples com dados de uma tabela. Utilizamos as rotinas SU_Aguarde e SU_BarraPerc (explicadas nas dicas anteriores).
Sub SU_CarregarGrid ()
    Dim VA_Cmd As String
    Dim dynatemp As dynaset
    Dim dynacont As dynaset
    Dim VA_Cont, VA_Curr
    Dim VA_SevErro 
    On Error GoTo Erro_Carregar_Grid
    SU_Aguarde True, "Carregando tabela de cidades..."
    'rotina acima explicada na DICA ANTERIOR
    '... limpar o Grid
    '... formatar TB_Cidade.text 

    'query
    VA_Cmd = "Select * From CIDADE"
    If Len(TB_Cidade.Text) > 0 Then
        VA_Cmd = VA_Cmd + " Where CIDADE.Nome >= '" & (TB_Cidade.Text) & "' "
        VA_Cmd = VA_Cmd + "And CIDADE.Nome <= '" & (TB_Cidade.Text) & Chr(255)     & "' "
    End If
    Set dynatemp = db.CreateDynaset(VA_Cmd, VGl_SQLop) 

    'query do contador
    VA_Cmd = "Select Count(*) From CIDADE"
    If Len(TB_Cidade.Text) > 0 Then
        VA_Cmd = VA_Cmd + " Where CIDADE.Nome >= '" & (TB_Cidade.Text) & "' "
        VA_Cmd = VA_Cmd + "And CIDADE.Nome <= '" & (TB_Cidade.Text) & Chr(255)      & "' "
    End If
    Set dynacont = db.CreateDynaset(VA_Cmd, VGl_SQLop)
    If Not dynacont.EOF Then
        VA_Cont = dynacont(0)
    Else
        VA_Cont = 0
    End If
    If VA_Cont = 0 Then
        MsgBox "Nenhum registro de cidade encontrado."
        SU_Aguarde False, ""
        Gr_Grid.Row = 1
        '... marcar outra linha do grid
        Exit Sub
    End If
    'carga do grid
    Gr_Grid.Rows = VA_Cont + 1
    VA_Curr = 1
    Do While Not dynatemp.EOF
        SU_BarraPerc CInt(VA_Curr * 100 / VA_Cont), False
        'rotina explicada na DICA ANTERIOR
   Gr_Grid.Row = VA_Curr
        Gr_Grid.Col = 0
        Gr_Grid.Text = dynatemp("CodCidade")
        Gr_Grid.Col = 1
        Gr_Grid.Text = dynatemp("NomeCidade")
        Gr_Grid.Col = 2
        Gr_Grid.Text = dynatemp("UF")
        VA_Curr = VA_Curr + 1
        dynatemp.MoveNext
    Loop
     'desliga a barra de percentual
  SU_BarraPerc 100, false
  '... demais lgicas
  '... (tratamento de erro e formataes)
End Sub
Como esta rotina de carga de grid  enorme (e no VB4, o DBGrid faz isto sozinho), o cdigo acima apenas mostra a formao do Select Count e a chamada a SU_BarraPerc.
Por Charles A. Mller



---------------------------------------------------------------------------------

48 - VB3 - Mantendo constantes
Melhore o uso do arquivo CONSTANT.TXT. Para um novo projeto, copie o arquivo CONSTANT.TXT para MYCONST.TXT (para o diretrio do seu projeto). Inclua MYCONST.TXT no seu projeto (menu File ? Add File). Substitua (menu Edit ? Replace ou CTRL + R) todas as expresses Global por ' Global neste arquivo.
Quando for necessria uma nova constante, basta verificar se a mesma j foi definida pela Microsoft e remover o a ' do comentrio (reverter a substituio).
Por Stan Mlynek*

---------------------------------------------------------------------------------

49 - VB3/VB4 - Inconsistncia no caminho da aplicao (app.path)
Esteja atento quando usar a propriedade path (caminho) do objeto Application (App, aplicao). Se seu executvel est rodando na raiz de um drive, App.Path retornar o nome (letra:) na unidade e uma barra (algo como C:\). Apareceu quando o executvel est em um subdiretrio, a barra final no  acrescentada (C:\SUBDIR). Para testar e acrescentar a barra, use o cdigo abaixo que, retornar C:\SUBDIR\.
MyPath = App.Path
If Not Right(MyPath, 1) = Chr(92) then
 'chr 92 = "\"
 MyPath = MyPath & Chr(92)
End If
Por Clint Walker*

---------------------------------------------------------------------------------

50 - VB3/VB4 - Bloqueando funes Copiar e Colar 
   If KeyAscii = 3 Or KeyAscii = 22 Then KeyAscii = 0
    'CTRL+C = 3 e CTRL+V = 22, valores no constantes na tabela ANSI,
   'geram estas combinaes. Recurso no documentado
End Sub
Por Pedro Velazquez Dvila*



---------------------------------------------------------------------------------

51 - VB3/VB4 - Digitao em Grid
O controle Grid  uma tabela de exibio de dados, que no permite a digitao direta de valores em suas clulas (no estou falando do DBGrid).  possvel "simular" a aceitao de teclas atravs de cdigo. Basta um clique de mouse na clula e digitar. O programador deve ter includo as rotinas abaixo nos eventos KeyDown e KeyPress.
Sub Grid1_KeyDown (KeyCode As Integer, Shift As Integer)
    Select Case KeyCode
     Case &H8 'BACKSPACE
        If Len(Grid1.Text) > 0 Then
            Grid1.Text = Left(Grid1.Text, (Len(Grid1.Text) - 1))
        End If
     Case &H2E 'DEL
        Grid1.Text = ""
    End Select
End Sub
Sub Grid1_KeyPress (KeyAscii As Integer)
    Select Case KeyAscii
        Case Is <> 8, 9, 10, 13'no imprimveis
            Grid1.Text = Grid1.Text & Chr(KeyAscii)
    End Select
End Sub
No evento KeyPress todos os caracteres imprimveis so acrescentados ao texto da clula ativa do Grid. O evento KeyDown apaga o ltimo caracter com BACKSPACE ou o texto inteiro com a tecla DEL.
Por Charles A. Mller.

---------------------------------------------------------------------------------

52 - VB3/VB4 - O Caracter ENTER
Ele nunca aparece, mas existe. No Word  representado por um , nas caixas de texto do VB aparecolor="#000099">End Sub
No evento KeyPress todos os caracteres imprimveis so acrescentados ao texto da clula ativa do Grid. O evento KeyDown apaga o ltimo caracter com BACKSPACE ou o texto inteiro com a tecla DEL.
Por Charles A. Mller.

---------------------------------------------------------------------------------

52 - VB3/VB4 - O Caracter ENTER
Ele nunca aparece, mas existe. No Word  representado por um , nas caixas de texto do VB aparece um ? (caracter no imprimvel). Mas como aceitar e gerar este caracter?
1) No evento KeyPress, o caracter digitado (parmetro KeyAscii) vale 10 ou 13 (os dois valores do ENTER na tabela de caracteres ANSI).
2) Em quaisquer consistncias (como TextBox_Change ou anlise de variveis string) a funo Asc retornar 10 ou 13.
 Texto = Left(Texto, (Len(Texto) - 1))
 If Asc(texto) = 10 Or Asc(texto) = 13 Then MsgBox "Foi digitado um ENTER"
3) Numa textbox,  preciso gerar (via funo chr) o caracter 10 mais o caracter 13.
 text1.Text = "linha 1"
 text1.Text = text1.Text & Chr$(13) & Chr$(10) & "linha 2"
 text1.Text = text1.Text & Chr$(13) & Chr$(10)
 text1.Text = text1.Text & Chr$(13) & Chr$(10) & "linha 4"
4) Numa MsgBox, basta gerar o caracter 13.
Dim vmsg As String
vmsg = "linha 1"
vmsg = vmsg & Chr$(13) & "linha 2"
vmsg = vmsg & Chr$(13)
vmsg = vmsg & Chr$(13) & "linha 4"
MsgBox vmsg, 0, "texto 2"
Por Charles A. Mller.

---------------------------------------------------------------------------------

53 - VB3/VB4 - Limpando Combos Read-Only
Numa ComboBox com a propriedade Style = 2 (dropdown list), a propriedade Text  somente-para-leitura. Isto impede limpeza e troca de contedo por esta propriedade, em construes como estas:
Combo1.Text = "" 'ou
Combo1.Text = "novo contedo"
A soluo  limpar a combo com o mtodo clear e adicionar o valor novo.
Combo1.Clear
Combo1.AddItem "novo contedo "
Por Charles A. Mller.

---------------------------------------------------------------------------------

54 - VB3/VB4 - Brancos no controle Masked Edit Box
O controle MS Masked Edit apenas aceita entrada de dados dentro da mscara formatada (mask). Isto impede o programador de limpar a text do controle diretamente (masked1.Text = ""), pois, o caracter espao (ou nulo) pode no se encaixar no formato da mscara. Por exemplo, algumas possuem o formato # (aceitam somente nmeros). Logo, o "" no seria aceito. Este problema  resolvido por este cdigo:
vTemp = masked1.mask
masked1.Mask = ""
masked1.Text = ""
masked.mask = vTemp
Removendo a mscara  possvel limpar o texto. Depois, basta devolver a mscara original ao controle. Uso isto no evento Data1_ValidationError quando adiciono um novo registro.
Por Scott Wallace*

---------------------------------------------------------------------------------

55 - VB3/VB4 - Forando caracteres maisculos
Para facilitar a digitao de maisculos, independente do pressionamento de CAPS LOCK,  converta cada caracter no evento KeyPress.
Private Sub Form_KeyPress (KeyAscii As Integer)
 KeyAscii = Asc(UCase(Chr(KeyAscii)))
End Sub
Para que esta rotina funcione para todos os campos do form, altere a propriedade KeyPreview do mesmo para true.
Balamurali Balaji*

---------------------------------------------------------------------------------


56 - VB3/VB4 - Pinte meu mundo ... nas cores padro!
Apenas aps executar o ltimo "make EXE", troque seu esquema de cores e veja quantos fundos de cores voc possui fora do padro (escolhido pelo usurio final, via Painel de Controle). Infelizmente, muitos controles customizados (VBX/OCX) pecam neste detalhe importante.
Atravs do Painel de Controle, tente o esquema "deserto" no Windows 95, ou "vero" no Windows 3.1x, ou ainda, crie um outro esquema horroroso. Isto o ajudar a testar suas aplicaes de cores.
O VB4 dispe de 24 cores de sistema como constantes. No VB Help, procure por "Color Constants" ou "VBTranslateColor". Copie o valor hexadecimal para a propriedade de cor de seu objeto se ele foi erroneamente redefinido (fora do padro). Tambm  possvel copiar os valores de controles que estejam corretos, mas cuidado, a face do boto por exemplo, pode no ser cinza.
Por Clint Walker*
Nota do VBPJ*: Na nova paleta de cores do VB4, h um boto Default, que altera as cores do objeto selecionado para o padro do Windows. Verifique se a propriedade Appearance  3D para obter melhores resultados.
Notas do Frum Access (Charles A. Mller):
1)  uma regrinha antiga. Nunca mude as cores que, o usurio, que  o cliente, define externamente (no Windows), a menos que isto traga utilidade. Nestes casos, esteja atento para o significado das cores e sua harmonia (afinal, penteadeiras de camarim na tela no so desejveis).
2) No VB3, existem 19 cores de sistema nas constantes de CONSTANT.TXT.
3) Observamos (no CCE e VBA) que o VB5 ter, em sua paleta de cores, uma lista de alterao automtica para as cores padro (alm do boto default).

---------------------------------------------------------------------------------

57 - VB3 - Desmarcar todos os itens de uma lista
Uma forma rpida de retirar qualquer seleo de uma listbox :
list1.Selected (-1) = False
Isto no funciona em VB4.
Por John Mller*

---------------------------------------------------------------------------------

58 - VB4 - Ordenando Colunas da ListView
D ao seu controle ListView (32 bits) a funcionalidade de ordenao do Windows 95 Explorer. Este cdigo ordena a lista por qualquer coluna. Se a lista j estiver ordenada por esta coluna, a ordem ser invertida.
Private Sub ListView1_ColumnClick _
 (ByVal ColumnHeader As ColumnHeader)
 With ListView1
  If (ColumnHeader.Index -1) = .SortKey Then
   .SortOrder = (.SortOrder + 1) Mod 2
  Else
   .Sorted = False
   .SortOrder = 0
   .SortKey = ColumnHeader - 1
   .Sorted = True
  End If
 End With
End Sub
Por Joe Tuttle*

---------------------------------------------------------------------------------

59 - VB4 - Problemas com o Print
O cdigo abaixo funciona em VB3:
Cls
Print Spc(10); "Informe seu nome:";
CurrentX = 0
CurrentY = CurrentY + 1
Print Spc(10); "Informe seu nome:";
Este cdigo falha em VB4.  Retirando o ltimo ponto-e-vrgula do primeiro print:
Print Spc(10); "Informe seu nome:"
Acrescente Debug. antes de Print para testar:
Cls
Debug.Print Spc(10); "Informe seu nome:"
CurrentX = 0
CurrentY = CurrentY + 1
Debug.Print Spc(10); "Informe seu nome:";
Ou mude o comando para:
Print Space(10); "Informe seu nome:";
Por David Ferber*

---------------------------------------------------------------------------------

60 - VB4 - Use o Code Profiler para depurao (debug)
Algumas vezes, um erro de execuo se manifesta apenas aps a criao de um EXE e no em tempo de debug. O add-in Code Profiler poder ajud-lo.
1) Faa uma cpia do seu fonte.
2) Selecione o add-in Code Profiler.
3) Selecione o(s) arquivo(s) de cdigo a serem analisados.
4) Selecione a opo Line Hit Count.
5) Selecione o boto Add Profiler Code.
6) Compile (make EXE) o programa (MYAPP.EXE).
7) Execute o seu cdigo com erro.
8) Volte ao Code Profiler e selecione View Results no menu File.
Veja a ltima linha que foi executada ao ocorrer o erro. Voc ter que executar seu cdigo em modo debug enquanto olha os resultados do Code Profiler.
Por Rich Spencer*

---------------------------------------------------------------------------------

61 - VB3/VB4 - Onde est o Beep?
Este cdigo elimina o beep  quando se tecla ENTER ou TAB em uma text box que atingiu seu nmero mximo de caracteres.
Private Sub Form_KeyPress(KeyAscii As Integer)
If KeyAscii = 13 Or KeyAscii = 9 Then
  KeyAscii = 0
 End If
End Sub
Por Lonnie Brioadnax, Michael Ottomanelli e Preston Werntz*

---------------------------------------------------------------------------------

62 - VB3/VB4 - TAB automtico para o prximo campo
Esta dica  til para desenvolvimento de aplicaes VB com a forma de edio de terminais 3270 (IBM Mainframe). Quando o usurio termina de preencher um campo em um terminal 3270, o foco  imediatamente transmitido para o prximo campo.
Sub Text1.KeyUp (keycode as integer, shift as integer)
 If keycode > 47 and keycode < 123 then
  If Len(Me.ActiveControl.Text) = (Me.ActiveControl.MaxLenght) then
   Sendkeys "{TAB}"
  End If
 End If
End Sub
Por Lonnie Brioadnax, Michael Ottomanelli e Preston Werntz*

---------------------------------------------------------------------------------

63 - VB3/VB4 - Simplificando a condio de um IF
Quando voc escreve um comando IF (Se) assim:
If Category = "CM" Or Category = "M2" Or Category = "P1" Or Category = "ZZ" Then
 ProcesseEmpregado
End If
Poderia simplificar para:
Dim ValidValues As String
ValidValues = "CM M2 P1 ZZ"
If (InStr(1, ValidValues, Category)) > 0 Then
 ProcesseEmpregado
End If
Isto torna o cdigo mais rpido e mais fcil de ser entendido. Note que separei os valores com " " para no aparecerem strings como "CMM2P1ZZ"; voc poder utilizar espaos ou outros separadores como vrgulas, ponto-e-vrgulas etc.
Por Jaspreet Singh*
Notas de Redao (Charles A. Mller):
1) Este teste ainda aceitar "C", " P", "2 P" e outras expresses invlidas, por conterem o separador ou terem tamanho invlido. Para corrigir esta falha, basta usar espao (apenas) como separador e testar o tamanho da categoria.
 Category = Trim(Category)
 If (InStr(1, ValidValues, Category)) > 0 And Len(Category) = 2 Then
 '...
2) Este truque pode ser usado para vrias validaes, como ValidValues = "abcdefghijlmnopqrstuvxz".
3) Outra forma, ainda mais fcil,  criar um pequeno Select Case, separando os valores vlidos por vrgulas:
Select Case Category
  Case "CM",  "M2", "P1", "ZZ"
  ProcesseEmpregado
End Select

---------------------------------------------------------------------------------

64 - VB3/VB4 - Eliminando o IF quando possvel
Se voc atribui true ou false para uma varivel (ou propriedade), aps testar certas condies, poderia faz-lo sem o IF. Veja:
If (age > 18 And sex = "M") And (NecessitaSeContigente = True ) Then ServicoMilitar = True
Pode substituir por:
ServicoMilitar = (age > 18 And sex = "M") And (NecessitaSeContigente)
Outro exemplo:
If (age > 25 And Category = "M1") Or (age > 35 And Category = "C1") Or _
(Age > 45 And Category = "P1") Then ExecuteDemissao
Poderia ser:
Dim condio As Integer 'boolean
condio = (age > 25 And Category = "M1") Or (age > 35 And Category = "C1") Or (Age > 45 And Category = "P1")
If condio Then ExecuteDemissao
Por Jaspreet Singh*

---------------------------------------------------------------------------------

65 - VB4 - Forms redimensionveis sem barra de ttulo
Se voc alterar as propriedades (de um form) Caption = "" e ControlBox = False, uma BorderStyle = 3 (fixed) ir ser mostrada. Diferente da BorderStyle = 0 (none),  as propriedades 3D (VB4) so mantidas. Utilizando BorderStyle = 5 (sizable toolwindows, no VB4), voc ter um form redimensionvel.
 possvel (VB3/VB4) alternar o contedo da Caption, limpando-a quando conveniente. E no se esquea de acrescentar um boto de Fechar (unload) no seu form!
Por Clint Walker*

---------------------------------------------------------------------------------

66 - VB3/VB4 - Adicionando segurana a uma base de dados Jet
Para dar segurana a uma base de dados Jet (.MDB), verso 2.5 (Access 2/VB3/VB4-16 bit) ou verso 3.0 (Access 7/VB4-32 bit), siga estes passos:
1) Use o Access Workgroup Administrator para criar um novo grupo de trabalho, com uma no nula Workgroup ID.
2) Inicie o Access e altere a senha para o usurio default Admin.
3) Crie um novo usurio, adicione-o no grupo de Administrao, com os privilgios de administrador. Remova a conta Admin do grupo de administradores.
4) Reinicie o Access, conectando-se como novo usurio, e altere a senha.
5) Execute o Access Security Wizard (para o Access 2, copie de www.microsoft.com/accdev).
6) Crie o(s) usurios e o(s) grupo(s) de usurio, definindo seus privilgios.
7) No defina nenhuma permisso para o Admin.
Por Paul Litwin*

---------------------------------------------------------------------------------

67 - VB3/VB4 - Passe nothing aos forms com cautela
 uma boa idia passar o valor nothing a variveis de form para recuperar memria alocada pelo mdulo. Executando este recurso para um form j carregado,  entretanto, ir colocar o mdulo em um estado confuso. Veja:
Form2.show
Set Form2 = nothing
Form2.show
MsgBox forms.count & " forms carregados"
Unload Form2
Unload Form2
A segunda linha do cdigo tornou form2 nothing, mas o segundo use do form2.show ir mostrar uma segunda instncia do form2. A Forms Collection ir conhecer as duas instncias, mas apenas uma ser descarregada (Unload Form2).
Para contornar este problema, em VB4, esteja certo que o form est descarregado. No  possvel executar Set Me = Nothing. Mas, com a estrutura For Each (no existente no VB3)  possvel se conseguir o Nothing, no evento Form_Unload.
Private Sub Form_Unload (Cancel As Integer)
 Dim Form As Form
 For Each Form In Forms
  If Form Is Me Then
   Set Form = Nothing
   Exit For
  End If
 Next Form
End Sub
Por Willian Storage*

---------------------------------------------------------------------------------

68 - VB3/VB4 - Prevenindo interao do usurio, via MousePointer e Enabled
Mudar a propriedade MousePointer do form no impede a ao do usurio, via mouse ou teclado, apenas altera o desenho do ponteiro.
Para impedir que o usurio interaja com o sistema em algumas operaes, desenvolvi esta dica, aplicvel a MDI parent forms (janelas principais de interface mltipla) e seus MDI children forms (janelas filhas). Em alguns processos demorados (como carga de banco de dados) mude a propriedade enabled de um MDI child para false, assim:
'antes
Me.Enabled = False
Me.MousePointer = 11 'hourglass (ampulheta)
ExecutarProcessoDemorado
'depois
Me.Enabled = True
Me.MousePointer = 0 'padro
No caso de um MDI com muitos filhos ativos, crie uma Forms Collection e desative (enabled = false) cada form. Depois de desativ-los, use MDIForm.Hourglass = false.
Por Al Gehrig Jr*

---------------------------------------------------------------------------------

 
 
69 - VB4 - Depure simultaneamente o servidor  OLE e a aplicao
O VB4 no apenas permite a criao de servidores OLE, mas, tambm permite depurar (debug) o servidor e a aplicao cliente ao mesmo tempo. Se voc criar um servidor OLE remoto, altere a propriedade Instancing para Creatable SingleUse. Isto tornar o debugging muito mais interessante.
Cada vez que a classe for chamada, a aplicao tentar criar outra instncia do servidor. O servidor estar rodando em tempo de desenho, e o VB no iniciar outra cpia de si mesmo para carregar o servidor novamente. A soluo, , temporariamente, definir Instancing = Creatable MultiUse para uso nos testes. No se esquea de voltar para Creatable SingleUse antes de compilar o servidor OLE.
Por L.J. Johnson*

---------------------------------------------------------------------------------

 
 
70 - VB4 - Identificando uma unidade de CD em Rede
A API de 32 bits  bem mais rica que a de 16 bits. Entretanto, a funo GetDriveType mostra os Drives CDs em Rede, apenas como DRIVE_REMOTE (de rede). Isto  uma verdade, mas no completa. Combine a chamada a GetDriveType com uma chamada a GetVolumeInformation para determinar se o drive , ao mesmo tempo, de rede e CD.
A chamada indica o sistema de arquivos: FAT, NTFS, HPFS ou CDFS (CD File System).
Declare Function GetVolumeInformation  _
 Lib "Kernel32" _
  Alias "GetVolumeInformationA" _
 (ByVal lPRootPathName as String _
 ByVal lpVolumeNameBuffer As String _
 ByVal nVolumeNameSize As Long _
 ByVal lpVolumeSerialNumber As Long _
 ByVal lpMaximumComponentLenght As Long _
 ByVal lpFileSystemFlags As Long _
 ByVal lpFileSystemNameSize As Long) _
As Long
'...
pstrRootPath = "E:\"
pstrVolName = Space$(256)
pstrSystemType = Space$(32)
plngSysTypeSize = Clng(Len(pstr(SystemType))
plnVolNameSize = Clng(Len(pstrVolName))
plngRtn = GetVolumeInformation _
 (pstrRoothPath, pstrVolName, _
 plngVolNameSize, plngVolSerialNum,
 plngMaxFileNameLen, plngSysFlags, _
 pstrSystemType, plngSysTypeSize)
Por L. J. Johnson*

---------------------------------------------------------------------------------

 
 
71 - VB4 - Soluo para bug no DBGrid
H um srio bug (erro) em VB4, no controle Databoud Grid usado com forms modais.  Por exemplo, crie trs forms: form1, form2 e form3. Adicione um Command1 (boto) em cada form. No evento click  do boto em form1, chame o form2 como modal. No evento click  do boto em form2 chame o form3 como modal. Adicione um DBGrid no form3. No evento click  do boto em form3, use unload form3.
Execute o form1 e aperte nos referidos botes. No clique do terceiro boto, ocorre um erro de pilha (stack error) com o Visual Basic (tanto em 16 como em 32 bits). Rodando em Windows 3.1x, o sistema trava completamente.
Soluo: no use DBGrid com forms modais. Se, entretanto, voc precisar de um form modal, simule-o. Basta alterar a propriedade do form2 (o que chamou) para false. Voc poder criar uma property para fazer referncia ao form que chamou.
With FormModal
 .propCaller = Me
 .Show
End With
Agora altere Caller.Enabled = false no evento Load do form "modal". Volte para true no evento Unload.
Por Luis Miguel da Costa Pereira Ferreira*

---------------------------------------------------------------------------------

 
 
72 - VB4 - Propriedade Count, de Control Array, no documentada
No VB4, cada control array (vetor de controles)   uma collection e possui uma propriedade Count. Isto no ocorre com o VB3.  possvel, ento, se criar um loop (lao de repetio) tendo o Count como valor mximo.
Esta caracterstica no aparece nem nos manuais, nem no help do VB4. Talvez, pelo fato de que  uma control array collection no possui todas as propriedades e mtodos das demais collections. A propriedade Count e o mtodo Item so suportados, enquanto os mtodos Add e Remove no o so.
Este pequeno exemplo usa o Count para determinar qual elemento de um vetor de botes de opo foi selecionado.
Private Sub FindSelectedOption ( )
 Dim ij As Integer
 For ij = 0 To Option1.Count - 1
  If Option1(ij).Value Then
   MsgBox str(ij),0, "Opo Selecionada"
  End If
 Next ij
End Sub
Esta rotina trabalha apenas com nmeros contnuos. Se os elementos forem 0, 1, 3 e 4, ocorrer um erro (run time error 340), ao se tentar fazer referncia ao item 2.
Por Craig Everett*

---------------------------------------------------------------------------------

 
 
73 - VB4 - Determinando se um objeto foi definido (Set)
VB4 providencia uma srie de novas capacidades de uso de objetos. Porm, um objeto deve ser "setado" (definido) antes de ser referenciado. A nica forma de verificar se um objeto j foi definido  atravs do cdigo de erro (91).
Por exemplo:
Public Function IsSomething (ob As Object) As Long
 Dim J as Long
 Err.Clear
 On Error Resume Next
 If TypeOf ob Is TextBox Then
  J = 1
 End If
 Select Case Err.Number
  Case 91
  'error 91 = object not set
   IsSomethig = false
  Case 0
   IsSomething = true
  Case Else
   '... outro erro ocorreu
 End Select
 On Error GoTo 0
End Function
Por Evan Dickinson*

---------------------------------------------------------------------------------

 
 
74 - VB3/VB4 - Criando Inner Joins (SQL) numa base Access (Jet)
A palavra reservada In, da linguagem SQL (estrutura Inner Join) funciona em bases externas (ODBC), mas causa problemas em bases do Access (MDB). A sintaxe correta :
SELECT Authors.*
FROM C:\VB\Biblio1.Authors
INNER JOIN C:\VB\Biblio2.MDB.Titles
INNER JOIN C:\VB\Biblio3.MDB.Publishers
INNER JOIN C:\VB\Biblio4.MDB.[Publisher Comments]
ON Publishers.PubID = [Publisher Comments].PubID
ON Titles.PubID = Publishers.PubID
ON Authors.Au_ID = Titles.Au_ID
Os comandos de uso do SQL (como CreateDynaset) devem estar em uma s linha (ou _, no VB4). Usamos como exemplo, a base BIBLIO.MDB dividida em 4 bases, uma com cada tabela.
Ao usar ODBC, trabalhe com a clusula IN. Veja no Help do VB detalhes sobre o SQL.
Por Mark P. Atwood*, texto revisado por Charles A. Mller

---------------------------------------------------------------------------------

 
 
75 - VB4 - O desafio de criar Add-ins
Escrever add-ins (recursos adicionais) para o VB4 pode ser desafiador, recompensador e melindroso. Se voc no tomar cuidado, o VB poder "estranhar" algumas coisas e abortar.  Podem aparecer vrias mensagens, dependendo do sistema operacional. As mensagens so diversas, mas o resultado  o mesmo.
Por exemplo, no Windows 95, aparecem mensagens como "Este programa causou um erro e vai ser encerrado" ou "se o problema persistir, contate o fornecedor". No Windows 3.1x, podem ser causados GPFs.
Este erros ocorrem quando a IDE est sendo descarregada (unloaded) e ser executada numa posterior abertura do VB com o aviso "xxxxx add-in could not be loaded, do you want to remove it from the list of add-ins?"
Aps isto, voc ter que executar novamente o add-in para registr-lo como relacionado ao VB. Vejamos dois casos destes erros:
1) Referenciando uma propriedade da VBIDE Instance Object, como AcitveProject.FileName no evento ConnectAddin da Conector Class.
2) Conectando mais menus ou submenus que voc desconectou.
Programao , predominantemente, uma cincia exata e muitas "regras no documentadas" so uma real necessidade ao se criar um add-in.
Por Les Smith*

---------------------------------------------------------------------------------

 
 
76 - VB4 - Evitando Erros de Atualizao em Bases Access
Evite o erro de acesso 3260 ("Couldn't update; currently record is locked by user '<userName>' on machine '<userMachineID>'"), que ocorre quando duas ou mais aplicaes acessam a mesma tabela de uma base de dados Access (Jet). O acesso  realizado por objetos recordset (como table ou dynaset), sobre uma tabela que contenha uma chave (primria ou no).
Se uma das aplicaes est ociosa (apenas abriu o registro e ainda no o alterou) e outra aplicao tenta alterar ou adicionar dados, o erro citado ocorre. Para evitar este problema, inclua o mtodo Idle dbFreeLOcks aps o recordset ser aberto. Se  for um table recordset,  inclua-o aps ter definido a propriedade Index. Veja um exemplo:
Set db = Workspaces(0).Opendatabase("Test.mdb")
Set TB = Db.OpenRecordSet("Customer_Master", dbOpenTable)
TB.Index = "PrimaryKey"
DB.Engine.Idle (dbFreeLocks)
Por Rajesh Patil*

---------------------------------------------------------------------------------

 
 
77 - VB4 - Descarregando DLLs fora de controle
Quando uso VB em Windows 95, s vezes ocorre que, um programa torne o sistema operacional instvel. Costumava derrubar o Windows 95 e reiniciar para limpar a memria de todos os VBXs e DLLs. Mas descobri, recentemente, uma forma mais prtica:
Criei um arquivo DOS Batch chamado RESTART.BAT, no seu disco rgido, com este contedo:
 EXIT
No Windows 95, criei um atalho para este BAT. O modo DOS  selecionado, nas propriedades, como Program / Advanced. Este caminho  muito mais rpido que um reboot.
Por Michael J. Dyer*

---------------------------------------------------------------------------------

 
78 - VB3/VB4 - Movendo itens em uma list box
Para, atravs do mouse, mover a localizao de um item numa list box, use o cdigo abaixo.
'declarations:
Dim Tmp_Text As String
Dim Old_index As Integer
Dim New_index As Integer
'mouse events:
Sub List1_MouseDown (Button As Integer, _
  Shift As Integer, X As Single, Y As Single)
 Old_index = List1.ListIndex
 Tmp_text = List1.text
End Sub
Sub List1_MouseUp (Button As Integer, _
  Shift As Integer, X As Single, Y As Single)
 New_index  = List1.ListIndex
 If Old_index <> New_index Then
  List1.RemoveItem Old_Index
  List1.AddItem Tmp_Text, New_Index
 End If
End Sub
Por Mrcio Cristiano de Castro Scotti*

---------------------------------------------------------------------------------

 
 
79 - VB3/VB4 - Sub Main, iniciando um projeto sem interface
Nem sempre  necessrio ou til que um sistema (projeto VB) inicie com uma janela (form). Uma alternativa, nem sempre utilizada,  o de iniciar o projeto executando uma rotina sem form. Alguns exemplos:
1) Processo de inicializao muito longo, com abertura de banco de dados, testes para verificar se o sistema pode ou no ser inicializado, leitura de Registry ou arquivos INI, etc.
2) Quando o sistema rodar em "background", ou seja, em segundo plano. Este sistema no ter janelas (forms) para interao com o usurio.
No Visual Basic, o recurso  bastante simples. Primeiro, se informa ao VB que o projeto iniciar com uma Sub Main (esta informao  passada nas opes de projeto - Options ?   Project ?   Start Up Form = Sub Main.) Depois, basta incluir em um dos mdulos de cdigo (.BAS), uma rotina com este nome.
Sub Main
 'rotinas de inicializao e leitura de opes
 'logon, abertura de banco de dados e restante da inicializao
 'mostra o primeiro form
  form1.show
End Sub
Por Charles A. Mller.

---------------------------------------------------------------------------------

 
 
80 - VB3/VB4 - Capturando parmetros
Todos se recordam das velhas linhas de comando nos programas DOS: dir /s, pkunzip -v, del /p, mysys /?, myeditor myfile.txt  entre outros. Com estes recursos, os programas j sabiam o que fazer ao serem chamados. No Windows, este recurso ainda  utilizado, principalmente quando se deseja automatizar tarefas. O prprio Registry do Windows passa os devidos parmetros ao executar uma aplicao associada a um tipo de arquivo. Assim, aplicativos da linha Office podem ser disparados para abertura e impresso de arquivos ou execuo de macros. Para "capturar" a linha de comando com os parmetros de um executvel em VB, basta utilizar a funo Command:
Select Case UCase(Trim(Command$))
 Case "/A"
  frmAvanc.Show 'usurios avanados
 Case "/M"
  frmMedios.Show 'usurios mdios
 Case Else
  frmBasico.Show 'default, usurios novatos
End Select
A captura de parmetros ocorre normalmente na sub main ou num evento load do form inicial.
Por Charles A. Mller.

---------------------------------------------------------------------------------

 
 
81 - VB3/VB4 - Onde est o fim?
Uma aplicao do Visual Basic pode ser encerrada de vrias formas:
1) com o fechamento (unload) do form principal.
2) com o comando Stop (apenas como interrupo na depurao).
3) com o comando End.
Este ltimo, fecha todos os arquivos e limpa todas as variveis. O problema do End  que esta palavra faz parte de outros comandos como End Sub e End If (fechamento de blocos). Imagine se voc precisar depurar um programa para descobrir quais os pontos em que ele  encerrado, como diferenciar o End "puro" dos outros? Basta chamar sempre uma funo pblica (codificada em um .BAS) que "substituir" o End. Somente esta funo ter End, facilitando o controle do cdigo.
Public Sub SU_AbortaSis
 End 'nico local para o End
End Sub
Private Sub Form_Unload (Cancel As Integer)
 ...
 SU_GravaConfiguracoes
 SU_AbortaSis
End Sub
Por Charles A. Mller.

---------------------------------------------------------------------------------

 
 
82 - VB3/VB4 - F1 e o Help de Contexto
As aplicaes Windows acessam Help (ajuda) diretamente atravs do pressionamento da tecla F1. Muitas porm, utilizam menus (?? Contedo) ou botes (Ajuda). Nestes casos deve aparecer a pgina de ajuda indicada na propriedade HelpContextID do form ou controle. A soluo ao programador pode ser o uso de API, com a funo WinHelp, na biblioteca User (como sugere o exemplo SAMPLES\ICONWRKS). Uma forma mais simples,  simular o pressionamento de F1:
Sub AjudaConteudo_Click ()
 SendKeys "{F1}"
End Sub
Por Charles A. Mller.

---------------------------------------------------------------------------------

 
 
83 - VB3/VB4 - Validando CGC e CPF
Essa  brasileirssima. Os nmeros de CGC e CPF possuem dgitos verificadores para... adivinhem ... verificar!
Isto  obvio. A validao deve ser feita (por qualquer sistema decente) para impedir a digitao por engano e os CGCs e CPFs falsos ("que coisa feia, tentando passar a perna na gente"). A funo abaixo no  de minha autoria, mas, achei no meu "ba" de cdigo.
Function Fu_consistir_CgcCpf (Vl_CgcCpf As String)
    ' Esta Rotina Devolver True  Se o Cgc/Cpf Informado For valido
    '                    ou False Se o Cgc/Cpf No For Correto
    ' Para Chamar esta Rotina de Consistncia
    ' 1 ) Atribuir o valor do CgcCpf a uma Variavel String
    ' 2 ) Chamar a Rotina com : Fu_consistir_CgcCpf (Variavel)
    ' Uma Forma Simples de fazer a Consistencia
   '  Copiando as linhas abaixo (exemplo)
    ' para dentro do Programa
    ' Dim Vl_CgcCpf As String
    ' Vl_CgcCpf = Me.CgcCpf.Text
    ' If Fu_consistir_CgcCpf(Vl_CgcCpf) = False then
    '  MsgBox "( Cgc/Cpf Informado No  um Cgc/Cpf Correto )"
    '  Me.CgcCpf.SetFocus
    '  Exit Sub
    ' End if 
   Fu_consistir_CgcCpf = False
    Dim VA_CgcCpf           As String
    Dim VA_Digito           As String
    Static Numero(15)       As Integer
    Dim VA_Resto            As Integer
    Dim VA_Resultado        As Integer
    Dim VA_SomaDigito10     As Integer
    Dim VA_resto1           As Integer 

    VA_CgcCpf = Format(Vl_CgcCpf, "@@@@@@@@@@@@@@")
    VA_Digito = Mid(VA_CgcCpf, 13, 2) 

    Numero(1) = Val(Mid(VA_CgcCpf, 1, 1))
    Numero(2) = Val(Mid(VA_CgcCpf, 2, 1))
    Numero(3) = Val(Mid(VA_CgcCpf, 3, 1))
    Numero(4) = Val(Mid(VA_CgcCpf, 4, 1))
    Numero(5) = Val(Mid(VA_CgcCpf, 5, 1))
    Numero(6) = Val(Mid(VA_CgcCpf, 6, 1))
    Numero(7) = Val(Mid(VA_CgcCpf, 7, 1))
    Numero(8) = Val(Mid(VA_CgcCpf, 8, 1))
    Numero(9) = Val(Mid(VA_CgcCpf, 9, 1))
    Numero(10) = Val(Mid(VA_CgcCpf, 10, 1))
    Numero(11) = Val(Mid(VA_CgcCpf, 11, 1))
    Numero(12) = Val(Mid(VA_CgcCpf, 12, 1))
    Numero(13) = Val(Mid(VA_CgcCpf, 13, 1))
    Numero(14) = Val(Mid(VA_CgcCpf, 14, 1)) 

    If Len(Trim(Vl_CgcCpf)) > 11 Then  ' Cgc
        VA_Resultado = Numero(1) * 2
        If VA_Resultado > 9 Then
            VA_SomaDigito10 = VA_Resultado + 1
        Else
            VA_SomaDigito10 = VA_Resultado
        End If
        VA_Resultado = Numero(3) * 2
        If VA_Resultado > 9 Then
            VA_SomaDigito10 = VA_SomaDigito10 + VA_Resultado + 1
        Else
            VA_SomaDigito10 = VA_SomaDigito10 + VA_Resultado
        End If
        VA_Resultado = Numero(5) * 2
        If VA_Resultado > 9 Then
            VA_SomaDigito10 = VA_SomaDigito10 + VA_Resultado + 1
        Else
            VA_SomaDigito10 = VA_SomaDigito10 + VA_Resultado
        End If
        VA_Resultado = Numero(7) * 2
        If VA_Resultado > 9 Then
            VA_SomaDigito10 = VA_SomaDigito10 + VA_Resultado + 1
        Else
            VA_SomaDigito10 = VA_SomaDigito10 + VA_Resultado
        End If
        VA_SomaDigito10 = VA_SomaDigito10 + Numero(2) + Numero(4) + Numero(6)
        If Mid(Str(VA_SomaDigito10), Len(Str(VA_SomaDigito10)), 1) = "0" Then
            VA_Resto = 0
        Else
            VA_Resto = 10 - Val(Mid(Str(VA_SomaDigito10), _                Len(Str(VA_SomaDigito10)), 1))
        End If
        If VA_Resto <> Numero(8) Then
            Exit Function
        End If
        VA_Resultado = (Numero(1) * 5) + (Numero(2) * 4) _
   + (Numero(3) * 3) + (Numero(4) * 2)  _
   + (Numero(5) * 9) + (Numero(6) * 8) +  _
   (Numero(7) * 7) + (Numero(8) * 6) +  _
   (Numero(9) * 5) + (Numero(10) * 4) + _
   (Numero(11) * 3) + (Numero(12) * 2)
       ' Atribui para resto o resto da diviso
   ' de VA_resultado dividido por 11
     VA_Resto = VA_Resultado Mod 11
   If VA_Resto < 2 Then
            VA_resto1 = 0
        Else
            VA_resto1 = 11 - VA_Resto
        End If
        If VA_resto1 <> Numero(13) Then
            Exit Function
        End If
        VA_Resultado = (Numero(1) * 6) + _
   (Numero(2) * 5) + (Numero(3) * 4) + _
   (Numero(4) * 3) + (Numero(5) * 2) +  _
   (Numero(6) * 9) + (Numero(7) * 8) + _
   (Numero(8) * 7) + (Numero(9) * 6) + _
   (Numero(10) * 5) + (Numero(11) * 4) + _
   (Numero(12) * 3) + (Numero(13) * 2)
        ' Atribui para resto o resto da diviso
   ' de VA_resultado dividido por 11
   VA_Resto = VA_Resultado Mod 11
        If VA_Resto < 2 Then
            VA_resto1 = 0
        Else
            VA_resto1 = 11 - VA_Resto
        End If
        If VA_resto1 <> Numero(14) Then
            Exit Function
        End If
    Else  ' Cpf
        VA_Resultado = (Numero(4) * 1) + _
   (Numero(5) * 2) + (Numero(6) * 3) _
    + (Numero(7) * 4) + (Numero(8) * 5) _
    + (Numero(9) * 6) + (Numero(10) * 7)_
    + (Numero(11) * 8) + (Numero(12) * 9)
        VA_Resto = VA_Resultado Mod 11
        If VA_Resto > 9 Then
            VA_resto1 = VA_Resto - 10
        Else
            VA_resto1 = VA_Resto
        End If
        If VA_resto1 <> Numero(13) Then
            Exit Function
        End If 

        VA_Resultado = (Numero(5) * 1)  _
   + (Numero(6) * 2) + (Numero(7) * 3) _
   + (Numero(8) * 4) + (Numero(9) * 5) + _
   (Numero(10) * 6) + (Numero(11) * 7) + _
   (Numero(12) * 8) + (VA_Resto * 9)
        VA_Resto = VA_Resultado Mod 11
        If VA_Resto > 9 Then
            VA_resto1 = VA_Resto - 10
        Else
            VA_resto1 = VA_Resto
        End If
        If VA_resto1 <> Numero(14) Then
            Exit Function
        End If 

    End If
Fu_consistir_CgcCpf = True
End Function
Por Chales A. Mller



---------------------------------------------------------------------------------

 
 
84 - VB3/VB4 - Performance com a SQL Passthrough
Quando voc acessa uma base dados via ODBC (Open Database Connectivity), os drivers ODBC atuaro como tradutores dos seus comandos SQL. A razo disto  que, existe uma linguagem SQL genrica (SQL ANSI) e dialetos SQL distintos nos vrios produtos (linguagens e bancos) disponveis no mercado. Assim, cada fornecedor de banco de dados poder incluir recursos (como storned procedures) e sintaxes especficas em seus produtos; existem o SQL da Oracle, o SQL da Informix, o SQL da Sybase etc. Escrevendo seus comandos em SQL ANSI, o ODBC ir "interpretar", em tempo de execuo, os comandos para a sintaxe SQL do banco que seu usurio acessa. Esta operao tem uma vantagem e uma desvantagem:
1) A vantagem  que um s aplicativo, a priori, poder ser executado - sem alterao de fontes - em qualquer banco de dados Client Server, pelo padro ODBC. Alm da portabilidade de cdigo fonte, existe o ganho em interoperabilidade: o programa poder acessar, ao mesmo tempo, bases diferentes. A interoperabilidade  necessria em empresas, por exemplo, que passaram por processos de fuso ou incorporao com outra empresa (que usa outra "marca" de banco de dados).
2) Desvantagem: a "traduo" impacta consideravelmente na performance do sistema, o aplicativo (que pode estar rodando em uma grande rede) tornar-se- muito mais lento.
A soluo  pedir ao ODBC que "pule" a traduo que seria realizada pelos seus drivers. Assim, ganha-se tempo de execuo. Veja este exemplo:
Dim VA_Cmd As String 'comando SQL
Dim snapCidade As Snapshop
Dim VA_Cod As Integer 'cdigo da cidade (campo chave)
Const SQLPASSTRHOUGH = 64
'...
VA_Cmd = "Select Cidade, Nome from CIDADE where Cidade = " & VA_Cod
Set snapCidade = db.CreateSnapshop(VA_Cmd, SQLPASSTRHOUGH)
A SQL Passthrough  o parmetro para "pular" a traduo. No VB4, a constante chama-se dbSQLPassThrough.
O comando SQL passado deve estar na sintaxe especfica do SGBD (ou DBMS) utilizado. Mesmo assim, o sistema poder continuar como portvel e interopervel, seguindo-se os passos abaixo (cdigo parametrizado):
1) Programe todas as consultas em todos os dialetos SQL utilizados pelos seus usurios, escreva o cdigo de um modo fcil de ser compreendido e alterado.
2) Execute a consulta especfica do banco tal no momento tal. A informao de qual banco poder estar em entradas de arquivos INI ou no Registry.
Por Charles A. Mller

---------------------------------------------------------------------------------

 
 
85 - VB4 - Listas erradas de API
Os utilitrios APILOD16.EXE e APILOD32.EXE acessam o arquivo WIN32API para passar os parmetros de tipos de dados (Type Declarations) necessrios para chamar funes Win32 API. Porm existem erros. Por exemplo:
WIN32API.TXT (incorretamente)diz:
Type COMSTAT
 fCtsHold As Long     'errado
 fDsrHold As Long     'errado
 fRlsHold As Long     'errado
 fXoffHold As Long    'errado
 fXoffSnet As Long    'errado
 fEof As Long         'errado
 fTxim As Long        'errado
 fReserved As Long    'errado
 cbInQue As Long
 cbOutQue As Long
End Type
WINT31API.TXT, corretamente, diz:
Type COMSTAT
 bunch_Of_Bits As Long
 cbInQue As Long
 cbOutQue As Long
End Type
Por Andy Rosa*

---------------------------------------------------------------------------------

 
 
86 - VB3/VB4 - Centralizando Forms (I)
Para mostrar as janelas no meio da tela, podem ser utilizadas estas rotinas. Quando se deseja centralizar o prprio form, o parmetro ser a palavra Me e a rotina ser chamada do evento Form_Load.
Sub CenterForm (f As Form)
    Screen.MousePointer = 11
    f.Top = (Screen.Height) / 2 - f.Height / 2
    f.Left = Screen.Width / 2 - f.Width / 2
    Screen.MousePointer = 0
End Sub
Para um suave deslocamento do centro, interessante para forms modais, utilize apenas 85% da medida Height da tela:
f.Top = (Screen.Height * .85) / 2 - f.Height / 2
Exemplo de aplicao:
Form1.Load
CenterForm Form1
Form1.Show
Outro exemplo:
Sub Form_Load ( )
 CenterForm Me
 '...
End Sub
Para centralizar um form no em relao a tela, mas a outro form, utilize a rotina abaixo. Ela  til quando h um form principal do sistema, que geralmente  um MDIForm.
Sub SU_CenterChild (f As Form)
 'centraliza um form dentro do MDIform  (chamado aqui de F00)
 Dim VA_X, VA_Y
   VA_X = (((F00.ScaleWidth - f.Width) \ 2) + F00.Left)
   VA_Y = (((F00.ScaleHeight - f.Height) \ 2) + F00.Top)
   f.Move VA_X, VA_Y
End Sub
Por Charles A. Mller

---------------------------------------------------------------------------------

 
 
87 - VB4 - Centralizando Forms (II - A verso)
A dica anterior mostra como centralizar forms no VB3. A dica tambm  aplicvel ao VB4. Abaixo, h uma outra verso desta rotina. Ela usar um parmetro opcional (frmParent). O ltimo form lido ser centralizado em relao ao "parent" (pai, o principal). Na falta do frmParent, a centralizao ocorrer em relao a tela. Lembramos que esta implementao  somente para a verso 4 do VB.
Public Sub CenterForm(Optional frmParent)
 If Forms.Count = 0 then Exit Sub
 If IsMissing (frmParent) Or Not TypeOf frmParente Is Form  then
  Forms(Forms.Count -1).Move _
  (Screen.Width - Forms(Forms.Count -1).Width / 2, _
  (Screen.Height - Forms(Forms.Count -1).Height / 2
 Else
  Forms(Forms.Count -1).Move _
  (frmParent.Width - Forms(Forms.Count -1).Width / 2, _
  (frmParent..Height - Forms(Forms.Count -1).Height / 2
 End If
End Sub
Por Denis Basaric*

---------------------------------------------------------------------------------

 
 
88 - VB3 - Menu Colar Alternativo
Se voc usa alguns controles, como o QuickPack Pro (da Crescent),  impossvel atribuir CTRL+V para Editar-Colar. Pois, o texto do Clipboard ser colado duas vezes.  Para manter a tecla de atalho, atribua mnuPaste.caption = "Co&lar" + Chr$(9) + "Ctrl + V", na Sub Main ou no form_Load.
Por Daniele Alberti*

---------------------------------------------------------------------------------

 
 
89 - VB3/VB4 - J estou no ar?
Algumas aplicaes para Windows podem ter vrias instncias, ou seja, podem ser executadas repetidas vezes ao mesmo tempo no mesmo computador.  o caso do Bloco de Notas, do Paint, da Calculadora e de outros. Existem programas cuja mltipla execuo no  interessante, por questes de produtividade ao usurio (como o Word, o File Manager e o Excel) ou segurana (como aplicaes que usam banco de dados). Os sistemas comerciais (de banco de dados), em geral, s podem ser executados em uma sesso ao mesmo tempo. O controle disto no VB  feito atravs do objeto App.
 Dim SaveTitle as string
 If App.PrevInstance Then
   SaveTitle = App.Title
   App.Title = "... segunda chamada ao mesmo programa."
   Me.Caption = "... segunda chamada ao mesmo programa, serei fechado"
   'se for a Sub Main, a linha acima, obviamente, no existe
   'as linhas abaixo fecham a segunda chamada e alternam para
   'a primeira
   AppActivate SaveTitle
   SendKeys "% R", True
   End
 End If
O cdigo acima deve ser a primeira coisa a ser executada na sua aplicao. Assim, ao invs de abrir uma segunda sesso do programa, o Windows ir alternar para a sesso j aberta. Isto tambm pode ser feito por APIs (FindWindow, ShowWindow e SetFocus, da biblioteca User), mas, tem o mesmo efeito e  mais trabalhoso.
Por Charles A. Mller.

---------------------------------------------------------------------------------

 
 
90 - VB3/VB4 - Seja Feliz
Voc que j passa horas e horas diante do computador (do VB, do Windows e outros bichos), tire um tempo para um filme, um livro, a famlia e os amigos. 
At a prxima!
Algumas dicas de Visual Basic foram implementadas em uma verso (3 ou 4) e podem ser utilizadas na outra verso.  necessrio, porm, que o leitor observe as pequenas diferenas de sintaxe existentes entre duas verses. Por exemplo, o VB3 no aceita o caracter _ para mudana de linha.
As dicas de autor assinalado (*) so uma adaptao do Visual Basic Programmers Journal Technical Tips Supplement (3rd Ed., 08/96), da Fawcett Technical Publications (001-415-833-7100). Acrescentamos traduo e algumas melhorias, alm de dicas nossas. At a prxima! 

Gostaria de participar de um prximo guia de dicas? Ento envie a sua contribuio para editor@forumaccess.com. As dicas podero ser de VB3, VB4, VB5 (inclusive CCE), VBScript, VBA, VBA5 e Access. 

*Charles A. Mller , de Curitiba,  Editor Adjunto de Visual Basic da Revista Frum Access, tcnico em Processamento de Dados e Acadmico de Comunicao (PUC PR). Atua como consultor em Internet, Multimdia e Visual Basic.
 
 




 
-------------------------------------------------------------------------------------
###@@@$$$&&&***!!!+++???~~~~|||^^^^)))%%%///```(((''']]]---\\\@@@$$$&&&***!!!+++####
####@@@$$$&&&***!!!+++???~~~~|||^^^^)))%%%///```(((''']]]---\\\@@@$$$&&&***!!!+++###
### Montado em 2004 por Eliel Vieira - elielvieira03@yahoo.com                   ###
### Montado em 2004 por Eliel Vieira - elielvieira03@yahoo.com                   ###
### Montado em 2004 por Eliel Vieira - elielvieira03@yahoo.com                   ###
### Montado em 2004 por Eliel Vieira - elielvieira03@yahoo.com                   ###
### Montado em 2004 por Eliel Vieira - elielvieira03@yahoo.com                   ###
###@@@$$$&&&***!!!+++???~~~~|||^^^^)))%%%///```(((''']]]---\\\@@@$$$&&&***!!!+++####
####@@@$$$&&&***!!!+++???~~~~|||^^^^)))%%%///```(((''']]]---\\\@@@$$$&&&***!!!+++###
###  Fonte: http://www.truquesedicas.com/dicas/visual_basic/                     ###
###  Fonte: http://www.truquesedicas.com/dicas/visual_basic/                     ###
###  Fonte: http://programadores1.vilabol.uol.com.br/dicas.htm                   ###
###  Fonte: http://www.mrvbscripthomepage.hpg.ig.com.br/VBasic/90DicasVB.html    ###
###  Fonte: http://geocities.yahoo.com.br/rairepe/vb_basico.htm#Dicas            ###
###@@@$$$&&&***!!!+++???~~~~|||^^^^)))%%%///```(((''']]]---\\\@@@$$$&&&***!!!+++####
####@@@$$$&&&***!!!+++???~~~~|||^^^^)))%%%///```(((''']]]---\\\@@@$$$&&&***!!!+++###
-------------------------------------------------------------------
