Sei sulla pagina 1di 210

1

SUMRIO SUMRIO..............................................................................................................................1 ARQUIVOS........................................................................................................................................8 Carregando um arquivo texto para um ListBox.............................................................................8 Checando se um arquivo texto est em branco..............................................................................8 Copiando Arquivos.........................................................................................................................9 Criando um arquivo texto em branco...........................................................................................10 Descobrindo e Alterando Atributos de Arquivos.........................................................................10 Excluindo Arquivos......................................................................................................................12 Funo que Abre um Arquivo Texto e Retorna seu Contedo....................................................13 Funos para Manipulao de Arquivos INI................................................................................13 Gravar cada informao em uma linha nova de um arquivo........................................................16 Imprimindo Arquivos Texto pelo VB...........................................................................................16 Procurar um arquivo em diretrios e subdiretrios......................................................................16 Salvando o contedo de um TextBox num Arquivo Texto..........................................................17 Verificando a Data da ltima Alterao de um Arquivo.............................................................18 Verificando a existencia de um arquivo.......................................................................................18 BANCO DE DADOS........................................................................................................................19 Abrindo Bancos de Dados Externos - DAO & ADO...................................................................19 DAO..........................................................................................................................................19 ADO..........................................................................................................................................19 Abrindo Relatrios do Access pelo VB........................................................................................20 Abrir Banco de Dados com Senha - DAO & ADO......................................................................20 DAO..........................................................................................................................................20 ADO..........................................................................................................................................20 Compactar Banco de Dados - DAO & ADO................................................................................21 Compactar banco de dados protegido por senha - DAO & ADO................................................23 Criando Banco de Dados com Tabelas e ndices via VB - DAO.................................................26 Filtrar Recordset j aberto - DAO................................................................................................27 Funo que Cria a Clausula Where para Voc.............................................................................29 Listando o Nome de Todas as Tabelas de um BD - ADO & DAO.............................................30 Passar parametro para SQL armazenada em DB - ADO.............................................................31 Procurando no Banco de Dados (Find - FindFirst - FindNext) - DAO & ADO..........................32 (DAO).......................................................................................................................................32 (ADO).......................................................................................................................................33 Reparar Banco de Dados - DAO...................................................................................................34 Salvar informaes do Access para dBase - DAO.......................................................................34 Soluo para a Aspa Simples (') em Strings de SQL...................................................................34 Trabalhando com Recordsets Desconectados - ADO..................................................................35 Trabalhando com Recordsets Dinmicos - ADO.........................................................................35 Usando o IIF em Consultas SQL..................................................................................................36 Utilizando o ADO - [Bsico]........................................................................................................36 A. Abertura de Banco de Dados e de Tabelas..........................................................................37 B. Manipulao de Dados.........................................................................................................38 Utilizar algum programa que compacte os DBs...........................................................................39 CLCULOS......................................................................................................................................43 Calcula a idade em anos entre duas datas.....................................................................................43 Calcula a Raiz Quadrada de um Nmero.....................................................................................43 Calculando a Diferena entre Duas Datas em Dias......................................................................43

2 Calculo de Mensalidades..............................................................................................................43 Contas corretas com ponto fluante...............................................................................................44 Dias teis entre duas datas............................................................................................................44 Descobrindo Dias no Ano.............................................................................................................45 Descobrindo Dias no Ms.............................................................................................................45 Trabalhando com Data Juliana.....................................................................................................46 CONTROLES...................................................................................................................................47 Alterando Propriedades de Controles (no Array) em um Loop.................................................47 Alterando Propriedades de um Array de Controles em um Loop................................................47 Coordenadas do controle em relaao a area de trabalho..............................................................48 Criando Objetos em Run Time (VB6.0).......................................................................................48 Determinando a classe de qualquer objeto...................................................................................49 Determinando se um objeto foi definido (Set).............................................................................49 Manipulando Controles num Form Usando-se o Teclado...........................................................50 Testar se um controle existe..........................................................................................................50 ToolTipText personalizado...........................................................................................................50 Verificar se um controle est com o foco.....................................................................................51 Criao de AtiveXs.......................................................................................................................52 Colocando as Tecla de Atalho para Funcionar num OCXs.....................................................52 Manipulando Propriedades do Form onde seu OCX Est.......................................................52 O Projeto est em Run ou Design Time?.................................................................................53 Pegando o hWnd do Verdadeiro Container..............................................................................53 Qual tipo de Compatibilidade devo Usar?................................................................................54 Registrando e Desregistrando ActiveX via Cdigo VB...........................................................54 FlexGrid........................................................................................................................................56 Deixando um FlexGrid Zebrado (com 2 Cores Intercaladas)..................................................56 Exportar dados de FlexGrid para Excel....................................................................................56 Para imprimir o conteudo de um FlexGrid...............................................................................58 ComboBox....................................................................................................................................59 Abrir um ComboBox assim que receber o foco.......................................................................59 Ajustando a Largura do Drop-Down de um ComboBox.........................................................59 Descobrindo a largura atual do Drop-Down............................................................................59 Adicionando itens ao ComboBox em Run-Time.....................................................................60 Adicionando itens ao ComboBox em Design-Time................................................................61 Auto preenche o ComboBox de acordo com o texto encontrado............................................62 Preenchendo um ComboBox com os Registros de um Banco de Dados.................................63 DbGrid...........................................................................................................................................64 Auto Ajustar Colunas no DBGrid............................................................................................64 Destacando uma linha em um DBGrid.....................................................................................64 Mudar de Coluna no DBGrid com TAB..................................................................................64 Preenchendo o DBGrid via Cdigo..........................................................................................64 DriveListBox.................................................................................................................................66 Cdigos Erro do DriveListBox.................................................................................................66 Form..............................................................................................................................................67 Animando a Barra de Ttulo de um Form................................................................................67 Arrastar um controle ou Formulrio sem Ttulo......................................................................68 Carregar Vrias Instancias do Mesmo Formulrio..................................................................68 Centralizar um Form MDIChild...............................................................................................68 Criando forms de formatos especiais........................................................................................68 Criando um Form Circular........................................................................................................69

3 Crinado um Form com Cantos Arredondados..........................................................................69 Criando um Form Elptico........................................................................................................70 Criando um Form em forma de Estrela (Polgono)..................................................................71 Criando um Form em forma de Tringulo...............................................................................72 Criando um Form com forma do Logotipo do Windows.........................................................72 Criando um Form no Formato da Imagem Desejada...............................................................73 Criando uma Tela de Splash para seu Programa......................................................................75 Degrad em Forms....................................................................................................................76 Fazer um form maior que a tela................................................................................................76 Fechando todos os Forms Abertos............................................................................................77 Formulrio ficar por cima de todos..........................................................................................77 Pintar um local do formulario com a cor escolhida.................................................................78 Removendo o move..................................................................................................................78 Removendo os Botes MIN-MAX de Forms MDI..................................................................78 Saber se um form est aberto....................................................................................................79 Grid................................................................................................................................................80 Digitao em Grid.....................................................................................................................80 ImageList.......................................................................................................................................81 Alterando o Contedo da ImageList sem Desvincula-la da ToolBar......................................81 ListBox..........................................................................................................................................82 Achar uma palavra num ListBox..............................................................................................82 Colocando ScrollBar Horizontal num ListBox........................................................................82 Desmarcar todos os itens de uma lista......................................................................................83 Movendo itens em uma ListBox...............................................................................................83 Multiplas Colunas em um ListBox...........................................................................................84 ListView........................................................................................................................................86 Ordenando Colunas da ListView..............................................................................................86 Masked Edit Box...........................................................................................................................87 Limpar o controle Masked Edit Box........................................................................................87 Mens............................................................................................................................................88 Colocando bitmaps em menus..................................................................................................88 Menus popup em caixa de Texto..............................................................................................89 Microsoft Comm Control..............................................................................................................90 Trabalhando com Microsoft Comm Control............................................................................90 PictureBox.....................................................................................................................................91 Carregando figuras em Pictures................................................................................................91 Dimenses de um bitmap..........................................................................................................91 Rolando textos em PictureBox.................................................................................................92 Salvando e Pintando em cima de figuras..................................................................................92 RichTextBox.................................................................................................................................94 Imprimindo o Contedo de um RichTextBox..........................................................................94 Localizando um Texto num RichTextBox...............................................................................94 Uso Geral do Controle RichTextBox.......................................................................................94 TextBox.........................................................................................................................................96 Apenas Nmeros num TexBox.................................................................................................96 Bloqueando funes Copiar e Colar em caixas de texto..........................................................96 Forando Caracteres Maisculos ou Minsculos.....................................................................96 O Caracter ENTER...................................................................................................................97 Procurando Strings em um TextBox........................................................................................97 Selecionando Texto do TextBox ao Receber Foco..................................................................99

4 Rolar um TextBox linha a linha................................................................................................99 ToolBar........................................................................................................................................100 Deixando a ToolBar (do VB5) no Estilo Flat.........................................................................100 True DbGrid................................................................................................................................100 Como ligar o True DbGrid a um Array..................................................................................100 Deixando um True DBGrid Zebrado (com 2 Cores Intercaladas).........................................101 Detectar a Linha Selecionada num True DBGrid..................................................................101 Navegao de Linha no True DBGrid....................................................................................102 DIRETRIOS.................................................................................................................................103 Capturar o caminho DOS de um arquivo...................................................................................103 Criando mltiplos nveis de diretrios........................................................................................103 Como interceptar mudanas em um diretrio............................................................................103 Diretrio onde o Programa foi Instalado....................................................................................106 Funo para Unir um Diretrio a um Subdiretrio....................................................................107 Pegar o Diretrio de Arquivos Temporrios (Windows\Temp)................................................108 Pegar o Diretrio do System.......................................................................................................108 Pegar o Diretrio do Windows...................................................................................................109 CDRom........................................................................................................................................111 Abrir e fechar a gaveta do CDROM.......................................................................................111 Disquetes.....................................................................................................................................111 Formatando um Disquete........................................................................................................111 Drive............................................................................................................................................112 Ler propriedades de drives, pastas e arquivos........................................................................112 Hard Disk....................................................................................................................................121 Saber o Nmero Serial do HD................................................................................................121 Impressoras.................................................................................................................................122 Imprimindo Direto para a Impressora....................................................................................122 Selecionando a impressora que ser usada na impresso.......................................................122 Monitores....................................................................................................................................123 Obter a resoluo de tela.........................................................................................................123 Resoluo do Monitor.............................................................................................................123 Mouse..........................................................................................................................................123 Capturar a Posio do Mouse.................................................................................................123 USANDO AS APIs GetCursorPos E WindowFromPoint.................................................124 USANDO AS APIs SetCapture E ReleaseCapture............................................................124 Verificando se o cursor do mouse est ou no sobre o Form ...........................................124 Verificando se o cursor do mouse est ou no sobre um controle.....................................125 Como limitar a rea de movimento do mouse........................................................................125 Desativamento do mouse........................................................................................................126 Inverter os botes do mouse...................................................................................................126 Mudar a Posio do Mouse via Cdigo (sem Move-lo)........................................................127 Teclados......................................................................................................................................128 Acionar o CAPS LOCK via cdigo........................................................................................128 Internet.............................................................................................................................................129 Acionar o navegador padro em um URL especfico................................................................129 Acionar uma conexo Dial-Up pelo VB.....................................................................................129 Capturar o nome da conexao Dial-Up........................................................................................130 Criar um link para um e-mail......................................................................................................130 Dar um Ping................................................................................................................................131 Desconectar da Internet Via Cdigo no VB...............................................................................131

5 Discar com o modem via API.....................................................................................................132 Enviar E-mail pelo VB via MAPI..............................................................................................132 Exibir um arquivo direto da Internet/Intranet num TextBox.....................................................133 Salvando uma Pgina HTML.....................................................................................................133 Transferncia de arquivos via FTP.............................................................................................134 Verificando se o Computador est Conectado Internet...........................................................135 Multimdia.......................................................................................................................................137 Criando um CD Player................................................................................................................137 Criar tela de apresentao no CD-ROM.....................................................................................140 Detectando se o Micro tem Placa de Som..................................................................................140 Gravando uma Trilha do CD para um Arquivo Wave...............................................................141 Rodando um Vdeo AVI.............................................................................................................141 Tocar Arquivos MIDI.................................................................................................................142 Tocar Arquivos WAVE..............................................................................................................143 Programao Inteligente.................................................................................................................144 Cuidado com Variveis Tipo Variant!!!.....................................................................................144 Eliminando o If...End If Quando Possvel..................................................................................144 Executar com Compilao Completa.........................................................................................145 Faa amplo uso das constantes intrnsecas do VB.....................................................................145 Instanciando Objetos Corretamente............................................................................................146 Saber se o Objeto est Vazio......................................................................................................146 Usando a Immediate Window.....................................................................................................147 Usando o Auto Completar..........................................................................................................147 Usando o DoEvents.....................................................................................................................147 Usando o Object Browser...........................................................................................................148 Use o With para Atribuir Valores Propriedades de Objetos...................................................148 Verificando Valor da Propriedade de um Objeto Mais Rapdamente.........................................148 REDES........................................................................................................................................150 Buscar data e hora do servidor....................................................................................................150 Devolve o nome do micro na rede..............................................................................................151 Identificando uma unidade de CD em Rede...............................................................................151 Mapeando uma Unidade de Rede...............................................................................................152 Retornar o nome do usurio logado............................................................................................152 VBA.................................................................................................................................................153 Copiando Textos de Documentos do Word................................................................................153 Trocar dados com o Excel...........................................................................................................153 Validaes.......................................................................................................................................155 Funo para Verificar se um Ano Bissexto ou No................................................................155 Validar Carto de Crdito...........................................................................................................155 Validar CGC................................................................................................................................156 Validar CPF.................................................................................................................................157 Validar Datas...............................................................................................................................157 Validar E-Mail............................................................................................................................160 Validar Informaes Fornecidas pelo Usurio...........................................................................162 Validar Texto em MaskEditBox.................................................................................................166 Valor por Extenso.......................................................................................................................166 Verificar a Validade do PIS........................................................................................................168 Variados...........................................................................................................................................169 Acionar um HTML Help pelo VB..............................................................................................169 Acionar um Help (*.HLP) pelo VB............................................................................................169

6 Cancelando Processos Longos....................................................................................................169 Carregando forms do VB4 no VB3............................................................................................170 Confirmando o Termino do Programa........................................................................................170 Como Registrar Uma HotKey.....................................................................................................171 Convertendo Identificadores em Rtulos e Cabealhos.............................................................173 Criando grficos sem utilizar OCX nem DLL...........................................................................173 Criando uma Animao no VB...................................................................................................174 Dar uma Pausa em seu Programa...............................................................................................175 Fazer um aplicativo ser acionado silenciosamente.....................................................................175 MsgBox que no seja modal.......................................................................................................175 Programa que d "Bom dia", "Boa tarde" e "Boa noite" nos Horrios Corretos.......................176 Recebendo Parmetros Externos num Programa feito em VB..................................................176 Saber se um programa foi encerrado..........................................................................................176 Tecla ENTER Agindo como TAB..............................................................................................177 Testar caminho da aplicao.......................................................................................................178 Usando as Setas de Movimento Para Mudar de Controle..........................................................178 Use o Code Profiler para depurao...........................................................................................178 Uso racional do SendKeys..........................................................................................................179 Verificar o Formato de Data Configurado no Windows............................................................179 Variveis..........................................................................................................................................181 Apresentando Corretamente Nmeros no Formato de Moeda...................................................181 Ateno na Declarao de Variveis!!!......................................................................................181 Arredondamento numrico.........................................................................................................182 Busca Binria..............................................................................................................................182 Capturar o formato da Moeda.....................................................................................................182 Classificar um array em ordem alfabtica..................................................................................183 Criar Arrays com Type definido pelo usurio............................................................................183 Facilitando a Declarao de Variveis.......................................................................................184 Fazendo Alteraes em Strings com o Mid................................................................................185 Funo para Tira Acentos de Strings..........................................................................................185 Funo que Inverte Nomes (Sobrenome, Nome).......................................................................186 Funo Replace para VB5.0.......................................................................................................186 Funo Split para o VB5.............................................................................................................187 Primeiras Letras das Palavras de uma String em Maiusculo.....................................................188 Saber as variveis do ambiente...................................................................................................188 Windows..........................................................................................................................................190 Abrir a janela propriedades do sistema.......................................................................................190 Abrir arquivo com o programa que o criou................................................................................190 Capturar Tela e Salvar em Arquivo............................................................................................190 Chamando o ScreenSaver Atravs de API.................................................................................190 Chamando Telas Especficas do Painel de Controle..................................................................191 Como associar uma extenso ao programa.................................................................................194 Como Fazer Logoff, Desligar ou Reiniciar o Computador pelo VB.........................................196 Criar atalho para arquivo facilmente..........................................................................................197 Executar um programa DOS.......................................................................................................197 Impedir que o programa aparea nos processos do windows....................................................197 Impedir que o programa seja encerrado com Ctrl+Alt+Del.......................................................197 Limpando a Lixeira pelo VB Atravs de API............................................................................198 Minimizar um Programa Para o System Tray............................................................................198 Mudando a Resoluo de vdeo..................................................................................................201

7 Mudando o Papel de Parede pelo VB.........................................................................................202 Mudar a definio de data do Windows.....................................................................................202 Ocultar/Mostrar a Barra de Tarefas do Windows......................................................................203 Usando a rea de Transferencia.................................................................................................204 Usando a Caixa "Sobre" Padro do Windows............................................................................206 Usando a Funo Environ$.........................................................................................................207 Verificando se um array foi ou no inicializado........................................................................209

ARQUIVOS
Carregando um arquivo texto para um ListBox
Private Sub AbreArquivo() Dim sArquivo As String, sLinha As String Dim iARQ As Integer sArquivo = App.Path & "MeuTexto.TXT" If Right$(App.Path, 1) <> "\" Then sArquivo = App.Path & "\MeuTexto.TXT" End If 'Verificando se o arquivo existe: If Dir$(sArquivo) = "" Then 'O arquivo NO existe. MsgBox "O arquivo no existe!", vbExclamation, _ "ATENO!!!" Exit Sub End If iARQ = FreeFile Open sArquivo For Input As iARQ 'Verificando se o arquivo est em branco: If LOF(iARQ) = 0 Then 'O arquivo est em branco. MsgBox "O arquivo est em branco!", vbExclamation, _ "ATENO!!!" 'Fecha o arquivo Close iARQ Exit Sub End If 'Limpa o ListBox: List1.Clear Do While Not EOF(iARQ) 'Enquanto chegar ao fim do arq... 'Pega a linha atual: Line Input #iARQ, sLinha 'Adiciona-a no ListBox: List1.AddItem sLinha Loop 'Fecha o arquivo Close iARQ End Sub Detalhe, voc dever mudar "MeuTexto.TXT" para o nome do arquivo que voc deseja abrir e "List1" para o nome do ListBox onde as linhas sero adicionadas.

Checando se um arquivo texto est em branco


'Se o Arquivo ainda esta fechado use: If FileLen("NomeDoArquivo") = 0 Then Arquivo est em branco Else Arquivo tem contedo End If

'Se o Arquivo est aberto use: If LOF(ARQ) = 0 Then Arquivo est em branco Else Arquivo tem contedo End If

Copiando Arquivos
Copiando Arquivos Atravs de Comandos do VB:
'O comando p/ copiar arquivos o FileCopy. 'Sintaxe: FileCopy ArquivoOrigem, DiretrioDestino 'Exemplo: FileCopy "C:\Desenho.BMP", "C:\Windows\" 'Voc tambm pode copiar este arquivo (p/ o mesmo, ou 'outro diretrio) mudando o nome deste arquivo. Exemplo: FileCopy "C:\Desenho.BMP", "C:\Windows\Imagem.BMP"

Copiando Arquivos Atravs de API:


'O problema do FileCopy do VB q ele no mostra visualmente a 'operao (barra de progresso e etc) com no Explorer. Ao invs 'de copiar arquivos com o FileCopy, use a rotina API abaixo: 'Num mdulo: Option Explicit Public Declare Function SHFileOperation Lib "shell32.dll" _ Alias "SHFileOperationA" (lpFileOp As SHFILEOPSTRUCT) _ As Long Public Const FO_COPY As Long = &H2 Public Const FOF_ALLOWUNDO As Long = &H40 Public Type SHFILEOPSTRUCT hWnd As Long wFunc As Long pFrom As String pTo As String fFlags As Integer fAnyOperationsAborted As Boolean hNameMappings As Long lpszProgressTitle As String End Type Public Sub CopiarArq(Origem As String, Destino As String) Dim RST As Long Dim FLOP As SHFILEOPSTRUCT FLOP.hWnd = 0 FLOP.wFunc = FO_COPY 'Arquivo de origem: FLOP.pFrom = Origem & vbNullChar & vbNullChar 'Para copiar TODOS os arquivos, use:

10
'FLOP.pFrom = "C:\*.*" & vbNullChar & vbNullChar 'Diretrio ou arquivo de destino: FLOP.pTo = Destino & vbNullChar & vbNullChar FLOP.fFlags = FOF_ALLOWUNDO RST = SHFileOperation(FLOP) If RST <> 0 Then 'Erro na cpia MsgBox Err.LastDllError, vbCritical Or vbOKOnly Else If FLOP.fAnyOperationsAborted <> 0 Then MsgBox "Falha na cpia!!!", vbCritical Or vbOKOnly End If End If End Sub 'P/ copiar um arquivo, execute a rotina: CopiarArq ArquivoOrigem, DiretrioDestino 'Por exemplo: CopiarArq "C:\Desenho.BMP", "C:\Windows\" 'Ou: CopiarArq "C:\Desenho.BMP", "C:\Windows\Imagem.BMP"

Criando um arquivo texto em branco


Dim ARQ As Integer ARQ = FreeFile 'ATENO!!! Esta prxima linha abre o arquivo 'e, se ele contiver algo, TUDO ser apagado! Open "NomeDoArquivo" For Output As ARQ 'Faz o que tiver q ser feito com o arquivo 'Fecha o arquivo Close ARQ

Descobrindo e Alterando Atributos de Arquivos


'Num mdulo: Public Type Attrib Archive As Boolean Hidden As Boolean ReadOnly As Boolean System As Boolean End Type Public Function MudaAtributo(ByVal sNomeArq As _ String, ByRef m_Attrib As Attrib) As Boolean Dim AtributoMudar As Integer If m_Attrib.Archive = True Then AtributoMudar = AtributoMudar + vbArchive End If If m_Attrib.Hidden = True Then AtributoMudar = AtributoMudar + vbHidden End If

11
If m_Attrib.ReadOnly = True Then AtributoMudar = AtributoMudar + vbReadOnly End If If m_Attrib.System = True Then AtributoMudar = AtributoMudar + vbSystem End If If Dir(sNomeArq, vbReadOnly + vbArchive + _ vbSystem + vbHidden) = "" Then MudaAtributo = False Exit Function End If On Error GoTo Erro SetAttr sNomeArq, AtributoMudar On Error GoTo 0 MudaAtributo = True Exit Function Erro: MudaAtributo = False End Function Public Function PegaAtributo(ByVal sNomeArq As _ String, ByRef m_Attrib As Attrib) As Boolean Dim AtributoReceber As Integer If Dir(sNomeArq, vbReadOnly + vbArchive + _ vbSystem + vbHidden) = "" Then PegaAtributo = False Exit Function End If On Error GoTo Erro AtributoReceber = GetAttr(sNomeArq) On Error GoTo 0 m_Attrib.Archive = AtributoReceber And vbArchive m_Attrib.Hidden = AtributoReceber And vbHidden m_Attrib.ReadOnly = AtributoReceber And vbReadOnly m_Attrib.System = AtributoReceber And vbSystem PegaAtributo = True Exit Function Erro: PegaAtributo = False End Function 'P/ saber os atributos, proceda da seguinte maneira: Private Sub cmdPegar_Click() Dim ATR As Attrib If Not PegaAtributo("C:\Cezar.BMP", ATR) Then Debug.Print "Erro ao Pegar" Exit Sub End If MsgBox "Atrubutos do Arquivo: C:\Cezar.BMP" & _ vbCrLf & "A - " & ATR.Archive & vbCrLf & _ "H - " & ATR.Hidden & vbCrLf & _ "R - " & ATR.ReadOnly & vbCrLf & _ "S - " & ATR.System End Sub

12
Ele retornar da seguinte forma: ATR.Archive => Atributo Archive (Arquivo) ATR.Hidden => Atributo Hidden (Oculto) ATR.ReadOnly => Atributo ReadOnly (Somente p/ Leitura) ATR.System => Atributo System (Arquivo de Sistema) 'P/ mudar os atributos, proceda da seguinte 'maneira: Private Sub cmdMudar_Click() Dim ATR As Attrib ATR.Archive = True ATR.Hidden = False ATR.ReadOnly = False ATR.System = False If Not MudaAtributo("C:\Cezar.BMP", ATR) Then Debug.Print "Erro ao Pegar" Exit Sub End If Call cmdPegar_Click End Sub Ento, aps ele mudar os atributos, ele ir confirmar (chamando a Sub anterior) e lhe mostrar o resultado (os novos valores p/ os atributos...). Detalhe, os parmetros da funo MudaAtributo so: ATR.Archive => Atributo Archive (Arquivo) ATR.Hidden => Atributo Hidden (Oculto) ATR.ReadOnly => Atributo ReadOnly (Somente p/ Leitura) ATR.System => Atributo System (Arquivo de Sistema)

Excluindo Arquivos
Excluindo Arquivos Atravs de Comandos do VB (SEM usar a Lixeira):
'O comando p/ excluir arquivos o KILL. 'Sintaxe: Kill Caminho\NomeDoArquivo.QualquerCoisa 'Exemplo: Kill "C:\Desenho.BMP"

Excluindo Arquivos Atravs de API (USANDO a Lixeira):


O comando KILL do VB apaga o arquivo SEM manda-lo p/ a Lixeira. Ou seja, o perdemos para sempre. O cdigo a seguir nos ensina como deletar um arquivo enviando-o para a LIXEIRA do computador: 'Num mdulo: Option Explicit Public Declare Function SHFileOperation Lib "shell32.dll" _ Alias "SHFileOperationA" (lpFileOp As SHFILEOPSTRUCT) _ As Long Public Const FO_DELETE As Long = &H3 Public Const FOF_ALLOWUNDO As Long = &H40

13

Public Type SHFILEOPSTRUCT hWnd As Long wFunc As Long pFrom As String pTo As String fFlags As Integer fAnyOperationsAborted As Boolean hNameMappings As Long lpszProgressTitle As String End Type Public Sub ExcluirArq(ByVal FileName As String) Dim FLOP As SHFILEOPSTRUCT Dim RST As Long FLOP.wFunc = FO_DELETE FLOP.pFrom = FileName FLOP.fFlags = FOF_ALLOWUNDO 'deletando o arquivo RST = SHFileOperation(FLOP) End Sub 'P/ excluir um arquivo, execute a rotina: ExcluirArq "C:\Desenho.BMP"

Funo que Abre um Arquivo Texto e Retorna seu Contedo


Function AbreArquivo(sArquivo As String) As String Dim iARQ As Integer Dim sLinha As String Dim sResult As String iARQ = FreeFile Open sArquivo For Input As iARQ Do While Not EOF(iARQ) 'Pega o contedo da linha Line Input #iARQ, sLinha 'Quebra a linha e concatena (soma) o resultado sResult = sResult + Chr(13) & Chr(10) + sLinha Loop AbreArquivo = sResult 'Fecha o arquivo Close iARQ End Function 'P/ usar: Text1.Text = AbreArquivo("C:\Texto.TXT")

Funos para Manipulao de Arquivos INI


Digamos que, por exemplo, voc precise salvar certas configuraes de seu programa em um arquivo INI. Digamos ainda que voc tenha que salvar neste arquivo INI os seguintes parmetros:

14
* Parmetro1 => Posio X do Form * Parmetro2 => Posio Y do Form * Parmetro3 => Nome do usurio * Parmetro4 => Senha * Parmetro5 => Uma opo qualquer. (Lembre-se que isto apenas um exemplo!) Muito bem. Ento, coloque as seguintes declaraes e funes num mdulo: Public INI_Parametro1 As Public INI_Parametro2 As Public INI_Parametro3 As Public INI_Parametro4 As Public INI_Parametro5 As Public Sub Ler_INI(ByVal Dim sLinha As String Dim iARQ As Integer String String String String String sArquivoINI As String)

If Dir$(sArquivoINI) = "" Then 'O arquivo INI no existe MsgBox "O arquivo INI no existe!!!", vbCritical, _ "ATENAO!!!" Exit Sub End If iARQ = FreeFile Open sArquivoINI For Input As iARQ Do While Not EOF(iARQ) Line Input #iARQ, sLinha Select Case Separa_Parametro(sLinha) Case "Parmetro1" INI_Parametro1 = Separa_Valor(sLinha) Case "Parmetro2" INI_Parametro2 = Separa_Valor(sLinha) Case "Parmetro3" INI_Parametro3 = Separa_Valor(sLinha) Case "Parmetro4" INI_Parametro4 = Separa_Valor(sLinha) Case "Parmetro5" INI_Parametro5 = Separa_Valor(sLinha) End Select Loop Close iARQ End Sub Public Sub Salvar_INI(ByVal sArquivoINI As String) Dim iARQ As Integer iARQ = FreeFile Open sArquivoINI For Output As iARQ Print Print Print Print Print Print #iARQ, #iARQ, #iARQ, #iARQ, #iARQ, #iARQ, "[Geral]" "Parmetro1 "Parmetro2 "Parmetro3 "Parmetro4 "Parmetro5 = = = = = " " " " " & & & & & INI_Parametro1 INI_Parametro2 INI_Parametro3 INI_Parametro4 INI_Parametro5

Close iARQ End Sub

15

Private Function Separa_Parametro(ByVal Texto _ As String) As String Dim i As Integer For i = 1 To Len(Texto) If Mid$(Texto, i, 1) = "=" Then Separa_Parametro = Trim(Left$(Texto, i - 1)) Exit For End If Next i End Function Private Function Separa_Valor(ByVal Texto As _ String) As String Dim i As Integer For i = 1 To Len(Texto) If Mid$(Texto, i, 1) = "=" Then Separa_Valor = Trim(Right$(Texto,Len(Texto)-i)) Exit For End If Next i End Function Lendo o Arquivo INI: P/ pegar o valor dos parmetros gravado no arquivo INI: Ler_INI("Caminho\NomeDoArquivo.INI") Ele * A * A * A * A * A retornar cada parmetro em sua varivel INI_Parametro1 conter varivel INI_Parametro2 conter varivel INI_Parametro3 conter varivel INI_Parametro4 conter varivel INI_Parametro5 conter varivel. Veja: o valor do Parmetro1 o valor do Parmetro2 o valor do Parmetro3 o valor do Parmetro4 o valor do Parmetro5

Gravando no Arquivo INI: P/ gravar o valor dos parmetros no arquivo INI, preencha as variveis, e: Salvar_INI("Caminho\NomeDoArquivo.INI") Ele gravar o contedo * Parmetro1 = Gravar * Parmetro2 = Gravar * Parmetro3 = Gravar * Parmetro4 = Gravar * Parmetro5 = Gravar das variveis o contedo da o contedo da o contedo da o contedo da o contedo da em seus respectivos parmetros. Veja: varivel INI_Parametro1 varivel INI_Parametro2 varivel INI_Parametro3 varivel INI_Parametro4 varivel INI_Parametro5

Voc s dever modificar os nomes das variveis dos parmetro que sero recuperado/gravado no arquivo INI conforme a sua necessidade. O nome dos parmetros dever ser modificado nas Subs Ler_INI (no Select Case) e Salvar_INI (no comando Print). As modificaes segem esta sintaxe: * Modificaes no Select Case: Case "Nome_Do_Parmetro" * Modificaes no comando Print: Print #iARQ, "Nome_Do_Parmetro = " & INI_Nome_Do_Parmetro O nome das variveis devero seguir a seguinte sintaxe:

16
INI_Nome_Do_Parmetro ATENO!!! Caso algum parmetro no tenha sido preenchido na hora de gravar, NADA SER GRAVADO (ficar algo como "Parmetro1 = ")!!! Caso, na hora de ler o arquivo INI, ele no encontre o valor de certo parmetro (foi gravado algo como "Parmetro1 = "), ele no avisar. Ento, bom verificar estas variveis depois de preenchidas com a Sub Ler_INI.

Gravar cada informao em uma linha nova de um arquivo


'Voc dever abrir o arquivo com a instruo Open e: Print #ARQ, "O que se deseja grava" 'Depois s fechar o arquivo: Close ARQ

Imprimindo Arquivos Texto pelo VB


O modo mais fcil de se imprimir um arquivo texto este: 'Num mdulo: Public Function ImprimeArq(ByVal sArq As String) As _ Boolean Dim lArq As Long Dim sTexto As String If Dir$(sArq) = "" Then 'O arquivo no existe ImprimeArq = False Exit Function End If iArq = FreeFile() Open sArq For Binary Access Read As iArq sTexto = Space$(LOF(iArq)) Get #iArq, , sTexto Close iArq Printer.Print sTexto Printer.EndDoc ImprimeArq = True End Function 'A, chame-a assim: Dim bRet As Boolean bRet = ImprimeArq("C:\Caminho\Do\Arq\NomeDoArq.TXT")

Procurar um arquivo em diretrios e subdiretrios


Private NumFiles%, FilesNames$() Private FilesDates() As Date, FilesSizes&() Sub ScanPath(ByVal Path$, ByVal Files$) Dim i%, DirCount%, Buf$, DirName$, Dim FileName$, SubDir$() Const ATTR_DIRECTORY = 16 On Error Resume Next 'Le os arquivos locais FileName$ = Dir(Path$ + Files$) Do While FileName$ <> "" 'Esta inferior ou igual a data solicitada

17
NumFiles% = NumFiles% + 1 ReDim Preserve FilesNames$(NumFiles%), _ FilesDates(NumFiles%), FilesSizes&(NumFiles%) FilesNames$(NumFiles% - 1) = LCase(Path$ + _ FileName$) FilesDates(NumFiles% - 1) = FileDateTime(Path$ + _ "\" + FileName$) FilesSizes&(NumFiles% - 1) = FileLen(Path$ + _ "\" + FileName$) FileName$ = Dir Loop 'Identifica os subdiretorios DirName$ = Dir(Path$ + "*.*", ATTR_DIRECTORY) DirCount% = 0 Do While DirName$ <> "" 'Ignora "." e ".." If DirName$ <> "." And DirName$ <> ".." Then 'E diretorio??? If (GetAttr(Path$ + DirName$) And _ ATTR_DIRECTORY) = ATTR_DIRECTORY Then 'Sim, adiciona DirCount% = DirCount% + 1 ReDim Preserve SubDir$(DirCount%) SubDir$(DirCount% - 1) = DirName$ End If End If DirName$ = Dir Loop For i% = 0 To DirCount% - 1 'Faz uma recursividade, varrendo subdiretorios 'deste diretorio Call ScanPath(Path$ + SubDir$(i%) + "\", Files$) Next End Sub

Salvando o contedo de um TextBox num Arquivo Texto


Public Sub SalvaArq(ByVal sArquivo As String, _ ByVal sTexto As String) Dim iARQ As Integer, iRet As Integer iARQ = FreeFile If Dir$(sArquivo) <> "" Then iRet = MsgBox("O arquivo j existe. Voc " & _ "deseja sobrescreve-lo?", vbQuestion + _ vbYesNo, "ATENO!!!") If iRet = vbNo Then Exit Sub End If End If Open sArquivo For Output As iARQ Print #iARQ, sTexto Close iARQ End Sub 'P/ usar, chame-a passando o nome do arquivo e 'o texto. Veja: SalvaArq "C:\Texto.TXT", Text1.Text

18

Verificando a Data da ltima Alterao de um Arquivo


'Num mdulo: Public Function DataArq(ByVal sArq As _ String) As String If Dir$(sArq) <> "" Then DataArq = FileDateTime(sArq) Else DataArq = "ERRO" End If End Function 'P/ chamar, no evento que voc quizer: Private Sub Command1_Click() Dim sVar As String sVar = DataArq("C:\Quadrado 02.BMP") If sVar <> "ERRO" Then Text1.Text = sVar End If End Sub

Verificando a existencia de um arquivo


If Dir$("X:\XXXX\XXXXX.XXX") <> "" Then 'O arquivo existe Else 'O arquivo no existe End If

19

BANCO DE DADOS
Abrindo Bancos de Dados Externos - DAO & ADO
Caso voc venha a ter a necessidade de abrir uma base de dados externa, como um arquivo do Excel (por exemplo), use uma chave de conexo com a base de dados externa. Veja este exemplo:

DAO
Sub DAOAbrirBDExterno() Dim DB As DAO.Database Set DB = DBEngine.OpenDatabase(App.Path & _ "\Plan.XLS", False, False, "Excel 5.0;") DB.Close End Sub

ADO
Sub ADOAbrirBDExterno() Dim CNN As New ADODB.Connection CNN.Open "Provider=Microsoft.Jet.OLEDB.4.0;" & _ "Data Source=" & App.Path & "\Plan.XLS;" & _ "Extended " & "Properties=Excel 5.0;" CNN.Close End Sub Veja nesta tabela, os principais tipos de chaves de conexo usadas. Base de Dados dBase III dBase IV dBase 5 Paradox 5.x Excel 5.0/Excel 95 Excel 97 Excel2000 HTML Import HTML Export Text Chave de Conexo (String) dBase III; dBase IV; dBase 5.0; Paradox 5.x; Excel 5.0; Excel 97; Excel 8.0; HTML Import; HTML Export; Text; ODBC; DATABASE=database; UID=user; PWD=password; DSN=datasourcename;

ODBC

20

Abrindo Relatrios do Access pelo VB


Para usar este cdigo, necessrio fazer uma referncia biblioteca de automao do Access, em Project/References. 'No evento desejado: Dim sCaminho As String Dim objAccess As Access.Application 'Cria uma instncia do Access Set objAccess = New Access.Application 'Caminho do arquivo de banco de dados sCaminho = App.Path & "\Banco.MDB" If Right$(App.Path,1) = "\" Then sCaminho = App.Path & "Banco.MDB" End If With objAccess .Visible = False 'O Access firar invisvel .OpenCurrentDatabase filepath:=sCaminho .DoCmd.OpenReport "Relatrio", acViewNormal End With Set objAccess = Nothing ATENO!!! Para funcionar, a mquina onde voc for instalar seu programa DEVE ter o Access instalado, pois este cdigo "abre" o Access, mostrando o relatrio (o Access em si fica invisvel).

Abrir Banco de Dados com Senha - DAO & ADO


Caso voc tenha definido uma senha para seu banco de dados, abra-o desta maneira:

DAO
Sub DAOAbrirBDProtegido() Dim DB As DAO.Database 'O parmetro pwd (q a senha - 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. Set DB DBEngine.OpenDatabase(App.Path & "\SeuBD.MDB", _ False, False, ";pwd=senha") DB.Close End Sub

ADO
Sub ADOAbrirBDProtegido() Dim CNN As New ADODB.Connection CNN.Open "Provider=Microsoft.Jet.OLEDB.4.0;" & _ "Data Source=" & App.Path &"\SeuBD.MDB;Jet " & _ "OLEDB:Database Password=senha;" CNN.Close End Sub

21
Onde "senha" a sua senha. Quer dizer, subistitua "senha" pela senha do banco de dados.

Compactar Banco de Dados - DAO & ADO


Antes de comear:
Certifique-se que o banco de dados est fechado, pois se estiver aberto por algum usurio vai dar zebra. Certifique-se que no ha arquivo igual ao nome do arquivo temporrio. Se houver, delete. Ento vamos l: 'Usando DAO: Private Sub DAO_CompactarDB() 'Iniciamos o tratamento de erros. 'Se algo der errado, vamos para a linha 'indicada. On Error Goto ErroCompactar 'Declaramos as variveis Dim S_DbNome As String, S_DbTemp As String 'Descobrimos o caminho do Arquivo Original 'e do Arquivo Temp S_DbNome = App.Path & "\Armarinho.mdb" S_DbTemp = App.Path & "\AdmTmp.mdb" If Right$(App.Path, 1) = "\" Then S_DbNome = App.Path & "Armarinho.mdb" S_DbTemp = App.Path & "AdmTmp.mdb" End If 'Descobrimos se o Arquivo Temp existe... If Dir$(S_DbTemp) <> "" Then 'Se existe, deletamos (vide *Kill l em baixo) Call Kill(S_DbTemp) End If 'Compactamos o banco de dados com o 'nome de Arquivo Temp DBEngine.CompactDatabase S_DbNome, S_DbTemp 'Se Arquivo Original existir... If Dir$(S_DbNome) <> "" Then 'deleta Call Kill(S_DbNome) End If 'Aqui, vc poderia usar a instruo 'Name (vide *Name l em baixo) DBEngine.CompactDatabase S_DbTemp, S_DbNome Se na linha acima preferir usar a instruo Name, sua sintaxe seria como 'a linha aqui em baixo, portanto, a linha aqui em cima no existiria. Alternativa para a ultima linha acima>>> Name S_DbTemp As S_DbNome 'Se chegamos at aqui, avisa ao usurio que 'tudo correu bem... MsgBox "Compactao do Banco de Dados " & _ S_DbNome & " executada com sucesso.", _

22
vbOKOnly + vbInformation, "Compactao" Exit Sub ErroCompactar: 'Se caiu aqui, porque houve erro. Avise ao usurio. MsgBox "Houve um erro inesperado ao compactar o " & _ S_DbNome & " ." , vbOKOnly + vbInformation, _ "Compactao" 'Limpa o erro. No obrigatrio mais de bom 'costume fazer. Err.Clear End Sub 'Usando ADO: 'Marque nas referncias "Microsoft Jet and Replication 'Objects 2.1 Library" e: Private Sub ADO_CompactarDB() 'Iniciamos o tratamento de erros. 'Se algo der errado, vamos para a linha indicada. On Error Goto ErroCompactar 'Declaramos as variveis Dim JR As New JRO.JetEngine Dim S_DbNome As String, S_DbTemp As String 'Descobrimos o caminho do Arquivo Original 'e do Arquivo Temp S_DbNome = App.Path & "\Armarinho.mdb" S_DbTemp = App.Path & "\AdmTmp.mdb" If Right$(App.Path, 1) = "\" Then S_DbNome = App.Path & "Armarinho.mdb" S_DbTemp = App.Path & "AdmTmp.mdb" End If 'Descobrimos se o Arquivo Temp existe... If Dir$(S_DbTemp) <> "" Then 'Se existe, deletamos (vide *Kill l em baixo) Call Kill(S_DbTemp) End If 'Compactamos o banco de dados com o 'nome de Arquivo Temp JR.CompactDatabase "Provider=Microsoft.Jet.OLEDB.4.0;" & _ "Data Source=" & S_DbNome & ";", _ "Provider=Microsoft.Jet.OLEDB.4.0;" & _ "Data Source=" & S_DbTemp & ";Jet." & _ "OLEDB:Engine Type = 4;" 'Este "Engine Type" no final indica a verso do Access que est 'sendo usada. Veja os valores e as verses correspondentes: '5 (Defaut) para Access 2000 '4 para Access 97 '3 para Access 95/6 '2 para Access 2 '1 para Access 1 'Se Arquivo Original existir... If Dir$(S_DbNome) <> "" Then 'deleta Call Kill(S_DbNome) End If 'Aqui, vc poderia usar a instruo

23
'Name (vide *Name l em baixo) JR.CompactDatabase "Provider=Microsoft.Jet.OLEDB.4.0;" & _ "Data Source=" & S_DbTemp & ";", _ "Provider=Microsoft.Jet.OLEDB.4.0;" & _ "Data Source=" & S_DbNome & ";Jet." & _ "OLEDB:Engine Type = 4;" 'Se chegamos at aqui, avisa ao usurio que 'tudo correu bem... MsgBox "Compactao do Banco de Dados " & _ S_DbNome & " executada com sucesso.", _ vbOKOnly + vbInformation, "Compactao" Set JR = Nothing Exit Sub ErroCompactar: 'Se caiu aqui, porque houve erro. Avise ao usurio. MsgBox "Houve um erro inesperado ao compactar o " & _ S_DbNome & " ." , vbOKOnly + vbInformation, _ "Compactao" 'Limpa o erro. No obrigatrio mais de bom 'costume fazer. Err.Clear End Sub

Kill >>> Esta expresso DELETA o arquivo especificado do HD, mais deve ser
usada com cuidado. Este arquivo deletado NO ser armazenado na lixeira. Para usa-la, vc deve se certificar que o arquivo realmente exista.

Name >>> A instruo Name, copia um arquivo para outro local com 'outro
nome'. No lugar do segundo CompactDatabase, vc poderia usar a instruo Name. Isto s uma questo de escolha. Eu coloquei assim como ilustrao, mais os dois modos funcionam. Cuidado: como na instruo CompactDatabase, na instruo Name o arquivo que ser copiado tem que existir, caso contrrio dar erro.

Compactar banco de dados protegido por senha - DAO & ADO


Problema:
Neste exemplo, vc tem um banco de dados que quer compactar e este banco de dados protegido por senha

Soluo:

Ao usar a instruo "CompactDatabase", vc exclui os espaos vazios. Para isto, vc deve descobrir o nome e caminho do DB e sua respectiva 'senha'. Ento, vc fornece um nome temporrio para o DB, chama a instruo CompactDatabase com o nome temporario, o nome original e a senha (vide *Senha l em baixo) e depois vc renomeia para o nome original.

Antes de comear:

Certifique-se que o banco de dados est fechado, pois se estiver aberto por algum usurio vai dar zebra. Certifique-se que no ha arquivo igual ao nome do arquivo temporrio. Se houver, delete. Ento vamos l: 'Usando DAO: Private Sub DAO_CompactarDB() 'Iniciamos o tratamento de erros.

24
'Se algo der errado, vamos para a linha indicada. On Error Goto ErroCompactar 'Declaramos as variveis Dim S_DbNome As String, S_DbTemp As String 'Descobrimos o caminho do Arquivo Original 'e do Arquivo Temp S_DbNome = App.Path & "\Armarinho.mdb" S_DbTemp = App.Path & "\AdmTmp.mdb" If Right$(App.Path, 1) = "\" Then S_DbNome = App.Path & "Armarinho.mdb" S_DbTemp = App.Path & "AdmTmp.mdb" End If 'Descobrimos se o Arquivo Temp existe... If Dir$(S_DbTemp) <> "" Then 'Se existe, deletamos (vide *Kill l em baixo) Call Kill(S_DbTemp) End If 'Compactamos o banco de dados com o 'nome de Arquivo Temp DBEngine.CompactDatabase S_DbNome, S_DbTemp, _ , , ";PWD=rosakom" 'Se Arquivo Original existir... If Dir$(S_DbNome) <> "" Then 'deleta Call Kill(S_DbNome) End If 'Aqui, vc poderia usar a instruo 'Name (vide *Name l em baixo) DBEngine.CompactDatabase S_DbTemp, S_DbNome, _ , , ";PWD=rosakom" Se na linha acima preferir usar a instruo Name, sua sintaxe seria como 'a linha aqui em baixo, portanto, a linha aqui em cima no existiria. Alternativa para a ultima linha acima>>> Name S_DbTemp As S_DbNome 'Se chegamos at aqui, avisa ao usurio que 'tudo correu bem... MsgBox "Compactao do Banco de Dados " & _ S_DbNome & " executada com sucesso.", _ vbOKOnly + vbInformation, "Compactao" Exit Sub ErroCompactar: 'Se caiu aqui, porque houve erro. Avise ao usurio. MsgBox "Houve um erro inesperado ao compactar o " & _ S_DbNome & " ." , vbOKOnly + vbInformation, _ "Compactao" 'Limpa o erro. No obrigatrio mais de bom 'costume fazer. Err.Clear End Sub 'Usando ADO: 'Marque nas referncias "Microsoft Jet

25
'and Replication Objects 2.1 Library" e: Private Sub ADO_CompactarDB() 'Iniciamos o tratamento de erros. 'Se algo der errado, vamos para a linha indicada. On Error Goto ErroCompactar 'Declaramos as variveis Dim JR As New JRO.JetEngine Dim S_DbNome As String, S_DbTemp As String 'Descobrimos o caminho do Arquivo Original 'e do Arquivo Temp S_DbNome = App.Path & "\Armarinho.mdb" S_DbTemp = App.Path & "\AdmTmp.mdb" If Right$(App.Path, 1) = "\" Then S_DbNome = App.Path & "Armarinho.mdb" S_DbTemp = App.Path & "AdmTmp.mdb" End If 'Descobrimos se o Arquivo Temp existe... If Dir$(S_DbTemp) <> "" Then 'Se existe, deletamos (vide *Kill l em baixo) Call Kill(S_DbTemp) End If 'Compactamos o banco de dados com o 'nome de Arquivo Temp JR.CompactDatabase "Provider=Microsoft.Jet.OLEDB.4" & _ ".0;Data Source=" & S_DbNome & ";" & _ "Jet OLEDB:Database Password=rosakom;", _ "Provider=Microsoft.Jet.OLEDB.4.0;" & _ "Data Source=" & S_DbTemp & ";" & _ "Jet.OLEDB:Engine Type = 4;" 'Este "Engine Type" no final indica a verso do Access que est 'sendo usada. Veja os valores e as verses correspondentes: '5 (Defaut) para Access 2000 '4 para Access 97 '3 para Access 95/6 '2 para Access 2 '1 para Access 1 'Se Arquivo Original existir... If Dir$(S_DbNome) <> "" Then 'deleta Call Kill(S_DbNome) End If 'Aqui, vc poderia usar a instruo 'Name (vide *Name l em baixo) JR.CompactDatabase "Provider=Microsoft.Jet.OLEDB.4" & _ ".0;Data Source=" & S_DbTemp & ";" & _ "Jet OLEDB:Database Password=rosakom;", _ "Provider=Microsoft.Jet.OLEDB.4.0;" & _ "Data Source=" & S_DbNome & ";" & _ "Jet.OLEDB:Engine Type = 4;" 'Se chegamos at aqui, avisa ao usurio que 'tudo correu bem... MsgBox "Compactao do Banco de Dados " & _ S_DbNome & " executada com sucesso.", _ vbOKOnly + vbInformation, "Compactao"

26
Set JR = Nothing Exit Sub ErroCompactar: 'Se caiu aqui, porque houve erro. Avise ao usurio. MsgBox "Houve um erro inesperado ao compactar o " & _ S_DbNome & " ." , vbOKOnly + vbInformation, _ "Compactao" 'Limpa o erro. No obrigatrio mais de bom 'costume fazer. Err.Clear End Sub

Senha >>> No exemplo usamos uma senha qualquer. Ento, onde est rosakom deve
ser substituda por sua senha.

Kill >>> Esta expresso DELETA o arquivo especificado do HD, mais deve ser

usada com cuidado. Este arquivo deletado NO ser armazenado na lixeira. Para usa-la, vc deve se certificar que o arquivo realmente exista.

Name >>> A instruo Name, copia um arquivo para outro local com 'outro

nome'. No lugar do segundo CompactDatabase, vc poderia usar a instruo Name. Isto s uma questo de escolha. Eu coloquei assim como ilustrao, mais os dois modos funcionam. Cuidado: como na instruo CompactDatabase, na instruo Name o arquivo que ser copiado tem que existir, caso contrrio dar erro.

Criando Banco de Dados com Tabelas e ndices via VB - DAO


1 - A criao de um banco de dados via cdigo bastante simples: Dim WRK As Workspace Dim DB As Database Set WRK = DBEngine.Workspaces(0) 'Cria o banco de dados: Set DB = WRK.CreateDatabaseE("Banco.MDB", _ dbLangGeneral) 'Feche o banco de dados e o Workspace: DB.Close WRK.Close set DB = Nothing set WRK = Nothing 2 - Para se criar uma tabela voc ter que criar seus campos, expecificando o valor de certas propriedades. Neste exemplo, criaremos uma tabela contendo 3 campos: Cdigo, Nome e DataNasc. Veja o cdigo a seguir: Dim WRK As Workspace Dim DB As Database Dim TB As New TableDef Dim Campo1 As New Field Dim Campo2 As New Field Dim Campo3 As New Field Set WRK = DBEngine.Workspaces(0) 'Abre o banco de dados: Set DB = WRK.OpenDatabase("Banco.MDB") 'Atribui nome e utras propriedades tabela 'e aos campos: TB.Name = "Tabela"

27
Campo1.Name = "Cdigo" Campo1.Type = dbInteger Campo2.Name = "Nome" Campo2.Type = dbText Campo2.Size = 60 Campo3.Name = "DataNasc" Campo3.Type = dbDate 'Cria os campos na tabela TB.Fields.Append Campo1 TB.Fields.Append Campo2 TB.Fields.Append Campo3 'Cria a tabela: DB.TableDefs.Append TB 'Feche o banco de dados, a tabela e o Workspace: TB.Close DB.Close WRK.Close Set TB = Nothing set DB = Nothing set WRK = Nothing 3 - Criando ndices: Os ndices so muito teis em rotinas de procura de dados em tabelas, pois, alm de serem mais rpidos, eles requerem menos cdigo para realizar estas buscas. Veja como criar um ndice em um campo de uma tabela j existente: Dim WRK As Workspace Dim DB as Database Dim TB as Table Dim Index1 as New Index Dim Index2 as New Index Set WRK = DBEngine.Workspaces(0) 'Abre o banco de dados e a tabela: set DB = WRK.OpenDatabase("Banco.MDB") Set TB = DB.OpenTable("Tabela") 'Atribui nome e utras propriedades aos 'ndices: Index1.Name = "Cd" Index1.Fields = "Cdigo" Index1.Unique = True Index1.Primary = True Index1.Name = "Nom" Index2.Fields = "Nome" Index2.Unique = False Index2.Primary = False 'Cria os indices na tabela: TB.Indexes.Append Index1 TB.Indexes.Append Index2 'Feche o banco de dados, a tabela e o Workspace: TB.Close DB.Close WRK.Close Set TB = Nothing set DB = Nothing set WRK = Nothing

Filtrar Recordset j aberto - DAO


J tentou usar o mtodo FILTER? Ex:

28

Sub FilterX() Dim dbsNorthwind As Database Dim rstPedidos As Recordset Dim intPedidos As Integer Dim strPas As String Dim rstPedidosPas As Recordset Dim strMessage As String Set dbsNorthwind = OpenDatabase("Northwind.mdb") Set rstPedidos = dbsNorthwind.OpenRecordset("Pedidos", _ dbOpenSnapshot) 'Preenche o Recordset. rstPedidos.MoveLast intPedidos = rstPedidos.RecordCount 'Obtm a entrada do usurio. strPas = Trim(InputBox("Digite um " & _ "pas para filtrar em:")) If strPas <> "" Then 'Abre um objeto Recordset filtrado. Set rstPedidosPas = FilterField(rstPedidos, _ "PasDeDestino", strPas) With rstPedidosPas 'Verifica RecordCount antes de preencher o Recordset; 'caso contrrio, um erro pode ser gerado. If .RecordCount <> 0 Then .MoveLast 'Imprime o nmero de registros do objeto Recordset 'original e do objeto Recordset filtrado. strMessage = "Pedidos no conjunto de registros " & _ "original: " & vbCr & intPedidos & vbCr & _ "Pedidos no conjunto de registros " & _ "filtrado (Pas = '" & strPas & "'): " & _ vbCr & .RecordCount MsgBox strMessage .Close End With End If rstPedidos.Close dbsNorthwind.Close End Sub Function FilterField(rstTemp As Recordset, strField As _ String, strFilter As String) As Recordset 'Define um filtro no objeto Recordset especificado e em 'seguida abre um novo objeto Recordset. rstTemp.Filter = strField & " = '" & strFilter & "'" Set FilterField = rstTemp.OpenRecordset End Function Observao Para ver os efeitos de filtrar rstPedidos, voc deve definir sua propriedade Filter e, em seguida, abrir um segundo objeto Recordset baseado em rstPedidos. Observao: Quando voc conhece os dados que deseja selecionar, em geral mais eficiente criar um Recordset com uma instruo SQL. Este exemplo mostra como voc pode criar apenas um Recordset e obter os registros de um pas especfico.

29
Sub FilterX2() Dim dbsNorthwind As Database Dim rstPedidos As Recordset Set dbsNorthwind = OpenDatabase("Northwind.mdb") 'Abre um objeto Recordset que seleciona registros de 'uma tabela baseada no pas da remessa. Set rstPedidos = dbsNorthwind.OpenRecordset("SELECT * " & _ "FROM Pedidos WHERE PasDeDestino = " & _ "'USA'", dbOpenSnapshot) rstPedidos.Close dbsNorthwind.Close End Function

Funo que Cria a Clausula Where para Voc


'Num mdulo, coloque a funo Plic e esta 'seguinte: Public Sub CreateSQL(ByRef SQL As String, _ ByVal sFldCriteria As String, ByVal _ Value As Variant, Optional ByVal _ sAMais As String) Select Case VarType(Value) Case vbString If Value <> vbNullString Then If sAMais <> vbNullString Then Value = Left(sAMais, 1) & Value & _ Right(sAMais, 1) Value = Trim$(Value) End If If SQL = vbNullStrin Then SQL = " Where " & sFldCriteria & _ Plic(Value) Else SQL = SQL & " AND " & sFldCriteria & _ Plic(Value) End If End If Case vbCurrency, vbSingle, vbDecimal, _ vbDouble, vbInteger, vbByte, vbLong If SQL = vbNullStrin Then SQL = " Where " & sFldCriteria & _ Str(Value) Else SQL = SQL & " AND " & sFldCriteria & _ Str(Value) End If Case vbDate If SQL = vbNullStrin Then SQL = " Where " & sFldCriteria & _ Format$(Value, "\#yyyy/mm/dd hh:nn:ss\#") Else SQL = SQL & " AND " & sFldCriteria & _ Format$(Value, "\#yyyy/mm/dd hh:nn:ss\#") End If Case vbBoolean If SQL = vbNullStrin Then SQL = " Where " & sFldCriteria & _ CStr(Value)

30
Else SQL = SQL & " AND " & sFldCriteria & _ CStr(Value) End If End Select End Sub 'Exempos de uso: Dim sMySQL as String sMySQL = vbNullString CreateSQL sMySQL, "Campo1 = ", Text1.Text CreateSQL sMySQL, "Campo2 > ", Text2.Text ..... rs.Open "SELECT * FROM Tabela" & sMySQL, cnn, ... ..... Neste caso, quando o programa chegar na linha rs.Open, sMySQL conter o seguinte: " Where Campo1 = 'Contedo de Text1.Text' And Campo2 > 'Contedo de Text2.Text'" Se voc precisar usar o comando Like, use assim: sMySQL = vbNullString CreateSQL sMySQL, "Campo1 Like ", Text1.Text, "%%" Ele retornar: " Where Campo1 Like '%Contedo de Text1.Text%' Vantagens: no precisa ficar fazendo testes a cada montagem do SQL, a funo testa se tem algo e monta a clausula Where direitinho.

Listando o Nome de Todas as Tabelas de um BD - ADO & DAO


***

Usando ADO

***

'No evento que voc desejar: Dim ADOXCat As New ADOX.Catalog ADOXCat.ActiveConnection = "PROVIDER=Microsoft.Jet." & _ "OLEDB.4.0;Data Source=" & _ "C:\Banco.MDB;" For i = 0 To ADOXCat.Tables.Count - 1 Debug.Print ADOXCat.Tables.Item(i).Name Next i Depois desta rotina ter sido executada, o nome de TODAS as tabelas do banco de dados estar na janela Immediate Windows... ***

Usando DAO

***

'No evento que voc desejar: Dim DB As DAO.Database Dim i As Integer Set DB = Workspaces(0).OpenDatabese("C:\Banco.MDB") For i = 0 To DB.TableDefs.Count - 1 If (DB.TableDefs(i).Attributes And _ dbSystemObject) <> dbSystemObject Then Print DB.TableDefs(i).Name End If

31
Next

Passar parametro para SQL armazenada em DB - ADO


Sub ADOExecuteParamQuery() Dim cnn As New ADODB.Connection Dim cat As New ADOX.Catalog Dim cmd As ADODB.Command Dim rst As New ADODB.Recordset Dim fld As ADODB.Field 'Open the connection cnn.Open "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\nwind.mdb;" 'Open the catalog cat.ActiveConnection = cnn 'Get the Command object from the Procedure Set cmd = cat.Procedures("Sales by Year").Command 'Specify the parameter values cmd.Parameters("Forms!Sales by Year Dialog!" & _ "BeginningDate")=#8/1/1993# cmd.Parameters("Forms!Sales by Year Dialog!" & _ "EndingDate")=#8/31/1993# 'Open the recordset rst.Open cmd, , adOpenForwardOnly, adLockReadOnly, adCmdStoredProc 'Display the records in the debug window While Not rst.EOF For Each fld In rst.Fields Debug.Print fld.Value & ";"; Next Debug.Print rst.MoveNext Wend 'Close the recordset rst.Close 'Apesar da documentao no faz-lo, *EU acrescento*... '(chato 8^)) n?) Set rst = Nothing cmd.Close Set cmd = Nothing 'cat.Close '<< No achei no Doc, referncia ao .Close Set cat = Nothing '<< S ACHEI Nothing cnn.Close Set cnn = Nothing 'Fim do *EU Acrescento* End Sub

32

Procurando no Banco de Dados (Find - FindFirst - FindNext) - DAO & ADO


(DAO)
No DAO, exite o comando FindFirst que faz a procura a partir do incio da tabela, achando a primeira ocorrencia daquilo a que est sendo procurado. 'Abre o Recordset e ento: Dim sArg as String sArg = InputBox ("Por favor, digite o Nome do " &_ "Cliente:", "Localizar Nome") 'P/ procurar EXATAMENTE o que foi digitado: RS.FindFirst "NomeCliente = '" & sArg & "'" 'P/ procurar algum nome que COMECE com o que 'foi digitado: RS.FindFirst "NomeCliente like '" & sArg & "*'" 'P/ procurar algum nome que TERMINE com o que 'foi digitado: RS.FindFirst "NomeCliente like '*" & sArg & "'" 'P/ procurar algum nome que tenha o que foi 'digitado em qualquer parte (inicio/meio/fim): RS.FindFirst "NomeCliente like '*" & sArg & "*'" If RS.NoMatch then 'Nenhum registro foi encontrado. Else 'Foi encontrado um registro. Endif Bom, se algum registro tiver sido encontrado, voc poder pesquizar a prxima ocorrencia (prximo registro que contenha aquele valor procurado no campo que se est sendo feita a pesquiza), usando o comando FindNext: RS.FindNext 'Ou: RS.FindNext 'Ou: RS.FindNext 'Ou: RS.FindNext "NomeCliente = '" & sArg & "'" "NomeCliente like '" & sArg & "*'" "NomeCliente like '*" & sArg & "'" "NomeCliente like '*" & sArg & "*'"

If RS.NoMatch then 'Nenhum registro foi encontrado. Else 'Foi encontrado um registro. Endif Bem, a nica coisa que voc precisa saber para usar os comandos FindFirst, FindLast, FindNext e FindPrevious, que o FindFirst faz a procura SEMPRE a partir do incio da tabela, que o FindLast faz a procura SEMPRE a partir do fim da tabela e os outros dois (FindNext e FindPrevious) fazem a procura SEMPRE a partir do ponto da tabela em que esto.

33

(ADO)
No ADO no existe os comandos FindFirst, FindLast, FindNext e FindPrevious, mas existe o comando Find. Usando este comando (Find) voc no poder usar o RS.NoMatch, pois ele no trabalha desta forma. Mas como eu posso fazer procuras do tipo "achar a primeira ocorrencia", "achar a prxima ocorrencia" e etc na minha tabela, sendo que eu s tenho o comando Find??? Bem, veja a sintaxe que voc ir entender: RS.Find "[Campo] = [Valor]", [SkipRows], [Tipo] Partes da sintaxe: [Campo] => Campo do banco de dados. O nome deve ser IDENTICO ao que est no banco de dados. [Valor] => Aquilo que se est procurando. [SkipRows] => Valor entre 0 e 1. Depende do tipo de procura que est sendo feita. [Tipo] => Constante que indica como a procura dever ser feita. Veja esta tabela para saber o que colocar em [SkipRows] e em [Tipo] conforme a sua procura: Mtodo DAO ADO-SkipRows ADO - Search direction adScarchForward (se no estiver posicionado no primeiro registro, FindFirst 0 execute o MoveFirst antes do Find) adScarchBackward (se no estiver posicionado no ltimo FindLast 0 registro, execute o MoveLast antes do Find) FindNext 1 adScarchForward FindPrevious 1 adScarchBackward Veja um exemplo de FindFirst no ADO usando o comando Find: 'Abre o Recordset e ento: Dim sArg as String RS.MoveFirst '<<<- MUITO importante!!! sArg = InputBox ("Por favor, digite o Nome do " &_ "Cliente:", "Localizar Nome") 'P/ procurar EXATAMENTE o que foi digitado: RS.Find "NomeCliente = '" & sArg & "'", adSearchForward 'P/ procurar algum nome que COMECE com o que 'foi digitado: RS.Find "NomeCliente like '" & sArg & "*'", adSearchForward 'P/ procurar algum nome que TERMINE com o que 'foi digitado: RS.Find "NomeCliente like '*" & sArg & "'", adSearchForward 'P/ procurar algum nome que tenha o que foi 'digitado em qualquer parte (inicio/meio/fim): RS.Find "NomeCliente like '*" & sArg & "*'", adSearchForward If RS.EOF Then 'Nenhum registro foi encontrado.

34
Else 'Foi encontrado um registro. Endif Bem, seguindo essa filosofia, veja: 'FindLast: RS.Find "NomeCliente like '" & sArg & "'", adScarchBackward 'FindNext: RS.Find "NomeCliente like '" & sArg & "'", 1, adSearchForward 'FindPrevious: RS.Find "NomeCliente like '" & sArg & "'", 1, adScarchBackward

Reparar Banco de Dados - DAO


'Reparar banco de dados Dim PERG PERG = MsgBox("Deseja reparar o banco de dados agora?", _ vbQuestion + vbYesNo, "Reparar DB?") If PERG = vbYes Then DBEngine.RepairDatabase "C:\agenda.mdb" MsgBox "Operao realizada com sucesso!", vbInformation, _ "DB Reparado!" Else MsgBox "Operao cancelada", vbInformation, _ "DB no Reparado!" End If

Salvar informaes do Access para dBase - DAO


DB.EXECUTE "INSERT INTO Tabela IN 'C:\TEMP' 'dBase III;' SELECT * FROM Tabela"

Soluo para a Aspa Simples (') em Strings de SQL


Public Function Plic(ByVal sTexto As String) As _ String If InStr(sTexto, Chr(39)) Then Plic = Chr(39) & Replace(sTexto, _ Chr(39), Chr(39) & Chr(39)) & _ Chr(39) Else Plic = Chr(39) & sTexto & Chr(39) End If End Function 'P/ usar, por exemplo: Text1.Text = Plic(Text1.Text) 'No caso, se for p/ passar p/ uma string SQL, veja: Dim MySQL As String MySQL = "Select * From Clientes Where Nome = " & _

35
Plic(Text1.Text) (...) ATENO!!! Se voc estiver usando o VB5.0 (ou mais antigo), nele NO tem a funo Replace. P/ corrigir isto veja a dica Funo Replace para VB5.0.

Trabalhando com Recordsets Desconectados - ADO


Digamos que voc faa uma tela de pesquiza do seu cadastro (com um Grid e etc), e goste de abrir e fechar a conexo/Recordset quando necessrio (ou seja, programao direcionada a multipos usurios - rede). Nesse caso, voc pode abrir o Recordset e desconecta-lo da conexo, ou seja, do banco de dados. Para isso, proceda da seguinte forma: 'Sete o CursorLocation do Recordset como adUseClient: RS.CursorLocation = adUseClient 'Abra o Recordset com AdLockBatchOptimistic: RS.Open etc etc etc, AdLockBatchOptimistic 'Desconecta o Recordset: Set RS.ActiveConnection = Nothing 'Agora sim voc pode fechar a conexo e tudo mais... 'P/ setar este Recordset p/ um Grid, por exemplo: Set Grid.DataSource = RS

Trabalhando com Recordsets Dinmicos - ADO


Digamos que em um programa qualquer voc precise usar um recordset para guardar dados em memria... Dados que no sero salvos num banco de dados, ou que podero vir a ser salvos mais tarde ou no. Um exemplo disso seria num cadastro de vendas. Enquanto a venda no salva, os produtos que esto sendo vendidos nessa venda no sero cadastrados. Quando a venda for salva, a sim isto seria salvo numa tabela de produtos da venda, a qual guarda tambm o cdigo da venda. Ento veja como fazer: 'No declarations do Form: Dim RS As ADODB.Recordset No evento Form_Load: Private Sub Form_Load() Set RS = New ADODB.Recordset 'Cria os campos necessrios With RS.Fields .Append "Campo1", AdInteger, 100 .Append "Campo2", adVarChar, 100 End With 'No caso, o nome dos campos so "Campo1" e '"Campo2". '"Campo1" do tipo numrico inteiro e

36
'"Campo1" do tipo caracter de 100 espaos... RS.Open End Sub Bom, depois disso voc poder navegar por este Recordset (RS.MoveFirst, RS.MovePrevious, RS.MoveNext, RS.MoveLast), fazer procuras nele com o Find, com o Seek, apagar, adiciona e atualizar registros. Veja: RS.AddNew RS![Campo1] = Text1.Text RS![Campo2] = Text1.Text RS.Update Voc pode at salvar esse Recordset num arquivo e depois abri-lo novamente, veja: 'Salvando RS.Save "c:\temp\arq.dat"

Usando o IIF em Consultas SQL


Digamos que voc precise atribuir um determinado valor a uma varivel, dependendo do contedo de outra (inseri um valor ou outro). Neste caso, podese utilizar o comando IIF. Syntaxe: IIF([Condio], [Valor Verdadeiro], [Valor Falso]). Este comando retornar [Valor Verdadeiro] no caso da [Condio] ser verdadeira ou [Valor Falso] no caso da [Condio] ser falsa. Ex: Dim iX As Integer, sRet As String iX = 3 sRet = IIF(X > 1, "X maior que 1", _ "X menor ou igual a 1") Depois disso, sRet conter a String "X maior que 1". Voc pode usar o IIF fcilmente numa consulta SQL. Digamos que voc precise fazer uma consulta SQL, onde tenha que testar o contedo de um campo e retornar valores diferentes conforme o contedo deste campo. Num caso como este, pode-se utilizar o comando IIF. Por exemplo, digamos que voc far uma consulta na tabela de alunos e voc quer criar um campo onde, se a mdia do aluno for maior ou igual a 5, ele seja preenchido com o texto "Aprovado", ou ento "Reprovado". Veja como ficaria: SELECT Nome, Mdia, IIF(Mdia>=5,"Aprovado","Reprovado") AS Status FROM Alunos

Utilizando o ADO - [Bsico]


Esta dica mostra os passos bsicos p/ se usar o ADO ao invs do DAO.

37

A. Abertura de Banco de Dados e de Tabelas


'1 - Criar uma Conexo Dim Conexo As ADODB.Connection Set Conexo = New ADODB.Connection '2 - Criar uma Recordset Dim Tabela As ADODB.Recordset Set Tabela = New ADODB.Recordset '3 - Criar uma Varivel para SQL Dim SQLString As String '4 - Abrir o Banco de Dados (Definir o SGBD a ser Utilizado) Conexo.Open "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & _ App.Path & "\Banco.MDB" '5 - Definir o Valor Inicial para a Varivel de SQL SQLString = "Select * From Tabela" '6 - Abrir o Recordset (Tabela) Tabela.Open SQLString, Conexo, [CursorType], [LockType] Explicaes:

[CursorType]: Opcional. Um valor CursorTypeEnum que determina o tipo de


cursor que o provedor deve usar ao abrir o Recordset. Pode ser uma das seguintes constantes: Constante adOpenForwardOnly Descrio Cursor somente progressivo. Padro. Idntico ao cursor esttico exceto pelo fato de que possvel somente efetuar rolagem progressiva pelos registros. Isso melhora o desempenho em situaes em que necessria somente uma passagem pelo recordset. Cursor do conjunto de teclas. Como um cursor dinmico, exceto pelo fato de que no possvel consultar os registros que outros usurio adicionaram, embora os registros excludos por outros usurios sejam inacessveis a partir do recordset. As alteraes nos dados feitas por outros usurios permanecem visveis. Cursor dinmico. Adies, alteraes e excluses feitas por outros usurios so visveis e todos os tipos de movimentos pelo recordset so permitidos, exceto indicadores, se o provedor no der suporte a eles. Cursor esttico. Uma cpia esttica de um recordset que pode ser usada para localizar dados ou gerar relatrios. Adies, alteraes ou excluses feitas por outros usurios no so visveis.

adOpenKeyset

adOpenDynamic

adOpenStatic

[LockType]: Opcional. Um valor LockTypeEnum que determina qual tipo de

bloqueio (simultaneidade) o provedor deve usar ao abrir o Recordset. Pode ser uma das seguintes constantes: Constante adLockReadOnly adLockPessimistic adLockOptimistic Descrio Padro. Somente leitura - no possvel alterar os dados. Bloqueio pessimista, registro por registro - o provedor faz o que for necessrio para garantir o xito da edio dos registros, em geral, bloqueando-os na fonte de dados imediatamente acima de uma edio. Bloqueio otimista, registro por registro - o provedor

38
usa o bloqueio otimista, bloqueando os registros somente quando o mtodo Update for chamado. Atualizaes em lotes otimistas - necessrias para o modo de atualizao em lotes em oposio ao modo de atualizao imediata.

adLockBatchOptimistic

B. Manipulao de Dados
A manipulao continua idem ao do DAO, com a diferena de no existir mais o metodo Edit. Veja os exemplos: Adicionando um Registro: Tabela.AddNew Tabela![Campo1] = Valor1 Tabela![Campo2] = Valor2 Tabela![Campo3] = Valor3 Tabela![Campo4] = Valor4 Tabela.Update Alterando um Registro: Tabela![Campo1] = NovoValor1 Tabela![Campo2] = NovoValor2 Tabela![Campo3] = NovoValor3 Tabela![Campo4] = NovoValor4 Tabela.Update Excluindo um Registro: Dim RES RES = MsgBox("Deseja excluir o registro atual?", _ 48 + vbYesNo, "Excluir???") If RES = vbYes Then Tabela.Delete If Not Tabela.EOF Then Tabela.MoveFirst 'Sub que joga os valores dos campos da 'tabela p/ os TextBoxes MostraDados End If End If Movendo entre Registros: Coloque 4 botes no Form, com Captions "|<", "<", ">" e ">|", todos com o nome cmdMove, formando assim um array de botes de indices 0 3. No evento Click deste array de botes, coloque o seguinte cdigo: Private Sub cmdMove_Click(Index As Integer) Select Case Index Case 0 Tabela.MoveFirst Case 1 If Not Tabela.BOF Then Tabela.MovePrevious If Tabela.BOF Then Tabela.MoveFirst End If Case 2 If Not Tabela.EOF Then Tabela.MoveNext

39
If Tabela.EOF Then adoPrimaryRS.MoveLast End If Case 3 Tabela.MoveLast End Select End Sub

Utilizar algum programa que compacte os DBs


Option Explicit Private WinZipPath$ Private Data_Path$, Data_BaseName$, Data_BaseExt$ Private Type STARTUPINFO cb As Long lpReserved As String lpDesktop As String lpTitle As String dwX As Long dwY As Long dwXSize As Long dwYSize As Long dwXCountChars As Long dwYCountChars As Long dwFillAttribute As Long dwFlags As Long wShowWindow As Integer cbReserved2 As Integer lpReserved2 As Long hStdInput As Long hStdOutput As Long hStdError As Long End Type Private Type PROCESS_INFORMATION hProcess As Long hThread As Long dwProcessID As Long dwThreadID As Long End Type Private Declare Function WaitForSingleObject Lib _ "Kernel32" (ByVal hHandle As Long, ByVal _ dwMilliseconds As Long) As Long Private Declare Function CreateProcessA Lib _ "Kernel32" (ByVal lpApplicationName As _ Long, ByVal lpCommandLine As String, ByVal _ lpProcessAttributes As Long, ByVal _ lpThreadAttributes As Long, ByVal _ bInheritHandles As Long, ByVal _ dwCreationFlags As Long, ByVal _ lpEnvironment As Long, ByVal _ lpCurrentDirectory As Long, lpStartupInfo _ As STARTUPINFO, lpProcessInformation As _ PROCESS_INFORMATION) As Long Private Declare Function CloseHandle Lib "Kernel32" _ (ByVal hObject As Long) As Long Private Declare Function GetDiskFreeSpace Lib _

40
"Kernel32" Alias "GetDiskFreeSpaceA" ( _ ByVal lpRootPathName As String, _ lpSectorsPerCluster As Long, lpBytesPerSector _ As Long, lpNumberOfFreeClusters As Long, _ lpTtoalNumberOfClusters As Long) As Long Private Private Private Private Private Private Private Private Const Const Const Const Const Const Const Const NORMAL_PRIORITY_CLASS = &H20& INFINITE = -1& SW_NORMAL = 1 SW_HIDE = 0 SW_SHOW = 5 SW_SHOWMINNOACTIVE = 7 SW_SHOWNA = 8 STARTF_USESHOWWINDOW = 1&

Private Sub mnu_UtilitariosBaseDadosCompac_Click() Dim SourceFile$, OutFile$, OutExt$ On Error Resume Next 'With FormMsgBox ' .Label1.Visible = False ' Set .Label2.Font = .Label1.Font ' .Label2.Caption = "Copactando Base de Dados." ' .Label3.Visible = True ' .Label3.Caption = "Aguarde!" ' .pnl_Flood.Visible = False ' .Show ' .Refresh 'End With SourceFile$ = CompressBD(OutFile$,OutExt$) If SourceFile$<>Data_Path$+"\"+OutFile$+OutExt$ Then Err.Clear Kill Data_Path$+"\"+Data_BaseName$+".bak" Name Data_Path$+"\"+Data_BaseName$+Data_BaseExt$ As _ Data_Path$+"\"+Data_BaseName$+".bak" Name Data_Path$+"\"+OutFile$+OutExt$ As _ Data_Path$+"\"+Data_BaseName$+Data_BaseExt$ End If 'Unload FormMsgBox Call AbreDataBase End Sub Private Sub mnu_UtilitariosEnviarDisquete_Click() Dim i%, SourceFile$,OutFile$,OutExt$,RetErrNbr&,RetErrDesc$ On Error Resume Next 'With FormMsgBox ' .Label1.Visible = False ' Set .Label2.Font = .Label1.Font ' .Label2.Caption = "Copactando Base de Dados." ' .Label3.Visible = True ' .Label3.Caption = "Aguarde!" ' .pnl_Flood.Visible = False ' .Show ' .Refresh 'End With SourceFile$ = CompressBD(OutFile$,OutExt$) 'FormMsgBox.Label2.Caption = "Zipando Base copiada." 'FormMsgBox.Refresh Call ZipCopyFile(SourceFile$, "a:", OutFile$, OutExt$, _ RetErrNbr&, RetErrDesc$)

41
'Unload FormMsgBox If RetErrNbr& <> 0 Then Kill "a:\" & OutFile$ & OutExt$ MsgBox RetErrDesc$, vbInformation Else MsgBox "Arquivo '" & OutFile$ & OutExt$ & _ "' copiado para o disquete.", vbInformation End If Call AbreDataBase End Sub Function CompressBD$(OutFile$, OutExt$) Dim i% On Error Resume Next If FileDateTime(Data_Path$+"\"+Data_BaseName$ + _ Data_BaseExt$)>FileDateTime(Data_Path$+"\COMPAC" + _ Data_BaseExt$) Then ' For i% = Forms.Count - 1 To 0 Step -1 ' If Forms(i%).Name <> "MDIForm" And _ ' Forms(i%).Name <> "FormMsgBox" And _ ' Forms(i%).Name <> "FormFlyOver" Then ' Unload Forms(i%) ' End If ' DoEvents: DoEvents ' Next Call CloseDataBase Screen.MousePointer = vbHourglass Err.Clear ChDir Data_Path$ If "COMPAC" <> Data_BaseName$ Then Kill "COMPAC" + Data_BaseExt$ End If CompactDatabase Data_Path$ + "\" + Data_BaseName$ + _ Data_BaseExt$, Data_Path$ + "\COMPAC" + Data_BaseExt$ End If OutFile$ = "COMPAC" OutExt$ = Data_BaseExt$ If Err.Number = 0 Then CompressBD = Data_Path$+"\COMPAC"+Data_BaseExt$ Else CompressBD = Data_Path$+"\"+Data_BaseName$+Data_BaseExt$ End If Screen.MousePointer = vbNormal End Function Function ZipCopyFile(ByVal InFile$, OutPath$, OutFile$, _ OutExt$, ErrNumber&, ErrDesc$) As Boolean Dim i%, FreeSpace&, szCommandLine$ Dim lDiskFree&, lRet&, lBytes&, lSect&, lClust&, lTot& Dim ProcInfo As PROCESS_INFORMATION Dim StartProc As STARTUPINFO On Error Resume Next ErrNumber& = -1 ErrDesc$ = "Erro desconhecido." Err.Clear If WinZipPath$ <> "" Then Screen.MousePointer = vbHourglass szCommandLine$ = Aspas(WinZipPath$) & " -a " & _ Aspas(OutPath$ + "\" + OutFile$) & " " & _ Aspas(InFile$) StartProc.cb = Len(StartProc) If CreateProcessA(0&, szCommandLine$, 0&, 0&, 1&, _

42
NORMAL_PRIORITY_CLASS, 0&, 0&, StartProc, _ ProcInfo) Then lRet& = WaitForSingleObject(ProcInfo.hProcess, INFINITE) CloseHandle (ProcInfo.hThread) CloseHandle (ProcInfo.hProcess) If FileDateTime(InFile$) > FileDateTime(OutPath$ + "\" + _ OutFile$ + ".zip") Then GoTo ZipStartErro End If Else GoTo ZipStartErro End If Screen.MousePointer = vbNormal If Err.Number = 0 Then OutExt$ = ".zip" ErrNumber& = 0 ErrDesc$ = "" ZipCopyFile = True Else GoTo ZipStartErro End If Else ZipStartErro: Screen.MousePointer = vbHourglass If Mid(OutPath$, 2, 1) = ":" Then lRet = GetDiskFreeSpace(Left(OutPath$, 2) + "\", lSect, lBytes, lClust, lTot) lDiskFree = (lBytes * lSect) * lClust If Err.Number <> 0 Then lDiskFree = 2147483647 Err.Clear If FileLen(InFile$) > lDiskFree Then ErrNumber& = 0 ErrDesc$ = "Disco cheio." ZipCopyFile = False Exit Function End If End If Err.Clear FileCopy InFile$, OutPath$ & OutFile$ & OutExt$ Screen.MousePointer = vbNormal ZipCopyFile = (Err.Number = 0) ErrNumber& = Err.Number ErrDesc$ = Err.Description End If End Function Public Sub AbreDataBase() 'Abro a base de dados End Sub Public Sub CloseDataBase() 'Fecho as tabelas, recorsets e a basededados/conexo End Sub Public Function Aspas$(ByVal Value) If InStr(Value, """") Then Aspas = "'" & Trim(Value) & "'" Else Aspas = """" & Trim(Value) & """" End If End Function

43

CLCULOS
Calcula a idade em anos entre duas datas
Public Function Age(Bdate As Date, DateToday _ As Date) As Integer If Month(DateToday) < Month(Bdate) Or _ (Month(DateToday) = Month(Bdate) And _ Day(DateToday)<Day(Bdate)) Then Age = Year(DateToday) - Year(Bdate) - 1 Else Age = Year(DateToday) - Year(Bdate) End If End Function

Calcula a Raiz Quadrada de um Nmero


Para fazer o calculo da raiz quadrada de qualquer nmero, s usar a funo Sqr. Veja este exemplo: Dim iNum As Integer iNum = Sqr(25) Depois desta operao, iNum conter o nmero 5. 8^) By Tamanhoni - ValewZAO!!! 8^)))

Calculando a Diferena entre Duas Datas em Dias


Este clculo bem simples de ser feito. Veja o cdigo: Private Sub Calcula_DT() Dim dData As Date, sMsg As String dData = InputBox("Digite uma data:") sMsg = "Dias at a data escolhida: "& _ DateDiff("d", Now, dData) Msgbox sMsg End Sub

Calculo de Mensalidades
Digamos que voc precise gerar 4 datas a partir de uma data digitada pelo usurio (para um controle de parcelas, por exemplo. No caso, seriam 5 parcelas). Veja: Para isso usaremos a funo DateAdd() que tem a seguinte sintxe: DateAdd(Intervalo,Numero,Data) Intervalos: "d" - Dias

44
"m" - Meses "y" - Anos Ento ficaria: Dim MyArray(4) As Date Dim i As Integer MyArray(0) = "14/05/2000" For i = 1 To 4 MyArray(i) = DateAdd("m", i, "14/05/2000") Next By Maximiliano Damian Rodrigues - ValewZAO!!! 8^))

Contas corretas com ponto fluante


Algum j notou que o Visual Basic no muito bom em matemtica? Tente fazer 18.51 + (-17.59) e voc ir receber .9200000000000002. Isso ocorre, porque no Visual Basic, os valores com ponto flutuante so armazenados no formato padro IEEE. A representao da mquina sobre valores numricos em binrio. Qualquer valor inteiro pode ser representado "EXATAMENTE" na forma binria, mas nos casos de valores com ponto flutuante, isso no acontece. Por exemplo, o decimal 0.0001 no pode ser representado exatamente em binrio (0.0001 uma frao repetitiva com um perodo de 104 bits!). Ento, os valores com ponto flutuante so aproximados para o prximo valor que pode ser representado em binrio. Logo, eles tendem a causar algum erro nos calculos quando so utilizados. No nosso exemplo, ambos 18.51 e 17.59 no podem ser representados exatamente pelo padro de ponto flutuante. A soma deles incluir um pequeno erro. Observe que o erro bastante pequeno e essencialmente a soma (quando vista em uma preciso de 14/15 pontos decimais usando a funo Format$) correta. Para exibir o resultado exato para o usurio, faa o seguinte: Format$(18.51 + (-17.59), "###.#####")

Dias teis entre duas datas


Function DiasUteis(dtInicio As Variant, _ dtFinal As Variant) As Integer Dim intSemanas As Integer Dim varDataCont As Variant Dim intFimDias As Integer dtInicio = DateValue(dtInicio) dtFinal = DateValue(dtFinal) intSemanas = DateDiff("w",dtInicio,dtFinal) varDataCont = DateAdd("ww",intSemanas,dtInicio) intFimDias = 0 Do While varDataCont < dtFinal If Format(varDataCont,"ddd") <> "Sun" And _ Format(varDataCont,"ddd") <> "Sat" Then

45
intFimDias = intFimDias + 1 End If varDataCont = DateAdd("d", 1, varDataCont) Loop DiasUteis = intSemanas * 5 + intFimDias End Function

Descobrindo Dias no Ano


* Primeiro Dia do Ano Data = Now() - Datepart("y", Now()) + 1 'Now() pode ser substitudo por algo como '#04/06/1996#, ou #16/08/2000#, etc... * Ultimo Dia do Ano Data = Dateadd("yyyy", 1, Now() - _ Datepart("y", Now())) 'Now() pode ser substitudo por algo como '#04/06/1996#, ou #16/08/2000#, etc... * Nmero de Dias at o Fim do Ano Data = Dateadd("yyyy", 1, Now() - _ Datepart("y", Now())) - Now() 'Now() pode ser substitudo por algo como '#04/06/1996#, ou #16/08/2000#, etc... * Nmero de Dias at o Natal Data = Dateadd("yyyy", 1, Now() - _ Datepart("y", Now())) - Now() - 7 'Now() pode ser substitudo por algo como '#04/06/1996#, ou #16/08/2000#, etc... * Nmero de Dias no Ano Data = Dateadd("yyyy", 1, Now() - _ Datepart("y", Now())) - (Now() - Datepart("y", Now())) 'Now() pode ser substitudo por algo como '#04/06/1996#, ou #16/08/2000#, etc... Obs.: Esses nmeros (2000 - ano, 5 - ms) podem ser modificados, claro...

Descobrindo Dias no Ms
* Primeiro Dia do Ms: Data = DateSerial(2000, 5, 1) * ltimo Dia do Mes: Data = DateSerial(2000, 5 + 1, 0) * Nmero de Dias no Mes Data = Datepart("d", DateSerial(2000, _ 5 + 1, 0)) Nesses exemplos, 2000 o ano e 5 o ms...

46
Recomendo uma olhada BEM de perto na funo DateSerial(Ano, Mes, Dia). Ela faz muito mais coisas.

Trabalhando com Data Juliana


'Converte para Data Juliana Public Function CDate2Julian(MyDate As Date) _ As String CDate2Julian = Format$(MyDate - _ DateSerial(Year(MyDate) - _ 1, 12, 31), "000") End Function 'Converte de Data Juliana para Data Public Function CJulian2Date(JulDay As _ Integer, Optional YYYY) As Date If IsMissing(YYYY) Then YYYY = Year(Date) If Not IsNumeric(YYYY) Or _ YYYY \ 1 <> YYYY Or YYYY < 100 Or _ YYYY > 9999 Then Exit Function If JulDay > 0 And JulDay < 366 Or _ JulDay = 366 And YYYY Mod 4 = 0 And _ YYYY Mod 100 <> 0 Or _ YYYY Mod 400 = 0 Then CJulian2Date = DateSerial(YYYY, 1, JulDay) End If End Function

47

CONTROLES
Alterando Propriedades de Controles (no Array) em um Loop
Digamos que voc tenha 5 TextBoxes, cada um com um nome diferente (quer dizer, NO estaria formando um array). Ento, vamos dizer que voc presice desabilitar (.Enabled = False) todos eles. Como voc faria? 'Voc faria assim?: Text1.Enabled = False Text2.Enabled = False Text3.Enabled = False Text4.Enabled = False Text5.Enabled = False Deste modo at funcionaria, mas tem um modo mais fcil de se fazer isso... Veja: Dim cObjeto As Control For Each cObjeto In Controls If TypeOf cObjeto Is TextBox Then cObjeto.Enabled = False End If Next A vantagem de se usar este mtodo que, caso voc tenha MUITOS TextBoxes, o cdigo ficaria, sem dvida, menor. Com este mtodo NO IMPORTA quantos nem quais so os nomes dos TextBoxes! Ele ir, no caso, desabilitar TODOS eles!

Alterando Propriedades de um Array de Controles em um Loop


Digamos que voc tenha 5 TextBoxes com um mesmo nome (quer dizer, um array de TextBoxes - Text1(0), Text1(1), Text1(2), Text1(3), Text1(4)). Ento, vamos dizer que voc presice desabilitar (.Enabled = False) todos eles. Como voc faria? 'Voc faria assim?: Text1(0).Enabled = False Text1(1).Enabled = False Text1(2).Enabled = False Text1(3).Enabled = False Text1(4).Enabled = False Deste modo at funcionaria, mas tem um modo mais fcil de se fazer isso... Veja: Dim iNum As Integer For iNum = 0 To 4 Text1(iNum).Enabled = False Next A vantagem de se usar este mtodo que, caso voc tenha MUITOS TextBoxes, o cdigo ficaria, sem dvida, menor. Agora, digamos que voc queira fazer isto sem expecificar a quantidade de TextBoxes (0 at 4 seriam 5 TextBoxes). Como voc faria, usando o 1

48
exemplo??? Meio complicado, n? Ento veja como fazer isso usando o 2 exemplo: Dim iNum As Integer For iNum = 0 To Text1.Count - 1 Text1(iNum).Enabled = False Next

Coordenadas do controle em relaao a area de trabalho


Public Type RECT Left As Long Top As Long Right As Long Bottom As Long End Type Public Declare Function GetWindowRect Lib "user32" Alias _ "GetWindowRect" (ByVal hwnd As Long, lpRect As RECT _ ) As Long ' Uso: Dim R As RECT GetWindowRect(Controle.hWnd, R) "R" retornar com as coordenadas do controle (ou qq coisa que tenha hWnd) na tela. Cuidado que em Pixel!!!

Criando Objetos em Run Time (VB6.0)


Neste exemplo criaremos uma ScrollBar. Para podermos usar seus eventos (Click, Change e etc), precisaremos declarar a varivel com a palavra chave WithEvents. Veja: Private WithEvents MyHSBar As HScrollBar Private Sub Form_Load() 'Cria a instancia da ScrollBar Set MyHSBar = Form1.Controls.Add("VB.HScrollBar", _ "HScroll1") 'Agora precisamos alterar algumas propriedades 'para a ScrollBar poder ficar visvel. With MyHSBar .Top = 0 .Left = 0 .Height = 255 .Width = Me.ScaleWidth .Visible = True End With 'Pronto. A ScrollBar j est instanciada e 'visvel no Form. End Sub Private Sub MyHSBar_Change() 'Podemos at usar os eventos da ScrollBar, como 'j foi comentado antes. MsgBox "HEI!!! Voc me clicou!!!", vbCritical End Sub

49

Agora coloque este cdigo num Form e teste! 8^) P.S.: S funciona no VB6.0...

Determinando a classe de qualquer objeto


'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

Determinando se um objeto foi definido (Set)


VB providencia uma srie de novas capacidades de uso de objetos. Porm, um objeto deve ser "setado" (definido) antes de ser referenciado. Existem formas 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 ' Outra maneira simples seria apenas: If Not MeuObjeto Is Nothing Then ' Se chegou aqui pq foi definido..... Else ' O objeto no foi definido..... End If

50

Manipulando Controles num Form Usando-se o Teclado


Se voc preferir usar o teclado ao invs do mouse para mover ou alterar o tamanho dos controles num Form, voc pode usar as combinaes de teclas abaixo durante a criao de suas telas: Para alterar o tamanho dos controles use a tecla Shift e as teclas de setas como segue: Shift+Seta Shift+Seta Shift+Seta Shift+Seta p/ p/ p/ p/ Direita => Aumenta a largura do controle (Width) Esquerda => Diminue a largura do controle (Width) Baixo => Aumeta a altura do controle (Height) Cima => Diminue a altura do controle (Height)

Para mover os controles use a tecla Ctrl e as teclas de setas como segue: Ctrl+Seta Ctrl+Seta Ctrl+Seta Ctrl+Seta p/ p/ p/ p/ Direita => Move o controle para a direita. Esquerda => Move o controle para a esquerda. Baixo => Move o controle para baixo. Cima => Move o controle para cima.

Se voc selecionar mais de um controle, as operaes acima afetaro todos eles.

Testar se um controle existe


Private Sub Command1_Click() On Error GoTo SaiComErro If Me("Label1").Name <> vbNullString Then MsgBox "Sim" End If Exit Sub SaiComErro: MsgBox "Nao" End Sub

ToolTipText personalizado
Este cdigo transforma um formulrio retangular em um quadrado de cantos arredondados. Ponha um Label no formulrio para exibir o que voc quiser, e no evento Deactivate do Form, ou Click, MouseMove, ou qualquer outro, de um Unload no Form, para ele sumir. Private Declare Function SetWindowRgn Lib "user32" (ByVal hwnd As _ Long, ByVal hRgn As Long, ByVal bRedraw As Boolean) As Long 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 Sub Form_Load() Dim RoundRect As Long Me.Move 0, 0 RoundRect = CreateRoundRectRgn((Me.Left + 60) / Screen.TwipsPerPixelX, _ (Me.Top + 400) / Screen.TwipsPerPixelY, _ (Me.Left + 2600) / Screen.TwipsPerPixelX, _ (Me.Top + 1500) / Screen.TwipsPerPixelY, 20, 20)

51
SetWindowRgn Me.hwnd, RoundRect, True Me.Move (Screen.Width - 2550) / 2, (Screen.Height - 1100) / 2 End Sub

Verificar se um controle est com o foco


If Screen.ActiveControl.Name = "txtContrato" Then End If If TypeOf Screen.ActiveControl Is TextBox Then Debug.Print , " um TextBox" Else Debug.Print , "No um TextBox" End If

52

Criao de AtiveXs
Colocando as Tecla de Atalho para Funcionar num OCXs
Este cdigo ser muito til quando voc estiver criando um OCX de um boto, de uma espcie de Label ou qqr outro tipo de controle que contenha Caption. Antes de mais nada, tenho que explicar-lhe o como esta propriedade funcionar, quer dizer, qual ser sua ao conforme a propriedade CanGetFocus do UserControl estiver setada: * True - Ele d um clique no UserControl; * False - NADA. A menos que voc coloque a propriedade ForwardFocus como True (neste caso, ele jogar o foco p/ o prximo controle na lista do TabIndex assim como faz o Label). Ento vamos ao cdigo: 'Num Mdulo: Public Function SelectKeys(ByVal sTexto As _ String) As String Dim iNum As Integer If sTexto <> "" And InStr(sTexto, "&") <> 0 Then For iNum = 1 To Len(sTexto) If Mid(sTexto, iNum, 1) = "&" And _ Mid(sTexto, iNum - 1, 1) <> "&" And _ Mid(sTexto, iNum + 1, 1) <> "&" And _ iNum <> Len(sTexto) Then SelectKeys = SelectKeys & Mid(sTexto, iNum + 1, 1) End If Next Else SelectKeys = "" End If End Function 'No local onde voc "PINTA" o texto no 'UserControl, logo aps pinta-lo, coloque 'esta linha de cdigo: UserControl.AccessKeys = SelectKeys(VarDoCaption) P.S.: Eu recomendo que voc pinte o UserControl TODO no evento UserControl_Paint, chamando-o das funes que recebem valores para as propriedades, pois assim ficar mais fcil de fazer-se um controle sobre todo este processo.

Manipulando Propriedades do Form onde seu OCX Est


muito fcil de se verificar propriedades do Form onde seu UserControl est. Digamos que voc precise verificar se a propriedade KeyPreview do Form est setada como True ou como False. Para isto, bastaria o seguinte cdigo: If UserControl.Extender.Parent.KeyPreview Then MsgBox "A propriedade KeyPreview do Form " & _ "est setada como True!!!" Else MsgBox "A propriedade KeyPreview do Form " & _ "est setada como False!!!"

53
End If Tambm muito fcil de se modificar propriedades do Form onde seu UserControl est. Digamos que voc precise modificar a propriedade AutoRedraw do Form para True ou como False. Para isto, bastaria o seguinte cdigo: UserControl.Extender.Parent.AutoRedraw = True 'Ou UserControl.Extender.Parent.AutoRedraw = False Observao: Tome cuidado quando for alterar propriedades do Form, pois assim voc poder estar alterando personalizaes feitas pelo programador que est usando seu OCX.

O Projeto est em Run ou Design Time?


Para saber isto muito simples. Basta um If: If Ambient.UserMode Then 'O projeto est em Run-Time, ou seja, 'ele est sendo executado. Else 'O projeto est em Design-Time. End If

Pegando o hWnd do Verdadeiro Container


Digamos que voc queira pegar o hWnd do Form onde seu UserControl est. Bem, como eu expliquei na dica "Manipulando Propriedades do Form onde seu OCX est", bastaria usar isto: Dim m_hWnd As Long m_hWnd = UserControl.Parent.hWnd Ok. Mas voc concorda que o usurio do seu UserControl pode coloca-lo dentro de um controle container (um PictureBox, por exemplo)? Pois . Acontece que se voc usar o cdigo anterior, ele SEMPRE vai retornar o hWnd do Form. NUNCA do controle container (caso haja um). Para resolver isto basta usar a API GetParent, como demonstro a seguir: 'Num mdulo: Public Declare Function GetParent Lib _ "user32" (ByVal hWnd As Long) _ As Long 'No seu cdigo: Dim m_hWnd As Long m_hWnd = GetParent(UserControl.hWnd) S finalizando, caso no haja um controle container, quer dizer, o UserControl est colocado diretamente no Form, o hWnd retornado pela API GetParent ser do Form. Pronto.

54

Qual tipo de Compatibilidade devo Usar?


A compatibilidade binaria muito til em ActiveXs, pois permite que, caso voc altere seus ActiveXs, no precise refazer as telas de seus programas que o usamvam. Mas para isto voc deve ter alguns cuidados: 1 - Quando voc compilar o projeto a primeira vez usa a opo "Project Compatibility" e deixa a caixa de referencia em branco. 2 - Depois de compilado, (compile sempre pro diretorio do Windows\System), copie a ActiveX gerada para o diretorio dos fontes ou em um sub-diretorio (por exemplo para o subdiretrio "Versoes"). Depois abra o projeto, mude para a opo "Binary Compatibility" e na caixa de referencia digite o diretorio/nome da ActiveX que a "COPIA" (no aquela que est no diretorio do Windows\System - que para onde voc compilar novamente). Grave tudo e feche o projeto. Detalhe, usar a opo "Binary Compatibility" significa que o CLSID, o IID e LIBID serao mantidos entre as versoes. 3 - Na proxima vez que voc chamar o projeto, o VB ir olhar para a ActiveX que voc referenciou para deixar a proxima compilao "binariamente compativel" (isso significa que a interface publica da ActiveX continuar igual e o usuario da ActiveX no precisar compilar novamente o projeto que a usa). Ai ento voc pode compilar quantas vezes quiser (sempre no diretorio do Windows\System). No esquea que qualquer alterao que voc fizer na interface pblica da ActiveX ir resultar na "incompatibilidade" mesmo que voc esteja usando a opo dentro do VB. Em quase todos os casos o proprio VB ir mostrar uma mensagem enorme explicando que voc est mudando a interface e bla bla bla... Voc tambm no pode incluir novas propriedades/metodos/eventos na ActiveX, porque vai dar problema...

Registrando e Desregistrando ActiveX via Cdigo VB


Esta dica descreve como os controles de ActiveX podem ser registados e desregistrados diretamente do VB. Cada controle ActiveX contm duas funes que, quando chamadas o registram ou desregistram no sistema. Estas funes so DLLRegisterServer e DLLUnregisterServer. O seguinte cdigo demonstra como registar e desregistrados os controles Microsoft Common Controls OCX, ComCtl32.OCX. 'Num mdulo: Public Declare Function RegComCtl32 Lib _ "ComCtl32.OCX" Alias _ "DllRegisterServer" () As Long Public Declare Function UnRegComCtl32 Lib _ "ComCtl32.OCX" Alias _ "DllUnregisterServer" () As Long Const ERROR_SUCCESS = &H0 'Num Form coloque dois botes e insira 'este cdigo: Private Sub Command1_Click() 'P/ Registrar: If RegComCtl32 = ERROR_SUCCESS Then

55
MsgBox "Registration Successful" Else MsgBox "Registration Unsuccessful" End If End Sub Private Sub Command2_Click() 'P/ DESregistrar: If UnRegComCtl32 = ERROR_SUCCESS Then MsgBox "UnRegistration Successful" Else MsgBox "UnRegistration Unsuccessful" End If End Sub

Nota: Cada chamada a essa funo do ActiveX pode levar um tempo de at 5 segundos.

56

FlexGrid
Deixando um FlexGrid Zebrado (com 2 Cores Intercaladas)
Function EImpar(ByVal iNum As Long) As Boolean 'Verifica se o nmero impar 'Se for impar a funo retorna True. 'Se for par a funo retorna False. EImpar = (iNum Mod 2) End Function Sub FlexCores(lCorPar As Long, lCorImpar As Long) Dim iLinha As Integer SeuMSFlexGrid.FillStyle = flexFillRepeat For iLinha = 1 To SeuMSFlexGrid.Rows - 1 With SeuMSFlexGrid .Row = iLinha If EImpar(iLinha) Then 'Se a linha for impar: 'Seleciona a partir da primeira coluna .Col = 1 'Seleciona at a ltima coluna .ColSel = .Cols - 1 'Aplica a cor .CellBackColor = lCorImpar Else 'Se a linha for par: 'Seleciona a partir da primeira coluna .Col = 1 'Seleciona at a ltima coluna .ColSel = .Cols - 1 'Aplica a cor .CellBackColor = lCorPar End If End With Next SeuMSFlexGrid.FillStyle = flexFillSingle End Sub 'Sintaxe: FlexCores(Cor das linhas pares, Cor das linhas impares) 'Exemplo: FlexCores(&HFFFFFF, &HC0FFFF)

Exportar dados de FlexGrid para Excel


Sub CopyToExcel(InFlexGrid As MSFlexGrid, Nome$, _ ByVal TextoAdicional$) Dim R%, c%, Buf$, LstRow%, LstCol% Dim FormatMoney As Boolean Dim MyExcel As Excel.Application Dim wbExcel As Excel.Workbook Dim shExcel As Excel.Worksheet On Error Resume Next Set MyExcel = If Err.Number Set MyExcel End If Set wbExcel = Set shExcel = GetObject(, "Excel.Application") <> 0 Then = CreateObject("Excel.Application") MyExcel.Workbooks.Add wbExcel.Worksheets.Add

57
shExcel.Name = Nome$ shExcel.Activate LstCol% = 0 For c% = 0 To InFlexGrid.Cols - 1 InFlexGrid.Col = c% LstRow% = 0 shExcel.Columns(Chr(Asc("A")+c%)).ColumnWidth=InFlexGrid.ColWidth(c%)/72 For R% = 0 To InFlexGrid.Rows - 1 InFlexGrid.Row = R% Err.Clear Buf$ = InFlexGrid.TextMatrix(R%, c%) If Buf$ <> "" Then FormatMoney = False If InStr(Buf$, vbCrLf) Then Buf$ = StrTran(Buf$, vbCrLf, vbLf) Do While Right(Buf$, 1) = vbLf Buf$ = Left(Buf$, Len(Buf$) - 1) Loop shExcel.Range(Chr(Asc("A") + c%)).WrapText = True ElseIf Format(CDbl(Buf$),csFormatMoneyZero)=Buf$ Then If Err.Number = 0 Then Buf$ = Str(CDbl(Buf$)) FormatMoney = True End If End If If Buf$ <> "" Then If InFlexGrid.MergeRow(R%) Then For LstCol% = c% To 1 Step -1 If InFlexGrid.TextMatrix(R%,LstCol%-1)<>InFlexGrid.TextMatrix(R %,c%) Then Exit For End If Next If LstCol% <> c% Then shExcel.Range(Chr(Asc("A")+LstCol%) & (R%+1), _ Chr(Asc("A")+c%) & (R%+1)).MergeCells=True shExcel.Range(Chr(Asc("A")+LstCol%) & (R%+1), _ Chr(Asc("A")+c%) & (R%+1)).BorderAround End If End If If InFlexGrid.MergeCol(c%) And LstRow% <> R% Then If InFlexGrid.TextMatrix(LstRow%,c%)=InFlexGrid.TextMatrix(R%,c %)Then shExcel.Range(Chr(Asc("A")+c%) & (LstRow%+1), _ Chr(Asc("A")+c%) & (R%+1)).MergeCells=True shExcel.Range(Chr(Asc("A")+c%) & (LstRow%+1), _ Chr(Asc("A")+c%) & (R%+1)).BorderAround Else LstRow% = R% End If End If shExcel.Range(Chr(Asc("A")+c%) & _ (R%+1)).Font.Color=InFlexGrid.CellForeColor If R%<InFlexGrid.FixedRows Or c%<InFlexGrid.FixedCols Then shExcel.Range(Chr(Asc("A")+c%) & _ (R%+1)).Font.Bold=True ' shExcel.Range(Chr(Asc("A")+c%) & _ ' (r%+1)).Font.BackColor = 40 End If shExcel.Range(Chr(Asc("A")+c%) & (R%+1)).Value=Buf$ If FormatMoney Then

58
shExcel.Range(Chr(Asc("A")+c%) & _ (R%+1)).NumberFormat="#,##0.00;#,##0.00;#,##0.00" End If End If End If Next Next If TextoAdicional$ <> "" Then ' shExcel.Rows(Str(r%+2)).Delete (xlShiftUp) Do While Right(TextoAdicional$, 1) = vbLf TextoAdicional$ = Left(TextoAdicional$, _ Len(TextoAdicional$) - 1) Loop shExcel.Range("A" & (R% + 2)).Value = TextoAdicional$ End If MyExcel.Visible = True Set shExcel = Nothing Set wbExcel = Nothing Set MyExcel = Nothing End Sub

Para imprimir o conteudo de um FlexGrid


Dim intTamanho as Integer intTamanho = MSFlexGrid.Width MSFlexGrid.Width = Printer.Width Printer.PaintPicture MSFlexGrid.Picture, 0, 0 Printer.EndDoc MSFlexGrid.Width = intTamanho

59

ComboBox
Abrir um ComboBox assim que receber o foco
Private Declare Function SendMessage Lib "user32" _ Alias "SendMessageA" (ByVal hwnd As Long, _ ByVal wMsg As Long, ByVal wParam As Long, _ lParam As Long) As Long Private Sub Combo1_GotFocus() Const CB_SHOWDROPDOWN As Long = &H14F Dim Tmp As Long Tmp = SendMessage(Combo1.hwnd,CB_SHOWDROPDOWN,1,ByVal 0&) End Sub Ou no evento GotFocus Private Sub Combo1_GotFocus() SendKeys "%" & "{DOWN}" End Sub

Ajustando a Largura do Drop-Down de um ComboBox Descobrindo a largura atual do Drop-Down


'Coloque este cdigo num mdulo: Private Const CB_GETDROPPEDWIDTH As Long = &H15F Private Const CB_ERR As Long = -1 Private Declare Function SendMessage Lib "USER32" _ Alias "SendMessageA" (ByVal hwnd As Long, _ ByVal Msg As Long, ByVal wParam As Long, _ ByVal lParam As Long) As Long Public Function GetDropdownWidth(cbohWnd As _ Long) As Long Dim lRetVal As Long 'Descobrindo a largura atual do Drop Down: lRetVal = SendMessage(cbohWnd, _ CB_GETDROPPEDWIDTH, 0&, 0&) If lRetVal <> CB_ERR Then 'Ele retornar a largura do Drop Down 'em pixels. GetDropdownWidth = lRetVal Else GetDropdownWidth = 0 End If End Function 'P/ chamar use assim: Dim iLargura As Integer iLargura = GetDropdownWidth(Combo1.hWnd) 'Pronto. A varivel iLargura conter a 'largura do Drop Down em pixels.

60

Adicionando itens ao ComboBox em Run-Time


Voc pode adicionar itens e atualizar a largura do Drop Down automaticamente. Veja como: 'Coloque este cdigo num mdulo: Option Explicit Private Private Private Private Const Const Const Const CB_GETDROPPEDWIDTH As Long = &H15F CB_SETDROPPEDWIDTH As Long = &H160 CB_ERR As Long = -1 DT_CALCRECT As Long = &H400

Public Type Rect Left As Long Top As Long Right As Long Bottom As Long End Type Private Declare Function DrawText Lib "user32" _ Alias "DrawTextA" (ByVal hDC As Long, _ ByVal lpStr As String, ByVal nCount As _ Long, lpRect As Rect, ByVal wFormat As _ Long) As Long Private Declare Function SendMessage Lib "user32" _ Alias "SendMessageA" (ByVal hwnd As Long, _ ByVal wMsg As Long, ByVal wParam As Long, _ ByVal lParam As Any) As Long Public Function cboAdiciona(ByRef ctl As Control, _ ByVal sNewItem As String, Optional ByVal _ dwNewItemData As Variant) As Long Dim RC As Rect Dim newWidth As Long Dim currWidth As Long Dim sysScrollWidth As Long Dim OldFont As StdFont If ctl.Tag <> "" Then currWidth = CLng(ctl.Tag) End If Set OldFont = ctl.Parent.Font Set ctl.Parent.Font = ctl.Font Call DrawText(ctl.Parent.hDC, sNewItem, -1&, _ RC, DT_CALCRECT) newWidth = RC.Right + 5 Set ctl.Parent.Font = OldFont If newWidth > currWidth Then Call SendMessage(ctl.hwnd, CB_SETDROPPEDWIDTH, _ newWidth, 0&) ctl.Tag = newWidth End If ctl.AddItem sNewItem If Not IsMissing(dwNewItemData) Then If IsNumeric(dwNewItemData) Then ctl.ItemData(ctl.NewIndex) = dwNewItemData End If

61
End If cboAdiciona = ctl.NewIndex End Function 'P/ usar, adicione os itens desta maneira (se 'voc usar com Combo1.AddItem NO FUNCIONAR!): Call cboAdiciona(Combo1, "Texto") 'Esta funo retorna o valor do ListIndex do 'novo item. Ento, voc pode usar esta funo 'recebemdo o valor do ListIndex p/ usa-lo de 'alguma forma. Veja como fazer isto: Dim NovoIndex As Long NovoIndex = cboAdiciona(Combo1, "Texto") MsgBox "O Item " & NovoIndex & " foi adicionado!"

Adicionando itens ao ComboBox em Design-Time


Se voc quizer adicionar os itens em Design-Time e atualizar a largura do Drop Down RunTime, faa da seguinte maneira:
'Coloque este cdigo num mdulo: Private Const CB_SETDROPPEDWIDTH As Long = &H160 Private Const CB_ERR As Long = -1 Private Declare Function SendMessage Lib "USER32" _ Alias "SendMessageA" (ByVal hwnd As Long, _ ByVal Msg As Long, ByVal wParam As Long, _ ByVal lParam As Long) As Long Public Function SetDropdownWidth(cboHwnd As Long, _ NewWidthPixel As Long) As Boolean Dim lRetVal As Long 'Ajustando a largura do Drop-Down: lRetVal = SendMessage(cboHwnd, _ CB_SETDROPPEDWIDTH, NewWidthPixel, 0) If lRetVal <> CB_ERR Then SetDropdownWidth = True Else SetDropdownWidth = False End If End Function 'No Form, coloque: Private Sub Form_Load() Dim iLar1 As Integer, iLar2 As Integer Dim iNum As Integer, OldFont As StdFont iLar2 = 0 OldFont = Me.Font Me.Font = Combo1.Font Me.ScaleMode = 3 For iNum = 0 To Combo1.ListCount - 1 Combo1.ListIndex = iNum iLar1 = Me.TextWidth (Combo1.Text) If iLar1 > iLar2 Then iLar2 = iLar1 End If Next iLar2 = iLar2 + 5

62
Call SetDropdownWidth(Combo1.hWnd, iLar2) Me.Font = OldFont End Sub

Auto preenche o ComboBox de acordo com o texto encontrado


Duas rotinas, a Combo1_Change() que auto preenche o combo de acordo com o texto encontrado e uma outra Combo1_LostFocus() que impede que o Compo perca o focus se o texto digitado no existir... PS: Declare as variaveis... OK? 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 CB_FINDSTRING As Long = &H14C Const CB_ERR As Long = (-1) Private Sub Combo1_Change() With Combo1 'Procura pelo texto j digitado strPartial = .Text I = SendMessage(.hwnd,CB_FINDSTRING,-1, _ ByVal strPartial) 'Se achou, adiciona o resto do Texto If I <> CB_ERR Then 'Pega o texto inteiro strTotal = .List(I) 'Compute number of unmatched characters j = Len(strTotal) - Len(strPartial) If j <> 0 Then 'Adiciona o resto da string encontrada m_bEditFromCode = True .SelText = Right$(strTotal, j) 'Marca os caracteres adicionados .SelStart = Len(strPartial) .SelLength = j End If End If End With End Sub Private Sub Combo1_LostFocus() With Combo1 if Len(.Text) then 'Procura pelo texto digitado strPartial = .Text I = SendMessage(.hwnd,CB_FINDSTRING,-1,ByVal strPartial) 'Se no achou, retorna o focus para o Combo If I = CB_ERR Then .SetFocus End if End With End Sub

63

Preenchendo um ComboBox com os Registros de um Banco de Dados


Bom, primeiro voc deve abrir o Recordset (tanto faz se isso feito em DAO ou ADO) e, depois disso feito, execute esta rotina: 'Abre o Recordset... RS.MoveFirst Do While Not RS.EOF Combo1.AddItem RS![Nome do Campo] RS.MoveNext Loop Uma dica interessante seria, por exemplo, exibir na ComboBox o campo Nome e guardar na prpria ComboBox o valor do campo Cdigo. Veja como fazer isto: 'Abre o Recordset... RS.MoveFirst Do While Not RS.EOF Combo1.AddItem RS![Nome] Combo1.ItemData(Combo1.NewIndex) = RS![Cdigo] RS.MoveNext Loop Ento, digamos que voc queira jogar na varivel sNom o Nome selecionado na ComboBox e na varivel iCod o cdigo correspondente a este nome selecionado. Para isso, proceda da seguinte forma: 'No evento que voc quizer, coloque isto: Dim sNom As String, iCod As Integer If Combo1.ListIndex <> -1 Then iCod = Combo1.ItemData(Combo1.ListIndex) sNom = Combo1.Text End If

64

DbGrid
Auto Ajustar Colunas no DBGrid
Private Sub DBGrid1_ColResize(ByVal ColIndex As Integer, _ Cancel As Integer) Dim DB As Database, RS As Recordset, FL As Field Dim Tamanho As Double 'Cada caracter corresponde a 120 twips na horizontal Tamanho = Len(DBGrid1.Columns(ColIndex).Caption) * 120 Set DB = OpenDatabase("C:\Dir Do VB\Biblio.mdb") Set RS = DB.OpenRecordset("Authors") Set FL = RS.Fields(DBGrid1.Columns(ColIndex).DataField) Do While Not RS.EOF 'Verifica o tamanho de cada valor do campo On Error Resume Next If Tamanho < Me.TextWidth(FL.Value) Then Tamanho = Me.TextWidth(FL.Value) End If RS.MoveNext Loop DBGrid1.Columns(ColIndex).Width = Tamanho End Sub

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

Mudar de Coluna no DBGrid com TAB


E bem simples fazer isto. Basta voc mudar algumas propriedades do DBGrid: Mude a propriedade TabAction p/ "2-Grid Navigation"; Mude a propriedade WrapCellPointer para True. s usar!

Preenchendo o DBGrid via Cdigo


Para preencher um DBGRID dentro de um cdigo, basta referenciar a coluna e a linha e passar o valor desejado. Por exemplo, se voc quiser preencher a clula da linha 2, coluna 3, defina a propriedade ROW=2 e Col=3. Depois, defina a propriedade Text com o valor desejado.

65

Ex.: 'Limpa TODO o contedo do DBGrid1 DBGrid1.Cls 'Seleciona a linha 2 DBGrid1.Row = 2 'Seleciona a coluna 3 DBGrid1.Col = 3 'Atribui o texto DBGrid1.Text = "Texto a ser inserido"

66

DriveListBox
Cdigos Erro do DriveListBox
Private Sub Dir1_Change() 'Faz com que os arquivos que iro aparecer no 'FileListBox sero os do diretrio selecionado 'no DirListBox File1.Path = Dir1.Path End Sub Private Sub Drive1_Change() 'tratamento de erro On Error GoTo ErrorDRV 'Indica que os diretrios que iro aparecer no 'DriveListBox sero o da unidade selecionada Dir1.Path = Drive1.Drive Exit Sub ErrorDRV: MsgBox "No h disco nesta unidade !", vbCritical End Sub

67

Form
Animando a Barra de Ttulo de um Form
Para criar uma animao na barra de ttulo do Form (tipo Marquee), basta voc colocar no Form o cdigo abaixo. 'Ser usado p/ parar a animao quando o Form 'for fechado. Coloque no Declarations do Form: Dim bFechado As Boolean Private Sub Form_Activate() Dim iTempo As Single, bDiminui As Boolean Dim iNum As Integer, iLarg As Integer Dim iLargT As Integer, Texto As String iTempo = Timer Do While Not bFechado If Timer > iTempo + 0.01 Then iTempo = Timer Select Case bDiminui Case False iNum = iNum + 1 Texto = String(iNum, " ") & _ "Mensagem do Marquee" iLargT = TextWidth(Texto) iLarg = ScaleWidth - 1110 If iLargT >= iLarg Then iNum = iNum - 2 bDiminui = True Texto = String(iNum, " ") & _ "Mensagem do Marquee" End If Case Else iNum = iNum - 1 If iNum < 1 Then iNum = 1 Texto = "Mensagem do Marquee" bDiminui = False Else Texto = String(iNum, " ") & _ "Mensagem do Marquee" End If End Select Caption = Texto End If DoEvents Loop End Sub Private Sub Form_Unload(Cancel As Integer) bFechado = True End Sub Detalhe, modifique as linhas onde aparece "Mensagem do Marquee" pelo texto que voc quizer que aparea.

68

Arrastar um controle ou Formulrio sem Ttulo


'Na parte geral do Form: 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 Function ReleaseCapture Lib _ "user32" () As Long 'No evento Mouse_Down Dim rec& If Button And 1 Then ReleaseCapture rec& = SendMessage(Me.hwnd, &HA1, 2, 0&) End IF 'OBS.: Esta dica pode tambm ser usada para arrastar controles (Legal!!!).

Carregar Vrias Instancias do Mesmo Formulrio


Dim Formulario As Form1 Set Formulario = New Form1 Load Formulario Formulario.Show

Centralizar um Form MDIChild


Para centralizar um Form MDIChild ou coloc-lo em qualquer lugar da tela utilize a seguinte rotina no evento Load: 'P/ centralizar: Private Sub Form_Load() Me.Left = (MDIForm1.ScaleHeight - Me.Height) / 2 Me.Top = (MDIForm1.ScaleWidth - Me.Width) / 2 End Sub 'Ou, p/ ele aparecer em um ponto qualquer (que 'voc tenha escolhido): Private Sub Form_Load() Me.Left = Valor Me.Top = Valor End Sub

Criando forms de formatos especiais


Esta uma das mais interessantes. Voc pode criar forms de formatos especiais facilmente. Experimente o exemplo abaixo e veja que efeito interessante: ' Declare estas duas APIs na seo General Declarations do form: Private Declare Function CreateEllipticRgn Lib _ "gdi32" (ByVal X1 As Long, ByVal Y1 As _

69
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 Sub Form_Load() Show 'o form! SetWindowRgn hWnd,CreateEllipticRgn(0,0,300,200),True End Sub

Criando um Form Circular


'No Declarations do form: 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 'No Form_Load: Private Sub Form_Load() Dim hr&, dl& Dim usew&, useh& usew& = me.Width / Screen.TwipsPerPixelX useh& = me.Height / Screen.TwipsPerPixelY x = 0 'Deixa o Form ficar em forma crcular hr& = CreateEllipticRgn(0, 0, usew, useh) dl& = SetWindowRgn(me.hWnd, hr, True) End Sub

Crinado um Form com Cantos Arredondados


Voc pode criar facilmente Forms ou controles usando o cdigo a seguir: 'Coloque num Form coloque um CommandButton 'chamado Command1. 'No Declarations: 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 Private Declare Function GetClientRect Lib "user32" _ (ByVal hWnd As Long, lpRect As Rect) As Long Private Type Rect Left As Long Top As Long Right As Long Bottom As Long End Type Sub Retangulo(m_hWnd As Long, Fator As Byte)

70
Dim RGN As Long Dim RC as Rect Call GetClientRect(m_hWnd, RC) RGN = CreateRoundRectRgn(RC.Left, RC.Top, RC.Right, _ RC.Bottom, Fator, Fator) SetWindowRgn m_hWnd, RGN, True End Sub 'Fator a distncia da curvatura do canto arredondado 'No evento click do CommandButton: Private Sub Command1_Click() Me.BackColor = &H808080 'Apenas para destacar a cor 'Coloca o formulrio com os cantos arredondados 'e fator 80 de rea Retangulo Me.hWnd, 80 Retangulo Command1.hWnd, 30 End Sub

Criando um Form Elptico


Poucos programas utilizam esse recurso do Windows 95 que cria Forms e at mesmmo outros objetos em forma elptica. 'Coloque num Form coloque um CommandButton 'chamado Command1. 'No 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 Private Declare Function GetClientRect Lib "user32" _ (ByVal hWnd As Long, lpRect As Rect) As Long Private Type Rect Left As Long Top As Long Right As Long Bottom As Long End Type Sub Eliptico(m_hWnd As Long) Dim RGN As Long Dim RC as Rect Call GetClientRect(m_hWnd, RC) RGN = CreateEllipticRgn(RC.Left, RC.Top, RC.Right, _ RC.Bottom) SetWindowRgn m_hWnd, RGN, True End Sub 'No evento click do CommandButton: Private Sub Command1_Click() Me.BackColor = &H808080 'Apenas para destacar a cor Eliptico Me.hWnd 'O formulrio fica Elptico Eliptico Command1.hWnd 'O boto fica Elptico

71
End Sub

Criando um Form em forma de Estrela (Polgono)


Essa API possibilita a criao de um Form 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 Forms citados anteriormente. Veja o Exemplo, que cria um formulrio na forma de uma estrela de quatro pontas: 'No Declarations: 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 'Determina as oito coordenadas de uma estrela de 'quatro pontas (em Pixel) Pontos(1).X = 0 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)

72

Criando um Form em forma de Tringulo


'Coloque este cdigo num Form: Option Explicit Private Type POINTAPI x As Long y As Long End Type Private Type tP P(1 To 3) As POINTAPI End Type 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 Sub Form_Load() Dim z As tP Me.ScaleMode = vbPixels z.P(1).x = ((Me.ScaleHeight - Me.ScaleLeft) / _ 2) + 13 z.P(1).y = 26 z.P(2).x = 26 z.P(2).y = Me.ScaleHeight - Me.ScaleLeft z.P(3).x = Me.ScaleHeight - Me.ScaleLeft z.P(3).y = Me.ScaleHeight - Me.ScaleLeft SetWindowRgn hWnd, CreatePolygonRgn(z.P(1), _ 3, 3), True End Sub

Criando um Form com forma do Logotipo do Windows


'Coloque o seguinte cdigo no form: Private Type RECT Left As Long Top As Long Right As Long Bottom As Long End Type Private Declare Function BeginPath Lib "gdi32" _ (ByVal hdc As Long) As Long Private Declare Function TextOut Lib "gdi32" _ Alias "TextOutA" (ByVal hdc As Long, _ ByVal X As Long, ByVal Y As Long, ByVal _ lpString As String, ByVal nCount As _ Long) As Long Private Declare Function EndPath Lib "gdi32" _ (ByVal hdc As Long) As Long Private Declare Function PathToRegion Lib _ "gdi32" (ByVal hdc As Long) As Long Private Declare Function GetRgnBox Lib "gdi32" _ (ByVal hRgn As Long, lpRect As RECT) _ As Long Private Declare Function CreateRectRgnIndirect _ Lib "gdi32" (lpRect As RECT) As Long Private Declare Function CombineRgn Lib "gdi32" _

73
(ByVal hDestRgn As Long, ByVal hSrcRgn1 _ As Long, ByVal hSrcRgn2 As Long, ByVal _ nCombineMode As Long) As Long Declare Function DeleteObject Lib "gdi32" _ (ByVal hObject As Long) As Long Declare Function SetWindowRgn Lib "user32" _ (ByVal hwnd As Long, ByVal hRgn As Long, _ ByVal bRedraw As Boolean) As Long Declare Function ReleaseCapture Lib _ "user32" () As Long 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 Private Private Private

Private Const RGN_AND As Long = 1 Private Const WM_NCLBUTTONDOWN As Long = &HA1 Private Const HTCAPTION As Long = 2 Private Function GetTextRgn() As Long Dim hRgn1 As Long, hRgn2 As Long Dim rct As RECT BeginPath hdc TextOut hdc, 10, 10, Chr$(255), 1 EndPath hdc hRgn1 = PathToRegion(hdc) GetRgnBox hRgn1, rct hRgn2 = CreateRectRgnIndirect(rct) CombineRgn hRgn2, hRgn2, hRgn1, GN_AND DeleteObject hRgn1 GetTextRgn = hRgn2 End Function Private Sub Form_DblClick() Unload Me End Sub Private Sub Form_Load() Dim hRgn As Long Me.Font.Name = "Wingdings" Me.Font.Size = 200 hRgn = GetTextRgn() SetWindowRgn hwnd, hRgn, 1 End Sub Private Sub Form_MouseDown(Button As Integer, Shift _ As Integer, X As Single, Y As Single) ReleaseCapture SendMessage hwnd, WM_NCLBUTTONDOWN, HTCAPTION, _ ByVal 0& End Sub 'Depois s executar q o Form ficar no formato do 'logotipo do Windows!!!

Criando um Form no Formato da Imagem Desejada


'No mdulo: Public Declare Function SetWindowRgn Lib "user32" _ (ByVal hwnd As Long, ByVal hRgn As Long, _ ByVal bRedraw As Boolean) As Long Public Declare Function DeleteObject Lib "gdi32" _

74
(ByVal hObject As Long) As Long Public Declare Function ReleaseCapture Lib _ "user32" () As Long Public 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 Function CreateCompatibleDC Lib _ "gdi32" (ByVal hdc As Long) As Long Private Declare Function SelectObject Lib _ "gdi32" (ByVal hdc As Long, ByVal hObject _ As Long) As Long Private Declare Function GetObject Lib "gdi32" _ Alias "GetObjectA" (ByVal hObject As _ Long, ByVal nCount As Long, lpObject As _ Any) 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 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 DeleteDC Lib "gdi32" _ (ByVal hdc As Long) As Long Private Declare Function GetPixel Lib "gdi32" _ (ByVal hdc As Long, ByVal X As Long, _ ByVal Y As Long) As Long Public Const WM_NCLBUTTONDOWN As Long = &HA1 Public Const HTCAPTION As Long = 2 Private Type BITMAP bmType As Long bmWidth As Long bmHeight As Long bmWidthBytes As Long bmPlanes As Integer bmBitsPixel As Integer bmBits As Long End Type Public Function GetBitmapRegion(cPicture As _ StdPicture, cTransparent As Long) Dim hRgn As Long, tRgn As Long Dim X As Integer, Y As Integer, X0 As Integer Dim hdc As Long, BM As BITMAP 'Cria um novo DC, ento procuramos a imagem hdc = CreateCompatibleDC(0) If hdc Then 'Coloca o novo DC na Imagem SelectObject hdc, cPicture 'Pega as dimenses e cria uma nova regio 'de retangulo GetObject cPicture, Len(BM), BM hRgn = CreateRectRgn(0, 0, BM.bmWidth, BM._ bmHeight) 'Inicia procurando a imagem de cima para 'baixo For Y = 0 To BM.bmHeight

75
For X = 0 To BM.bmWidth 'Procura uma linha de pxeis no 'transparentes While X <= BM.bmWidth And GetPixel(hdc, _ X, Y) <> cTransparent X = X + 1 Wend 'Marca o Incio da linha de pxeis no 'transparentes X0 = X 'Procura uma linha com Pxeis 'transparentes While X <= BM.bmWidth And GetPixel(hdc, _ X, Y) = cTransparent X = X + 1 Wend 'Cria uma nova regio que corresponda 'linha dos pxeis transparentes e ento 'remove ele da regio principal If X0 < X Then tRgn = CreateRectRgn(X0, Y, X, Y + 1) CombineRgn hRgn, hRgn, tRgn, 4 'Libera a memria usada para a nova 'regio temporria DeleteObject tRgn End If Next X Next Y 'Volta ao endereo de memria da imagem pronta GetBitmapRegion = hRgn 'Libera memria apagando a imagem DeleteObject SelectObject(hdc, cPicture) End If 'Libera memria apagando o DC criado DeleteDC hdc End Function A funo GetBitmapRegion pede dois parmetros: a figura e uma cor a ser apagada. Se o fundo da sua figura for preto, voc pode usar a constante vbBlack e apagar toda a cor preta da figura. Lembrando que se a cor estiver dentro da figura, ela ser apagada tambm, deixando o form transparente naquele lugar.

'Coloque a imagem na propriedade Picture do Form 'e, no Form_Load: Private Sub Form_Load() Dim hRgn As Long If hRgn Then DeleteObject hRgn hRgn = GetBitmapRegion(Me.Picture, vbBlack) SetWindowRgn Me.hwnd, hRgn, True End Sub

Criando uma Tela de Splash para seu Programa


Para ter uma tela de splash (aquela que aparece enquanto o programa est sendo carregado) em seu programa, siga os seguintes passos:

76
1 - Coloque em seu projeto um novo Form e configure-o conforme o seu gosto para que ele seja sua tela de splash. 2 - Abra a tela de propriedades do seu projeto e selecione este form que voc acaba de criar em "Startup Object:" (para que ele seja o 1 form a aparecer quando seu programa for executado). 3 - Coloque este cdigo nesse form: Private Sub Form_Activate() Screen.MousePointer = 11 DoEvents 'Troque este "frmPrincipal" pelo nome do 'principal form de seu programa. frmPrincipal.Show 'Esta linha uma chamada de API. 'Para saber mais sobre ela veja a 'dica Dar uma Pausa em seu Programa Sleep (1000) Unload Me Screen.MousePointer = 0 End Sub Private Sub Form_Load() 'Esta linha uma chamada de API. 'Para saber mais sobre ela veja a 'dica Formulrio ficar por cima de todos Call SetWindowPos(frmSplash.hWnd, -1, 150, _ 130, 0, 0, &H1) End Sub O uso do DoEvents nesse caso para permitir que o primeiro Form (o frmSplash) aparea sobreposto atraves da chamada da API SetWindowPos. Se no for colocado o DoEventes o SetWindowsPos no funcionar.

Degrad em Forms
'Degrad se faz utilizando a variao de cores: 'Ex: para fazer num Form (tons de azul) Dim k as integer Form1.AutoRedraw=True Form1.ScaleWidth = 255 Form1.DrawWidth = 2 For k = 0 to 255 Form.line (k, 0)-(k+1,Form1.height),rgb(0,0,k) Next

Fazer um form maior que a tela


Faa um form com o tamanho da tela. Insira um picturebox no form. Finalmente, via cdigo, aumente o tamanho do picture e ajuste os valores da barra de rolagem. Scroll.Max = (Picture1.Height - Me.Height) / 10

77
'P/ rolar a barra: Sub Scroll_Change() Picture1.Top= -1 * Picture1.Top + Scroll.Value End Sub

Fechando todos os Forms Abertos


'Crie a seguinte funo: Public Function Fechar() Dim FRM As Integer FRM = Forms.Count Do While FRM > 0 Unload Forms(FRM-1) If FRM = Forms.Count Then Exit Do End If FRM = FRM - 1 Loop End Function 'Ento, qdo quizer que seu programa seja finalizado, 'ao invs de usar o comando "End", chame esta funo: Fechar

Formulrio ficar por cima de todos


'Na seo geral do mdulo: Public 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 'No evento Form_Load do formulrio. Call SetWindowPos(Me.hwnd,-1,0,0,0,0,&H1 Or &H2)

Passe nothing aos forms com cautela 'Use esta funo para dar Nothing em seus forms 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

78

Pintar um local do formulario com a cor escolhida


Private Declare Function FloodFill Lib _ "gdi32" (ByVal hDC As Long, ByVal _ X As Long, ByVal Y As Long, ByVal _ crColor As Long) As Long Private Sub Form_Click() ScaleMode = vbPixels 'Windows draws in pixels. ForeColor = vbBlack 'Set draw line to black. Line (100, 50)-(300, 50) 'Draw a triangle. Line -(200, 200) Line -(100, 50) FillStyle = vbFSSolid 'Set FillStyle to solid. FillColor = RGB(128, 128, 255) 'Set FillColor. 'Call Windows API to fill. FloodFill hDC,200,100,ForeColor End Sub

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)

Removendo os Botes MIN-MAX de Forms MDI


'Coloque o seguinte cdigo num mdulo: Private Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long, ByVal dwNewLong As _ Long) As Long Private Declare Function GetWindowLong Lib "user32" Alias "GetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long) As Long Private Const WS_MINIMIZEBOX As Long = &H20000 Private Const WS_MAXIMIZEBOX As Long = &H10000 Private Const GWL_STYLE As Long = (-16) 'No evento MDIForm_Load do MDIForm: Sub MDIForm_Load() Dim lWnd as Long lWnd = GetWindowLong(Me.hWnd, GWL_STYLE) _ _ _ _

79

'Tira o boto de minimizar lWnd = lWnd And Not (WS_MINIMIZEBOX) 'Tira o boto de maximizar lWnd = lWnd And Not (WS_MAXIMIZEBOX) lWnd = SetWindowLong(Me.hWnd, GWL_STYLE, lWnd) End Sub

Saber se um form est aberto


dim v as Integer For v = 0 To Forms.Count if Forms(v).Name = "NomeDoForm" Then msgbox "Est aberto!" Exit For End If Next

80

Grid
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.

81

ImageList
Alterando o Contedo da ImageList sem Desvincula-la da ToolBar
Para fazer isto, em disign-time, recorte a Toolbar (selecione-a e Ctrl+X) e altere o contedo da ImageList (adicionar imagens, excluir imaens e etc). Ento, cole a Toolbar novamente (selecione o Form e Ctrl+V). ATENO!!! Isso PODE no ser til se houver mudanas nos ndices dos botes.

82

ListBox
Achar uma palavra num ListBox
Public Const LB_FINDSTRING As Long = &H18F Public Const LB_FINDSTRINGEXACT As Long = &H1A2 Public 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 Sub Text1_Change() ListBox1.ListIndex = Sendmessage(ListBox1.hWnd, _ LB_FINDSTRING, -1, _ Byval Text1.Text) End Sub

Colocando ScrollBar Horizontal num ListBox


'Coloque o seguinte cdigo num mdulo: Option Explicit Private Private Private Private Const Const Const Const LB_GETHORIZONTALEXTENT As Long = &H193 LB_SETHORIZONTALEXTENT As Long = &H194 DT_CALCRECT As Long = &H400 SM_CXVSCROLL As Long = 2

Public Type Rect Left As Long Top As Long Right As Long Bottom As Long End Type Private Declare Function DrawText Lib "user32" _ Alias "DrawTextA" (ByVal hDC As Long, _ ByVal lpStr As String, ByVal nCount As _ Long, lpRect As Rect, ByVal wFormat As _ Long) As Long Private Declare Function GetSystemMetrics Lib _ "user32" (ByVal nIndex As Long) As Long 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 Public Function AdicionaItem(ByRef ctl As Control, _ ByVal sNewItem As String, Optional ByVal _ dwNewItemData As Variant) As Long Dim RC As Rect Dim newWidth As Long Dim currWidth As Long Dim sysScrollWidth As Long Dim OldFont As StdFont If ctl.Tag <> "" Then currWidth = CLng(ctl.Tag) End If

83

Set OldFont = ctl.Parent.Font Set ctl.Parent.Font = ctl.Font Call DrawText(ctl.Parent.hDC, sNewItem, -1&, _ RC, DT_CALCRECT) Set ctl.Parent.Font = OldFont sysScrollWidth = GetSystemMetrics(SM_CXVSCROLL) newWidth = RC.Right + sysScrollWidth If newWidth > currWidth Then Call SendMessage(ctl.hwnd, _ LB_SETHORIZONTALEXTENT, newWidth, _ ByVal 0&) ctl.Tag = newWidth End If ctl.AddItem sNewItem If Not IsMissing(dwNewItemData) Then If IsNumeric(dwNewItemData) Then ctl.ItemData(ctl.newIndex) = dwNewItemData End If End If AdicionaItem = ctl.newIndex End Function 'No form: Private Sub Form_Load() 'Detalhe, NO use o List1.AddItem!!! 'Veja como adiciona algumas linhas... Call AdicionaItem(List1, "Coloque o texto que ser adicionado aqui") Call AdicionaItem(List1, "No se preocupe se o texto for muito grande") Call AdicionaItem(List1, "Ele ser exibido, seja como for!!!") End Sub Uma dica legal usar a propriedade TopIndex. Veja o exemplo: Dim NovoIndex As Long NovoIndex = AdicionaItem(List1, "Texto") List1.TopIndex = NovoIndex O resultado isso que ele ir posicionar a barra de rolagem vertical da ListBox para que este item recem-adicionado possa ficar visvel..

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.

Movendo itens em uma ListBox


Para, atravs do mouse, mover a localizao de um item numa ListBox, use o cdigo abaixo. 'declarations:

84
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 TmpText, NewIndex End If End Sub

Multiplas Colunas em um ListBox


'Num mdulo: 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 Const LB_SETTABSTOPS = &H192 Public Sub ListColumns(lListHandle As Long) Dim iNumColumns As Long 'Coloque o n de colunas que o ListBox 'ter -1 no array a seguir: Dim iListTabs(1) As Long Dim Ret As Long 'O ListBox ter 2 colunas iNumColumns = 2 'A 1 coluna ter 24 caracteres e a 2 48 '24 caracteres * 4 = 96 iListTabs(0) = 96 ' 96/4 = 24 caracteres '48 caracteres * 4 = 192 iListTabs(1) = 192 ' 192/4 = 48 caracteres Ret = SendMessage(lListHandle, _ LB_SETTABSTOPS, iNumColumns, iListTabs(0)) End Sub 'No Form_Load: Private Sub Form_Load() 'lListHandle o handle da ListBox Call ListColumns(lstLista.hwnd) End Sub P/ adicionar os tens faa da seguinte maneira: Lista.AddItem "Coluna 1" & vbTab & "Coluna 2" Por exemplo (seguindo o nome da ListBox passado p/ a funo no Form_Load):

85
lstLista.AddItem "Coluna "Coluna lstLista.AddItem "Coluna "Coluna lstLista.AddItem "Coluna "Coluna lstLista.AddItem "Coluna "Coluna 1 data1" & vbTab & _ 02 data1" 01 data2" & vbTab & _ 02 data2" 001 data3" & vbTab & _ 02 data3" 0001 data4" & vbTab & _ 02 data4"

86

ListView
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 (ByBal _ ColumnHeader As ColumnHeader) Whith 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

87

Masked Edit Box


Limpar o controle Masked Edit Box
O controle MS MaskedEditBox 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: 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. vTemp = MaskEd1.Mask MaskEd1.Mask = "" MaskEd1.Text = "" MaskEd.Mask = vTemp

88

Mens
Colocando bitmaps em menus
Com esta dica voc poder dar um incremento visual em seus programas, incluindo bitmaps nos tens de menu. Coloque o cdigo a seguir em um mdulo: Declare Function GetMenu Lib "user32" (ByVal _ hWnd As Long) As Long Declare Function GetSubMenu Lib "user32" (ByVal _ hMenu As Long, ByVal nPos As Long) As Long Declare Function GetMenuItemID Lib "user32" _ (ByVal hMenu As Long, ByVal nPos As _ Long) As Long Declare Function SetMenuItemBitmaps Lib "user32" _ (ByVal hMenu As Long, ByVal nPosition _ As Long, ByVal wFlags As Long, ByVal _ hBitmapUnchecked As Long, ByVal _ hBitmapChecked As Long) As Long Public Const MF_BITMAP As Long = &H4& Type MENUITEMINFO cbSize As Long fMask As Long fType As Long fState As Long wID As Long hSubMenu As Long hbmpChecked As Long hbmpUnchecked As Long dwItemData As Long dwTypeData As String cch As Long End Type Declare Function GetMenuItemCount Lib "user32" _ (ByVal hMenu As Long) As Long Declare Function GetMenuItemInfo Lib "user32" _ Alias "GetMenuItemInfoA" (ByVal hMenu As _ Long, ByVal un As Long, ByVal b As Boolean, _ lpMenuItemInfo As MENUITEMINFO) As Boolean Public Const MIIM_ID As Long = &H2 Public Const MIIM_TYPE As Long = &H10 Public Const MFT_STRING As Long = &H0& Agora crie um formulrio, coloque nele uma picture box (autosize=true) com um bitmap de tamanho mximo 13x13 e adicione o seguinte cdigo em um boto: Private Sub Command1_Click() 'Recupera o handle do menu formulrio hMenu& = GetMenu(Form1.hwnd) 'Recupera o handle do 1 menu hSubMenu& = GetSubMenu(hMenu&, 0)

89
'Pega o menuId do 1 submenu hID& = GetMenuItemID(hSubMenu&, 0) 'Adiciona o bitmap ao submenu SetMenuItemBitmaps hMenu&, hID&, MF_BITMAP, _ Picture1.Picture, Picture1.Picture 'Voc pode colocar dois bitmaps no menu 'Uma para o estado selecionado, e outro 'para o no selecionado. End Sub

Menus popup em caixa de Texto


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 = True End If End Sub

90

Microsoft Comm Control


Trabalhando com Microsoft Comm Control
Defina Settings, Porta e tudo mais do do MsComm1, e: 'P/ abra a porta: MSComm1.PortOpen = True 'P/ receber dados: While MSComm1.PortOpen = True If MSComm1.InBufferCount > 0 Then Text1= Text1& MSComm1.Input End If DoEvents Wend 'P/ enviar dados: MSComm1.Output = Text2 'P/ fechar a conexo: MSComm1.PortOpen = False

91

PictureBox
Carregando figuras em Pictures
Em qualquer objeto que tenha a propriedade PICTURE, possvel defini-la em tempo de desenho, informando o arquivo (BMP, ICO, DIB, WMF) que contm a imagem. Salvando o form com texto(FRM), as imagens so salvas como binrias em arquivos FRX. 'COPIAR DE OUTRO OBJETO Me.Picture = Picture1.Picture 'COPIAR A FIGURA DA REA DE TRANSFERENCIA (COLAR) Me.Picture =ClipBoard.GetData() 'ABRIR FIGURA DE UM ARQUIVO Me.Picture = LoadPicture("C:\Windows\Winlogo.bmp") 'LIMPANDO FIGURA Me.Picture = LoadPicture()

Dimenses de um bitmap
Voc pode utilizar o controle PictureBox com a propriedade AutoSize=True. Carregue o bitmap no PictureBox, usando a funo LoadPicture. O controle ir ajustar o seu tamanho automaticamente, para que o bitmap caiba nele. As propriedades Height e Width deste controle contm as dimenses do bitmap. Note que os valores destas propriedades esto em Twips. Uma outra forma, utilizar a API GetObject. Esta funo retorna a estrutura do Bitmap em dois membros, bmWidth e bmHeight representando as dimenses do bitmap em pixels. Veja o exemplo abaixo: Coloque o seguinte cdigo em um mdulo: Type BITMAP '14 bytes bmType As Integer bmWidth As Integer bmHeight As Integer bmWidthBytes As Integer bmPlanes As String * 1 bmBitsPixel As String * 1 bmBits As Long End Type Declare Function GetObjectAPI% Lib "GDI" Alias _ "GetObject"(ByVal hObject%, ByVal nCount%, _ lpObject As Any) Coloque o seguinte cdigo aonde voc quer obter as dimenses do bitmap. (O Bitmap deve ser carregado em um PictureBox chamado Picture1): Dim bmp As BITMAP, ret% ret = GetObjectAPI(picture1.Picture, Len(bmp), bmp) Print "Width = " & Str$(bmp.bmWidth) & ", Height = " & _ Str$(bmp.bmHeight)

92

Rolando textos em PictureBox


'Num mdulo: Public Function MostrarTexto() Static Count As Integer Static Texto As String If Len(Texto) = 0 Then Count = 1 Texto = "Rolando texto numa Picture Box!" End If Picture1.Cls Picture1.Print Mid$(Texto, Count); Texto; Count = Count + 1 If Count > Len(Texto) Then Count = 1 End If End Function 'No Form: 'Coloque uma PictureBox e um Timer com interval=1000. Private Sub Timer1_Timer() MostrarTexto End Sub

Salvando e Pintando em cima de figuras


A propriedade IMAGE permite pintar com os mtodos (PRINT, PSET, LINE e CIRCLE) em tempo de execuo. Para imcorporar uma imagem picture, basta fazer: Picture1.Picture = Picture1.image Esta linha de comando atribui o resultado dos grficos imagem principal. No exemplo abaixo, serve para riscar um arquivo: Dim X As Integer Dim Y As Integer Picture1.Picture = LoarPicture("C:\Windows\Logo.ico") X = Picture1.ScaleWidth Y = Picture1.ScaleHeight Picture1.Line (0, 0)-(X, Y), RGB(255, 0, 0) Picture1.Picture = Picture1.Image SavePicture Picture1, "C:\Windows\Logo.bmp" No exemplo acima, a picture somente converte o trao aps receber a image. Detalhe: independente do formato da imagem contida em picture, a propriedade image contm sempre um bitmap. Assim, o truque acima uma tima forma de converter ICO e WMF em BMP. cones e metafiles podem possuir um fundo transparente. Quando transformamos em bitmaps incorporam os pontos (e a cor) de fundo. Veja o exemplo:

93
'*** CONVERTENDO ICO EM BMP *** Picture1.Picture = LoadPicture("C:\Icons\Mylogo.ico") 'ATRIBUINDO COR DE FUNDO Picture1.BackColor = RGB(255, 255, 255) Picture1.Picture = Picture1.Image 'CONVERTENDO EM BMP SavePicture Picture1, "C:\Windows\Mylogo.bmp"

94

RichTextBox
Imprimindo o Contedo de um RichTextBox
Para imprimir o contedo de um RichTextBox, basta voc passar a ele o hDC da impressora. Veja: 'No evnto que voc desejar: RichTextBox1.SelPrint Printer.hDC Mas e para imprimir numa impressora selecionada num CommonDialog??? Tambm simples. Veja o exemplo: 'No evnto que voc desejar: 'Seleciona as Flags necessrias CommonDialog1.Flags = cdlPDReturnDC + _ cdlPDNoPageNums If RichTextBox1.SelLength = 0 Then CommonDialog1.Flags = cdlFontes.Flags + _ cdlPDAllPages Else CommonDialog1.Flags = cdlFontes.Flags + _ cdlPDSelection End If 'Abre o CommonDialog para seleo/configurao 'de impressoras CommonDialog1.ShowPrinter 'Manda imprimir o contedo do RichTextBox na 'impressora selecionada no CommonDialog RichTextBox1.SelPrint CommonDialog1.hDC

Localizando um Texto num RichTextBox


Isto muito simples de ser feito. Veja o cdigo a seguir: 'No declarations do Form: Public sFind As String 'No evento onde voc deseja localizar um determinado 'Texto no RichTextBox: sFind = InputBox("Localizar o que?", "Procura", sFind) If sFind = "" Then Exit Sub RichTextBox1.Find sFind 'Para localizar a prxima ocorrencia do mesmo texto: RichTextBox1.SelStart = RichTextBox1.SelStart + _ RichTextBox1.SelLength + 1 RichTextBox1.Find sFind, , Len(RichTextBox1) Pronto. Se o texto digitado existir no RichTextBox, ele ser selecionado.

Uso Geral do Controle RichTextBox


'Para abrir um arquivo: CommonDialog1.ShowOpen RichTextBox1.LoadFile (CommonDialog1.FileName)

95

'Para salvar um arquivo: CommonDialog1.ShowSave RichTextBox1.SaveFile (CommonDialog1.FileName) 'Para mudar a fonte usada (muda apenas p/ o pedao 'de texto selecionado, ou para todo o texto que vier 'a ser digitado apartir daquele ponto): CommonDialog1.Flags = cdlCFBoth + cdlCFEffects CommonDialog1.ShowFont With RichTextBox1 .SelFontName = CommonDialog1.FontName .SelFontSize = CommonDialog1.FontSize .SelBold = CommonDialog1.FontBold .SelItalic = CommonDialog1.FontItalic .SelStrikeThru = CommonDialog1.FontStrikethru .SelUnderline = CommonDialog1.FontUnderline End With

96

TextBox
Apenas Nmeros num TexBox
'Coloque num form um TextBox e um CommandButton. 'No Declarations ponha: Option Explicit Private Declare Function GetWindowLong& Lib "user32" _ Alias "GetWindowLongA" (ByVal hwnd As Long, _ ByVal nIndex As Long) Private Declare Function SetWindowLong& Lib "user32" _ Alias "SetWindowLongA" (ByVal hwnd As Long, _ ByVal nIndex As Long, ByVal dwNewLong As Long) Private Const ES_NUMBER As Long = &H2000& Private Const GWL_STYLE As Long = (-16) 'No Click do CommandButton ponha: Private Sub Command1_Click() Dim tmpValue& Dim fAlignment& Dim ret& fAlignment& = ES_NUMBER tmpValue& = GetWindowLong&(Text1.hwnd, GWL_STYLE) ret& = SetWindowLong&(Text1.hwnd, GWL_STYLE, tmpValue& Or fAlignment&) Text1.Refresh End Sub Quando voc executar perceber que o TextBox permite que voc digite QUALQUER coisa, mas quando voc precionar o CommandButton ele S receber nmeros. Ele no aceitar nem mesmo o ponto (.) e a virgula (,).

Bloqueando funes Copiar e Colar em caixas de texto


Bloqueando funes Copiar e Colar em caixas de texto as funes Copiar (CTRL+C) e Colar (CTRL+V) esto sempre disponveis para TextBoxes, mas e se voc no desejar que estas funes funcionem? Voc deve supor que o evento KeyDown consegue detectar CTR+C e CTRL+V, mas no detecta. No evento KeyPress, estas teclas podem ser capturadas: Sub Text1_KeyPress (KeyAscii As Integer) 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

Forando Caracteres Maisculos ou Minsculos


Para facilitar a digitao de caracteres maisculos ou minsculos, independente do pressionamento de Caps Lock ou do Shift, converta cada caracter no evento KeyPress. Private Sub Controle_KeyPress (KeyAscII as Integer) 'Converter p/ maisculos KeyAscII = Asc(UCase(Chr(KeyAscII)))

97
'Converter p/ maisculos KeyAscII = Asc(LCase(Chr(KeyAscII))) End Sub Para que esta rotina funcione para todos os campos do form, altere a propriedade KeyPreview do mesmo para True e coloque o cdigo no evento Form_KeyPress.

O Caracter ENTER
Ele nunca aparece, mas existe. No Word representado por um , nas caixas de texto do VB aparece um y (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 text1.Text text1.Text text1.Text = = = = "linha 1" text1.Text & Chr$(13) & Chr$(10) & "linha 2" text1.Text & Chr$(13) & Chr$(10) 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

Procurando Strings em um TextBox


'No Declarations do Form: Private iLast As Integer Private iFirst As Integer Private sFind As String Private Sub Text1_GotFocus() 'Valor Default p/ as variaveis iLast = 1 iFirst = 1 End Sub Private Sub Text1_KeyUp(KeyCode As Integer, _ Shift As Integer) Dim sMensagem As String, sTitulo As String

98
Dim sDefault As String, bCtrlDown As Boolean Dim bProcura As Boolean, iNum As Integer Dim iPos As Integer, iPos_Fim As Integer bCtrlDown = (Shift And vbCtrlMask) > 0 bProcura = False If KeyCode = vbKeyF And bCtrlDown Then 'A Tecla Ctrl+F foi pressionada sMensagem = "Entre com o Texto a ser procurado!" sTitulo = "Procura" sDefault = "" sFind = InputBox(Mensagem, Titulo, Default) If sFind = "" Then Exit Sub 'Marca como a tecla F3 tivesse sido pressionada. KeyCode = 114 'Forca a passagem pela Busca End If 'As rotinas abaixo verificam se a tecla apertada 'F3. A primeira coisa a ser feita verificar se 'realmente existe em algum ponto do TextBox a string 'informada no InputBox. 'Existindo a string, entao verificado se a busca 'ser feita "para baixo" (F3) ou "para cima" (Shift+F3) If KeyCode = 114 Then If InStr(Text1.Text, sFind) = 0 Then MsgBox "Texto no encontrado!", vbInformation Exit Sub End If If Shift = 1 Then If iFirst = 0 Or InStr(Mid(Text1.Text, 1, _ iFirst), sFind) = 0 Then iFirst = Len(Text1.Text) End If For iNum = (iFirst - 1) To 1 Step -1 If Mid(Text1.Text, i%, _ Len(Find_String)) = Find_String Then iPos = iNum Exit For End If DoEvents Next For iNum = (iFirst - 1) To 1 Step -1 If Mid(Text1.Text, iNum, _ Len(sFind)) = sFind Then iPos_Fim = Len(sFind) + iNum Exit For End If DoEvents Next iLast = iPos_Fim iFirst = iPos Text1.SelStart = iPos - 1 Text1.SelLength = iPos_Fim - iPos Else iPos = InStr(iLast, Text1.Text, sFind) iFirst = iPos If iPos = 0 Then iLast = 1 iPos = InStr(iLast, Text1.Text, sFind)

99
End If iPos_Fim = Len(sFind) + iPos iLast_Pos = iPos_Fim Text1.SelStart = iPos - 1 Text1.SelLength = iPos_Fim - Pos End If End If End Sub

Selecionando Texto do TextBox ao Receber Foco


'Basta colocar no evento GotFocus do TextBox, 'por exemplo Text1, a seguinte rotina: Private Sub Text1_GotFocus() Text1.SelStart = 0 Text1.SelLength = Len(Text1.Text) End Sub

Rolar um TextBox linha a linha


Public Declare Function SendMessage Lib "user32" Alias "SendMessageA" _ (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, _ lParam As Any) As Long SendMessage(SuaText.hWnd, EM_LINESCROLL, 0, 5&) ' Onde o IParam o numero de linhas a ser rolado.

100

ToolBar
Deixando a ToolBar (do VB5) no Estilo Flat
'Num mdulo: Private Declare Function FindWindowEx Lib "user32" _ Alias "FindWindowExA" (ByVal hWnd1 As Long, _ ByVal hWnd2 As Long, ByVal lpsz1 As String, _ ByVal lpsz2 As String) As Long Private Declare Function SendTBMessage Lib "user32" _ Alias "SendMessageA" (ByVal hwnd As Long, _ ByVal wMsg As Long, ByVal wParam As Integer, _ ByVal lParam As Any) As Long Private Private Private Private Private Const Const Const Const Const WM_USER As Long = &H400 TBSTYLE_FLAT As Long = &H800 TBSTYLE_TRANSPARENT As Long = &H8000 TB_SETSTYLE As Long = (WM_USER + 56) TB_GETSTYLE As Long = (WM_USER + 57)

Public Sub MakeToolbarFlat(theToolbar As Control) Dim Res As Long Dim Style As Long Style = SendTBMessage(FindWindowEx(theToolbar.hwnd, _ 0&, "ToolbarWindow32", vbNullString), _ TB_GETSTYLE, 0&, 0&) Style = Style Or TBSTYLE_FLAT Or TBSTYLE_TRANSPARENT Res = SendTBMessage(FindWindowEx(theToolbar.hwnd, 0&, _ "ToolbarWindow32", vbNullString), TB_SETSTYLE, _ 0, Style) theToolbar.Refresh End Sub 'P/ chamar, no evento Form_Load (por exemplo) coloque: Private Sub Form_Load() Call MakeToolbarFlat(Toolbar1) End Sub

True DbGrid
Como ligar o True DbGrid a um Array
O True DbGrid um controle completo. Voc pode, por exemplo, querer lig-lo a um array ao invs de um banco de dados (ou seja, os dados ficaro na memria). Para isso, siga os passos: 1 - Insira o True DbGrid em seu Form; 2 - Altere a propriedade DataMode dele p/ 4 - Storage; 3 - Em Project/References, adicione a biblioteca "APEX XArray Object", prpria dele. Ento, use o cdigo a seguir: 'No declarations do Form: Dim MeuArray As New XArray 'Ento, no evento Form_Load: Private Sub Form_Load()

101
'Redimensiona o array p/ ter 5 linhas (1 5) 'e 2 colunas (0 1): 'Array.ReDim 1, n de linhas, 0, n de colunas -1 MeuArray.ReDim 1, 5, 0, 1 'Inseri dados no array: MeuArray.Value(1, 0) = "Linha 1, Coluna 0" MeuArray.Value(1, 1) = "Linha 1, Coluna 1" MeuArray.Value(2, 0) = "Linha 2, Coluna 0" MeuArray.Value(2, 1) = "Linha 2, Coluna 1" MeuArray.Value(3, 0) = "Linha 3, Coluna 0" MeuArray.Value(3, 1) = "Linha 3, Coluna 1" MeuArray.Value(4, 0) = "Linha 4, Coluna 0" MeuArray.Value(4, 1) = "Linha 4, Coluna 1" MeuArray.Value(5, 0) = "Linha 5, Coluna 0" MeuArray.Value(5, 1) = "Linha 5, Coluna 1" 'Atribui o array ao True DBGrid: Set TDBGrid1.Array = MeuArray End Sub

Deixando um True DBGrid Zebrado (com 2 Cores Intercaladas)


'No evento Form_Load: Private Sub Form_Load() TDBGrid1.EvenRowStyle.BackColor = &HC0FFFF TDBGrid1.OddRowStyle.BackColor = &HFFFFFF TDBGrid1.AlternatingRowStyle = True End Sub Parece ser simples de mais para ser verdade, no ? Pois , mas funciona!!! Eu no tinha o True DBGrid em meu micro, ento fiz o download s p/ testar e funcionou!!!

Detectar a Linha Selecionada num True DBGrid


Digamos que voc esteja criando um programa, onde tenha um Form de pesquizas. Nesse Form teria um um TrueGrid, onde seriam exibidos dados de um cadastro de clientes, por exemplo. Uma coisa bastante interessante seria permitir que o usurio desse um duplo clique em uma linha do True DBGrid para abrir um outro Form com detalhes daquele registro. Isto possvel de ser feito, usando-se o evento DblClick do True DBGrid, bastando ento criar uma sub-rotina que detecte a linha selecionada e abra o Form de detalhes. Se o programador quiser criar tambm um boto Detalhes, basta associar essa sub-rotina ao evento Click do boto. Veja o exemplo: Private Sub TDBGrid1_DblClick() Call VerDetalhes End Sub Private Sub cmdDetalhes_Click() Call VerDetalhes End Sub Private Sub VerDetalhes() 'Passa para o Form frmDetalhes o contedo da

102
'coluna 0 (zero) da linha que estiver 'selecionada (Cdigo do cliente, por exemplo...) frmDetalhes.Texto = TDBGrid1.Columns(0).Text 'Abre o Form frmDetalhes... frmDetalhes.Show vbModal End Sub

Navegao de Linha no True DBGrid


Digamos que voc criou uma tela de pesquisa de um cadastro qualquer no seu programa (usando string de SQL e etc) e queira exibir isto num Grid, mas NO quer que o usurio possa selecionar mais de um registro (uma coluna inteira, por exemplo). Neste caso o ideal seria que, quando o usurio selecionasse um registro, o Grid selecionasse a linha toda do Grid... Para fazer isto, usando o True DBGrid, coloque o seguinte cdigo no seu Form: Private Sub Form_Load() With TDBGrid1 .AllowUpdate = False .EditDropDown = False .InsertMode = False .AllowColSelect = False .MultiSelect = 0 .MarqueeStyle = 3 .HighlightRowStyle.BackColor = vbHighlight .HighlightRowStyle.ForeColor = vbHighlightText End With End Sub

103

DIRETRIOS
Capturar o caminho DOS de um arquivo
Public Declare Function GetShortPathName Lib _ "kernel32" Alias "GetShortPathNameA" _ (ByVal lpszLongPath As String, ByVal _ lpszShortPath As String, ByVal cchBuffer _ As Long) As Long Public Const MAX_PATH As Long = 260 Dim sDirLong As String Dim sDirDOS As String Call GetShortPathname(sDirLong, sDirDOS, MAX_PATH)

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 End If Wend End Sub Sub Test() Call CreateLongDir ("C:\", "Test\MyApp\MyDir\Long " & _ "Directory Name\") End Sub

Como interceptar mudanas em um diretrio


Claro que apos a ocorrer a mudanca essa funcao nao vai retornar qual o arquivo modificado. O ideal (tem outro jeito?) manter uma lista do status dos arquivos na pasta (e se for o caso, subpastas) em uma coleo ou array. Depois de receber uma notificacao criar uma nova lista e comparar com a antiga pra descobrir o que mudou.

104
Have fun! 'Declaracoes: Public Declare Function FindFirstChangeNotification Lib _ "kernel32" Alias "FindFirstChangeNotificationA" _ (ByVal lpPathName As String, ByVal bWatchSubtree _ As Long, ByVal dwNotifyFilter As Long) As Long Public Declare Function FindCloseChangeNotification Lib _ "kernel32" (ByVal hChangeHandle As Long) As Long Public Declare Function FindNextChangeNotification Lib _ "kernel32" (ByVal hChangeHandle As Long) As Long Public Public Public Public Public Public Public Public Public Public Public Public Const Const Const Const Const Const Const Const Const Const Const Const FILE_NOTIFY_CHANGE_ATTRIBUTES As Long = &H4 FILE_NOTIFY_CHANGE_DIR_NAME As Long = &H2 FILE_NOTIFY_CHANGE_FILE_NAME As Long = &H1 FILE_NOTIFY_CHANGE_SECURITY As Long = &H100 FILE_NOTIFY_CHANGE_LAST_WRITE As Long = &H10 FILE_NOTIFY_CHANGE_SIZE As Long = &H8 WAIT_FAILED As Long = &HFFFFFFFF WAIT_OBJECT_0 As Long = &H0 WAIT_ABANDONED As Long = &H80 WAIT_ABANDONED_0 As Long = &H80 WAIT_TIMEOUT As Long = &H102 WAIT_IO_COMPLETION As Long = &HC0

Public Declare Function WaitForSingleObject Lib _ "kernel32" (ByVal hHandle As Long, ByVal _ dwMilliseconds As Long) As Long ' Public Declare Function WaitForSingleObjectEx Lib _ ' "kernel32" (ByVal hHandle As Long, ByVal _ ' dwMilliseconds As Long, ByVal bAlertable As _ ' Long) As Long Public Declare Function GetShortPathName Lib _ "kernel32" Alias "GetShortPathNameA" (ByVal _ lpszLongPath As String, ByVal lpszShortPath _ As String, ByVal cchBuffer As Long) As Long Public Const MAX_PATH As Long = 260 'Em um Form: Option Explicit Private hFind As Long Private bParar As Boolean ' Dois command button com captions "Assistir" e "Parar" ' Uma caixa de texto txtDir para conter o Path a ser monitorado ' Uma listbox List1 para mostrar o que esta acontecendo :-) Private Sub Command1_Click() Dim hEvento As Long Dim sPathParaApi As String * MAX_PATH Dim sPathLongo As String bParar = False '

105
' Nao sei se ' diretrios ' sPathParaApi sPathLongo = a funcao FindFirstChangeNotification aceita longos entao estou convertendo antes de mandar = String(MAX_PATH, Chr(0)) txtDir.Text

If GetShortPathName(sPathLongo,sPathParaApi,MAX_PATH) Then If hFind <> 0 Then Call FindCloseChangeNotification(hFind) hFind = 0 End If ' Ateno nisso ' FindFirstChangeNotification(Path, _ ' Deseja monitorar os subdiretorios?, _ ' Tipo de monitoracao) ' ' Tipos possiveis ' FILE_NOTIFY_CHANGE_ATTRIBUTES - Notifica se houve ' mudana nos atributos ' FILE_NOTIFY_CHANGE_DIR_NAME - Notifica se houve ' mudana no nome dos ' diretorios ' FILE_NOTIFY_CHANGE_FILE_NAME - Mudana no nome dos arqs, ' criao ou exclusao ' FILE_NOTIFY_CHANGE_SECURITY - Mudana de permisso ' FILE_NOTIFY_CHANGE_LAST_WRITE - Mudana na data de ultima ' gravao ' FILE_NOTIFY_CHANGE_SIZE - Mudana de tamanho ' ' Combinacoes so possivel com OR hFind = FindFirstChangeNotification(sPathParaApi, False, _ FILE_NOTIFY_CHANGE_FILE_NAME) If hFind = 0 Then MsgBox "Ops... Nao foi possivel inicializar", vbInformation, _ "Erro" End If Do ' ' ' ' ' Estou usando TimeOut pra dar tempo do usuario clicar em PARAR e poder sair desse Loop mas no obrigatrio.... PS.: Lembre se q WaitForSingleObject ir travar o thread at acontecer alguma coisa :-)

hEvento = WaitForSingleObject(hFind, 200) Select Case hEvento Case WAIT_FAILED List1.AddItem "WAIT_FAILED" Call FindCloseChangeNotification(hFind) hFind = 0 Exit Do Case WAIT_ABANDONED List1.AddItem "WAIT_ABANDONED" Call FindCloseChangeNotification(hFind) hFind = 0 Exit Do Case WAIT_ABANDONED_0 List1.AddItem "WAIT_ABANDONED_0" Call FindCloseChangeNotification(hFind)

106
hFind = 0 Exit Do Case WAIT_OBJECT_0 List1.AddItem "WAIT_OBJECT_0" ' ' Essa a notificacao que algo aconteceu.... ' ' Executa aes ' ' blah blah blah.... ' Case WAIT_IO_COMPLETION List1.AddItem "WAIT_IO_COMPLETION" Call FindCloseChangeNotification(hFind) hFind = 0 Exit Do Case WAIT_TIMEOUT DoEvents If bParar Then List1.AddItem "Stopped" Call FindCloseChangeNotification(hFind) hFind = 0 Exit Do End If If FindNextChangeNotification(hFind) = 0 Then List1.AddItem "Problemas..." Call FindCloseChangeNotification(hFind) hFind = 0 Exit Do End If End Select Loop Else MsgBox "Erro ao converter diretrio.", vbInformation, _ "Erro" End If End Sub Private Sub Command2_Click() bParar = True End Sub Private Sub Form_Load() ' Setei um default, mas isso vc pode mudar txtDir.Text = "C:\WINNT\Profiles\User\Desktop" End Sub

Diretrio onde o Programa foi Instalado


Para saber qual o diretrio onde est o executalvel (arquivo *.EXE) de seu programa proceda da seguinte forma: 'No evendo que voc quizer: Dim MeuDir as String MeuDir = App.Path If Right$(App.Path) = "\" Then MeuDir = App.Path & "\" End If

107
MsgBox MeuDir Ento, se, por exemplo, seu progama tiver sido instalado no diretrio "C:\Arquivos de Programas\Meu Programa" ele mostrar na mensagem o seguinte texto: "C:\Arquivos de Programas\Meu Programa\" Esta ltima barra (\) necessria no caso de voc querer concatenar (somar) essa varivel o nome de um banco de dados. Veja: MeuDir = MeuDir & "BancoDeDados.MDB" Nesse caso a varivel MeuDir passar a conter: "C:\Arquivos de Programas\Meu Programa\BancoDeDados.MDB". CASO o endereo no tenha essa ltima barra, o resultado seria "C:\Arquivos de Programas\Meu ProgramaBancoDeDados.MDB". Isto COM CERTEZA causaria um erro na hora de abrir o banco de dados. Mas, se assim, POR QUE no fazer "SIMPLESMENTE" assim: MeuDir = App.Path & "\BancoDeDados.MDB"??? Porque o App.Path pode vir a j conter essa barra. Por isso eu fiz assim: 'Joga p/ MeuDir o contedo de App.Path MeuDir = App.Path 'Verifica a existencia da barra If Right$(App.Path) = "\" Then 'CASO App.Path NO contenha a ltima barra, 'soma-a varivel MeuDir MeuDir = App.Path & "\" End If

Funo para Unir um Diretrio a um Subdiretrio


'Coloque esta funo num mdulo ou mesmo no form: Public Function Junta_Dirs(ByVal sDir1 As String, _ ByVal sDir1 As String) If Right$(Dir1, 1) = "\" Then If Left$(Dir2, 1) = "\" Then Junta_Dirs = Left$(Dir1, Len(Dir1) - 1) & Dir2 Else Junta_Dirs = Dir1 & Dir2 End If Else If Left$(Dir2, 1) = "\" Then Junta_Dirs = Dir1 & Dir2 Else Junta_Dirs = Dir1 & "\" & Dir2 End If End If If Right$(Junta_Dirs, 1) <> "\" Then Junta_Dirs = Junta_Dirs & "\" End If End Function 'P/ chamar: Dim Dir As String

108
Dir = 'OU: Dir = 'OU: Dir = 'OU: Dir = Junta_Dirs(App.Path,"\BMPs\")&"Desenho.BMP" Junta_Dirs(App.Path, "\BMPs")&"Desenho.BMP" Junta_Dirs(App.Path, "BMPs\")&"Desenho.BMP" Junta_Dirs(App.Path, "BMPs")&"Desenho.BMP"

'TODAS as anteriores iro funcionar. S NO use assim: Dir = Junta_Dirs(App.Path, "BMPs")&"\Desenho.BMP" 'Pois no ir funcionar.

Pegar o Diretrio de Arquivos Temporrios (Windows\Temp)


'NUM MDULO: Private Const MAX_PATH As Long = 260 Private Declare Function GetTempPath Lib "kernel32" _ Alias "GetTempPathA" (ByVal nBufferLenght _ As Long, ByVal lpBuffer As String) As Long Public Function GetTempDir() As String Dim strFolder As String Dim lngResult As Long strFolder = String(MAX_PATH, 0) lngResult = GetTempPath(MAX_PATH, strFolder) If lngResult <> 0 Then If Right(Left(strFolder, lngResult), 1) = "\" Then GetTempDir = Left(strFolder, lngResult) Else GetTempDir = Left(strFolder, lngResult) & "\" End If Else GetTempDir = "" End If End Function 'P/ CHAMAR: MsgBox "O Diretrio System do Windows : " & GetTempDir, _ vbOKOnly + 64, "Local do Diretrio System do Windows"

Pegar o Diretrio do System


'NUM MDULO: Private Const MAX_PATH As Long = 260 Private Declare Function GetSystemDirectory Lib _ "kernel32" Alias "GetSystemDirectoryA" _ (ByVal lpBuffer As String, ByVal nSize _ As Long) As Long Public Function GetSysDir() As String Dim strFolder As String Dim lngResult As Long strFolder = String(MAX_PATH, 0) lngResult = GetSystemDirectory(strFolder, MAX_PATH) If lngResult <> 0 Then If Right(Left(strFolder, lngResult), 1) = "\" Then GetSysDir = Left(strFolder, lngResult) Else GetSysDir = Left(strFolder, lngResult) & "\"

109
End If Else GetSysDir = "" End If End Function 'P/ CHAMAR: MsgBox "O Diretrio System do Windows : " & GetSysDir, _ vbOKOnly + 64, "Local do Diretrio System do Windows"

Pegar o Diretrio do Windows


'NUM MDULO: Private Const MAX_PATH As Long = 260 Private Declare Function GetWindowsDirectory Lib _ "kernel32" Alias "GetWindowsDirectoryA" _ (ByVal lpBuffer As String, ByVal nSize As _ Long) As Long Public Function GetWinDir() As String Dim strFolder As String Dim lngResult As Long strFolder = String(MAX_PATH, 0) lngResult = GetWindowsDirectory(strFolder, MAX_PATH) If lngResult <> 0 Then If Right(Left(strFolder, lngResult), 1) = "\" Then GetWinDir = Left(strFolder, lngResult) Else GetWinDir = Left(strFolder, lngResult) & "\" End If Else GetWinPath = "" End If End Function 'P/ CHAMAR: MsgBox "O Diretrio do Windows : " & GetWinDir, _ vbOKOnly + 64, "Local do Diretrio do Windows"

110

111

HARDWARE CDROM
Abrir e fechar a gaveta do CDROM
Private Declare Function mciSendString Lib "winmm.dll" _ Alias "mciSendStringA" (ByVal lpstrCommand As _ String, ByVal lpstrReturnString As String, _ ByVal uReturnLength As Long, ByVal hwndCallback _ As Long) As Long 'PARA ABRIR Call mciSendString("Set CDAudio Door Open Wait", 0&, _ 0&, 0&) 'PARA FECHAR Call mciSendString("Set CDAudio Door Closed Wait", 0&, _ 0&, 0&)

Disquetes
Formatando um Disquete
Este exemplo chama a caixa de dilogo Formatar Disquete do Windows Explorer. Coloque um boto num Form e coloque o seguinte cdigo: 'Num mdulo: Option Explicit Private Declare Function SHFormatDrive Lib _ "shell32" (ByVal hwnd As Long, ByVal _ Drive As Long, ByVal fmtID As Long, _ ByVal options As Long) As Long Private Declare Function GetDriveType Lib _ "kernel32" Alias "GetDriveTypeA" _ (ByVal nDrive As String) As Long Public Public Public Public Public Public Public Public Const Const Const Const Const Const Const Const DRIVE_CDROM = 5 DRIVE_FIXED = 3 DRIVE_RAMDISK = 6 DRIVE_REMOTE = 4 DRIVE_REMOVABLE = 2 SHFMT_ID_DEFAULT = &HFFFF SHFMT_OPT_FULL = 1 SHFMT_OPT_SYSONLY = 2

Public Sub FormatFloppy(hWndOwner As _ Long, ByVal DriveLetter As String) Dim DriveNum As Long, DriveType As Long Dim ret As Long DriveLetter = Left(DriveLetter, 1) & ":\" DriveNum = Asc(UCase(DriveLetter)) - Asc("A") DriveType = GetDriveType(DriveLetter) If DriveType = DRIVE_REMOVABLE Then

112
ret = SHFormatDrive(hWndOwner, _ DriveNum, SHFMT_ID_DEFAULT, _ SHFMT_OPT_FULL) Else MsgBox "O drive informado no um " & _ "drive de discos removveis", _ vbExclamation, "Formatar Disquete" End If End Sub 'No evento click do botao: Private Sub Command1_Click() FormatFloppy Me.hwnd, "A" 'Neste caso, estaria mandando formatar o drive A:. End Sub

Drive
Ler propriedades de drives, pastas e arquivos
'Ao: '- L propriedades de drives, pastas e arquivos '- Modifica data e hora em arquivos Private Declare Function GetDiskFreeSpace Lib "kernel32" _ Alias "GetDiskFreeSpaceA" (ByVal lpRootPathName _ As String, lpSectorsPerCluster As Long, _ lpBytesPerSector As Long, lpNumberOfFreeClusters _ As Long, lpTotalNumberOfClusters As Long) As Long Private Declare Function GetDriveType Lib "kernel32" Alias _ "GetDriveTypeA" (ByVal nDrive As String) As Long Private Type FILETIME dwLowDateTime As Long dwHighDateTime As Long End Type Private Type SYSTEMTIME wYear As Integer wMonth As Integer wDayOfWeek As Integer wDay As Integer wHour As Integer wMinute As Integer wSecond As Integer wMilliseconds As Integer End Type Private Private Private Private Const Const Const Const GENERIC_WRITE As Long = &H40000000 OPEN_EXISTING As Long = 3 FILE_SHARE_READ As Long = &H1 FILE_SHARE_WRITE As Long = &H2

Private Declare Function SetFileTimeWrite Lib "kernel32" _ Alias "SetFileTime" (ByVal hFile As Long, ByVal _ MullP As Long, ByVal NullP2 As Long, lpLastWriteTime _ As FILETIME) As Long

113

Private Declare Function SystemTimeToFileTime _ Lib "kernel32" (lpSystemTime As SYSTEMTIME, _ lpFileTime As FILETIME) As Long Private Declare Function CreateFile Lib "kernel32" Alias _ "CreateFileA" (ByVal lpFileName As String, ByVal _ dwDesiredAccess As Long, ByVal dwShareMode As Long, _ ByVal lpSecurityAttributes As Long, ByVal _ dwCreationDisposition As Long, ByVal _ dwFlagsAndAttributes As Long, ByVal hTemplateFile _ As Long) As Long Private Declare Function CloseHandle Lib "kernel32" (ByVal _ hObject As Long) As Long Private Declare Function LocalFileTimeToFileTime Lib _ "kernel32" (lpLocalFileTime As FILETIME, lpFileTime _ As FILETIME) As Long Private Const Tit As String = "Data & Hora" Dim arqAtual As String Dim blnDrvDir As Boolean Private Sub cmdAjuda_Click() ' Mensagem de ajuda Dim m$ m$ = "Este programa lhe permite visualizar informaes " m$ = m$ & "sobre drives, pastas e arquivos. Alm disso, " m$ = m$ & "altera data e hora de um, vrios ou todos os " m$ = m$ & "arquivos de um diretrio. Os arquivos para " m$ = m$ & "modificao devem ser selecionados na caixa " m$ = m$ & "Arquivos. A data (dd/mm/aaaa) e a hora (hh:mm:ss) " m$ = m$ & "so indicadas, respectivamente, nos campos Nova " m$ = m$ & "Data e Nova Hora. Clique na etiqueta Atributos para " m$ = m$ & "mais informaes sobre os tipos de arquivos. Os " m$ = m$ & "tamanhos de drives e arquivos so sempre expressos " m$ = m$ & "em bytes. O boto Atualizar renova as informaes " m$ = m$ & "na lista de arquivos. Use-o, por exemplo, depois de " m$ = m$ & " trocar um disco no drive A." & vbCrLf & vbCrLf m$ = m$ & "Data & Hora 1996-1999 Carlos Machado" MsgBox m$, vbOKOnly, Tit End Sub Private Sub cmdAlterar_Click() ' Dispara a alterao de data e hora On Error GoTo cmdAlterar_Click_Err Dim i As Integer Dim s As String Dim nomePath As String Dim Ano As Integer, Mes As Integer Dim Dia As Integer, Hora As Integer Dim Minuto As Integer, Segundo As Integer Dim DataeHora As Variant Dim sArquivo As String Dim x As Integer Dim sData As String Dim sHora As String Dim sReadOnly As String sData = Text1

114
Ano = Year(sData) ' Checa se CD-ROM If Label2(1) = "CD-ROM " Then MsgBox "Arquivos em CD-ROM no podem ser alterados.",vbCritical,Tit Text1.SetFocus Exit Sub End If ' Checa validade da data digitada If Not IsDate(sData) Then MsgBox "Data invlida.", vbCritical, Tit Text1.SetFocus: Exit Sub Else If Ano < 1980 Then MsgBox "O sistema de arquivos no suporta " & _ "datas anteriores a 1980.", vbCritical , Tit Text1.SetFocus: Exit Sub End If End If ' Se data vlida, segue (a hora j ) s = "Tem certeza de que deseja alterar o(s) arquivo(s) indicado(s)?" i = MsgBox(s, vbYesNo + vbQuestion + vbDefaultButton2, Tit) If i <> vbYes Then Exit Sub ' Liga a ampulheta: a operao pode demorar Screen.MousePointer = vbHourglass Mes = Month(sData) Dia = Day(sData) Hora = Val(labHora) Minuto = Val(labMinuto) Segundo = Val(labSegundo) DataeHora = DateSerial(Ano, Mes, Dia) + TimeSerial(Hora,Minuto,Segundo) ' Ajusta Path nomePath = Dir1.Path If Len(nomePath) > 3 Then nomePath = nomePath & "\" End If ' Define arquivo, data e hora: File1 Seleo mltipla (3) sReadOnly = "" For i = 0 To File1.ListCount - 1 If File1.Selected(i) Then sArquivo = nomePath & File1.List(i) If GetAttr(sArquivo) And vbReadOnly Then ' Lista de arquivos ready-only = no alterados sReadOnly = sReadOnly & File1.List(i) & vbCrLf End If x = AlterarDataHora(sArquivo, DataeHora) End If Next i ' Atualiza lista de arquivos cmdAtualizar_Click ' Desliga ampulheta Screen.MousePointer = vbDefault

115

' Exibe mensagem ao usurio s = "Alteraes realizadas com xito." If sReadOnly <> "" Then s = s & vbCrLf & vbCrLf s = s & "Ateno: os arquivos abaixo so do tipo " s = s & vbCrLf & "somente leitura e no foram " s = s & "alterados:" & vbCrLf & vbCrLf s = s & sReadOnly End If MsgBox s, vbInformation, Tit cmdAlterar_Click_Fim: Exit Sub cmdAlterar_Click_Err: MsgBox Error$(Err) Resume cmdAlterar_Click_Fim End Sub Private Sub cmdAtualizar_Click() ' Fora renovao da lista de arquivos On Error GoTo cmdAtualizar_Click_Err Dir1.Refresh File1.Refresh If File1.ListCount > 0 Then File1.SetFocus File1.Selected(0) = True End If cmdAtualizar_Click_Fim: Exit Sub cmdAtualizar_Click_Err: MsgBox Error$(Err) Resume cmdAtualizar_Click_Fim End Sub Private Sub cmdFechar_Click() End End Sub Private Sub Dir1_Change() ' Atualiza lista de arquivos On Error GoTo Dir1_Change_Err File1.Path = Dir1.Path blnDrvDir = True DefineArquivo Dir1_Change_Fim: Exit Sub Dir1_Change_Err: MsgBox Error$(Err) Resume Dir1_Change_Fim End Sub Private Sub Drive1_Change() On Error GoTo DRChange_Err Err = False Dim m$ ' Atualiza diretrio Dir1.Path = Drive1.Drive

116
InfoDisco blnDrvDir = True DefineArquivo DRChange_Fim: Exit Sub DRChange_Err: ' Erros e avisos If (Err = 71) Or (Err = 68) Then Beep '71: sem disco; 68: disco inexiste m$ = "No h disco no drive " & UCase$(Drive1.Drive) MsgBox m$, vbCritical, Tit ' Volta ao drive anterior ao erro Drive1.Drive = Dir1.Path Else m$ = "Erro nmero" & Str$(Err) & ", no previsto no programa: " & Error$ MsgBox m$, vbCritical, Tit End If Resume End Sub Private Sub File1_Click() ' Define arquivo ativo ' quando o usurio clica DefineArquivo End Sub Private Sub Form_Load() ' Fora um drive/dir inicial Drive1.Drive = "c:\" ' blnDrvDir avisa que o chamado de DefineArquivo ' interno. Desse modo, o arquivo 0 da lista ' selecionado, se houver. Evita que quando o ' usurio clique num arquivo, a seleo do ' arquivo 0 tambm seja feita, desselecionando ' o arquivo apontado pelo usurio. blnDrvDir = True ' Mostra atributos do arquivo 0 (se houver). DefineArquivo ' Disco InfoDisco ' Defaults: data atual, 12:00:00 Text1 = Format(Date, "dd/mm/yyyy") VScroll1.Value = 12 End Sub Private Sub DefineArquivo() ' Checa se o diretrio contm arquivos ' Seleciona arquivo 0 ' Exibe atributos Dim nomePath As String Dim TemArquivo As Boolean nomePath = Dir1.Path If File1.ListCount > 0 Then 'Tem arquivo If blnDrvDir Then File1.Selected(0) = True

117
blnDrvDir = False End If If Len(nomePath) > 3 Then Label2(8) = " " & nomePath & "\" & File1.Filename Else Label2(8) = " " & nomePath & File1.Filename End If arqAtual = Trim$(Label2(8)) TemArquivo = True Else 'No tem arquivo Label2(8) = "" TemArquivo = False End If Call InfoAtributos(TemArquivo) End Sub Private Sub Label2_Click(Index As Integer) ' Exibe mensagem que esclarece contedo ' de alguns campos de informao Dim m$ If Index = 4 Then ' Ajuda/atributos m$ = "Atributos de arquivos:" & vbCrLf m$ = m$ & " A archive (arquivo)" & vbCrLf m$ = m$ & " H hidden (oculto)" & vbCrLf m$ = m$ & " R read-only (somente leitura)" & vbCrLf m$ = m$ & " S system (sistema)" MsgBox m$, vbOKOnly, Tit ElseIf Index = 2 Or Index = 3 Or Index = 5 Then m$ = "Valor em bytes." & vbCrLf MsgBox m$, vbOKOnly, Tit Else End If End Sub Private Sub Text1_GotFocus() ' Seleciona o texto Text1.SelStart = 0 Text1.SelLength = Len(Text1.Text) End Sub Private Sub Text1_KeyPress(KeyAscii As Integer) ' S aceita nmeros (48-56) ou / (47) If (KeyAscii < 47 Or KeyAscii > 56) And KeyAscii <> 8 Then KeyAscii = 0 End Sub Private Sub InfoAtributos(blnTemArquivo As Boolean) On Error GoTo InfoAt_Err Dim i As Integer If blnTemArquivo Then ' Se tem arquivo, mostra ' Atributos Label2(4) = "" Label2(4) = LeAtributos() ' Tamanho, data, hora If blnTemArquivo Then Label2(5) = Format$(FileLen(arqAtual), "##,##0 ") Call LeDataHora End If

118
Else ' Arquivo no existe, limpa labels For i = 4 To 7 Label2(i) = "" Next End If InfoAt_Fim: Exit Sub InfoAt_Err: MsgBox Error$(Err) Resume InfoAt_Fim End Sub Private Sub LeDataHora() ' L e exibe data e hora do arquivo On Error GoTo LeDataHora_Err Dim vDataHora As Variant Dim sDataHora As String Dim iLen As Integer Dim sData As String, sHora As String ' 1. Garante data no formato dd/mm/yyyy ' 2. Hora 00:00:00 retorna nulo; corrige vDataHora = FileDateTime(arqAtual) sDataHora = CStr(vDataHora) iLen = Len(sDataHora) Select Case iLen Case 8 'dd/mm/yy sData = Format$(sDataHora, "dd/mm/yyyy ") sHora = "00:00:00 " Case 10 'dd/mm/yyyy sData = sDataHora & " " sHora = "00:00:00 " Case 17 'dd/mm/yy hh:mm:ss sData = Format$(Left$(sDataHora, 8), "dd/mm/yyyy ") sHora = Right$(sDataHora, 8) & " " Case 19 'dd/mm/yyyy hh:mm:ss sData = Left$(sDataHora, 10) & " " sHora = Right$(sDataHora, 8) & " " Case Else sData = "" sHora = "" End Select Label2(6) = sData Label2(7) = sHora LeDataHora_Fim: Exit Sub LeDataHora_Err: MsgBox Error$(Err) Resume LeDataHora_Fim End Sub Private Function LeAtributos() As String ' Fornece lista de atributos do arquivo On Error GoTo LeAttr_Err Dim atribs As String ' Limpa os atributos

119
atribs = "" ' L e mostra atributos If GetAttr(arqAtual) And If GetAttr(arqAtual) And If GetAttr(arqAtual) And If GetAttr(arqAtual) And If GetAttr(arqAtual) And If GetAttr(arqAtual) And If GetAttr(arqAtual) And If GetAttr(arqAtual) And atribs = atribs & " " LeAtributos = atribs LeAttr_Fim: Exit Function LeAttr_Err: LeAtributos = "" MsgBox Error$(Err) Resume LeAttr_Fim End Function Private Sub InfoDisco() ' Obtm e mostra informaes sobre o disco On Error GoTo InfoDisco_Err Label2(0) = "" Label2(0) = Dir$(Left$(arqAtual, 2), vbVolume) & " " LeTipoDeDrive TamanhoDoDrive InfoDisco_Fim: Exit Sub InfoDisco_Err: MsgBox Error$(Err) Resume InfoDisco_Fim End Sub Public Sub TamanhoDoDrive() ' Obtm tamanho do drive On Error GoTo TamDrive_Err Dim SectorsPerCluster&, BytesPerSector& Dim NumberOfFreeClusters&, TotalNumberOfClusters& Dim BytesFree&, BytesTotal&, PercentFree& Dim dl&, s$, spaceloc% Dim FreeBytes&, TotalBytes& s$ = Drive1.Drive ' Se h um espao, elimina volume label spaceloc = InStr(s$, " ") If spaceloc > 0 Then s$ = Left$(s$, spaceloc - 1) End If If Right$(s$, 1) <> "\" Then s$ = s$ & "\" dl& = GetDiskFreeSpace(s$, SectorsPerCluster, BytesPerSector, _ NumberOfFreeClusters, TotalNumberOfClusters) TotalBytes = TotalNumberOfClusters * SectorsPerCluster * BytesPerSector Label2(2) = Format(TotalBytes, "#,0 ") FreeBytes = NumberOfFreeClusters * SectorsPerCluster * BytesPerSector Label2(3) = Format(FreeBytes, "#,0 ") vbNormal Then atribs = atribs & "N" vbAlias Then atribs = atribs & "L" vbArchive Then atribs = atribs & "A" vbDirectory Then atribs = atribs & "D" vbHidden Then atribs = atribs & "H" vbReadOnly Then atribs = atribs & "R" vbSystem Then atribs = atribs & "S" vbVolume Then atribs = atribs & "V"

120

TamDrive_Fim: Exit Sub TamDrive_Err: MsgBox Error$(Err) Resume TamDrive_Fim End Sub Private Sub LeTipoDeDrive() ' Obtm o tipo de drive On Error GoTo LeTipoDeDrive_Err Const Const Const Const Const Const Const DRIVE_UNKNOWN = 0 DRIVE_NO_ROOT_DIR = 1 DRIVE_REMOVABLE = 2 DRIVE_FIXED = 3 DRIVE_REMOTE = 4 DRIVE_CDROM = 5 DRIVE_RAMDISK = 6

Dim tipo As String Dim nDrive As String Dim drvType As Long ' O drive para a funo deve ser "c:\" nDrive = Drive1.Drive If Len(nDrive) > 2 Then nDrive = Left$(nDrive, 2) End If nDrive = nDrive & "\" ' Chama a funo da API e traduz resultado drvType = GetDriveType(nDrive) Select Case drvType Case DRIVE_UNKNOWN: tipo = "Indeterminado " Case DRIVE_NO_ROOT_DIR: tipo = "No reconhecido " Case DRIVE_REMOVABLE: tipo = "Removvel " Case DRIVE_FIXED: tipo = "Fixo " Case DRIVE_REMOTE: tipo = "Rede " Case DRIVE_CDROM: tipo = "CD-ROM " Case DRIVE_RAMDISK: tipo = "RAM Disk " End Select Label2(1) = tipo LeTipoDeDrive_Fim: Exit Sub LeTipoDeDrive_Err: MsgBox Error$(Err) Resume LeTipoDeDrive_Fim End Sub Function AlterarDataHora(Filename As String, TimeStamp As Variant) As Integer On Error GoTo AlterarDataHora_Err Dim x As Long Dim Handle As Long Dim System_Time As SYSTEMTIME Dim File_Time As FILETIME Dim Local_Time As FILETIME 'Define a estrutura System_Time System_Time.wYear = Year(TimeStamp)

121
System_Time.wMonth = Month(TimeStamp) System_Time.wDay = Day(TimeStamp) System_Time.wDayOfWeek = Weekday(TimeStamp) - 1 System_Time.wHour = Hour(TimeStamp) System_Time.wMinute = Minute(TimeStamp) System_Time.wSecond = Second(TimeStamp) System_Time.wMilliseconds = 0 ' Converte system_time para file_time x = SystemTimeToFileTime(System_Time, Local_Time) ' Converte local_file_time para file_time (UTC) x = LocalFileTimeToFileTime(Local_Time, File_Time) ' Abre o arquivo para capturar o handle dele Handle = CreateFile(Filename, GENERIC_WRITE, FILE_SHARE_READ _ Or FILE_SHARE_WRITE, ByVal 0&, OPEN_EXISTING, 0, 0) ' Modifica data e hora do arquivo x = SetFileTimeWrite(Handle, ByVal 0&, ByVal 0&, File_Time) CloseHandle Handle x = AlterarDataHora AlterarDataHora_Fim: Exit Function AlterarDataHora_Err: MsgBox Error$(Err) Resume AlterarDataHora_Fim End Function Private Sub VScroll1_Change() labHora = Format$(VScroll1.Value, "0#") End Sub Private Sub VScroll2_Change() labMinuto = Format$(VScroll2.Value, "0#") End Sub Private Sub VScroll3_Change() labSegundo = Format$(VScroll3.Value, "0#") End Sub

Hard Disk
Saber o Nmero Serial do HD
'Num mdulo: Private Declare Function GetVolumeInformation Lib _ "kernel32" Alias "GetVolumeInformationA" _ (ByVal lpRootPathName As String, ByVal _ lpVolumeNameBuffer As String, ByVal _ nVolumeNameSize As Long, _ lpVolumeSerialNumber As Long, _ lpMaximumComponentLength As Long, _ lpFileSystemFlags As Long, ByVal _ lpFileSystemNameBuffer As String, ByVal _ nFileSystemNameSize As Long) As Long

122
Public Function DriveSerial(ByVal Drive As _ String) As Long 'Valor que retornar o serial do HD Dim RetVal As Long Dim Dim Dim Dim HDNameBuffer As String * 256 'Nome do HD FSBuffer As String * 256 'FS do HD a As Long 'auxiliar b As Long 'auxiliar

Call GetVolumeInformation(Drive, HDNameBuffer, _ 256, RetVal, a, b, FSBuffer, 256) DriveSerial = RetVal End Function 'P/ usar (no evento que voc quizer): Dim lNSerial As Long lNSerial = DriveSerial("C:\") MsgBox "O nmero seirial do HD : " & lNSerial

Impressoras
Imprimindo Direto para a Impressora
Para imprimir direto para a impressora (em modo draft - ideal para emisso de Notas Fiscais e Boletos), voce deve abrir a impressora com o comando Open e utilizar o Print para realizar a impresso: Open "Lpt1" For Output As #1 Usando o Print direto na impressora, voce poder enviar os caracteres especias para imprimir condensado ou mudar o passo da impressora. Exemplo: Print Print Print Print #1, #1, #1, #1, Chr(27) & "0" Chr(15) Chr(27) & "E" "" ' ' ' ' Muda o passo p/ 8 LPP Condensado Negrito Salta uma linha

Bom, existem outros comandos para cada impressora. Assim que eu conseguir algo, coloco aqui!!!

Selecionando a impressora que ser usada na impresso


'Num mdulo Public Function SelectPrinter(byVal Nome as String) As Boolean Dim X as Printer For each X in Printers If Ucase(Mid(X.DeviceName,1,8))=UCase(Mid(Nome,1,8)) then Set Printer=X SelectPrinter = True Exit For End If Next SelectPrinter = False End Function

123
'P/ chamar: Dim RET As Boolean RET = SelectPrinter("Epson LX-300") If RET = True Then 'A impressora foi encontrada e selecionada. Else 'A impressora NO foi encontrada. End If A funo definir esta impressora ("Epson LX-300", como no exemplo) como padro para a impresso a ser realizada.

ATENO!!!! Para que essa funo funcione, voc necessitar ter o Service Pack 3 do Visual Basic instalado em sua mquina para corrigir um bug do VB.

Monitores
Obter a resoluo de tela
Private Sub Obtem() Dim xTwips%, yTwips%, xPixels#, YPixels# xTwips = Screen.TwipsPerPixelX yTwips = Screen.TwipsPerPixelY YPixels = Screen.Height / yTwips xPixels = Screen.Width / xTwips Debug.print "A Resoluo : " & Str$(xPixels) + _ " por " + Str$(YPixels) End Sub

Resoluo do Monitor
H uma forma simples de se obter a resoluo de um monitor de vdeo usando uma API. 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 conforme queira End If End Sub

Mouse
Capturar a Posio do Mouse
Para saber se o mouse est sobre um objeto ou no, podemos usar de duas formas:

124 USANDO AS APIs GetCursorPos E WindowFromPoint


'Use um Timer e proceda da seguinte forma: 'No Declarations Private Declare Function GetCursorPos Lib "user32" _ (lpPoint As POINTAPI) As Long Private Declare Function WindowFromPoint Lib _ "user32" (ByVal xPoint As Long, ByVal _ yPoint As Long) As Long Private Type POINTAPI X As Long Y As Long End Type Private Controle_MouseMove(...) Timer1.Enabled = True 'O mouse est sobre o controle End Sub Private Sub Timer1_Timer() Dim P as POINT If GetCursorPos(P) Then If WindowFromPoint(P.X, P.Y) <> Controle.hWnd then Timer1.Enabled = False 'O mouse NO est mais sobre o controle End If End If End Sub

USANDO AS APIs SetCapture E ReleaseCapture


Verificando se o cursor do mouse est ou no sobre o Form
'Coloque num form um CommandButton e dois Labels. 'No Declarations Private Declare Function SetCapture Lib "user32" _ Alias "SetCapture" (ByVal hwnd As Long) _ As Long Private Declare Function ReleaseCapture Lib _ "user32" Alias "ReleaseCapture" () As Long Private Sub Form_Load() SetCapture Me.Hwnd End Sub Private Sub Command1_Click() ReleaseCapture End Sub Private Sub Form_MouseMove(Button As Integer, Shift _ As Integer, X As Single, Y As Single) Label1.Caption = X Label2.Caption = Y End Sub

125
Quando voc executar, perceber que, mesmo que o mouse no esteja sobre o Form, os Labels sero atualizados com as posies X e Y do mouse quando voc o mover. Quando voc clicar no CommandButton ele ir parar de detectar o mouse quando ele estiver fora do Form (o ReleaseCapture "desliga" o SetCapture).

Verificando se o cursor do mouse est ou no sobre um controle


'Coloque num form um CommandButton, dois Labels e 'um PictureBox. 'No Declarations Private Declare Function SetCapture Lib "user32" _ Alias "SetCapture" (ByVal hwnd As Long) _ As Long Private Declare Function ReleaseCapture Lib _ "user32" Alias "ReleaseCapture" () As Long Private Sub Form_Load() SetCapture Picture1.Hwnd End Sub Private Sub Command1_Click() 'Para de detectar o mouse no form todo. ReleaseCapture End Sub Private Sub Picture1_MouseMove(Button As Integer, Shift _ As Integer, X As Single, Y As Single) If X > -1 And X < Picture1.Width And Y > -1 And Y < _ Picture1.Height Then Picture1.BackColor = vbRed Else Picture1.BackColor = vbBlack EndIf End Sub Quando voc executar, perceber que, quando o mouse estiver sobre o PictureBox ele ficar vermelho e quando no estiver ficar preto. Quando voc clicar no CommandButton ele ir parar de detectar o mouse quando ele estiver fora do PictureBox (o ReleaseCapture "desliga" o SetCapture). Ento, ele no ficar mais preto, pois o VB no detectar mais quando o mouse "sair" do PictureBox...

Como limitar a rea de movimento do mouse


Digamos que, por um motivo qualquer, voc precise "limitar" a rea de movimentao do mouse. Para isso use a seguinte funo: 'Num mdulo: 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

126
Public Function LimitaArea(X1 As Integer, Y1 As _ Integer, X2 As Integer, _ Y2 As Integer) As Long Dim RC As RECT RC.Left = X1 RC.Top = Y1 RC.Right = X2 RC.Bottom = Y2 ClipCursor RC End Function 'No evento Form_Load, chame a funo passando os 'pontos aos quais o mouse ficar limitado: Private Sub Form_Load() LimitaArea 50,100, 300,200 'POR EXEMPLO End Sub 'No evento Form_Unload, volte ao normal da seguinte 'forma: Private Sub Form_Unload(Cancel As Integer) 'Volta ao estado Normal LimitaMouse 0, 0, Screen.Width / Screen.TwipsPerPixelX, _ Screen.Height / Screen.TwipsPerPixelY End Sub 'ATENO!!! Estas cordenadas devem ser passadas em pixeis!!!

Desativamento do mouse
1. Declare a API que oculta/exibe o mouse (no mdulo): Declare Function ShowCursor Lib "user32" Alias _ "ShowCursor" (ByVal bShow as Long) as Long 2. Chame-a no form_load: ShowCursor False 'oculta o mouse 3. No form_unload, re-exiba o mouse: ShowCursor True 4. Crie uma rotina Form_Mouse e Form_KeyDown. Se houver movimento e teclas pressionadas, finalize o programa. Unload Me 'descarrega o form e devolve o mouse End 'garante o fechamento do programa

Inverter os botes do mouse


'No Declarations: Declare Function SwapMouseButton(ByVal bSwap as _ Long) As Long 'Para inverter os botes do mouse: SwapMouseButton(1) 'Para voltar ao normal: SwapMouseButton(0)

127

Mudar a Posio do Mouse via Cdigo (sem Move-lo)


Esse recurso muito til para posicionar o ponteiro sobre botes e outros objetos sem mover o mouse, usando a API SetCursorPos. 'No Declarations: Private Declare Function SetCursorPos Lib _ "user32" (ByVal X As Long, ByVal Y _ As Long) As Long 'P/ colocar o cursor do mouse em qualquer parte 'do vdeo use o comando: SetCursorPos PosioX, PosioY 'Onde PosioX e PosioY so valores inteiros '(Integer) e so as coordenadas da posio em 'Pixel da tela p/ onde o mouse ir. 'Por exemplo: SetCursorPos 200, 250 'Use esta Sub para centralizar o ponteiro do 'mouse sobre um objeto no Form: Sub Posiciona(Controle As Control) Dim SX As Integer, SY As Integer SX = Screen.TwipsPerPixelX SY = Screen.TwipsPerPixelY SetCursorPos Me.Left / SX + Controle.Left / _ SX + (Controle.Width / SX / 2), _ Me.Top / SY + Controle.Top / SY + _ (Controle.Height / SY / 2) + 20 End Sub Obs: A ltima linha da Sub que faz com que o ponteiro do mouse se mova para a nova poisio da tela, conforme o resultado do calculo: Posio do Form no vdeo + Posio do controle no Form + largura do controle /2 Veja que no final existe uma soma (+20) que foi feita para compensar a barra de ttulo que no contada no formulrio. 'P/ testar, coloque dois CommandButton no Form e, 'em seus respectivos eventos, coloque: Private Sub Command1_Click() Posiciona Command2 'Centraliza o ponteiro no Command2 End Sub Private Sub Command2_Click() Posiciona Command1 'Devolve o ponteiro no Command1 End Sub

128

Teclados
Acionar o CAPS LOCK via cdigo
*** 1) Crie Uma Classe, Chame-a de Teclado, Copie o cdigo abaixo e cole na respectiva janela de cdigo: Option Explicit Private Declare Function GetKeyboardState Lib "user32" _ (pbKeyState As Any) As Long Private Declare Function SetKeyboardState Lib "user32" _ (lppbKeyState As Any) As Long Privatr Const KeyCaps = 20 Dim MatrizDoTeclado(128) As Integer Public Property Get CapsLock() As Boolean GetKeyboardState MatrizDoTeclado(0) If MatrizDoTeclado(KeyCaps / 2) Then CapsLock = True Else CapsLock = False End If End Property Public Property Let CapsLock(ATiva As Boolean) GetKeyboardState MatrizDoTeclado(0) 'Em C, True representa 1 e nao -1 If ATiva Then MatrizDoTeclado(KeyCaps / 2) = 1 Else MatrizDoTeclado(KeyCaps / 2) = 0 End If SetKeyboardState MatrizDoTeclado(0) End Property *** 2) Feito ? Agora experimente: a) . Tecle Ctrl+G para trazer a janela Depurar b) . Digite: Set X = New Teclado <Enter> X.CapsLock = True <Enter> '(A luz do Caps Lock Acende) X.CapsLock = False <Enter> '(A luz do Caps Lock Apaga)

129

INTERNET
Acionar o navegador padro em um URL especfico
>> Dica 1 'Na seo de declaraes coloque: 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 Private Const SW_SHOWNORMAL As Long = 1 'Coloque um boto em um form e adicione o cdigo: Private Sub Command1_Click() Dim i As Long i = ShellExecute (hwnd,"open", _ "http://www.silicio.com.br/index.html", _ "", "", SW_SHOWNORMAL) End Sub >> Dica 2 'Clique em Project - References e selecione Microsoft internet Controls e ento experimente o cdigo a seguir: Private Sub Command1_Click() On Error GoTo Err_IE Dim objIE4 As SHDocVw.InternetExplorer Set objIE4 = New SHDocVw.InternetExplorer With objIE4 .Navigate2 "www.silicio.com.br" .Visible = True End With Set objIE4 = Nothing Exit Sub Err_IE: Set objIE4 = Nothing End Sub >> Dica 3 Ou ento experimente este cdigo (NO funca em Win NT): Shell "start.exe http://www.silicio.com.br", vbHide

Acionar uma conexo Dial-Up pelo VB


Use o cdigo a seguir para chamar uma conexo DialUp previamente criada no seu computador.

130
Primeiro crie a rotina ChamarDialUp e depois coloque num evento de sua preferncia a chamada a esta rotina. Private Sub ChamarDialUp(ByVal sConect As String) Dim X As Long X = Shell("C:\Windows\rundll32.exe rnaui.dll,RnaDial " & _ sConect, 1) AppActivate X SendKeys "{enter}" DoEvents End Sub 'No evento que voc desejar: Call ChamarDialUp("Minha Conexo") Substitua "Minha Conexo" pelo nome da conexo que voc deseja ativar. Detalhe: Esta conexo deve existir em seu computador.

Capturar o nome da conexao Dial-Up


GetSettingString(HKEY_CURRENT_USER,"RemoteAccess", _ "Default",vbNullString) Vai lhe retornar o nome da conexao default. Da voc usa... HKEY_CURRENT_USER, "RemoteAccess\Profile\" & _ <nome da Default>, ....

Criar um link para um e-mail


Coloque num Form um TextBox onde o usurio vai digitar o endereo de e-mail. Presumindo-se que este TextBox ter o nome de Text1, texte esse cdigo: >> Dica 1 'Na seo de declaraes coloque: 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 Private Const SW_SHOWNORMAL As Long = 1 'No evento que voc desejar: Call ShellExecute(0&, vbNullString, "mailto:" & _ Text1.Text, vbNullString, vbNullString, _ SW_SHOWNORMAL) >> Dica 2 (NO funciona no Win NT) Shell "start.exe mailto:" & Text1.text, vbHide

131

Dar um Ping
Crie um .BAT, por exemplo, para o Ping, no diretrio do seu pgm e ative-o com um simples: Shell App.Path & "\Ping.Bat " & Nome_do_Arq_de_Destino L no Ping.Bat, Escreva: @echo off Ping >> %1 Aps sua execuo, poders ter o resultado no respectivo arquivo TXT.

Desconectar da Internet Via Cdigo no VB


'Num mdulo: Public Const Public Const Public Const Public Const Public Const RAS_MAXENTRYNAME As Integer = 256 RAS_MAXDEVICETYPE As Integer = 16 RAS_MAXDEVICENAME As Integer = 128 RAS_RASCONNSIZE As Integer = 412 ERROR_SUCCESS As Long = 0&

Public Type RasEntryName dwSize As Long szEntryName(RAS_MAXENTRYNAME) As Byte End Type Public Type RasConn dwSize As Long hRasConn As Long szEntryName(RAS_MAXENTRYNAME) As Byte szDeviceType(RAS_MAXDEVICETYPE) As Byte szDeviceName(RAS_MAXDEVICENAME) As Byte End Type Public Declare Function RasEnumConnections Lib _ "rasapi32.dll" Alias "RasEnumConnectionsA" _ (lpRasConn As Any, lpcb As Long, _ lpcConnections As Long) As Long Public Declare Function RasHangUp Lib _ "rasapi32.dll" Alias "RasHangUpA" _ (ByVal hRasConn As Long) As Long Public gstrISPName As String Public ReturnCode As Long Public Sub HangUp() Dim i As Long Dim lpRasConn(255) As RasConn Dim lpcb As Long Dim lpcConnections As Long Dim hRasConn As Long lpRasConn(0).dwSize = RAS_RASCONNSIZE lpcb = RAS_MAXENTRYNAME * lpRasConn(0).dwSize lpcConnections = 0 ReturnCode = RasEnumConnections(lpRasConn(0), _ lpcb, lpcConnections) If ReturnCode = ERROR_SUCCESS Then For i = 0 To lpcConnections - 1

132
If Trim(ByteToString(lpRasConn(i).szEntryName)) _ = Trim(gstrISPName) Then hRasConn = lpRasConn(i).hRasConn ReturnCode = RasHangUp(ByVal hRasConn) End If Next i End If End Sub Public Function ByteToString(bytString() As _ Byte) As String Dim i As Integer ByteToString = "" i = 0 While bytString(i) = 0& ByteToString = ByteToString & Chr(bytString(i)) i = i + 1 Wend End Function 'P/ usar: Call HangUp

Discar com o modem via API


Public Declare Function tapiRequestMakeCall _ Lib "TAPI32.DLL" (ByVal Dest As String, _ ByVal AppName As String, ByVal _ CalledParty As String, ByVal Comment _ As String) As Long Public Sub PhoneCall(sNumber As String, sName As String) Dim lRetVal As Long lRetVal = tapiRequestMakeCall(sNumber, _ App.Title, sName, "") If lRetVal <> 0 Then 'Erro qualquer ou no conseguiu! End If End Sub Crie um controle com um textbox e uma imagem de um telefone ao lado. Quando o Text tem algo, se o usurio clicar na imagem a funo executada.

Enviar E-mail pelo VB via MAPI


'Coloque este cdigo no evento que voc quizer: Dim objSession As Object Dim objMessage As Object Set objSession = CreateObject("MAPI.SESSION") Set objMessage = objSession.Inbox.Messages.Add objSession.Logon "Your Profile Name", , _ False, False objMessage.Subject = "Assunto do e-mail..." objMessage.Text = "Texto do e-mail..." 'Aqui voc deve colocar o caminho COMPLETO 'do arquivo que ir em anexo: objMessage.Attachments.Add "Anexo", , , _

133
"C:\anexo.XLS" 'Se for mais de um destinatrio, separe 'os endereod de e-mail por virgulas (,) 'ou ponto e virgula (;). objMessage.Recipients.Add _ "Endereos de e-mail do(s) destinatrio(s)" objMessage.Recipients.Resolve objMessage.Send

Exibir um arquivo direto da Internet/Intranet num TextBox


Digamos que voc precise exibir num TextBox um arquivo .TXT que est num servidor da Internet. Parece coisa do "outro mundo", no ? Pois bem, com esta dica voc vai ver que at simples de se fazer isto. Para realizar esta tarefa, coloque num Form dois TextBox, um CommandButton, o componente Microsoft Internet Transfer Control e escreva o cdigo seguir no evento Click do CommandButton: 'Text1 o TextBox onde o arquivo texto ser 'exibido. Por tanto dever ter a propriedade 'MultiLine = True. 'txtURL o TextBox onde o usurio dever 'digitar o endereo do texto na Internet. Private Sub Command1_Click() Dim sTxt As String, bVet() As Byte Dim iNum As Integer On Error GoTo Erro Command1.Enabled = False 'txtURL.Text dever conter o endereo 'do arquivo texto na Internet. Ex.: 'http://www.site.com/texto.txt bVet() = Inet1.OpenURL(txtURL.Text, 1) sTxt = "" For iNum = 0 To UBound(bVet) - 1 sTxt = sTxt + Chr(bVet(iNum)) Next Text1.Text = sTxt Command1.Enabled = True Exit Sub Erro: MsgBox "O documento requerido no foi " & _ "encontrado.", vbCritical End Sub

Salvando uma Pgina HTML


Coloque num Form um Winsock (Winsock1), um CommandButton (cmdDownload), um TextBox (txtSource) e colole nele este cdigo:

134
Private Sub Winsock1.Connect() Dim cCommand as String Dim cPage as String cPage = "http://fybra/index.html" cCommand = "GET " & cPage & " HTTP/1.0" & _ vbCrLf cCommand = cCommand & "Accept: */*" & vbCrLf cCommand = cCommand & "Accept: text/html" & _ vbCrLf cCommand = cCommand & vbCrLf Winsock1.SendData cCommand End Sub Private Sub Winsock1_DataArrival(ByVal _ bytesTotal As Long) Dim cWebData As String Winsock1.GetData cWebData, vbString txtSource.Text = txtSource.Text & webData End Sub Private Sub cmdDownload_Click() 'Winsock1.RemoteHost = "fybra/" Winsock1.RemotePort = 80 Winsock1.Connect End Sub Depois s salvar o contedo de txtSource para um arquivo .HTML...

Transferncia de arquivos via FTP


'Crie o controle no seu forms e um boto de 'comando com o seguinte: '***************************** Dim strURL As String Dim bData() As Byte Dim intFile As Integer strURL = "ftp://aaaaa:zzzzzz@ftp.mercur.com.br" & _ "/home/user/mercur/usuario.txt" intFile = FreeFile() bData() = Inet1.OpenURL(strURL, icByteArray) Open "C:\usuario.txt" For Binary Access Write As #intFile Put #intFile, , bData() Close #intFile '***************************** 'Alm disso, crie no inet1: '(Esse procedimento faz com que o arquivo 'seja copiado integralmente.) '***************************** Private Sub Inet1_StateChanged(ByVal State As Integer) On Error GoTo fim_anormal2 Select Case State Case icError, icDisconnected MsgBox "Erro na comunicao --> " & Err.Description GoTo Fim_a Case icResponseReceived ' 12 Dim vtData As Variant ' Data variable. Dim strData As String: strData = "" Dim bDone As Boolean: bDone = False vtData = Inet1.GetChunk(1024, icString)

135
Do While Not bDone strData = Data & vtData vtData = Inet1.GetChunk(1024, icString) If Len(vtData) = 0 Then bDone = True End If Me.Text1 = Me.Text1 + 1 If Me.Text1 > 100 Then Me.Text1 = 1 End If ProgressBar1.Value = Me.Text1 Dim TempoDePausa, Incio, Fim, TempoTotal TempoDePausa = 1 ' Define a durao. Incio = Timer ' Define a hora inicial. Do While Timer < Incio + TempoDePausa DoEvents ' Submete-se a outros processos. Loop Fim = Timer ' Define a hora final. TempoTotal = Fim - Incio ' Calcula o tempo total. Loop End Select GoTo Fim_a fim_anormal2: Dim a a = MsgBox("Erro de copia! " & Err.Description, vbCritical, Fim_a: End sub

"Erro")

Verificando se o Computador est Conectado Internet


'Num mdulo: Private Private Private Private Const ERROR_SUCCESS = 0& Const APINULL = 0& Const HKEY_LOCAL_MACHINE = &H80000002 ReturnCode As Long

Private Declare Function RegCloseKey Lib _ "advapi32.dll" (ByVal hKey As Long) _ As Long Private Declare Function RegOpenKey Lib _ "advapi32.dll" Alias "RegOpenKeyA" _ (ByVal hKey As Long, ByVal _ lpSubKey As String, phkResult As _ Long) As Long Private Declare Function RegQueryValueEx _ Lib "advapi32.dll" Alias _ "RegQueryValueExA" (ByVal hKey As _ Long, ByVal lpValueName As String, _ ByVal lpReserved As Long, lpType _ As Long, lpData As Any, lpcbData _ As Long) As Long Public Function EstaConectado() As Boolean Dim hKey As Long Dim lpSubKey As String Dim phkResult As Long Dim lpValueName As String Dim lpReserved As Long

136
Dim lpType As Long Dim lpData As Long Dim lpcbData As Long ActiveConnection = False lpSubKey = "System\CurrentControlSet\" & _ "Services\RemoteAccess" ReturnCode = RegOpenKey(HKEY_LOCAL_MACHINE, _ lpSubKey, phkResult) If ReturnCode = ERROR_SUCCESS Then hKey = phkResult lpValueName = "Remote Connection" lpReserved = APINULL lpType = APINULL lpData = APINULL lpcbData = APINULL ReturnCode = RegQueryValueEx(hKey, _ lpValueName, lpReserved, _ lpType, ByVal lpData, lpcbData) lpcbData = Len(lpData) ReturnCode = RegQueryValueEx(hKey, _ lpValueName, lpReserved, _ lpType, lpData, lpcbData) If ReturnCode = ERROR_SUCCESS Then If lpData = 0 Then ActiveConnection = False Else ActiveConnection = True End If End If RegCloseKey (hKey) End If End Function 'P/ chamar a funo, no evento que voc quizer: If EstaConectado = True Then 'Est conectado Else 'NO Est conectado End If

137

MULTIMDIA
Criando um CD Player
Coloque um textBox e cinco botoes no form. Insira um Class module, mude seu nome para CDAudio e codifique: Private Declare Function mciGetErrorString Lib _ "winmm.dll" Alias "mciGetErrorStringA" _ (ByVal dwError As Long, ByVal lpstrBuffer _ As String, ByVal uLength As Long) As Long Private Declare Function mciSendString Lib _ "winmm.dll" Alias "mciSendStringA" _ (ByVal lpstrCommand As String, ByVal _ lpstrReturnString As String, ByVal _ uReturnLength As Long, ByVal _ hwndCallback As Long) As Long Function StartPlay() mciSendString "play cd", 0, 0, 0 End Function Function SetTrack(Track As String) mciSendString "seek cd to " & Str(Track), 0, _ 0, 0 End Function Function StopPlay() mciSendString "stop cd wait", 0, 0, 0 End Function Function PausePlay() mciSendString "pause cd", 0, 0, 0 End Function Function EjectCD() mciSendString "set cd door open", 0, 0, 0 End Function Function CloseCD() mciSendString "set cd door closed", 0, 0, 0 End Function Function UnloadAll() mciSendString "close all", 0, 0, 0 End Function Function SetCDPlayerReady() mciSendString "open cdaudio alias cd wait " & _ shareable", 0, 0, 0 End Function Function SetFormat_tmsf() mciSendString "set cd time format tmsf wait", _ 0, 0, 0 End Function Function SetFormat_milliseconds() mciSendString "set cd time format " & _

138
milliseconds", 0, 0, 0 End Function Function CheckCD() As Integer Dim s As String * 30 mciSendString "status cd media present", s, _ Len(s), 0 CheckCD = CInt(s) End Function Function GetNumTracks() As Integer Dim s As String * 30 mciSendString "status cd number of tracks " & _ wait", s, Len(s), 0 GetNumTracks = CInt(Mid$(s, 1, 2)) End Function Function GetCDLength() As String Dim s As String * 30 mciSendString "status cd length wait", s, _ Len(s), 0 GetCDLength = s End Function Function GetTrackLength(TrackNum As Integer) As _ String Dim s As String * 30 mciSendString "status cd length track " & _ TrackNum, s, Len(s), 0 GetTrackLength = s End Function Sub GetCDPosition(ByRef Track As Integer, ByRef _ Min As Integer, ByRef Sec As Integer) Dim s As String * 30 mciSendString "status cd position", s, Len(s), 0 Track = CInt(Mid$(s, 1, 2)) Min = CInt(Mid$(s, 4, 2)) Sec = CInt(Mid$(s, 7, 2)) End Sub Function CheckIfPlaying() As Integer CheckIfPlaying = 0 Dim s As String * 30 mciSendString "status cd mode", s, Len(s), 0 If Mid$(s, 1, 7) = "playing" Then CheckIfPlaying = 1 End If End Function Function SeekCDtoX(Track As Integer) StopPlay SetTrack Track StartPlay End Function Function ReadyDevice() UnloadAll SetCDPlayerReady SetFormat_tmsf End Function

139

Function FastForward(Spd As Integer) Dim s As String * 40, Ply As Integer SetFormat_milliseconds mciSendString "status cd position wait", s, _ Len(s), 0 Ply = CheckIfPlaying If Ply = 1 Then mciSendString "play cd from " & _ CStr(CLng(s) + Spd), 0, 0, 0 Else mciSendString "seek cd to " & _ CStr(CLng(s) + Spd), 0, 0, 0 End If SetFormat_tmsf End Function Function ReWind(Spd As Integer) Dim s As String * 40, Ply As Integer SetFormat_milliseconds mciSendString "status cd position wait", s, _ Len(s), 0 Ply = CheckIfPlaying If Ply = 1 Then mciSendString "play cd from " & _ CStr(CLng(s) - Spd), 0, 0, 0 Else mciSendString "seek cd to " & _ CStr(CLng(s) - Spd), 0, 0, 0 End If SetFormat_tmsf End Function 'No form coloque: Dim Snd As CDAudio Private Sub Command1_Click() Snd.SeekCDtoX Val(Text1) End Sub Private Sub Command2_Click() Dim s As String s = Snd.GetCDLength MsgBox "Total de minutos do CD: " & s, , _ "CD len" End Sub Private Sub Command3_Click() Snd.CloseCD End Sub Private Sub Command4_Click() Snd.EjectCD End Sub Private Sub Command5_Click() Snd.StopPlay End Sub Private Sub Form_Load() Set Snd = New CDAudio

140
Snd.ReadyDevice End Sub Private Sub Form_Unload(Cancel As Integer) Snd.StopPlay Snd.UnloadAll Set Snd = Nothing End Sub

Criar tela de apresentao no CD-ROM


- Crie um programa VB SEM USAR NENHUMA OCX QUE NO FAA PARTE DO 'PACOTE' PADRO. No inclua nenhum componente na palete, trabalhe com os que aparecem originalmente; - Compile o programa e crie o EXE; - Coloque o EXE no CD e, NO MESMO DIRETRIO, coloque o arquivo MSVBVM50.DLL, que se encontra no diretrio \windows\system (ele instalado junto ao VB). AUTO-RUN Se quiser que o seu programa seja executado automaticamente quando a pessoa inserir o CD no drive (e o sistema estiver configurado para isso, claro), s criar, no diretrio raiz do CD, um arquivo chamado AUTORUN.INF, com o contedo: [Autorun] OPEN=PROGRAM.EXE ICON=CDICON.ICO Onde voc deve substituir PROGRAM.EXE pelo nome do seu executvel (com path completo, mas normalmente esse tipo de arquivo deve ser colocado na raiz do CD) e CDICON.ICO opcional, e indica um arquivo ICO com o cone que voc deseja que aparea no lugar do cone padro para o CD-ROM.

Detectando se o Micro tem Placa de Som


'Num mdulo: Private Declare Function waveOutGetNumDevs Lib _ "winmm.dll" Alias "waveOutGetNumDevs" () _ As Long Public Function HaveSoundCard() As Boolean Dim i As Integer i = waveOutGetNumDevs() If i > 0 Then HaveSoundCard = True Else HaveSoundCard = False End If End Function 'P/ usar: If HaveSoundCard Then MsgBox "Seu micro tem placa de som!", _ vbInformation, "Sound Card Test" Else MsgBox "Seu micro NO tem placa de som!", _ vbInformation, "Sound Card Test" End If

141

Gravando uma Trilha do CD para um Arquivo Wave


Esta funo usa o multimedia control interface (MCI) para controlar o drive de CD. 'Num mdulo: Private Declare Function mciSendString Lib _ "winmm.dll" Alias "mciSendStringA" _ (ByVal lpstrCommand As String, ByVal _ lpstrReturnString As String, ByVal _ uReturnLength As Long, ByVal _ hwndCallback As Long) As Long Public Sub RecordWave(TrackNum As Integer, _ Filename As String) ' Tracknum: Trilha a ser gravada ' Filename: Arquivo Wave a ser gerado On Local Error Resume Next Dim i As Long, RS As String, cb As Long, t# RS = Space$(128) i = mciSendString("stop cdaudio", RS, 128, cb) i = mciSendString("close cdaudio", RS, 128, cb) Kill filename RS = Space$(128) i = mciSendString("status cdaudio position track " & TrackNum, RS, 128, cb) i = mciSendString("open cdaudio", RS, 128, cb) i = mciSendString("set cdaudio time format milliseconds", RS, 128, cb) i = mciSendString("play cdaudio", RS, 128, cb) i = mciSendString("open new type waveaudio alias capture", RS, 128, cb) i = mciSendString("record capture", RS, 128, cb) t# = Timer + 1: Do Until Timer > t#: DoEvents: Loop i = mciSendString("save capture " & filename, RS, 128, cb) i = mciSendString("stop cdaudio", RS, 128, cb) i = mciSendString("close cdaudio", RS, 128, cb) End Sub O mtodo bastante simples. Veja o que ele faz: 1 - Para o CD (caso ele esteja tocando, claro); 2 - Toca a trilha selecionada; 3 - Grava um novo arquivo wave com a informao do CD (obs: isso tambem grava MIDI e sons do microfone, na verdade qualquer coisa que saia pelos alto falantes) 4 - Salva o som Wave; 5 - Para o CD novamente.

Rodando um Vdeo AVI


Esta dica demonstra como tocar um vdeo AVI sem usar o Multimedia (MCI) Control. 'Num mdulo: Public Declare Function mciSendString Lib _ "winmm.dll" Alias "mciSendStringA" _ (ByVal lpstrCommand As String, ByVal _ lpstrReturnString As String, ByVal _ uReturnLength As Long, ByVal _ hwndCallback As Long) As Long

142
'Num Form, adicione dois botes e coloque este 'cdigo: Dim returnstring As String, erg As Long Private Sub Command1_Click() 'Este cdigo abre o vdeo AVI Dim FileName As String FileName As String returnstring = Space(127) 'Arquivo AVI a ser tocado. FileName = "C:\Videos\Sei L\Welcome1.avi" erg = mciSendString("open " & Chr$(34) & _ FileName & Chr$(34) & _ " type avivideo alias video", _ returnstring, 127, 0) erg = mciSendString("set video time format ms", _ returnstring, 127, 0) erg = mciSendString("play video from 0", _ returnstring, 127, 0) End Sub Private Sub Command1_Click() 'Este cdigo fecha o vdeo AVI erg = mciSendString("close video", _ returnstring, 127, 0) End Sub

Tocar Arquivos MIDI


'Num mdulo: Public Declare Function mciExecute Lib "winmm.dll" _ (ByVal lpstrCommand As String) As Long Public Sub TocarMID(File As String, Optional Wait _ As Boolean) If File = "" Then Call mciExecute("close Musica") Else Call mciExecute("open " & File & " type " & _ "sequencer alias Musica") If Wait Then Call mciExecute("play Musica wait") Else Call mciExecute("play Musica") End If End If End Sub 'P/ abrir a msica MIDI (j tocando-o): TocarMID "C:\Musica.MID" 'P/ dar uma pausa: TocarMID "C:\Musica.MID", True 'P/ voltar a tocar a msica MIDI: TocarMID "C:\Musica.MID", False 'P/ fechar a msica: TocarMID ""

143

Tocar Arquivos WAVE


Public Declare Function sndPlaySound Lib "winmm.dll" _ Alias "sndPlaySoundA" (ByVal lpszSoundName As _ String, ByVal uFlags As Long) As Long Public Enum SndPlayFlags SND_SYNC = &H0 SND_ASYNC = &H1 SND_NODEFAULT = &H2 SND_MEMORY = &H4 SND_LOOP = &H8 SND_NOSTOP = &H10 End Enum Public Sub PlaySound(File As String, Optional Flags _ As SndPlayFlags) If File = "" Then Call sndPlaySound(0&, 0) Else Call sndPlaySound(File, Flags) End If End Sub 'P/ tocar PlaySound 'P/ parar PlaySound o som, utilize: "C:\Som.WAV" o som, utilize: ""

P.S.: Quando for tocar um som, voc pode passar alguma opo no parmetro Flags. As opes so: * SND_SYNC => Toca o WAVE sincronizado (default). * SND_ASYNC => Toca o WAVE sem sincronismo. * SND_NODEFAULT => No usa o som padro. * SND_MEMORY => Direciona o IpszSoundName para o lugar de um arquivo na memria. * SND_LOOP => Toca o WAVE em looping. At q voc mande-o parar. * SND_NOSTOP => No para o som que estiver tocando.

144

PROGRAMAO INTELIGENTE
Cuidado com Variveis Tipo Variant!!!
Evite usar as variveis do tipo Variant a todo custo, pois elas consomem MUITO mais memria. Para se ter uma idia, enquanto uma varivel String requisita 1 byte, uma Integer requisita 2bytes, uma Long requisita 4 bytes e uma Double ou Date requisita 8 bytes, uma Variant requisita, no mnimo, 16 bytes + 1 byte por caracter, ou seja, o dobro do maior valor requisitado dos outros tipos. At mesmo um objeto de OLE requisita apenas 4bytes! O uso de uma varivel Variant sacrifica um pouco o desempenho do programa exatamente pela requisio mais acentuada da memria e pelo fato do consumo mnimo da estrutura (16 bytes para variants com nmeros e 22 bytes mais o comprimento da string para variants com strings). Seu uso quase que s aprovado em funoes onde voc no tem como antecipar o tipo de varivel que ir receber... Pode ver que vrias declaraes de APIs uso parmetros Variant. O uso de variants como variveis globais ou estticas deve ser evitado a todo custo e nem deve ser empregada em qualquer tipo de loop (o desperdcio e a queda de desempenho seria multiplicado por cada passagem pela referncia.) O motivo disso tudo que o tipo Variant tem que ter, internamente, todos os mtodos e tratamentos dos outros tipos de dados. Veja que as converses so feitas automaticamente. Tambm tem o detalhe de este tipo de varivel no faz validao de nenhum tipo. Por exemplo, se voc colocar numa varivel Variant uma data e concatenar (somar) uma string ela aceita sem dar NENHUM tipo de erro. A nica vantagem das variveis tipo Variant que elas pode conter valores especiais, como Null, Error e Empty.

Eliminando o If...End If Quando Possvel


'Ao invs de: If sDados = "S" then bVar = True Else bVar = False End If 'Use: Dim bVar As Boolean bVar = (sDados = "S") Outra coisa que alguns programadores usam e TOTALMENTE desnecessrio so verificaes como esta: Dim bVar As Boolean '... 'Comandos '... If bVar = True Then '...

145
'Comandos '... Else '... 'Comandos '... End If Eu digo que desnecessrio, pois voc pode usar SIMPLESMENTE no colocando o " = True". Veja: Dim bVar As Boolean '... 'Comandos '... If bVar Then 'bVar igual a True. Else 'bVar igual a False. End If

Executar com Compilao Completa


Quando voc executa um programa pela IDE do VB, clicando no boto "Start" da ToolBar do VB, precionando F5 ou clicando no menu "Run"/"Start", o compilador verifica seus erros de programao a medida que os comandos vo sendo executados. Com a Compilao Completa, se houver algum erro em qualquer parte de seu programa, ele ser detectado. Para facilitar, voc pode criar na barra de ferramentas do VB um boto com a opo do menu "Run"/"Start With Full Compile". Ele ficar com uma imagem como a do Run, porm com 2 setas. Voc tambm pode simplesmente precionar Ctrl+F5, pois d na mesma...

Faa amplo uso das constantes intrnsecas do VB


Quando for necessrio, procure usar as constantes intrnsecas do VB, como vbNull, vbNullString, vbCrLf. Para MsgBoxes, por exemplo, temos vbInformation + vbYesNo, vbYes. E uma paulada de outras (verifique-as no Object Browser F2). Alm de tornar seu cdigo mais legvel (at pra voc), no estars redundando a declarao do que j existe e est disponvel. J fiz o teste (repitam por favor). Substituam todos os seus "" por vbNullString e outros penduricalhos repetitivos como Chr(10)+Chr(13) por vbCrLf, etc ... e comparem o tamanho final do EXE. Ps: Declare tambm suas prprias constantes (num mdulo .BAS) Public Public Public Public Const Const Const Const vbDbName = "NomeDoDB.MDB" 'O path adiciona depois vbCPFMask = "###,###,###\-##" vbCGCMask = "##,###,###\/####\-##" vbNumViado = 24

146
Public DataVazia As Date 'S use para comparao

Instanciando Objetos Corretamente


Evite fazer declaraes de objetos com "New", pois quando voc faz isso o VB NO est criando uma referencia. Ele s ir instanciar (criar a referencia) quando voc referencia-lo pela 1 vez (usar um mtodo ou alterar uma propriedade deste objeto). O problema disto que a cada vez que voc referenciar este objeto, o VB ir verificar se ele j foi instanciado ou no. Quer dizer, gera uma lentido neste processo... Confuso? Veja: Dim varObj As New Objeto 'O VB no instanciou o objeto. varObj.Propriedade = 7 'Aqui o VB verificou se o objeto j estava instanciado. Como ele 'notou que nao, ele instanciou varObj.Metodo 100 'Aqui o VB tambm verificou se o objeto ja estava instanciado. 'Isto causa lentido! 'E o pior: Set varObj = Nothing 'Descarregou-o da memria If varObj Is Nothing Then Msgbox "Objeto destrudo!" End If Ele NO vai mostrar a mensagem "Objeto destrudo!", pois o objeto no ser totalmente descarregado da memria!!! Para evitar tudo isso, declare apenas como "Objeto". 'Forma correta (recomendada): Dim varObj As Objeto Set varObj = New Objeto No esquea de liberar sua memria aps usar o objeto. P/ isso use Nothing: Set varObj = Nothing

Saber se o Objeto est Vazio


No possvel comparar um objeto (como Form ou outro controle) com IsEmpty para saber se ele possui um valor ou no. Entretando, possvel usar uma estrutura condicional usando o "Is Nothing". Veja: If Not frmMenu Is Nothing Then 'NO Est vazio Else 'EST vazio End If

147

Usando a Immediate Window


Durante um BreakPoint de execuo (Pausa) [CTRL+{Break}], use a Immediate Window para obter informaes sobre suas variveis e o ambiente do VB. P/ faze-la aparecer s prescionar [CTRL+G]. Na janela, experimente: ? Nome_da_sua_varivel (no esquea do escopo) ? Seu_Recordset!Nome_do_Campo ? Err.description

Usando o Auto Completar


O recurso de Auto Completar [CTRL+{Espao}] do VB muito til quando voc quer digirar o MNIMO possvel, ou se tem nomes longos de variveis, por exemplo. Experimente, com as seguintes variveis... Dim NomeDaVariavel As String, OutraVariavel As String ... digitar: nomed + [CTRL+{Espao}] outr + [CTRL+{Espao}]

Usando o DoEvents
Quando seu programa tiver a necessidade de realizar um processamento longo (utilizando loops como Do...Loop, For...Next,), seu programa (ou mesmo seu computador) poder travar. Para evitar isto utilize SEMPRE a funao DoEvents, que permite que o seu programa realize este processamento enquanto o usurio realiza outras tarefas. Alm do que fica uma coisa deselegante o seu programa ficar travando a cada comando que o usurio manda executar. 'Utilize o DoEvents desta maneira: Do 'Entra no Loop DoEvents '<--... Outros comandos ... Loop Outra utilidade do DoEvents em uma tela de Splash, pois esta necessita ficar por cima de toda as outras janelas (e isto conseguido com o uso da API SetWindowPos). O problema que sem o DoEvents ela NO fica por cima das outras MESMO usando essa API.

148

Usando o Object Browser


Tens dvidas sobre que eventos/mtodos/propriedades de determinado objeto j adicionado seu projeto? Use-o. Basta prescionar [F2] que ele aparecer.

Use o With para Atribuir Valores Propriedades de Objetos


Digamos que voc necessite mudar as propriedades de um objeto, um Label por exemplo. Ento, veja: '(01) Ao invz de: Label1.AutoSize = True Label1.Caption = "Bl, bl, bl..." Label1.Enabled = True Label1.Visible = True Label1.Refresh '(02) Use: With Label1 .AutoSize = True .Caption = "Bl, bl, bl..." .Enabled = True .Visible = True .Refresh End With Motivo: No exemplo 01, ele carrega na memria, uma instncia do objeto para cada atribuio, no caso, cria 5 instncias. J na segunda, ele cria APENAS uma instncia, ficando assim, mais rpido.

Verificando Valor da Propriedade de um Objeto Mais Rapdamente


Quando voc cria um objeto (classe, ActiveX Control ou ActiveX DLL), voc tem que criar duas funes para cada propriedade: uma usando "Property Get" e outra usando "Property Let" (ou "Property Set"). A funo que usa "Property Get" chamada quando voc verifica o valor contido na propriedade e a funo "Property Let" chamada quando voc atribui um novo valor a essa propriedade (a funo "Property Set" usada quando esta propriedade aceita um objeto uma imagem, por exemplo - e no um valor). Por este motivo, prefira acessar vrias vezes uma varivel do que uma propriedade. 'Ento, ao invs de usar desta maneira: If txtOpo.Text = "Nada" Then ... Comandos ... ElseIf txtOpo.Text = "Tudo" And Var = "S" Then ... Comandos ... ElseIf txtOpo.Text = "Tudo" And Var = "N" Then ... Comandos ... End If

149
'Use assim: Dim sTexto As String sTexto = txtOpo.Text If sTexto = "Nada" Then ... Comandos ... ElseIf sTexto = "Tudo" And Var = "S" Then ... Comandos ... ElseIf sTexto = "Tudo" And Var = "N" Then ... Comandos ... End If

150

REDES Buscar data e hora do servidor


Para chamar: Data = ServerTime("\\NomedaMaquina") ou Data = ServerTime("NomedaMaquina"). 'Coloque isso em um mdulo. Private Declare Function NetRemoteTOD Lib _ "NETAPI32.DLL" (ByVal server As _ String, buffer As Any) As Long Private Declare Sub CopyMemory Lib "kernel32" _ Alias "RtlMoveMemory" (hpvDest As _ Any, hpvSource As Any, ByVal cbCopy _ As Long) Private Declare Function NetApiBufferFree Lib _ "NETAPI32.DLL" (buffer As Any) As Long Private Type TIME_OF_DAY t_elapsedt As Long t_msecs As Long t_hours As Long t_mins As Long t_secs As Long t_hunds As Long t_timezone As Long t_tinterval As Long t_day As Long t_month As Long t_year As Long t_weekday As Long End Type Public Function ServerTime(ByVal pServerName _ As String) As Variant Dim t As TIME_OF_DAY Dim tPtr As Long Dim Result As Long Dim szServer As String Dim ServDate As Date If Left(pServerName, 2) = "\\" Then szServer = StrConv(pServerName,vbUnicode) Else szServer = StrConv("\\" & pServerName, _ vbUnicode) End If Result = NetRemoteTOD(szServer, tPtr) If Result = 0 Then Call CopyMemory(t, ByVal tPtr, Len(t)) ServDate = DateSerial(70, 1, 1) + _ (t.t_elapsedt / 60 / 60 / 24) ServDate = ServDate - (t.t_timezone / 60 / 24) NetApiBufferFree (tPtr) ServerTime = ServDate Else 'erro End If End Function

151

Devolve o nome do micro na rede


Public Declare Function GetComputerName Lib _ "kernel32" Alias "GetComputerNameA" _ (ByVal lpBuffer As String, nSize As _ Long) As Long Public Function GetComputer() As String Dim Buffer As String Dim Size As Long Dim dl As Long Size = 199 Buffer = String$(200, 0) dl = GetComputerName(Buffer, Size) If dl <> 0 Then GetComputer = Left$(Buffer, Size) Else GetComputer = "" End If End Function 'Vc chamada a funo assim: Dim Var as String Var = GetComputer()

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)

152

Mapeando uma Unidade de Rede


'Num mdulo: Public Declare Function WNetAddConnection Lib _ "mpr.dll" Alias "WNetAddConnectionA" _ (ByVal lpszNetPath As String, ByVal _ lpszPassword As String, ByVal _ lpszLocalName As String) As Long Public Declare Function WNetGetConnection Lib _ "mpr.dll" Alias "WNetGetConnectionA" _ (ByVal lpszLocalName As String, ByVal _ lpszRemoteName As String, cbRemoteName _ As Long) As Long Public Declare Function WNetCancelConnection _ Lib "mpr.dll" Alias _ "WNetCancelConnectionA" (ByVal lpszName As _ String, ByVal bForce As Long) As Long 'No evento desejado: Dim sCaminho As String, sUnidade as String sCaminho = "\\Computador\Caminho" sUnidade = "I:" 'Realiza a conexo WNetAddConnection sCaminho, _ "Se tiver senha, digite aqui", _ sUnidade 'Consulta caminho de uma determinada conexo, 'neste caso, na varivel caminho ser 'armazenado o local do caminho atual referente 'a unidade WNetGetConnection sUnidade, sCaminho, 255) 'Desconecta WNetCancelConnection Unidade, True

Retornar o nome do usurio logado


Public Declare Function GetUserName Lib _ "advapi32.dll" Alias "GetUserNameA" _ (ByVal lpbuffer As String, nSize _ As Long) As Long Public Function sUserID() As String Dim sBuffer As String Dim lSize As Long sBuffer = Space$(255) lSize = Len(sBuffer) GetUserName sBuffer, lSize If lSize > 0 Then sUserID = Left$(sBuffer, lSize - 1) MsgBox sUserID End If End Function

153

VBA
Copiando Textos de Documentos do Word
'No evento desejado: Dim Word As Object Set Word = CreateObject("Word.Application") 'Abre o documento Word.Documents.Open "C:\Meus Documentos\" & _ "NomeDoDocumento.DOC" 'Seleciona o documento inteiro Word.Documents("NomeDoDocumento.DOC").Select 'Joga o contedo da seleo numa caixa de Texto. Text1.Text = Word.Selection.Text Pesquise o VBA, pois utilizando-o possvel selecionar palavras, pargrafos, tabelas, etc. Ou seja, qualquer parte do documento.

Trocar dados com o Excel


Sub Importa(strArquivo As String) 'Nmero do arq Dim lngArquivo As Long 'Dados da 1 coluna Dim strUm As String 'Dados da 2 coluna Dim strDois As String 'Dados da 3 coluna Dim strTres As String 'Usada na substituio do ponto Dim strDecimal As Variant Range("A1").Select lngArquivo = FreeFile Open strArquivo For Input As lngArquivo Do While Not EOF(lngArquivo) Input #lngArquivo, strUm, strDois, strTres ActiveCell.Value = strUm ActiveCell.Offset(0, 1).Activate 'Obtem o ponto strDecimal = InStr(1, strDois, ".") If strDecimal <> 0 Then

154 'Se houver valor de retorno 'Substitui o ponto por vrgula Mid(strDois, strDecimal, 1) = "," 'Converte para moeda ActiveCell.Value = CCur(strDois) Else 'Seno 'No altera a string ActiveCell.Value = strDois End If ActiveCell.Offset(0, 1).Activate ActiveCell.Value = strTres If ActiveCell.Column = 3 Then 'Se coluna atual = 3(C) 'Muda de linha ActiveCell.Offset(rowOffset:=1, _ columnOffset:=-2).Activat End If Loop Close lngArquivo ThisWorkbook.SaveAs "c:\SeuArquivo.xls" End Sub Voc pode usar a rotina dentro de um loop passando como parmetro o nome do arquivo texto a ser aberto.

155

VALIDAES
Funo para Verificar se um Ano Bissexto ou No
'Num mdulo: Public Function IsBissexto(Year As Integer) _ As Boolean IsBissexto = (Month(DateSerial(Year, 2, _ 29)) = 2) End Function 'P/ usar: Private Sub Command1_Click() Dim bRet As Boolean bRet = IsBissexto(txtAno) If bRet Then MsgBox "O Ano Bissexto!!!" Else MsgBox "O Ano NO Bissexto!!!" End If End Sub

Validar Carto de Crdito


Function CheckCard(CCNumber As String) As Boolean Dim Counter As Integer, TmpInt As Integer Dim Answer As Integer Counter = 1 TmpInt = 0 While Counter <= Len(CCNumber) If IsEven(Len(CCNumber)) Then TmpInt = Val(Mid$(CCNumber, Counter, 1)) If Not IsEven(Counter) Then TmpInt = TmpInt * 2 If TmpInt > 9 Then TmpInt = TmpInt - 9 End If Answer = Answer + TmpInt 'Debug.Print Counter, TmpInt, Answer Counter = Counter + 1 Else TmpInt = Val(Mid$(CCNumber, Counter, 1)) If IsEven(Counter) Then TmpInt = TmpInt * 2 If TmpInt > 9 Then TmpInt = TmpInt - 9 End If Answer = Answer + TmpInt 'Debug.Print Counter, TmpInt, Answer Counter = Counter + 1 End If Wend Answer = Answer Mod 10 If Answer = 0 Then CheckCard = True End Function

156

Validar CGC
'Num mdulo: Public Function FU_ValidaCGC(cgc As String) As Boolean Dim retorno, a, j, i, d1, d2 If Len(cgc) = 8 And Val(cgc) > 0 Then a = 0 j = 0 d1 = 0 For i = 1 To 7 a = Val(Mid(cgc, i, 1)) If (i Mod 2) <> 0 Then a = a * 2 End If If a > 9 Then j = j + Int(a / 10) + (a Mod 10) Else j = j + a End If Next i d1 = IIf((j Mod 10) <> 0, 10 - (j Mod 10), 0) If d1 = Val(Mid(cgc, 8, 1)) Then FU_ValidaCGC = True Else FU_ValidaCGC = False End If Else If Len(cgc) = 14 And Val(cgc) > 0 Then a = 0 i = 0 d1 = 0 d2 = 0 j = 5 For i = 1 To 12 Step 1 a = a + (Val(Mid(cgc, i, 1)) * j) j = IIf(j > 2, j - 1, 9) Next i a = a Mod 11 d1 = IIf(a > 1, 11 - a, 0) a = 0 i = 0 j = 6 For i = 1 To 13 Step 1 a = a + (Val(Mid(cgc, i, 1)) * j) j = IIf(j > 2, j - 1, 9) Next i a = a Mod 11 d2 = IIf(a > 1, 11 - a, 0) If (d1 = Val(Mid(cgc, 13, 1)) And d2 = Val(Mid(cgc, _ 14, 1))) Then FU_ValidaCGC = True Else FU_ValidaCGC = False End If Else FU_ValidaCGC = False End If End If End Function 'P/ chamar:

157
Dim RET as Boolean RET = FU_ValidaCGC "15.545.974/5489-28" ' APENAS um Exemplo! If RET = True Then 'O CGC vlido Else 'O CGC NO vlido End If

Validar CPF
'Num mdulo: Public Function FU_ValidaCPF(CPF As String) As Boolean Dim soma As Integer Dim Resto As Integer Dim i As Integer 'Valida argumento If Len(CPF) <> 11 Then FU_ValidaCPF = False Exit Function End If soma = 0 For i = 1 To 9 soma = soma + Val(Mid$(CPF, i, 1)) * (11 - i) Next i Resto = 11 - (soma - (Int(soma / 11) * 11)) If Resto = 10 Or Resto = 11 Then Resto = 0 If Resto <> Val(Mid$(CPF, 10, 1)) Then FU_ValidaCPF = False Exit Function End If soma = 0 For i = 1 To 10 soma = soma + Val(Mid$(CPF, i, 1)) * (12 - i) Next i Resto = 11 - (soma - (Int(soma / 11) * 11)) If Resto = 10 Or Resto = 11 Then Resto = 0 If Resto <> Val(Mid$(CPF, 11, 1)) Then FU_ValidaCPF = False Exit Function End If FU_ValidaCPF = True End Function 'P/ chamar: Dim RET as Boolean RET = FU_ValidaCPF "518.284.565-28" ' APENAS um Exemplo! If RET = True Then 'O CGC vlido Else 'O CGC NO vlido End If

Validar Datas
'Num mdulo: Public Function ValidaData(ByVal sData _ As String, Optional ByVal sFormato _ As String) As Boolean

158
Dim Dim Dim Dim Dim Dim Dim Dia As Integer, Dia_Pos As Integer Mes As Integer, Mes_Pos As Integer Ano As Integer, Ano_Pos As Integer DDOk As Integer, MMOk As Integer YYOk As Integer, i As Integer m As Integer, Temp As String sBst As Boolean

If IsMissing(sFormato) Then sFormato = "DD/MM/YYYY" 'OU ento, voc pode pegar o formato 'que estiver configurado no Windows. End If Temp = Replace(sData, "-", "/") sData = Temp Temp = Replace(sFormato, "-", "/") sFormato = Temp Temp = "" DDOk = 0 MMOk = 0 YYOk = 0 For i = 1 To Len(sFormato) If UCase(Mid(sFormato, i, 1)) = "D" Then If DDOk > 2 Then ValidaData = False Exit Function Else DDOk = DDOk + 1 If Dia_Pos = 0 Then Dia_Pos = Mes_Pos + Ano_Pos + 1 End If End If ElseIf UCase(Mid(sFormato, i, 1)) = "M" Then If MMOk > 2 Then ValidaData = False Exit Function Else MMOk = MMOk + 1 If Mes_Pos = 0 Then Mes_Pos = Dia_Pos + Ano_Pos + 1 End If End If ElseIf UCase(Mid(sFormato, i, 1)) = "Y" Then If YYOk > 4 Then ValidaData = False Exit Function Else YYOk = YYOk + 1 If Ano_Pos = 0 Then Ano_Pos = Dia_Pos + Mes_Pos + 1 End If End If Else Select Case UCase(Mid(sFormato, i, 1)) Case "D", "M", "Y", "/" Case Else ValidaData = False Exit Function

159
End Select End If Next i If DDOk = 0 Or MMOk = 0 Then ValidaData = False Exit Function End If If YYOk = 0 Or YYOk > 4 Then ValidaData = False Exit Function End If If Not IsDate(sData) Then ValidaData = False Exit Function End If m = 0 For i = 1 To Len(sData) If Mid(sData, i, 1) = "/" Or _ i = Len(sData) Then If i = Len(sData) Then Temp = Temp & Mid(sData, i, 1) End If m = m + 1 If m = 3 Then m = 4 If Dia_Pos = m Then Dia = Temp ElseIf Mes_Pos = m Then Mes = Temp ElseIf Ano_Pos = m Then Ano = Temp End If Temp = "" Else Temp = Temp & Mid(sData, i, 1) End If Next i Select Case Mes Case 1, 3, 5, 7, 8, 10, 12 If Dia < 1 Or Dia > 31 Then ValidaData = False Exit Function End If Case 4, 6, 9, 11 If Dia < 1 Or Dia > 31 Then ValidaData = False Exit Function End If Case 2 If Dia < 1 Or Dia > 29 Then ValidaData = False Exit Function ElseIf Dia = 29 Then sBst = False If Ano = 0 Then sBst = True ElseIf Ano Mod 4 = 0 Then

160
sBst = True If Ano Mod 100 = 0 Then sBst = False If Ano Mod 400 = 0 Then sBst = True End If End If Else sBst = False End If If sBst = False Then ValidaData = False Exit Function End If End If Case Else ValidaData = False Exit Function End Select ValidaData = True End Function 'P/ chamar, no evento desejado: VarivelBoolean = ValidaData(Data, Formato) 'Exemplo: Dim bRESP As Boolean bRESP = ValidaData("31/03/2000", "M/D/Y") If bRESP Then MsgBox "A data vlida!!!" Else MsgBox "A data NO vlida!!!" End If 'Ele exibir "A data vlida!!!"

Validar E-Mail
'Num mdulo: Public Function ValidEMail(sEMail As String) As Boolean Dim nCharacter As Integer Dim Count As Integer Dim sLetra As String 'Verifica se o e-mail tem no MNIMO 5 'caracteres (a@b.c) If Len(sEMail) < 5 Then 'O e-mail invlido, pois tem menos 'de 5 caracteres ValidEMail = False MsgBox "O e-mail digitado tem menos de 5 " & _ "caracterec!!!" Exit Function End If 'Verificar a existencia de arrobas (@) no e-mail For nCharacter = 1 To Len(sEMail) If Mid(sEMail, nCharacter, 1) = "@" Then 'OPA!!! Achou uma arroba!!! 'Soma 1 ao contador Count = Count + 1 End If

161
Next 'Verifica o nmero de arrobas. 'TEM que ter """UMA""" arroba If Count <> 1 Then 'O e-mail invlido, pois tem 0 ou 'mais de 1 arroba ValidEMail = False MsgBox "O n de arrobas (@) do e-mail " & _ "invlido!!!" Exit Function Else 'O e-mail tem 1 arroba. 'Verificar a posio da arroba If InStr(sEMail, "@") = 1 Then 'O e-mail invlido, pois comea 'com uma @ ValidEMail = False MsgBox "O e-mail foi iniciado com uma " & _ "arroba (@)!!!" Exit Function ElseIf InStr(sEMail, "@") = Len(sEMail) Then 'O e-mail invlido, pois termina 'com uma @ ValidEMail = False MsgBox "O e-mail termina com uma arroba (@)!!!" Exit Function End If End If nCharacter = 0 Count = 0 'Verificar a existencia de pontos (.) no e-mail For nCharacter = 1 To Len(sEMail) If Mid(sEMail, nCharacter, 1) = "." Then 'OPA!!! Achou um ponto!!! 'Soma 1 ao contador Count = Count + 1 End If Next 'Verifica o nmero de pontos. 'TEM que ter PELO MENOS UM ponto. If Count < 1 Then 'O e-mail invlido, pois no tem pontos. ValidEMail = False MsgBox "O e-mail invlido, pois no contm " & _ "pontos (.)!!!" Exit Function Else 'O e-mail tem pelo menos 1 ponto. 'Verificar a posio do ponto: If InStr(sEMail, ".") = 1 Then 'O e-mail invlido, pois comea 'com um ponto ValidEMail = False MsgBox "O e-mail foi iniciado com um ponto (.)!!!" Exit Function ElseIf InStr(sEMail, ".") = Len(sEMail) Then 'O e-mail invlido, pois termina 'com um ponto. ValidEMail = False MsgBox "O e-mail termina com um ponto (.)!!!" Exit Function

162
ElseIf InStr(InStr(sEMail,"@"),sEMail,".") = 0 Then 'O e-mail invlido, pois termina 'com um ponto. ValidEMail = False MsgBox "O e-mail no tem nenhum ponto (.) aps " & _ "a arroba (@)!!!" Exit Function End If End If nCharacter = 0 Count = 0 'Verifica se o e-mail no tem pontos 'consecutivos (..) aps a arroba (@). If InStr(sEMail, "..") > InStr(sEMail, "@") Then 'O e-mail invlido, tem pontos 'consecutivos aps o @. ValidEMail = False MsgBox "O e-mail contm pontos consecutivos " & _ "(..) aps o arroba (@)!!!" Exit Function End If 'Verifica se o e-mail tem caracteres 'invlidos For nCharacter = 1 To Len(sEMail) sLetra = Mid$(sEMail, nCharacter, 1) If Not (LCase(sLetra) Like "[a-z]" Or sLetra = _ "@" Or sLetra = "." Or sLetra = "-" Or _ sLetra = "_" Or IsNumeric(sLetra)) Then 'O e-mail invlido, pois tem 'caracteres invlidos ValidEMail = False MsgBox "Foi digitado um caracter invlido " & _ "no e-mail!!!" Exit Function End If Next nCharacter = 0 'Bem, se a verificao chegou at aqui ' porque o e-mail vlido, ento... ValidEMail = True End Function 'P/ chamar a funo: Dim VALID As Boolean VALID = ValidEMail(Text1.Text) If VALID = True Then MsgBox "Tudo Ok na verificao!!!" Else MsgBox "Houve algum problema na verificao!!!" End If 'Quando voc for colocar esta funo num programa voc pode tirar as MsgBoxes, claro.

Validar Informaes Fornecidas pelo Usurio


PARA GARANTIR A DIGITAO CORRETA

163
Como validar informaes fornecidas pelo usurio usando as Expresses Regulares do VBScript. As expresses regulares mostradas fazem parte do VBScript, uma das linguagens que usam os servios do Windows Script, disponvel no Windows 98. Para experimentar os exemplos em sua mquina, voc precisa fazer o download da verso atualizada do Windows Scripting Host, no endereo http://www.microsoft.com/scripting/downloads/ws/x86/ste50ptb.exe (676 KB). Mais informaes sobre o tema podem ser encontradas no site dedicado ao Windows Scripting: http://msdn.microsoft.com/scripting. Alm de usar as expresses em arquivos texto do tipo VBS, do VBScript, voc pode tambm us-las no Visual Basic 5.0 ou 6.0 e nos ambientes de programao VBA, como nos aplicativos do Office 97 ou 2000. Nestes ltimos, para ativar as expresses regulares, acione o comando Ferramentas/Referncias e marque a opo Microsoft VBScript Regular Expressions. O JOGO DA STRING E DO PADRO (por Andrew Camargo Francis) No importa se voc est desenvolvendo para a Internet ou para uso local no Windows, uma das caractersticas mais importantes de um bom programa a capacidade de lidar elegantemente com situaes de erro. Em especial quando se trata de erros do usurio. Um aplicativo que formata o disco rgido e reinicia o micro toda vez que o usurio comete um erro certamente jamais receberia cinco estrelas do INFOLAB na categoria facilidade de uso. Para auxiliar os programadores nesta rdua tarefa, a nova verso 5.0 do VBScript traz um recurso conhecido como Expresses Regulares. Com elas possvel validar a entrada de dados feita pelo usurio de uma forma bastante prtica. Digamos que seu programa pea ao usurio que digite um nmero de telefone. Como saber se ele realmente forneceu um nmero de telefone ou apenas digitou "1234" no lugar? Poderamos escrever uma rotina que percorresse a string verificando caractere a caractere se aquilo parece ser um nmero de telefone. Com a expresso regular correta, podemos fazer exatamente isso, quase sem nenhuma programao. Como? Primeiro, vamos entender o que so as expresses regulares. Elas so simplesmente strings em que alguns caracteres (ou combinaes de caracteres) tm um significado especial. Por exemplo, a combinao "\d" significa um dgito. No algum dgito em particular mas qualquer um dos dez dgitos. Essas strings (mais conhecidas como padres) so comparadas com outras strings comuns, de tal maneira que os caracteres especiais "batam" com aquilo que eles representam. Assim, se voc comparar o padro "\d" com a string "\d" ir obter um resultado False, mas se voc o comparar com a string "6" ir obter True. Muito bem, j conhecemos o suficiente para validar uma string como sendo um nmero de telefone ou no. Vamos combinar que um telefone vlido tem 7 dgitos, ou seja, 3 dgitos seguidos por um trao, seguido por mais 4 dgitos. Montamos, ento, o seguinte padro: "\d\d\d-\d\d\d\d" Falta apenas um detalhe. Quando comparamos um padro com uma string, na verdade estamos buscando o padro dentro da string. Portanto, se aquele padro existir em algum lugar dentro da string, a comparao ser verdadeira. No o que queremos, pois "qwer555-1234zxcv" apesar de no ser um nmero vlido seria "aceito" pelo padro. Precisamos de mais alguns caracteres

164
especiais. O "^" usado para representar o comeo da string e o "$" o seu fim. Assim, o padro "^\d\d\d-\d\d\d\d$" resolve o nosso problema, pois no permite nenhum outro caractere entre o comeo da string e o primeiro dgito (idem para o fim). timo, temos um padro pronto. S precisamos saber agora como us-lo no VBScript. Para isso, existe o objeto RegExp. Neste primeiro momento, s precisamos de uma propriedade e um mtodo desse objeto. A propriedade Pattern armazena o padro que ser usado na comparao e o mtodo Test verifica se o padro encontrado na string fornecida. Podemos fazer um pequeno teste com o seguinte cdigo: Dim oExpr, resultado Set oExpr = New RegExp oExpr.Pattern = "^\d\d\d-\d\d\d\d$" resultado = oExpr.Test("555-1234") MsgBox resultado resultado = oExpr.Test("1234") MsgBox resultado A primeira string comparada com sucesso e a segunda no, exatamente como queramos. Agora que j temos funcionando a verso 1.0 da nossa expresso regular, podemos acrescentar alguns recursos. O usurio pode ter um telefone de oito dgitos. Como fazemos para validar os dois tipos de nmeros? O ponto de interrogao "?" funciona como uma espcie de "sufixo" dizendo que o caractere anterior (especial ou no) opcional. Assim, podemos ter trs ou quatro dgitos antes do trao: "^\d?\d\d\d-\d\d\d\d$" Essa seqncia muito grande de "\d"s torna a leitura (e compreenso) da expresso um pouco difcil. Podemos melhorar isso da seguinte forma: "^\d{3,4}-\d{4}$" Mudou tudo! Espero que para melhor. O sufixo "{n}" parecido com o "?" mas permite que voc diga quantas vezes o caractere anterior deve ser repetido (ou seja, n vezes). J o "{3,4}" diz que o "\d" anterior deve se repetir no mnimo 3 e no mximo 4 vezes. Fcil, no? Vamos supor agora que tenhamos de validar um endereo de e-mail em vez de um telefone. Para tanto, precisamos definir qual a "cara" de um e-mail, como fizemos para o telefone. Novamente vamos combinar um padro: uma seqncia de letras ou nmeros, um "@" e mais outra seqncia de letras e nmeros entremeada com pontos. Na primeira parte (antes do "@") precisamos do "\w" que representa qualquer letra maiscula ou minscula, qualquer dgito e tambm o "_". Como no sabemos quantos caracteres sero, vamos usar mais um sufixo. O "+" nos garante que haver uma ou mais letras e nmeros (pelo menos um necessrio): "\w+" A segunda parte um pouco mais complicada. Precisamos garantir que seja algo como "infoexame.com.br". Em outras palavras: - que haja uma seqncia de "\w" seguida por um "."; - que isso se repita quantas vezes forem necessrias; - e que no final tenhamos mais uma seqncia de "\w".

165
Parece difcil? Veja como se faz: "(\w+\.)+\w+" Usamos os parnteses para agrupar a primeira seqncia e o "." e fazer com que isso se repita com o segundo "+". Se voc prestou ateno, deve ter percebido um "\" a mais antes do ".". Para que isto? Acontece que o caractere "." tambm especial. Ele representa qualquer caractere! Mas aqui queremos apenas o ponto final. Nestes casos usamos o prefixo "\" antes de um caractere especial quando queremos representar o prprio caractere e no o seu significado. Juntando as partes, obtemos: "\w+@(\w+\.)+\w+" Podemos testar o padro com um cdigo similar ao anterior: Set oExpr = New RegExp oExpr.Pattern = "\w+@(\w+\.)+\w+" resultado = oExpr.Test ("eu@aqui.com") MsgBox resultado resultado = oExpr.Test ("asdf") MsgBox resultado Novamente, o primeiro teste verdadeiro e o segundo no. Se quisermos aceitar apenas endereos em que a primeira parte no contenha nmeros, como fica o padro correspondente? Uma possvel soluo usa o que se chama classe de caracteres. Uma classe simplesmente uma forma de agrupar caracteres de maneira que o grupo represente qualquer caractere da classe. Criamos uma classe colocando colchetes em volta de uma seqncia de caracteres: "[0123456789]" Esse padro representa qualquer dgito. O "\d" apenas uma forma bem mais curta de dizer a mesma coisa! Podemos reescrever isso de uma maneira mais sinttica: "[0-9]" Ou seja, criamos a classe dos caracteres de "0" at "9". Observe que o "-" s tem um significado especial quando se encontra entre colchetes. No exemplo do telefone, ele era um caractere normal. Portanto, a classe das letras (minsculas e maisculas) ficaria assim: "[a-zA-Z]" Acrescentando essa classe ao nosso padro temos: "[a-zA-Z]+@(\w+\.)+\w+" Como faramos para validar apenas os endereos de pessoas chamadas "Rosa" ou "Pereira"? Poderamos usar dois padres diferentes: "rosa@(\w+\.)+\w+" "pereira@(\w+\.)+\w+" Tambm podemos usar o caractere "|" que permite separar duas coisas num padro de maneira que uma das duas deva aparecer na string comparada:

166
"(rosa|pereira)@(\w+\.)+\w+" At agora havamos usado quase exclusivamente caracteres especiais, mas observe que os caracteres normais (representando a si mesmos) tambm so perfeitamente vlidos num padro. O mais importante que, nesses casos, geralmente desejamos que a comparao seja feita ignorando se as letras so maisculas ou minsculas. Para isso, contamos com a propriedade IgnoreCase: Set oExpr = New RegExp oExpr.Pattern = "(rosa|pereira)@(\w+\.)+\w+" oExpr.IgnoreCase = True resultado = oExpr.Test ("Rosa@aqui.com") MsgBox resultado resultado = oExpr.Test ("PEREIRA@aqui.com") MsgBox resultado Ambos os testes acima tm resultado True. H vrios outros caracteres especiais das expresses regulares, bem como outras propriedades e mtodos do objeto RegExp que no discutimos aqui. Alm da validao, as expresses podem ser usadas para outros fins, como a busca e a substituio em textos. O importante que, tendo dominado os seus fundamentos, o programador ter ao seu alcance uma poderosa ferramenta de manipulao de strings. Lembre-se de que muitas vezes h mais de um jeito de escrever a mesma coisa e que sempre importante testar a expresso para garantir que ela faa exatamente o que voc deseja. muito fcil se perder em meio a tantas letras, barras e outros smbolos de significado pouco intuitivo. Mas, afinal, ningum disse que elas eram bonitas -- as expresses regulares so apenas enxutas e prticas!

Validar Texto em MaskEditBox


Private Sub Mask1_Validate(Cancel as Boolean) Cancel = Not IsDate(Mask1.FormattedText) End Sub

Valor por Extenso


'Num mdulo: Public Function Extenso(ByVal Valor As _ Double, ByVal MoedaPlural As _ String, ByVal MoedaSingular As _ String) As String Dim StrValor As String, Negativo As Boolean Dim Buf As String, Parcial As Integer Dim Posicao As Integer, Unidades Dim Dezenas, Centenas, PotenciasSingular Dim PotenciasPlural Negativo = (Valor < 0) Valor = Abs(CDec(Valor)) If Valor Then Unidades = Array(vbNullString, "Um", "Dois", _ "Trs", "Quatro", "Cinco", _ "Seis", "Sete", "Oito", "Nove", _ "Dez", "Onze", "Doze", "Treze", _ "Quatorze", "Quinze", "Dezesseis", _

167
"Dezessete", "Dezoito", "Dezenove") Dezenas = Array(vbNullString, vbNullString, _ "Vinte", "Trinta", "Quarenta", _ "Cinqenta", "Sessenta", "Setenta", _ "Oitenta", "Noventa") Centenas = Array(vbNullString, "Cento", _ "Duzentos", "Trezentos", _ "Quatrocentos", "Quinhentos", _ "Seiscentos", "Setecentos", _ "Oitocentos", "Novecentos") PotenciasSingular = Array(vbNullString, " Mil", _ " Milho", " Bilho", _ " Trilho", " Quatrilho") PotenciasPlural = Array(vbNullString, " Mil", _ " Milhes", " Bilhes", _ " Trilhes", " Quatrilhes") StrValor = Left(Format(Valor, String(18, "0") & _ ".000"), 18) For Posicao = 1 To 18 Step 3 Parcial = Val(Mid(StrValor, Posicao, 3)) If Parcial Then If Parcial = 1 Then Buf = "Um" & PotenciasSingular((18 - _ Posicao) \ 3) ElseIf Parcial = 100 Then Buf = "Cem" & PotenciasSingular((18 - _ Posicao) \ 3) Else Buf = Centenas(Parcial \ 100) Parcial = Parcial Mod 100 If Parcial <> 0 And Buf <> vbNullString Then Buf = Buf & " e " End If If Parcial < 20 Then Buf = Buf & Unidades(Parcial) Else Buf = Buf & Dezenas(Parcial \ 10) Parcial = Parcial Mod 10 If Parcial <> 0 And Buf <> vbNullString Then Buf = Buf & " e " End If Buf = Buf & Unidades(Parcial) End If Buf = Buf & PotenciasPlural((18 - Posicao) \ 3) End If If Buf <> vbNullString Then If Extenso <> vbNullString Then Parcial = Val(Mid(StrValor, Posicao, 3)) If Posicao = 16 And (Parcial < 100 Or _ (Parcial Mod 100) = 0) Then Extenso = Extenso & " e " Else Extenso = Extenso & ", " End If End If Extenso = Extenso & Buf End If End If Next If Extenso <> vbNullString Then

168
If Negativo Then Extenso = "Menos " & Extenso End If If Int(Valor) = 1 Then Extenso = Extenso & " " & MoedaSingular Else Extenso = Extenso & " " & MoedaPlural End If End If Parcial = Int((Valor - Int(Valor)) * _ 100 + 0.1) If Parcial Then Buf = Extenso(Parcial, "Centavos", _ "Centavo") If Extenso <> vbNullString Then Extenso = Extenso & " e " End If Extenso = Extenso & Buf End If End If End Function 'P/ chamar a funo: Dim sRet As String Dim dValor As Double dValor = 1500.50 sRet = Extenso(dValor, "Reais", "Real") MsgBox sRet Ento, sRet conter "Um Mil e Quinhentos Reais e Cinqenta Centavos".

Verificar a Validade do PIS


Public Function PISPASEP(Fcamp As String) Dim FTAP As String Dim TOT As Integer Dim I As Integer If Val(Fcamp) = 0 Then PISPASEP = False Exit Function End If If Len(Fcamp) <> 11 Then PISPASEP = False Exit Function End If FTAB = "3298765432" TOT = 0 For I = 1 To 10 TOT = TOT + Val(Mid(Fcamp, I, 1)) * Val(Mid(FTAB, I, 1)) Next I RESTO = Int(TOT Mod 11) If RESTO <> 0 Then RESTO = 11 - RESTO End If If RESTO <> Val(Mid(Fcamp, 11, 1)) Then PISPASEP = False Exit Function End If PISPASEP = True End Function

169

VARIADOS
Acionar um HTML Help pelo VB
Public Declare Function HtmlHlp Lib "hhctrl.ocx" Alias _ "HtmlHelpA" (ByVal wHandle As Long, ByVal psfile _ As String, ByVal command As Integer, ByVal data _ As Long) As Long lngRet = HtmlHlp(Me.hwnd, App.Path & "\help.chm", &HF, 1000) Onde &HF significa sensvel ao contexto e 1000 uma ncora (id) que voc cria dentro do HtmlHelp Workshop.

Acionar um Help (*.HLP) pelo VB


'No Declarations do Form: Private Declare Function WinHelp Lib "user32" Alias _ "WinHelpA" (ByVal hwnd As Long, ByVal lpHelpFile _ As String, ByVal wCommand As Long, ByVal dwData _ As Long) As Long Private Const HELP_CONTENTS As Long = &H3& Private Const HELP_QUIT As Long = &H2 'P/ chamar (no evento que voc quizer): Dim CONF As Long Dim DIR As String DIR = App.Path & "SeuHelp.HLP" If Right(App.Path,1) <> "\" Then DIR = App.Path & "\SeuHelp.HLP" CONF = WinHelp(hwnd, DIR, HELP_CONTENTS, CLng(0))

Cancelando Processos Longos


Quando voc for trabalhar com processamentos longos (utilizando loops como Do...Loop, For...Next), procure criar um boto de cancelameno p/ este processo. Utilize SEMPRE tambm a funo DoEvents, que permite que o usurio realize outras tarefas enquanto o processo executado (clicar no boto "Cancelar", por exemplo), impedindo assim que o seu programa trave, ou trave seu computador. bastante simples de criar este boto de cancelamento. Veja: 'No Declarations: Dim bParar As Boolean 'Na Rotina onde ir utilizar o Loop: bParar = False Do DoEvents 'A linha a seguir fora a sada do Loop 'quando o boto "Cancelar" for precionado: If bParar = True Then Exit Do 'Ou Exit Sub ... Outros comandos ... Loop

170

'No boto Cancelar, mude o valor da varivel 'bParar p/ True: Private Sub Command1_Click() bParar = True End Sub Ento, por estar se usando o DoEvents, o usurio poder clicar no boto "Cancelar" e, quando ele fizer isto, a varivel bParar passara a ter o valor True, parando assim o processo.

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 Mude a verso 4.00 para VERSION 2.00, remova todos os sufixos VB, o 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. 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

Confirmando o Termino do Programa


Como faramos para perguntar ao usurio se ele "realmente" deseja finalizar o programa? Colocaramos um boto ou menu com o caption "Sair" e, se o usurio clicasse nele perguntaramos? Mas e se o usurio clicasse no boto "X" q fica no lado direito da barra de ttulos? Bem, para nossa sorte existe o evento QueryUnload em todo Form. Ento, proceda da seguinte forma: Private Sub Form_QueryUnload(Cancel As Integer, _ UnloadMode As Integer) Dim RES As VbMsgBoxResult 'Pergunta ao usurio se ele realmente deseja finalizar 'o programa RES = MsgBox("Voc deseja finalizar o programa???", _ vbQuestion + vbYesNo, "Sair???") If RES = vbNo Then 'O usurio NO deseja finalizar o programa. Cancel = 1 Else 'O usurio DESEJA finalizar o programa.

171
'Aqui coloque comandos, como salvar registros, 'por exemplo... End If End Sub Private Sub Form_Unload(Cancel As Integer) Set frmMenu = Nothing End Sub

Como Registrar Uma HotKey


'Num modulo: Option Explicit Private Const WM_HOTKEY = &H312 Public Declare Function RegisterHotKey Lib _ "user32" (ByVal hwnd As Long, ByVal _ id As Long, ByVal fsModifiers As _ Long, ByVal vk As Long) As Long ' ' Modificadores ' Public Const MOD_ALT = &H1 Public Const MOD_CONTROL = &H2 Public Const MOD_SHIFT = &H4 ' Tecla que ser nossa hotkey Public Const VK_F2 = &H71 Public Declare Function DefWindowProc Lib _ "user32" Alias "DefWindowProcA" _ (ByVal hwnd As Long, ByVal wMsg As _ Long, ByVal wParam As Long, ByVal _ lParam As Long) As Long Public Declare Function SendMessage Lib _ "user32" Alias "SendMessageA" _ (ByVal hwnd As Long, ByVal wMsg _ As Long, ByVal wParam As Long, _ lParam As Any) As Long #If UNICODE Then Public Declare Function SetWindowLong Lib _ "user32" Alias "SetWindowLongW" _ (ByVal hwnd As Long, ByVal nIndex _ As Long, ByVal dwNewLong As Any) _ As Long Public Declare Function GetWindowLong Lib _ "user32" Alias "GetWindowLongW" _ (ByVal hwnd As Long, ByVal nIndex _ As Long) As Long #Else Public Declare Function SetWindowLong Lib _ "user32" Alias "SetWindowLongA" _ (ByVal hwnd As Long, ByVal nIndex _ As Long, ByVal dwNewLong As Any) _ As Long Public Declare Function GetWindowLong Lib _ "user32" Alias "GetWindowLongA" _

172
(ByVal hwnd As Long, ByVal nIndex _ As Long) As Long

#End If Private Declare Function CallWindowProc Lib _ "user32" Alias "CallWindowProcA" _ (ByVal wndrpcPrev As Long, ByVal _ hwnd As Long, ByVal uMsg As Long, _ ByVal wParam As Long, lParam As _ Any) As Long Public Const GWL_USERDATA = (-21) Public Const GWL_WNDPROC = -4 Public Function WindowProc(ByVal hwnd As _ Long, ByVal uMsg As Long, ByVal _ wParam As Long, ByVal lParam As _ Long) As Long On Error Resume Next If uMsg = WM_HOTKEY And wParam = 1 Then 'wParam informa o ID da hotkey Form1.BahMetodo WindowProc = 1 Exit Function End If If Form1.OldWndProc <> 0 Then WindowProc = CallWindowProc(Form1.OldWndProc, _ hwnd, uMsg, wParam, ByVal lParam) End If End Function 'Agora em um Form chamado Form1: Option Explicit Public OldWndProc As Long Private Sub Form_Load() Dim Ret As Long 'Registra hotkey com ID 1 'Essa hotkey sera aciona com ALT + F2 'Se Ret <> 0 entao beleza, se = 0 j 'existe uma hotkey dessa definida Ret = RegisterHotKey(Me.hwnd, 1, MOD_ALT, _ VK_F2) ' 'Inicia subclassing ' OldWndProc = SetWindowLong(Me.hwnd, _ GWL_WNDPROC, AddressOf _ WindowProc) End Sub Private Sub Form_Unload(Cancel As Integer) Cancel = False Call SetWindowLong(Me.hwnd, GWL_WNDPROC, _ OldWndProc) End Sub ' ' Metodo chamado pela Hotkey ' Public Sub BahMetodo() MsgBox "Opa !"

173
End Sub Rode o projeto, minimize a janela, clique em outra janela, esqueca da janela e impulsivamente pressione ALT + F2 ;-)

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

Criando grficos sem utilizar OCX nem DLL


Um grfico nada mas que uma representao visual de um valor em relao a outros valores ou a uma meta pr-definida. Para gerar esta representao o processo bastante simples:

Caso 1 - Meta pr-definida:


Crie um projeto novo, Form1 ser criado por padro. Coloque o cdigo abaixo em Form1 e execute o programa. Private Sub Form_Load() AutoRedraw = True FillStyle = 0 ScaleMode = 3 'Dim Valor%(9) o mesmo que 'Dim Valor(0 to 9) As Integer Dim Valor%(9), Item% Dim PosX!, PosY!, PosX1!, PosY1! Const ValorMaior% = 100 'traa o fundo do grfico FillColor = &HFFFFFF Line (0, 0)-((UBound(Valor) + 1) * 20 + 10, ValorMaior% + 20), &H0&, B 'carrega valores aleatrios no grfico For Item = 0 To UBound(Valor) Valor(Item) = (Rnd * ValorMaior%)

174
Next 'traa o grfico For Item = 0 To UBound(Valor) PosX = (Item * 10) + ((Item + 1) * 10) PosY = ValorMaior + 10 PosX1 = (Item * 10) + ((Item + 1) * 10) + 10 PosY1 = ValorMaior - Valor(Item) + 10 FillColor = Valor(Item) * (&HFFFFFF / ValorMaior) Line (PosX, PosY)-(PosX1, PosY1), &H0&, B Next End Sub Este cdigo ir gerar um grfico de colunas baseado em valores aleatrios onde o valor limite definido por ValorMaior e cada cor representa um nvel de aproximao deste valor.

Caso 2 - Meta relativa:


Private Sub Form_Load() AutoRedraw = True FillStyle = 0 ScaleMode = 3 'Dim Valor%(9) o mesmo que Dim Valor(0 to 9) As Integer Dim Valor%(9), Item%, ValorMaior% Dim PosX!, PosY!, PosX1!, PosY1! 'carrega valores aleatrios no grfico e encontra o maior ValorMaior = 1 'Define o valor mnimo For Item = 0 To UBound(Valor) Valor(Item) = (Rnd * 100) ValorMaior = IIf(Valor(Item) > ValorMaior, Valor(Item), ValorMaior) Next 'traa o fundo do grfico FillColor = &HFFFFFF Line (0, 0)-((UBound(Valor) + 1) * 20 + 10, ValorMaior% + 20), &H0&, B 'traa o grfico For Item = 0 To UBound(Valor) PosX = (Item * 10) + ((Item + 1) * 10) PosY = ValorMaior + 10 PosX1 = (Item * 10) + ((Item + 1) * 10) + 10 PosY1 = ValorMaior - Valor(Item) + 10 FillColor = Valor(Item) * (&HFFFFFF / ValorMaior) Line (PosX, PosY)-(PosX1, PosY1), &H0&, B Next End Sub Este cdigo ir gerar um grfico de colunas baseado em valores aleatrios onde o valor limite o maior dos valores carregados, sendo que o limite mnimo 1 e cada cor representa um nvel de aproximao do maior valor ou de 1 caso todos os valores sejam nulos.

Criando uma Animao no VB


Crie um novo projeto, coloque no Form uma ImageList, um PictureBox (ou ImageBox, pois esta no recebe foco), um Timer (com Interval = 100, pelo menos) e coloque as figuras da animao na ImageList. Ento, coloque o seguinte cdigo no Form: Dim iAnim As Integer

175
Private Sub Form_Load() iAnim = 1 Call Timer1_Timer End Sub Private Sub Timer1_Timer() 'Img1 a ImageBox e ImgLst1 a ImageList. Set Img1.Picture = ImgLst1.ListImages(iAnim).Picture iAnim = iAnim + 1 If iAnim > ImageList1.ListImages.Count Then iAnim = 1 End If End Sub

Dar uma Pausa em seu Programa


'No declarations do Form onde voc 'deseja colocar essa "pausa": Private Declare Sub Sleep Lib "kernel32" _ (ByVal dwMilliseconds As Long) 'Ento, no evento que voc desejar, coloque 'esta linha: Sleep (2000)

Pronto. A ser dada uma pausa de 2000 milesegundos. Caso voc queira que essa pausa seja de mais ou menos tempo, altere este 2000 pelo nmero que voc quizer. Detalhe: Cada 1000 milesegundos correspondem a 1 segundo.

Fazer um aplicativo ser acionado silenciosamente


Para fazer um aplicativo ser acionado silenciosamente na abertura do Windows, basta adicionar seu caminho na chave: "HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run" partir deste momento ele ser acionado na abertura do Windows.

MsgBox que no seja modal


A funo MsgBox do Visual Basic no contempla esta opo. Porm, possvel fazer usando a funo API MessageBox. Declare e chame a API como segue (cdigo VB 3.0): Declare Function MessageBox% Lib "User" (ByVal _ hWnd%, ByVal lpText$, ByVal lpCaption$, _ ByVal wType%) Const MB_OKCANCEL As Long = &H1 Dim ret% ret = MessageBox(0, "I am a Modeless MessageBox", _ "Modeless MessageBox ", MB_OKCANCEL) Obs.: possvel tambm criar um formulrio com as mesmas caractersticas de um MessageBox e exib-lo de forma no modal.

176

Programa que d "Bom dia", "Boa tarde" e "Boa noite" nos Horrios Corretos
'No evento Form_Load() do Form principal: Private Sub Form_Load() Me.Show If Time$ > "19:00:00" Then MsgBox "Boa noite e seja bem vindo!!!", _ vbInformation ElseIf Time$ > "12:00:00" Then MsgBox "Boa tarde e seja bem vindo!!!", _ vbInformation ElseIf Time$ > "00:00:00" Then MsgBox "Bom dia e seja bem vindo!!!", _ vbInformation End If End Sub Assim, * "Bom * "Boa * "Boa ele lhe dir: dia e seja bem vindo!!!" - de manha tarde e seja bem vindo!!!" - de tarde noite e seja bem vindo!!!" - de noite

Recebendo Parmetros Externos num Programa feito em VB


Para fazer com que um programa feito em VB receba parmetros externos (como o %1, %2, etc dos arquivos .BAT), use a funco "Command$" no evento Form_Load. Veja o cdigo: Private Sub Form_Load() Dim sParametro as String sParametro = Command$ End Sub

Saber se um programa foi encerrado


Private Type STARTUPINFO cb As Long lpReserved As String lpDesktop As String lpTitle As String dwX As Long dwY As Long dwXSize As Long dwYSize As Long dwXCountChars As Long dwYCountChars As Long dwFillAttribute As Long dwFlags As Long wShowWindow As Integer cbReserved2 As Integer lpReserved2 As Long hStdInput As Long hStdOutput As Long hStdError As Long End Type Private Type PROCESS_INFORMATION hProcess As Long

177
hThread As Long dwProcessID As Long dwThreadID As Long End Type Private Declare Function WaitForSingleObject Lib _ "Kernel32" (ByVal hHandle As Long, ByVal _ dwMilliseconds As Long) As Long Private Declare Function CreateProcessA Lib _ "Kernel32" (ByVal lpApplicationName As _ Long, ByVal lpCommandLine As String, _ ByVal lpProcessAttributes As Long, ByVal _ lpThreadAttributes As Long, ByVal _ bInheritHandles As Long, ByVal _ dwCreationFlags As Long, ByVal _ lpEnvironment As Long, ByVal _ lpCurrentDirectory As Long, lpStartupInfo _ As STARTUPINFO, lpProcessInformation As _ PROCESS_INFORMATION) As Long Private Declare Function CloseHandle Lib "Kernel32" _ (ByVal hObject As Long) As Long Private Private Private Private Private Const Const Const Const Const NORMAL_PRIORITY_CLASS As Long = &H20& INFINITE As Long = -1& WAIT_FAILED As Long = &hFFFFFFFF WAIT_TIMEOUT As Long = &h102& STILL_ACTIVE As Long = &h103&

Private Sub Command1_Click() Dim lRet&, szCommandLine$ Dim ProcInfo As PROCESS_INFORMATION Dim StartProc As STARTUPINFO On Error Resume Next szCommandLine$ = "notepad.exe" StartProc.cb = Len(StartProc) If CreateProcessA(0&, szCommandLine$, 0&, 0&, 1&, _ NORMAL_PRIORITY_CLASS, 0&, 0&, StartProc, _ ProcInfo) Then 'T como INFINITE mas pode ser trocado para um 'valor em milisegundos e IRet& testado com WAIT_FAILED, 'WAIT_TIMEOUT e STILL_ACTIVE lRet& = WaitForSingleObject(ProcInfo.hProcess, INFINITE) CloseHandle (ProcInfo.hThread) CloseHandle (ProcInfo.hProcess) MsgBox "Deu Certo" Else MsgBox "Deu Erro" End If End Sub

Tecla ENTER Agindo como TAB


'No Form: 'Sete a propriedade KeyPreview do Form como true. 'Coloque este cdigo no evento KeyDown do form: Private Sub Form_KeyDown(KeyCode As Integer, Shift _ As Integer) If KeyCode = vbKeyReturn then

178
Sendkeys "{Tab}" KeyCode = 0 End If End Sub

Testar caminho da aplicao


Testando se o caminho j inclui "\" ou no: Private Sub Form_Load() Dim Teste As String Dim caminho As String Teste = App.Path If Right(Teste, 1) = "\" Then caminho = "Caminho" Else caminho = "\Caminho" End If Form1.Caption = App.Path & caminho End Sub Ou de uma forma mais "enxuta": Private Sub Form_Load() Form1.Caption = App.Path & caminho If Right(App.Path, 1) <> "\" Then Form1.Caption = App.Path & "\" & caminho End If End Sub

Usando as Setas de Movimento Para Mudar de Controle


Para usar as teclas de movimentao como a tecla TAB ou Shift+Tab, coloque a propriedade KeyPreview do Form como True e insira o seguinte cdigo no evento KeyDown: Private Sub Form_KeyDown(KeyCode As Integer, Shift As Integer) If KeyCode = vbKeyUp Then SendKeys "+{Tab}" KeyCode = 0 ElseIf KeyCode = vbKeyDown Then SendKeys "{Tab}" KeyCode = 0 End If End Sub

Use o Code Profiler para depurao


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) 2) 3) 4) 5) Faa uma cpia do seu fonte. Selecione o add-in Code Profiler. Selecione o(s) arquivo(s) de cdigo a serem analisados. Selecione a opo Line Hit Count. Selecione o boto Add Profiler Code.

179
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.

Uso racional do 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

Verificar o Formato de Data Configurado no Windows


'Num mdulo: Private Declare Function GetSystemDefaultLCID _ Lib "kernel32" () As Long Private Declare Function GetLocaleInfo Lib _ "kernel32" Alias "GetLocaleInfoA" ( _ ByVal Locale As Long, ByVal LCType _ As Long, ByVal lpLCData As String, _ ByVal cchData As Long ) As Long Private Const LOCALE_SSHORTDATE = &H1F Public Function GetShortDateFormat() As String 'usada como buffer da API Dim FormatString As String * 11 Dim ItWorked As Boolean 'retorno da api 'joga o separador decimal no buffer ItWorked = GetLocaleInfo(GetSystemDefaultLCID, _ LOCALE_SSHORTDATE, FormatString, 11) 'se conseguiu If ItWorked Then 'atribui o mesmo para funo GetShortDateFormat = Left(FormatString, _ InStr(FormatString, _ Chr(0)) - 1) Else 'seno atribui vazio para a funo GetShortDateFormat = "" End If End Function 'P/ chamar, no evento que voc desejar: txtRet.Text = GetShortDateFormat

180

Ele retornar algo como "dd/MM/yy".

181

VARIVEIS
Apresentando Corretamente Nmeros no Formato de Moeda
Digamos que voc, por exemplo, precise exibir numa TextBox um campo de um banco de dados em formato moeda. Ento, temos duas formas de fazer isto. Veja: '1 Forma: Text1.Text = Format$(RS![Campo], "$###,##0.00;$ ###,##0.00;0;\n\u\l\o") '2 Forma: Text1.Text = Format$(RS![Campo], "currency")

Ateno na Declarao de Variveis!!!


Voc j deve ter visto a declarao de variveis da seguinte forma: Dim Num1, Num2, Num3, Num4 As Integer Pois Num1 Num2 Num3 Num4 bem, declarando desta forma teremos: => Varivel do tipo VARIANT!!! => Varivel do tipo VARIANT!!! => Varivel do tipo VARIANT!!! => Varivel do tipo Integer

As variveis do tipo Variant aceitam QUALQUER tipo de dados. No entanto, com elas, seu programa perde performance (cerca de 40%! Vide dica "Cuidado com Variveis Tipo Variant!!!"). Ento, a maneira CORRETA de se vazer essa declarao seria: Dim Num1 As Integer, Num2 As Integer, Num3 As Integer, Num4 As Integer OU: Dim Dim Dim Dim Num1 Num2 Num3 Num4 As As As As Integer Integer Integer Integer

By 3D Man ----Outra dica sempre declare suas variveis com maisculas e minsculas. Dim NomeDaVariavel As String, OutraVariavel As String Ao digitar seu programa, digite-as completamente em minsculas (nomedavariavel e outravariavel). Aps sair da linha alterada o VB automaticamente as transformar para a forma da declarao, lhe dando um input visual de que voc escreveu-as corretamente.

182

Arredondamento numrico
Function Roun2 (X) Round2 = Int(X * 100 + ,5)/100 End Function Function RoundN (X As Interger, N As Interger) Dim Factor As Long Factor = 10 ^ N RoundN = Int(X * Factor + .5)/ Factor End Function

Busca Binria
Public Function InArray(pArray As Variant, _ pValor As String, Optional pInicio _ As Integer = -1, Optional pFim As _ Integer = -1) As Long Dim intInicio As Integer, intFim As Integer Dim intMeio As Integer If pInicio = -1 And pFim = -1 Then intInicio = LBound(pArray) intFim = UBound(pArray) Else intInicio = pInicio intFim = pFim End If intMeio = (intInicio + intFim) / 2 If pArray(intMeio) = Val(pValor) Or _ pArray(intInicio) = Val(pValor) Or _ pArray(intFim) = Val(pValor) Then InArray = intMeio Exit Function End If If intMeio = intInicio Or intMeio = intFim Then InArray = -1 Exit Function End If If pValor < pArray(intMeio) Then intFim = intMeio Else intInicio = intMeio + 1 End If InArray = InArray(pArray, pValor, intInicio, _ intFim) End Function

Capturar o formato da Moeda


------- OPO 1 Private Declare Function GetLocaleInfo Lib _ "kernel32" Alias "GetLocaleInfoA" ( _ ByVal Locale As Long, ByVal LCType _ As Long, ByVal lpLCData As String, _ ByVal cchData As Long) As Long

183

Const LOCALE_SCURRENCY As Long = &H14 Const LOCALE_SYSTEM_DEFAULT As Long = 0 Private Sub Form_Click() CurrencyFormat$ = Space(100) i% = GetLocaleInfo(LOCALE_SYSTEM_DEFAULT, _ LOCALE_SCURRENCY, CurrencyFormat$, 100) CurrencyFormat$ = Left(CurrencyFormat$, i% - 1) Debug.Print CurrencyFormat$ End Sub ------- OPO 2 Private Sub Form_Click() CurrencyFormat$ = Format(1,"Currency") CurrencyFormat$ = Trim(Left(CurrencyFormat$, _ InStr(CurrencyFormat$,"1")-1)) End Sub

Classificar um array em ordem alfabtica


Sub OrdemAlfa(sArray(), ByVal ini, ByVal fim) Dim i, j, aux For i = ini to fim - 1 For j = i + 1 to fim If StrComp(sArray(i), sArray(j), 1) = 1 then aux = sArray(i) sArray(i) = sArray(j) sArray(j) = aux End if Next Next End Sub

Criar Arrays com Type definido pelo usurio


'Na seo geral do formulrio: Private Type Carro Pneus As Integer Cor As String Fabricante As String Preo As Currency End Type 'No procedimento: Dim iNum As Integer, Veiculo() As Carro For iNum = 0 To 10 Redim Preserve Veiculo(iNum) Veiculo(iNum).Pneus = iNum Veiculo(iNum).Cor = "Preto" Veiculo(iNum).Fabricante = "VW" Veiculo(iNum).Preo = iNum Next

184

Facilitando a Declarao de Variveis


Existe a instruo DefType q ajuda muito na declarao de variveis. Essa instruo funciona a nvel de mdulo para definir o tipo de dados padro para variveis, argumentos passados a procedimentos e o tipo de retorno para os procedimentos (Function e Property Get) cujos nomes se iniciem pelos caracteres especificados. Sintaxe: DefType Letra, Letra ... O argumento "Letra" (que OBRIGATRIO) pode ser usado das seguintes formas: DefType I, N <- Define que TODAS as variveis iniciadas pelas letras "I" e "N" sero de determinado tipo. DefType A-E <- Define que TODAS as variveis iniciadas por letras entre "A" e "E" sero de determinado tipo.

Veja como colocar o DefType p/ cada tipo de varivel: DefBool DefByte DefInt DefLng DefCur DefSng DefDbl DefDate DefStr DefObj DefVar -> -> -> -> -> -> -> -> -> -> -> Tipo Tipo Tipo Tipo Tipo Tipo Tipo Tipo Tipo Tipo Tipo Boolean Byte Integer Long Currency Single Double Date String Object Variant

Exemplo: DefInt I DefStr S DefBool B Dim iNum, sTexto, bResposta, Acertos Pois bem, declarando desta forma teremos: iNum sTexto bResposta Acertos => => => => Varivel Varivel Varivel Varivel do do do do tipo tipo tipo tipo Integer String Boolean Variant

Perceba que no mais necessrio usar o "As Type". Repare tambm que a varivel "Acertos" foi declarada como Variant. Por que isso? Simples! Porque NO foi declarado um DefType p/ a letra "A". Ento, se tivessemos declarado esta varivel com o nome "iAcertos" ela seria declarada como Integer.

185

Fazendo Alteraes em Strings com o 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 = "Todo a Meu Texto" If Mid$(MyString, 6, 1) = "a" Then Mid$(MyString, 6, 1) = "o" 'Substituindo caracter End If Bem, depois dessa rotina, a varivel MyString conter "Todo o Meu Texto" e no mais "Todo a Meu Texto". Ateno!!!: Este comando s muda um certo nmero de caracteres pelo mesmo nmero de caracteres (ex.: se vc for mudar um caracter, como no exemplo anterior, voc s poder troca-lo por UM outro caracter...)!!!

Funo para Tira Acentos de Strings


'Coloque esta funo num mdulo ou mesmo no form: Public Function TiraAcentos(ByVal sTexto As String) As String Dim sAcentos(2, 8) As String Dim sCaracter As String Dim bAcentos As Boolean Dim i As Integer, j As Integer sAcentos(1, sAcentos(2, sAcentos(1, sAcentos(2, sAcentos(1, sAcentos(2, sAcentos(1, sAcentos(2, sAcentos(1, sAcentos(2, sAcentos(1, sAcentos(2, sAcentos(1, sAcentos(2, sAcentos(1, sAcentos(2, 1) 1) 2) 2) 3) 3) 4) 4) 5) 5) 6) 6) 7) 7) 8) 8) = = = = = = = = = = = = = = = = "" "a" "" "e" "" "i" "" "o" "" "u" "" "e" "" "o" "" "a"

TiraAcentos = sTexto 'Coloca o texto original como retorno For i = 1 To Len(sTexto) sCaracter = Mid$(sTexto, i, 1) 'Testa cada caracter If Asc(sCaracter) >= 192 And Asc(sCaracter) <= 255 Then bAcentos = True 'Indica a presena de acentos Exit For

186
End If Next If bAcentos = True Then 'Comparamos cada caracter com os elementos da matriz For i = 1 To Len(sTexto) For j = 1 To 8 sCaracter = Mid$(sTexto, i, 1) If Asc(sCaracter) >= 192 And Asc(sCaracter) <= 255 Then If sCaracter = sAcentos(1, j) Then Mid$(sTexto, i, 1) = sAcentos(2, j) TiraAcentos = sTexto End If End If Next Next End If End Function 'P/ chamar: Text1.Text = TiraAcentos(Text1.Text)

Funo que Inverte Nomes (Sobrenome, Nome)


'Num mdulo: Public Function Inverte(ByVal sNome As _ String) As String Dim sNom As String Dim iPos As Integer Dim iNum As Integer sNome = Trim(sNome) For iNum = Len(sNome) To 1 Step -1 sNom2 = Mid(sNome, iNum, 1) If sNom2 = " " Then iPos = iNum Exit For End If Next sNom = Right(sNome, (Len(sNome) - _ iPos)) & ", " sNom = sNom + Left(sNome, (iPos - 1)) Inverte = sNom End Function 'P/ usar: Dim sResult As String sResult = Inverte("Jos Carlos da Silva") 'Ento, sResult conter "Silva, Jos Carlos da"

Funo Replace para VB5.0


Private Function Replace(ByVal Texto _ As String, ByVal Isto As String, _ ByVal PorIsto As String) As String Dim i As Long

187
If Len(Isto) < 1 Then Replace = Texto Exit Function End If For i = 1 To Len(Texto) If Mid(Texto, i, Len(Isto)) = Isto Then Replace = Replace & PorIsto i = i + (Len(Isto) - 1) Else Replace = Replace & Mid(Texto, i, 1) End If Next i End Function P/ usar, digamos que o TextBox Text1 contenha um texto como "Eu sei l como isto funciona". Ento, depois dessa linha: Text1.Text Replace(Text1.Text, "sei l", "no sei") Text1 passar a conter "Eu no sei como isto funciona" Detalhe: Neste replace, voc pode fazer algo como Replace("Texto","-/-","*") que ele substituir sem problemas!!!!!!!!

Funo Split para o VB5


'Num mdulo coloque a seguinte funo: Public Function Split(ByVal Texto, _ Optional ByVal SearchStr As _ String = " ") As Variant Dim Words() As String, i As Integer Dim j As Integer, k As Integer If Len(Texto) Then k = 0 i = InStr(Texto, SearchStr) j = 1 Do While i ReDim Preserve Words(0 To k) Words(k) = Mid(Texto, j, i - j) k = k + 1 j = i + 1 i = InStr(j, Texto, SearchStr) Loop ReDim Preserve Words(0 To k) Words(k) = Mid(Texto, j, Len(Texto)) Else 'Fica compatvel com o Split() do VB6, 'retornando Ubound() = -1 ReDim Words(-1 To -1) End If Split = Words End Function 'P/ usar, por exemplo: Dim MeuArray As Variant, i As Integer MeuArray = Split("Sei l|Bl1|Bl2|Bl3", "|") For i = 0 To UBound(MeuArray) txtDestino(i).Text = MeuArray(i)

188

Primeiras Letras das Palavras de uma String em Maiusculo


Esta funo converte o texto para Maiusculo/Minusculo, deixando as primeiras letras das palavras em maiusculo, respeitando as excees da lingua portuguesa como: de, da, do, das, dos, a, e. Public Function MMCase(Texto As String) As String Dim sPalavra As String, iPosIni As Integer Dim iPosFim As Integer, sResultado As String iPosIni = 1 Texto = LCase(Texto) & " " Do Until InStr(iPosIni, Texto, " ") = 0 iPosFim = InStr(iPosIni, Texto, " ") sPalavra = Mid(Texto, iPosIni, iPosFim - iPosIni) iPosIni = iPosFim + 1 If sPalavra <> "de" And sPalavra <> "da" And _ sPalavra <> "do" And sPalavra <> "das" _ And sPalavra <> "dos" And sPalavra <> _ "a" And sPalavra <> "e" Then sPalavra = UCase(Left(sPalavra, 1)) & _ LCase(Mid(sPalavra, 2)) End If sResultado = sResultado & " " & sPalavra Loop MMCase = Trim(sResultado) End Function 'P/ usar: Dim sResult As String sResult = MMCase("JOS CARLOS DA SILVA") 'Ou: sResult = MMCase("jos carlos da silva") 'Ou: sResult = MMCase("jOS cARLOS dA sILVA") Enfim, com isso, sResult conter "Jos Carlos da Silva"

Saber as variveis do ambiente


Para saber as variveis do ambiente, inclusive o caminho do Windows, use ENVIRON MsgBox MsgBox MsgBox MsgBox MsgBox MsgBox MsgBox MsgBox Environ("winbootdir")'Windows (*) Environ("TMP")'Windows\Temp Environ("TEMP")'Windows\Temp Environ("PROMPT")'Prompt (**) Environ("COMSPEC")'COMMAND.COM (***) Environ("PATH")'OBJETO SELECIONADO (****) Environ("CMDLINE")'WIN (*****) Environ("windir")'Windows (*)

* = Caminho do Windows ** = Configurao do Prompt *** = Command.com do Windows (ex.: C:\Windows\command.com)

189
**** = Mouse, CDROM, etc. ***** = Chamada do Windows pela linha de comando >>>>> Se ENVIRON retornar "" porque a varivel do ambiente no foi encontrada. >>>>> ENVIRON pode ser chamada com argumento numrico por um FOR Ex.: Dim VarAmbiente() As String, I_Num As Integer For I_Num = 1 To 10 If Environ(I_Num) <> "" Then Redim Preserve VarAmbiente(I_Num) VarAmbiente(I_Num) = Environ(I_Num) End If Next

190

WINDOWS
Abrir a janela propriedades do sistema
Dim lngInfo As Long lngInfo = Shell("rundll32.exe shell32.dll,Control_RunDLL sysdm.cpl, , 0")

Abrir arquivo com o programa que o criou


Public Const SW_SHOW As Long = 5 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 Private Sub Button_Click() dim i& i& = ShellExecute(0,"open",CaminhoArquivoWord,"","",SW_SHOW) End Sub

Capturar Tela e Salvar em Arquivo


Adicione num Form um PictureBox (Picture1) e dois CommandButtons (Command1 q vai capturar a tela e Command2 q vai salvar o contedo de Picture1 no arquivo "C:\Teste.BMP") e coloque este cdigo: Private Declare Sub keybd_event Lib "user32" _ (ByVal bVk As Byte, ByVal bScan As _ Byte, ByVal dwFlags As Long, ByVal _ dwExtraInfo As Long) Private Sub Command1_Click() 'P/ capturar a tela: Picture1.AutoSize = True keybd_event vbKeySnapshot, 1, 0&, 0& DoEvents Picture1.Picture = Clipboard.GetData(vbCFBitmap) End Sub Private Sub Command2_Click() 'P/ salvar a imagem: SavePicture Picture1.Image, "C:\Teste.BMP"

Chamando o ScreenSaver Atravs de API


'Num mdulo: #If Win32 Then Private Declare Function SendMessage Lib _ "user32" Alias "SendMessageA" _ (ByVal hWnd As Long, ByVal wMsg _ As Long, ByVal wParam As Long, _ ByVal lParam As Long) As Long Const WM_SYSCOMMAND = &H112& Const SC_SCREENSAVE = &HF140&

191
#Else Private Declare Function SendMessage Lib _ "User" (ByVal hWnd As Integer, _ ByVal wMsg As Integer, ByVal _ wParam As Integer, lParam As Any) _ As Long Const WM_SYSCOMMAND = &H112 Const SC_SCREENSAVE = &HF140& #End If 'Para chamar o ScreenSaver, use o cdigo a 'seguir: Dim result As Long result = SendMessage(Form1.hWnd, WM_SYSCOMMAND, _ SC_SCREENSAVE, 0&)

Chamando Telas Especficas do Painel de Controle


Para chamar qualquer tela do Painel de Controle no se usa necessariamente uma API, mas sim se executa o programa rundll32.exe. De acordo com os parmetros cada tela chamada. Veja as chamadas das principais telas: 'Para chamar a tela principal do Painel de Controle: Call Shell("rundll32.exe shell32.dll,Control_RunDLL", _ vbNormalFocus) 'Para chamar a tela Adicionar ou Remover Programas: Call Shell("rundll32.exe shell32.dll,Control_RunDLL appwiz.cpl,,1", _ vbNormalFocus) 'Para chamar a tela Adicionar ou Remover Programas, na aba 'Instalao do Windows: Call Shell("rundll32.exe shell32.dll,Control_RunDLL appwiz.cpl,,2", _ vbNormalFocus) 'Para chamar a tela Adicionar ou Remover Programas, na aba 'Disco de Inicializao: Call Shell("rundll32.exe shell32.dll,Control_RunDLL appwiz.cpl,,3", _ vbNormalFocus) 'Para chamar a tela Vdeo, na aba Segundo Plano: Call Shell("rundll32.exe shell32.dll,Control_RunDLL desk.cpl,,0", _ vbNormalFocus) 'Para chamar a tela Vdeo, na aba Proteo de Tela: Call Shell("rundll32.exe shell32.dll,Control_RunDLL desk.cpl,,1", _ vbNormalFocus) 'Para chamar a tela Vdeo, na aba Aparncia: Call Shell("rundll32.exe shell32.dll,Control_RunDLL desk.cpl,,2", _ vbNormalFocus) 'Para chamar a tela Vdeo, na aba Configurao: Call Shell("rundll32.exe shell32.dll,Control_RunDLL desk.cpl,,3", _ vbNormalFocus) 'Para chamar a tela Configuraes Regionais, na aba 'Configuraes Regionais:

192
Call Shell("rundll32.exe shell32.dll,Control_RunDLL intl.cpl,,0", _ vbNormalFocus) 'Para chamar a tela Configuraes Regionais, na aba 'Nmero: Call Shell("rundll32.exe shell32.dll,Control_RunDLL intl.cpl,,1", _ vbNormalFocus) 'Para chamar a tela Configuraes Regionais, na aba 'Moeda: Call Shell("rundll32.exe shell32.dll,Control_RunDLL intl.cpl,,2", _ vbNormalFocus) 'Para chamar a tela Configuraes Regionais, na aba 'Hora: Call Shell("rundll32.exe shell32.dll,Control_RunDLL intl.cpl,,3", _ vbNormalFocus) 'Para chamar a tela Configuraes Regionais, na aba 'Data: Call Shell("rundll32.exe shell32.dll,Control_RunDLL intl.cpl,,4", _ vbNormalFocus) 'Para chamar a tela Joystick: Call Shell("rundll32.exe shell32.dll,Control_RunDLL joy.cpl", _ vbNormalFocus) 'Para chamar a tela Mouse: Call Shell("rundll32.exe shell32.dll,Control_RunDLL main.cpl @0", _ vbNormalFocus) 'Para chamar a tela Teclado: Call Shell("rundll32.exe shell32.dll,Control_RunDLL main.cpl @1", _ vbNormalFocus) 'Para chamar a tela Impressoras: Call Shell("rundll32.exe shell32.dll,Control_RunDLL main.cpl @2", _ vbNormalFocus) 'Para chamar a tela Fontes: Call Shell("rundll32.exe shell32.dll,Control_RunDLL main.cpl @3", _ vbNormalFocus) 'Para chamar a tela Mail e Fax: Call Shell("rundll32.exe shell32.dll,Control_RunDLL mlcfg32.cpl", _ vbNormalFocus) 'Para chamar a tela Multimdia, na aba Audio: Call Shell("rundll32.exe shell32.dll,Control_RunDLL mmsys.cpl,,0", _ vbNormalFocus) 'Para chamar a tela Multimdia, na aba Vdeo: Call Shell("rundll32.exe shell32.dll,Control_RunDLL mmsys.cpl,,1", _ vbNormalFocus) 'Para chamar a tela Multimdia, na aba MIDI: Call Shell("rundll32.exe shell32.dll,Control_RunDLL mmsys.cpl,,2", _ vbNormalFocus) 'Para chamar a tela Multimdia, na aba Msica de CD: Call Shell("rundll32.exe shell32.dll,Control_RunDLL mmsys.cpl,,3", _

193
vbNormalFocus) 'Para chamar a tela Multimdia, na aba Dispositivos: Call Shell("rundll32.exe shell32.dll,Control_RunDLL mmsys.cpl,,4", _ vbNormalFocus) 'Para chamar a tela Som: Call Shell("rundll32.exe shell32.dll,Control_RunDLL mmsys.cpl @1", _ vbNormalFocus) 'Para chamar a tela Modem: Call Shell("rundll32.exe shell32.dll,Control_RunDLL modem.cpl", _ vbNormalFocus) 'Para chamar a tela Rede: Call Shell("rundll32.exe shell32.dll,Control_RunDLL netcpl.cpl", _ vbNormalFocus) 'Para chamar a tela Senhas: Call Shell("rundll32.exe shell32.dll,Control_RunDLL password.cpl", _ vbNormalFocus) 'Para chamar a tela Sistema, na aba Geral: Call Shell("rundll32.exe shell32.dll,Control_RunDLL sysdm.cpl,,0", _ vbNormalFocus) 'Para chamar a tela Sistema, na aba Gerenciador 'de Dispositivos: Call Shell("rundll32.exe shell32.dll,Control_RunDLL sysdm.cpl,,1", _ vbNormalFocus) 'Para chamar a tela Sistema, na aba Perfis de Hardware: Call Shell("rundll32.exe shell32.dll,Control_RunDLL sysdm.cpl,,2", _ vbNormalFocus) 'Para chamar a tela Sistema, na aba Performance: Call Shell("rundll32.exe shell32.dll,Control_RunDLL sysdm.cpl,,3", _ vbNormalFocus) 'Para chamar a tela Opes de Acessibilidade, na aba 'Teclado: Call Shell("rundll32.exe shell32.dll,Control_RunDLL access.cpl,,1", _ vbNormalFocus) 'Para chamar a tela Opes de Acessibilidade, na aba 'Som: Call Shell("rundll32.exe shell32.dll,Control_RunDLL access.cpl,,2", _ vbNormalFocus) 'Para chamar a tela Opes de Acessibilidade, na aba 'Vdeo: Call Shell("rundll32.exe shell32.dll,Control_RunDLL access.cpl,,3", _ vbNormalFocus) 'Para chamar a tela Opes de Acessibilidade, na aba 'Mouse: Call Shell("rundll32.exe shell32.dll,Control_RunDLL access.cpl,,4", _ vbNormalFocus) 'Para chamar a tela Opes de Acessibilidade, na aba

194
'Geral: Call Shell("rundll32.exe shell32.dll,Control_RunDLL access.cpl,,5", _ vbNormalFocus) 'Para chamar a tela do Assistente (Adicionar novo 'Hardware): Call Shell("rundll32.exe shell32.dll,Control_RunDLL sysdm.cpl @1", _ vbNormalFocus) 'Para chamar a tela Data e Hora: Call Shell("rundll32.exe shell32.dll,Control_RunDLL timedate.cpl", _ vbNormalFocus) 'Para chamar a tela DiskCopy: Call Shell("rundll32 diskcopy.dll,DiskCopyRunDll", _ vbNormalFocus)

Como associar uma extenso ao programa


'*** Sempre tome muito cuidado, pois estars mechendo no Registro do Windows. *** 'Coloque num Modulo 'General Declarations Public Type mnuCommands Captions As New Collection Commands As New Collection End Type Public Type filetype Commands As mnuCommands Extension As String ProperName As String FullName As String ContentType As String IconPath As String IconIndex As Integer End Type Public Const REG_SZ As Long = 1 Public Const HKEY_CLASSES_ROOT As Long = &H80000000 Public Declare Function RegCloseKey Lib "advapi32.dll" _ (ByVal hKey As Long) As Long Public Declare Function RegCreateKey Lib "advapi32" _ Alias "RegCreateKeyA" (ByVal hKey As Long, ByVal _ lpszSubKey As String, phkResult As Long) As Long Public Declare Function RegSetValueEx Lib "advapi32" _ Alias "RegSetValueExA" (ByVal hKey As Long, _ ByVal lpszValueName As String, ByVal dwReserved _ As Long, ByVal fdwType As Long, lpbData As Any, _ ByVal cbData As Long) As Long 'Cdigo do Mdulo: Public Sub CreateExtension(newfiletype As filetype) Dim IconString As String Dim Result As Long, Result2 As Long, ResultX As Long Dim ReturnValue As Long, HKeyX As Long

195
Dim cmdloop As Integer IconString = newfiletype.IconPath & "," & _ newfiletype.IconIndex If Left$(newfiletype.Extension, 1) <> "." Then newfiletype.Extension = "." & _ newfiletype.Extension End If RegCreateKey HKEY_CLASSES_ROOT,newfiletype.Extension,Result ReturnValue = RegSetValueEx(Result, "", 0, REG_SZ, _ ByVal newfiletype.ProperName, _ LenB(StrConv(newfiletype.ProperName, _ vbFromUnicode))) ' Acertando o contedo If newfiletype.ContentType <> "" Then ReturnValue = RegSetValueEx(Result, "Content Type", 0, _ REG_SZ, ByVal CStr(newfiletype.ContentType), _ LenB(StrConv(newfiletype.ContentType, _ vbFromUnicode))) End If RegCreateKey HKEY_CLASSES_ROOT,newfiletype.ProperName,Result If Not IconString = ",0" Then RegCreateKey Result, "DefaultIcon", Result2 'Cria a chave do "ProperName\DefaultIcon" ReturnValue = RegSetValueEx(Result2, "", 0, REG_SZ, _ ByVal IconString, LenB(StrConv(IconString, _ vbFromUnicode))) End If 'Atribuir o valor padro para a chave ReturnValue = RegSetValueEx(Result, "", 0, REG_SZ, ByVal _ newfiletype.FullName,LenB(StrConv(newfiletype.FullName, _ vbFromUnicode))) RegCreateKey Result, ByVal "Shell", ResultX ' Criando as subkeys necessrias para cada comando For cmdloop = 1 To newfiletype.Commands.Captions.Count RegCreateKey ResultX, ByVal newfiletype.Commands.Captions(cmdloop), _ Result RegCreateKey Result, ByVal "Command", Result2 Dim CurrentCommand$ CurrentCommand = newfiletype.Commands.Commands(cmdloop) ReturnValue = RegSetValueEx(Result2, "", 0, REG_SZ, _ ByVal CurrentCommand$, LenB(StrConv(CurrentCommand$, _ vbFromUnicode))) RegCloseKey Result RegCloseKey Result2 Next RegCloseKey Result2 End Sub 'Ento, para associar a Extenso ".MEX" ao Notepad.exe utilize o segunite cdigo: Dim myfiletype As filetype myfiletype.ProperName = "MeuArquivo" myfiletype.FullName = "Meu Arquivo" myfiletype.ContentType = "AlgumTipoMIME" myfiletype.Extension = ".MEX" '<< Sua Extenso myfiletype.Commands.Captions.Add "Open"

196
myfiletype.Commands.Commands.Add "c:\windows\notepad.exe ""%1""" myfiletype.Commands.Captions.Add "Print" myfiletype.Commands.Commands.Add "c:\windows\notepad.exe ""%1"" /P" CreateExtension myfiletype 'Extension contem a extenso que se deseja associar; 'Propername o nome do tipo, que voc se referenciar '(no use espaos) 'FullName a descrio do Tipo 'ContentType a descrio que vers em seu browser, caso 'estivesse para fazer o download de um arquivo deste tipo. 'Voc pode pensar na extenso como um "atalho", o '"proper name" como o "nome" mesmo e o "fullname" como 'o "ttulo" ou "caption" da exenso. 'Esses "Commands" contm os "verbos" para o seu tipo. Quando 'voc clica com o direito sobre este tipo de arquivo, voc 'ver estas opo (verbos). O "Open" foi atribuido como "verbo" 'padro, assim quando der um duplo clique sobre o arquivo, ele 'executar o comando associado ao "Open".

Como Fazer Logoff, Desligar ou Reiniciar o Computador pelo VB


'Num mdulo: Public Declare Function ExitWindowsEx Lib "user32" _ Alias "ExitWindowsEx" (ByVal uFlags As Long, _ ByVal dwReserved As Long) As Long Public Public Public Public 'No Dim 'P/ RET 'P/ RET 'P/ RET Const Const Const Const EWX_LOGOFF As Long = 0 'Faz Logoff do usurio. EWX_SHUTDOWN As Long = 1 'Desligar o compitador. EWX_REBOOT As Long = 2 'Reiniciar o computador. EWX_FORCE As Long = 4 'Fora a ao desejada.

evento que voc desejar: RET as Long fazer logoff do usurio: = ExitWindowsEx(EWX_LOGOFF, 0) desligar o computador: = ExitWindowsEx(EWX_SHUTDOWN, 0) reiniciar o computador = ExitWindowsEx(EWX_REBOOT, 0)

'Se voc quizer "forar" a ao a ser executada, faa 'da seguinte maneira: 'P/ RET 'P/ RET 'P/ RET 'P/ RET fazer logon com outro usurio: = ExitWindowsEx(EWX_FORCE Or EWX_LOGOFF, 0) desligar o computador: = ExitWindowsEx(EWX_FORCE Or EWX_SHUTDOWN, 0) reiniciar o computador = ExitWindowsEx(EWX_FORCE Or EWX_REBOOT, 0) reiniciar o computador = ExitWindowsEx(EWX_FORCE Or EWX_REBOOT, 0)

197

Criar atalho para arquivo facilmente


txtCamNormal.LinkTopic = "Progman|Progman" txtCamNormal.LinkMode = 2 txtCamNormal.LinkExecute "[CreateGroup(Iniciar, 1)] " & _ "[AddItem(c:\windows\calc.exe, " & _ "Calculadora criada via DDE)]"

Executar um programa DOS


Shell ("Command.com /C MeuProgramaDOS.exe", vbHide) O /C fecha a janela DOS aps o aplicativo rodar e o vbHide mantem a janela oculta durante a execuo.

Impedir que o programa aparea nos processos do windows


1 - Coloque para false a propriedade ShowInTaskbar do Form 2 - Em um mdulo declare: Public Declare Function ShowWindow Lib "user32" _ Alias "ShowWindow" (ByVal hwnd As Long, _ ByVal nCmdShow As Long) As Long Public Const SW_HIDE As Long = 0 3 - No Form_Load adicione: Dim RetValue as Long RetValue = ShowWindow(Me.hWnd, SW_HIDE)

Impedir que o programa seja encerrado com Ctrl+Alt+Del


'Declara o seguinte em um Mdulo: Public Declare Function GetCurrentProcessId Lib _ "kernel32" () As Long Public Declare Function GetCurrentProcess Lib _ "kernel32" () As Long Public Declare Function RegisterServiceProcess _ Lib "kernel32" (ByVal dwProcessID As Long, _ ByVal dwType As Long) As Long Public Const RSP_SIMPLE_SERVICE As Long = 1 Public Const RSP_UNREGISTER_SERVICE As Long = 0 'Crie a seguinte Sub: Public Sub MakeMeService() Dim pid As Long Dim reserv As Long pid = GetCurrentProcessId() reserv = RegisterServiceProcess(pid,RSP_SIMPLE_SERVICE) End Sub 'Depois coloque o seguinte no FORM_LOAD: Private Form_Load() MakeMeService End Sub

198

Limpando a Lixeira pelo VB Atravs de API


'Num mdulo: Private Declare Function SHEmptyRecycleBin _ Lib "shell32.dll" Alias _ "SHEmptyRecycleBinA" (ByVal hwnd As _ Long, ByVal pszRootPath As String, _ ByVal dwFlags As Long) As Long 'Execuo normal Private Const SHERB_NORMAL = &H0 'Executar sem confirmao Private Const SHERB_NOCONFIRMATION = &H1 'Executar sem mostrar o progresso Private Const SHERB_NOPROGRESSUI = &H2 'Execuo sem som Private Const SHERB_NOSOUND = &H4 Private Const SHERB_NOALL = (SHERB_NOCONFIRMATION _ And SHERB_NOPROGRESSUI _ And SHERB_NOSOUND) Dim RetVal As Long Public Sub EmpRecBin() RetVal = SHEmptyRecycleBin(0&, _ vbNullString, SHERB_NORMAL) End Sub Voc pode alterar esta funo, trocando a constante SHERB_NORMAL, que passada API SHEmptyRecycleBin, pelas outras, conforme sua necessidade.

Minimizar um Programa Para o System Tray


'Num Mdulo: Public Declare Function Shell_NotifyIcon Lib _ "shell32.dll" Alias "Shell_NotifyIconA" _ (ByVal dwMessage As Long, lpData As _ NOTIFYICONDATA) As Long Public Type NOTIFYICONDATA cbSize As Long Hwnd As Long uID As Long uFlags As Long uCallbackMessage As Long hIcon As Long szTip As String * 64 End Type Public Public Public Public Public Public Public Public Public Public Const Const Const Const Const Const Const Const Const Const WM_LBUTTONDOWN = WM_LBUTTONDBLCLK WM_RBUTTONDOWN = WM_RBUTTONDBLCLK NIM_ADD = &H0 NIM_DELETE = &H2 NIM_MODIFY = &H1 NIF_ICON = &H2 NIF_MESSAGE = &H1 NIF_TIP = &H4 &H201 = &H203 &H204 = &H206

199
Public Enum Actions TrayAdd = &H0 TrayModify = &H1 TrayDelete = &H2 End Enum Public Sub SysTray(Action As Actions, Hwnd As _ Long, ToolTip As String, Icon As _ StdPicture) Dim STray As NOTIFYICONDATA STray.uID = vbNull STray.uCallbackMessage = &H200 STray.Hwnd = Hwnd STray.hIcon = Icon STray.szTip = ToolTip & vbNullChar STray.uFlags = NIF_MESSAGE Or NIF_ICON Or _ NIF_TIP STray.cbSize = Len(STray) Select Case Action Case NIM_ADD Call Shell_NotifyIcon(NIM_ADD, STray) Case NIM_MODIFY Call Shell_NotifyIcon(NIM_MODIFY, STray) Case NIM_DELETE Call Shell_NotifyIcon(NIM_DELETE, STray) End Select End Sub 'No Form, coloque o seguinte cdigo: Private Sub Form_Resize() If Me.WindowState = 1 Then Call SysTray(TrayAdd, Me.Hwnd, Me.Caption, _ Me.Icon) End If End Sub Private Sub Form_MouseMove(Button As Integer, _ Shift As Integer, X As Single, Y As _ Single) Dim Msg As Long If (Button + Shift + Y) = 0 Then Msg = X / Screen.TwipsPerPixelX Select Case Msg Case WM_LBUTTONDOWN 'Coloque aqui a rotina a ser executada 'quando ocorrer um clique com o boto 'esquerdo no icon do System Tray. Case WM_LBUTTONDBLCLK 'Coloque aqui a rotina a ser executada 'quando ocorrer um duplo clique com o 'boto esquerdo no icon do System Tray. 'Neste exemplo, a janela ser restaurada 'e o cone retirado so System Tray. Me.WindowState = 0 Call SysTray(TrayDelete, Me.Hwnd, _ Me.Caption, Me.Icon) Me.SetFocus Case WM_RBUTTONDOWN 'Coloque aqui a rotina a ser executada 'quando ocorrer um clique com o boto

200
'direito do rato no icon do System Tray. Case WM_RBUTTONDBLCLK 'Coloque aqui a rotina a ser executada 'quando ocorrer um duplo clique com o 'boto direito do rato no icon do System 'Tray. End Select End If 'Se voc precisar colocar algum outro cdigo neste 'evento, pode coloca-lo aqui sem maiores problemas. End Sub PRONTO!!!!! Agora s executar!!! 8^) Detalhe, voc tambm pode adicionar este cone ao System Tray quando o seu programa iniciar e s retira-lo quando o programa terminar. Neste caso, proceda da seguinte forma: Private Sub Form_Load() Call SysTray(TrayAdd, Me.Hwnd, Me.Caption, Me.Icon) End Sub Private Sub Form_QueryUnload(Cancel As Integer, _ UnloadMode As Integer) Call SysTray(TrayDelete, Me.Hwnd, Me.Caption, _ Me.Icon) End Sub Private Sub Form_MouseMove(Button As Integer, _ Shift As Integer, X As Single, Y As _ Single) Dim Msg As Long If (Button + Shift + Y) = 0 Then Msg = X / Screen.TwipsPerPixelX Select Case Msg Case WM_LBUTTONDOWN 'Coloque aqui a rotina a ser executada 'quando ocorrer um clique com o boto 'esquerdo no icon do System Tray. Case WM_LBUTTONDBLCLK 'Coloque aqui a rotina a ser executada 'quando ocorrer um duplo clique com o 'boto esquerdo no icon do System Tray. 'Neste exemplo, a janela ser restaurada 'e o cone retirado so System Tray. Me.WindowState = 0 Me.SetFocus Case WM_RBUTTONDOWN 'Coloque aqui a rotina a ser executada 'quando ocorrer um clique com o boto 'direito do rato no icon do System Tray. Case WM_RBUTTONDBLCLK 'Coloque aqui a rotina a ser executada 'quando ocorrer um duplo clique com o 'boto direito do rato no icon do System 'Tray. End Select End If 'Se voc precisar colocar algum outro cdigo neste 'evento, pode coloca-lo aqui sem maiores problemas.

201
End Sub

Mudando a Resoluo de vdeo


'Num mdulo: Private Declare Function EnumDisplaySettings Lib _ "user32" Alias "EnumDisplaySettingsA" _ (ByVal lpszDeviceName As Long, ByVal _ iModeNum As Long, lpDevMode As Any) As _ Boolean Private Declare Function ChangeDisplaySettings Lib _ "user32" Alias "ChangeDisplaySettingsA" _ (lpDevMode As Any, ByVal dwflags As Long) _ As Long Private Private Private Private Const Const Const Const CCDEVICENAME = 32 CCFORMNAME = 32 DM_PELSWIDTH = &H80000 DM_PELSHEIGHT = &H100000

Private Type DEVMODE dmDeviceName As String * CCDEVICENAME dmSpecVersion As Integer dmDriverVersion As Integer dmSize As Integer dmDriverExtra As Integer dmFields As Long dmOrientation As Integer dmPaperSize As Integer dmPaperLength As Integer dmPaperWidth As Integer dmScale As Integer dmCopies As Integer dmDefaultSource As Integer dmPrintQuality As Integer dmColor As Integer dmDuplex As Integer dmYResolution As Integer dmTTOption As Integer dmCollate As Integer dmFormName As String * CCFORMNAME dmUnusedPadding As Integer dmBitsPerPel As Integer dmPelsWidth As Long dmPelsHeight As Long dmDisplayFlags As Long dmDisplayFrequency As Long End Type Public Sub ChangeRes(iWidth As Single, iHeight _ As Single) Dim DevM As DEVMODE Dim a As Boolean Dim i As Long Dim b As Long i = 0 Do

202
a = EnumDisplaySettings(0&, i&, DevM) i = i + 1 Loop Until (a = False) DevM.dmFields = DM_PELSWIDTH Or DM_PELSHEIGHT DevM.dmPelsWidth = iWidth DevM.dmPelsHeight = iHeight b = ChangeDisplaySettings(DevM, 0) End Sub 'P/ fazer a chamada: Call ChangeRes(800, 600) S coloque resoluoes q o monitor suporta, seno alguns arquivos podero ser corrompidos...

Mudando o Papel de Parede pelo VB


'Coloque isto num modulo 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 Public Const SPIF_UPDATEINIFILE As Long = &H1 Public Const SPI_SETDESKWALLPAPER As Long = 20 Public Const SPIF_SENDWININICHANGE As Long = &H2 Public Sub SetWallpaper(ByVal sArquivo As String) Dim RT as long RT = SystemParametersInfo(SPI_SETDESKWALLPAPER, _ 0&, sArquivo, SPIF_UPDATEINIFILE Or _ SPIF_SENDWININICHANGE) End Sub 'P/ chamar: Call SetWallpaper NomeDoArquivo 'ATENO!!! Passe o nome do arquivo com o caminho 'completo! 'Exemplo: Call SetWallpaper "C:\Windows\Desenho.BMP"

Mudar a definio de data do Windows


Private Declare Function SetLocaleInfo Lib "kernel32" _ Alias "SetLocaleInfoA" (ByVal Locale As Long, _ ByVal LCType As Long, ByVal lpLCData As String) _ As Boolean Private Declare Function PostMessage Lib "user32" Alias _ "PostMessageA" (ByVal hwnd As Long, ByVal wMsg _ As Long, ByVal wParam As Long, ByVal lParam As _ Long) As Long Private Declare Function GetSystemDefaultLCID Lib _ "kernel32" () As Long Private Const LOCALE_SSHORTDATE As Long = &H1F Private Const WM_SETTINGCHANGE As Long = &H1A Private Const HWND_BROADCAST As Long = &HFFFF&

203

Private Sub Command1_Click() Dim dwLCID As Long dwLCID = GetSystemDefaultLCID() If SetLocaleInfo(dwLCID,LOCALE_SSHORTDATE,"dd/mmm/yyyy")=False Then MsgBox "Erro na definio da data." Exit Sub End If PostMessage HWND_BROADCAST, WM_SETTINGCHANGE, 0, 0

Ocultar/Mostrar a Barra de Tarefas do Windows


'Num mdulo: Option Explicit Public Declare Function FindWindow Lib _ "user32" Alias "FindWindowA" _ (ByVal lpClassName As String, _ ByVal lpWindowName As String) _ As Long Public 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 Public Const SWP_HIDEWINDOW As Long = &H80 Public Const SWP_SHOWWINDOW As Long = &H40 Public lRet As Long 'Insira o cogigo abaixo num Form: Private Sub Form_Load( ) lRet = FindWindow("Shell_traywnd", "") 'Esconde a barra de tarefas Call SetWindowPos(lRet, 0, 0, 0, 0, 0, _ SWP_HIDEWINDOW) End Sub Private Sub Form_Unload(Cancel As Integer) 'Como a varivel lRet foi declarada como 'Public e j contm o Handle da barra de 'tarefas do Windows, no ser necessrio 'usar a API FindWindows de novo... 'Restaura a barra de tarefas Call SetWindowPos(lRet, 0, 0, 0, 0, 0, _ SWP_SHOWWINDOW) End Sub Quando voc iniciar o seu programa, ele esconder a barra de tarefas do Windows e, quando voc finaliza-lo, ele ir exibi-la novamente.

204

Usando a rea de Transferencia


O objeto Clipboard tem algumas funes p/ copiar algo p/ a rea de transferencia, como tambm funes p/ se recuperar o que tem nela. Vejamos ento quais so estas funes: Comando: Clear <- Limpa o contedo da rea de transferencia. Sintaxe: Clipboard.Clear Comando: GetFormat <- Retorna True se um item na rea de transferencia corresponde ao formato especificado. Caso contrrio, ele retorna False. Sintaxe: Clipboard.GetFormat (format) Parametro format: OBRIGATRIO. Uma constante ou valor que especifique um dos formatos de elementos reconhecidos pelo VB. Esta constante ou valor deve estar entre parnteses. Constantes do Parametro format: Constante vbCFLink vbCFText vbCFBitmap vbCFMetafile vbCFDIB vbCFPalette Exemplo: If Clipboard.GetFormat(vbCFText) Then Text1.Text = "A rea de transferencia contm um texto" EndIf If Clipboard.GetFormat(vbCFBitmap) Then Text1.Text = "A rea de transferencia contm uma imagem Bitmap" EndIf Comando: GetData <- Retorna um objeto grfico (imagem) da rea de transferencia. Sintaxe: Clipboard.GetData (format) Parametro format: OPCIONAL. Uma constante ou valor que especifique um dos formatos de elementos grficos reconhecidos pelo VB. Se format for 0 ou omitido, GetData usa automaticamente o formato adequado. A constante ou valor deve estar entre parnteses Constantes do Parametro format: Constante vbCFBitmap vbCFMetafile Valor 2 3 Descrio Bitmap (arquivos .BMP) Metarquivo (arquivos .WMF) Valor &HBF00 1 2 3 8 9 Descrio Informaes de conversao DDE Texto Bitmap (arquivos .BMP) Metarquivo (arquivos .WMF) Bitmap independente de dispositivo (DIB) Paleta de cores

205
vbCFDIB vbCFPalette 8 9 Bitmap independente de dispositivo (DIB) Paleta de cores

Observaes: Caso no exista nenhum elemento grfico na rea de transferencia corresponde ao formato especificado, nada ser retornado. Se, na rea de transferencia, estiver presente somente uma paleta de cores um DIB de tamanho mnimo (1 x 1) ser criado. Exemplo: Set Pricture1.Picture = Clipboard.GetData() Comando: GetText <- Retorna um texto a partir da rea de transferencia. Sintaxe: Clipboard.GetText (format) Parametro format: OPICIONAL. Um valor ou constante que especifica um dos formatos reconhecidos pelo VB. O valor ou constante deve estar entre parnteses. Constantes do Parametro format: Constante vbCFLink vbCFRTF vbCFText Valor &HBF00 &HBF01 1 Descrio Informaes de conversao DDE RichText Format (arquivo .RTF) (Padro) texto

Observaes: Caso no exista nenhum texto na rea de transferencia corresponde ao formato especificado, ser retornada um texto de comprimento zero (""). Exemplo: Text1.Text = Clipboard.GetText(vbCFText) Comando: SetData <- Coloca uma figura na rea de transferencia usando o formato grfico especificado. Sintaxe: Clipboard.SetData data, format Parametro data: OBRIGATRIO. Imagem a ser copiada. Parametro format: OPCIONAL. Uma constante ou valor que especifique um dos formatos de elementos grficos reconhecidos pelo VB. Caso format for omitido, SetData determina automaticamente o formato. Constantes do Parametro format: Constante vbCFBitmap vbCFMetafile vbCFDIB vbCFPalette Valor 2 3 8 9 Descrio Bitmap (arquivos .BMP) Metarquivo (arquivos .WMF) Bitmap independente de dispositivo (DIB) Paleta de cores

Exemplo: Clipboard.SetData Picture1.Picture, vbCFBitmap

206
Comando: SetText <- Copia um texto p/ a rea de transferencia. Sintaxe: Clipboard.SetText data, format Parametro data: OBRIGATRIO. Texto a ser copiado. Parametro format: OPCIONAL. Uma constante ou valor que especifique um dos formatos reconhecidos pelo VB. Constantes do Parametro format: Constante vbCFLink vbCFRTF vbCFText Valor &HBF00 &HBF01 1 Descrio Informaes de conversao DDE RichText Format (arquivo .RTF) (Padro) texto

Exemplo: Clipboard.SetText Text1.Text, vbCFText Ateno: * Quando voc quizer copiar algo p/ a rea de transferencia, ANTES da cpia, limpe-a. * Quando voc for recuperar algo da rea de transferencia com o comando GetData ou SetData, ANTES verifique qual o formato do contedo da rea de transferencia com o comando GetFormat.

Usando a Caixa "Sobre" Padro do Windows


'Num mdulo: Private Declare Function ShellAbout Lib _ "shell32.dll" Alias "ShellAboutA" _ (ByVal hwnd As Long, ByVal szApp _ As String, ByVal szOtherStuff As _ String, ByVal hIcon As Long) As Long Private Function WinAbout(ByVal l_hWnd _ As Long, ByRef pIcon As _ StdPicture, Optional ByVal _ sCopyright As String) As Boolean Dim lRet As Long lRet = ShellAbout(l_hWnd, App.ProductName & _ " ", sCopyright, pIcon) WinAbout = lRet End Function 'No evento que voc desejar chamar a tela 'de About: Dim bRET As Boolean bRET = WinAbout(Me.hwnd, Me.Icon, _ "MinhaMarca Ltda.") If bRET = True Then MsgBox "A tela de About foi exibida " & _ "sem problemas.", vbInformation Else MsgBox "Houve algum erro e a tela de " & _ "About no foi exibida.", _ vbInformation End If

207
Detalhe: Para que esta funo exiba o nome do programa, preencha o campo "Product Name" na aba "Make" da tela de propriedades do projeto.

Usando a Funo Environ$


Um exemplo de uso desta funo seria p/ recuperar o diretrio do Windows (sem API). Veja: 'No evento que voc queira: Dim WinDir As String WinDir = Environ$("WinDir") Ele retorna algo como "C:\WINDOWS". A funo Environ$() retorna uma string associada a uma varivel de ambiente do Windows. Sintaxe: Environ$({EnvString | Number}) EnvString - a string q vc vai chamar pra descobrir o seu valor (no exemplo anterior era "WinDir", pra descobrir o diretrio do Windows. Number - o nmero (ndice) da varivel de ambiente. Se voc quizer saber todas as variveis de ambiente e seus respectivos valores, s criar um Form e colar esse cdigo dentro dele; as variveis sero listadas na janela de debug (Immediate). Private Sub Form_Load() Dim EnvString As String Dim Indx As Byte Indx = 1 Do Debug.Print Indx & " - " & EnvString EnvString = Environ(Indx) Indx = Indx + 1 Loop Until EnvString = "" End Sub

Usando o Registro do Windows (Registry) Quando ns ouvimos falar em "Registro do Windows" ou "Windows Registry", logo imaginamos que seja algo "de outro mundo"... Mas no . Na verdade, muito simples de se usar o Registro do Windows. Para facilitar na manuteno desses registros, o VB tem 3 funes: Funo(es) Ao Salvar configuraes de SaveSetting programa. GetSetting, GetAllSettings Ler configuraes de programa. Excluir configuraes de DeleteSetting programa.

208
Ento, vejamos como funcionam essas funes: SaveSetting: ============ Salva informaes no registro do Windows seguindo alguns parmetros. Sintaxe: SaveSetting [Nome do Aplicativo], [Seo], [Chave], [Valor] Vejamos a descrio dos parmetros: [Nome do Aplicativo]: Obrigatrio. Nome do aplicativo ou do projeto ao qual se aplica a definio. [Seo] : Obrigatrio. Nome da seo em que a definio da chave est sendo salva. [Chave] : Obrigatrio. Nome da definio de chave sendo salva. [Valor] : Obrigatrio. Valor com que ser armazenado. Exemplos: SaveSetting appname := "MeuProg", _ section := "Inicializao", _ key := "Superior", setting := 75 'Ou SaveSetting "MeuProg", "Inicializao", _ "Superior", 75 GetSetting: =========== Recupera o valor de uma chave salva no registro do Windows. Sintaxe: GetSetting([Nome do Aplicativo], [Seo], [Chave], [Valor Padro]) Vejamos a descrio dos parmetros: [Nome do Aplicativo]: Obrigatrio. Nome do aplicativo ou do projeto cuja definio de chave solicitada. [Seo] : Obrigatrio. Nome da seo onde se encontra a definio de chave. [Chave] : Obrigatrio. Nome da definio de chave a ser retornada. [Valor Padro] : Opcional. Valor a retornar se nenhum valor for definido na definio da chave. Se for omitido, default ser assumido como uma string vazia (""). Exemplo: Dim sRet As String sRet = GetSetting(appname := "MeuProg", _ section := "Inicializao", _ key := "Esquerda", _ default := "25") GetAllSettings: =============== Retorna TODAS as chaves e TODOS os valores salvos de determinado programa/seo. Sintaxe: GetAllSettings([Nome do Aplicativo], [Seo])

209
Vejamos a descrio dos parmetros: [Nome do Aplicativo]: Obrigatrio. Nome do aplicativo ou projeto cujas definies de chave so solicitadas. [Seo] : Obrigatrio. Nome da seo cujas definies de chave so solicitadas. Obs.: GetAllSettings retorna um Variant cujo contedo uma matriz bidimensional de seqncias de caracters contendo todas as definies de chave da seo especificada e seus valores correspondentes. Exemplo: Dim vRet As Variant, iDef As Integer vRet = GetAllSettings(appname := "MeuProg", _ section := "Inicializao") For iDef = LBound(vRet, 1) To UBound(vRet, 1) Debug.Print vRet(iDef, 0), vRet(iDef, 1) Next DeleteSetting: ============== Apaga (deleta) uma ou mais chaves de determinado registro... Sintaxe: DeleteSetting [Nome do Aplicativo], [Seo], [Chave] Vejamos a descrio dos parmetros: [Nome do Aplicativo]: Obrigatrio. Nome do aplicativo ou projeto ao qual se aplica a seo ou a definio de chave. [Seo] : Obrigatrio. Nome da seo da qual a definio da chave est sendo excluda. Se forem fornecidos somente [Nome do Aplicativo] e [Seo], a seo especificada ser excluda juntamente com todas as definies de chave relacionadas. [Chave] : Opcional. Nome da definio da chave sendo excluda. Exemplo: 'Deletar APENAS uma chave da seo: DeleteSetting "MeuProg", "Inicializao", _ "Superior" 'Deletar seo INTEIRA (e TODAS as 'chave da mesma): DeleteSetting "MeuProg", "Inicializao"

Verificando se um array foi ou no inicializado


Private Sub Command1_Click() Dim lista() As Integer, Teste As Boolean Experimente este cdigo usando Redim Preserve e depois no usando ReDim Preserve lista(0)

210 Teste = FoiIncializado(lista) End Sub Private Function FoiIncializado(ByRef mVetor() As Integer) As Boolean If ((Not mVetor) = -1) Then FoiIncializado = False Else FoiIncializado = True End If End Function

Potrebbero piacerti anche