VB - Criando uma aplicação do tipo Console
O VB é uma das ferramentas mais usadas para criar aplicações Windows , e , uma aplicação padrão Windows supõe a presença de pelo menos um formulário. Mas vamos supor que você seja do contra e que queira criar uma aplicação VB que interaja com o usuário sem usar formulários...uma aplicação do tipo console. E então ? dá ou não dá para fazer usando o VB ?
O VB é uma ferramenta que usamos para realizar tarefas de programação , é uma ótima ferramenta , mas nem sempre é a ferramenta ideal . Isto não quer dizer que você não possa fazer qualquer tarefa usando o VB , eu acho que até pode , o problema será a eficiência e o esforço dispendido para alcançar o objetivo. Por exemplo , se você tem um alicate e precisa pregar um prego na parede , embora o alicate não seja a ferramenta adequada para fazer a tarefa , você pode pregar o prego usando o alicate. Com o VB é mais ou menos assim , você tem que estar disposto a pagar o preço que a tarefa vai lhe exigir...
Então podemos dizer que não é impossível criar uma aplicação do tipo console no VB , mas você vai ter que pagar o preço para fazer isto. Vai ter que usar as API´s ...
Dica : Voce pode fazer o download do ApiWiewer 2002 para facilitar a usar as API´s !!
Por onde vamos começar ?? Que tal iniciar o VB e escolher a criação de um projeto padrão ? Então façamos isto... A primeira coisa que vai surgir é um projeto com um formulário padrão ( olha ele ai...) O que fazemos com ele ? Ora , você não quer criar uma aplicação sem formulários ? Então , tá esperando o que ??? Remova o formulário do projeto !!!!
Vamos dar uma espiada no projeto : Nada animador não é mesmo ???
Como eu disse vamos ter que usar as API´s do Windows para fazer este serviço. Então ao trabalho...
A primeira coisa a fazer é incluir um módulo no seu projeto : Menu Project | Add Module
Todo o nosso código será escrito no módulo inserido. O primeira ação será solicitar ao windows que aloque um console fazemos isto através da API :
Declare Function AllocConsole Lib "kernel32" () As Long
com isto estaremos criando uma janela console onde iremos trabalhar enviar e receber mensagens , tudo controlado pelo Windows. Para encerrar o processo usamos a seguinte API :
Declare Function FreeConsole Lib "kernel32" () As Long
Vamos agora declarar um subrotina Main() que irá invocar as API´s declaradas. Nosso código ficará assim :
Se executarmos o código agora , o sistema irá alocar a janela console e em seguida irá destruir o processo encerrando a janela console. Tudo rapidinho , mas já é um começo...
Nossa próxima etapa será obter um identificador para a janela console que vamos usar. Se você acha isto estranho, saiba que toda a janela gerada por um formulário tem um identificador ou handle , e, se você usar API´s para interagir com um formulário sempre terá um identificador hWnd.
Uma janela console possui um identificador para a entrada , saida e para erros. Podemos obter um identificador usando a seguinte API GetStdHandle :
Declare Function GetStdHandle Lib "kernel32" (ByVal nStdHandle As Long) As Long
o argumento nStdHandle é quem determina qual identificador será retornado. As constantes nos dão três possibilidades :
Vamos avançar um pouco mais no nosso projeto , vamos agora escrever no Console. Para escrever no console vamos usar a API WriteConsole :
Declare Function WriteConsole Lib "kernel32" Alias "WriteConsoleA" (ByVal hConsoleOutput As Long, lpBuffer As Any, ByVal nNumberOfCharsToWrite As Long, lpNumberOfCharsWritten As Long, lpReserved As Any) As Long |
Vamos usar esta API para escrever no console , mas antes vamos ver como definir o título da janela console. Fazemos isto usando a API SetConsoleTitle :
Declare Function SetConsoleTitle Lib "kernel32" Alias "SetConsoleTitleA" (ByVal lpConsoleTitle As String) As Long |
Para usar a API apenas passamos uma string com o título da janela console e pronto.
Vamos agora finalmente usar a API WriteConsole para escrever na janela console , antes , vamos dar um toque de para tornar o trabalho mais colorido. Para podermos imprimir na janela console usando cores usaremos a API SetConsoleTextAttribute :
Declare Function SetConsoleTextAttribute Lib "kernel32" (ByVal hConsoleOutput As Long, ByVal wAttributes As Long) As Long |
as cores são passadas pelo argumento wAttributes , assim :
e ainda podemos combinar os valores assim :
Private Const FOREGROUND_YELLOW = FOREGROUND_RED OR FOREGROUND_GREEN
Vou tocar em outro ponto muito importante antes de entrarmos na reta final do nosso aplicativo console : como obter a resposta do usuário e exibí-la na janela console ? A API ReadConsole é usada para ler o buffer da janela do console e dar conta do recado:
Declare Function ReadConsole Lib "kernel32" Alias "ReadConsoleA" (ByVal hConsoleInput As Long, lpBuffer As Any, ByVal nNumberOfCharsToRead As Long, lpNumberOfCharsRead As Long, lpReserved As Any) As Long |
a API ReadConsole somente irá responder depois que o usuário pressionar ENTER.
Por isto vamos precisar de mais duas API´s ( calma que ja estou acabando...) . A primeira para definir o modo do buffer de entrada , a API : SetConsoleMode :
Declare Function SetConsoleMode Lib "kernel32" (ByVal hConsoleHandle As Long, ByVal dwMode As Long) As Long |
passamos para esta API o identificador para a entrada e uma valor indicando qual tipo de entrada será gravada. Dependendo do modo usado podemos ter:
- input
- output
Agora que ja temos uma visão geral do processo vamos juntar todas as partes e criar a aplicação console: Para você testar o código abaixo , copie e cole o código no módulo inserido no projeto.
'-------------------------------------------------------- '(C) Copyright 1999 by Scott Lloyd. All Rights Reserved. 'Scott Lloyd Option Explicit Private Declare Function AllocConsole Lib "kernel32" () As Long Private Declare Function FreeConsole Lib "kernel32" () As Long Private Declare Function GetStdHandle Lib "kernel32" _ (ByVal nStdHandle As Long) As Long Private Declare Function ReadConsole Lib "kernel32" Alias _ "ReadConsoleA" (ByVal hConsoleInput As Long, _ ByVal lpBuffer As String, ByVal nNumberOfCharsToRead As Long, _ lpNumberOfCharsRead As Long, lpReserved As Any) As Long Private Declare Function SetConsoleMode Lib "kernel32" (ByVal _ hConsoleOutput As Long, dwMode As Long) As Long Private Declare Function SetConsoleTextAttribute Lib _ "kernel32" (ByVal hConsoleOutput As Long, ByVal _ wAttributes As Long) As Long Private Declare Function SetConsoleTitle Lib "kernel32" Alias _ "SetConsoleTitleA" (ByVal lpConsoleTitle As String) As Long Private Declare Function WriteConsole Lib "kernel32" Alias _ "WriteConsoleA" (ByVal hConsoleOutput As Long, _ ByVal lpBuffer As Any, ByVal nNumberOfCharsToWrite As Long, _ lpNumberOfCharsWritten As Long, lpReserved As Any) As Long ''''C O N S T A N T E S''''''''''''''''''''''''''''''''''''' Private Const STD_INPUT_HANDLE = -10& Private Const STD_OUTPUT_HANDLE = -11& Private Const STD_ERROR_HANDLE = -12& 'CONSTANTES PARA CORES USADAS EM SetConsoleTextAttribute. Private Const FOREGROUND_BLUE = &H1 Private Const FOREGROUND_GREEN = &H2 Private Const FOREGROUND_RED = &H4 Private Const FOREGROUND_INTENSITY = &H8 Private Const BACKGROUND_BLUE = &H10 Private Const BACKGROUND_GREEN = &H20 Private Const BACKGROUND_RED = &H40 Private Const BACKGROUND_INTENSITY = &H80 'SetConsoleMode (input) Private Const ENABLE_LINE_INPUT = &H2 Private Const ENABLE_ECHO_INPUT = &H4 Private Const ENABLE_MOUSE_INPUT = &H10 Private Const ENABLE_PROCESSED_INPUT = &H1 Private Const ENABLE_WINDOW_INPUT = &H8 'SetConsoleMode (output) Private Const ENABLE_PROCESSED_OUTPUT = &H1 Private Const ENABLE_WRAP_AT_EOL_OUTPUT = &H2 Private hConsoleIn As Long Private hConsoleOut As Long Private hConsoleErr As Long Private Sub Main() Dim szUserInput As String AllocConsole 'Cria uma instancia para o console SetConsoleTitle "Criando uma aplicação Console no VB" 'define o titulo da janela console 'pega o identificador do console hConsoleIn = GetStdHandle(STD_INPUT_HANDLE) hConsoleOut = GetStdHandle(STD_OUTPUT_HANDLE) hConsoleErr = GetStdHandle(STD_ERROR_HANDLE) 'imprime o prompt do usuario. SetConsoleTextAttribute hConsoleOut, _ FOREGROUND_RED Or FOREGROUND_GREEN _ Or FOREGROUND_BLUE Or FOREGROUND_INTENSITY _ Or BACKGROUND_BLUE ConsolePrint "Criando uma aplicação Console no VB" & vbCrLf SetConsoleTextAttribute hConsoleOut, _ FOREGROUND_RED Or FOREGROUND_GREEN _ Or FOREGROUND_BLUE ConsolePrint "Qual o seu nome --> " 'Pega o nome do usuario szUserInput = ConsoleRead() If Not szUserInput = vbNullString Then ConsolePrint "Olá, " & szUserInput & "!" & vbCrLf Else ConsolePrint "Olá, como vai !" & vbCrLf End If 'termina o programa ConsolePrint "tecle ENTER para sair" Call ConsoleRead FreeConsole 'Destroi o console End Sub Private Sub ConsolePrint(szOut As String) WriteConsole hConsoleOut, szOut, Len(szOut), vbNull, vbNull End Sub Private Function ConsoleRead() As String Dim sUserInput As String * 256 Call ReadConsole(hConsoleIn, sUserInput, Len(sUserInput), vbNull, vbNull) ConsoleRead = Left$(sUserInput, InStr(sUserInput, Chr$(0)) - 3) End Function |
Executando o projeto teremos :
Este artigo foi baseado ( praticamente traduzido) no artigo de Scott Lloyd.
Espero que gostem , tchau...
José Carlos Macoratti