|
原文地址:http://dev.yesky.com/9/2652009.shtml
即使是初学VB的人,对于如何用它来建立一个GUI界面的标准Windows应用程序,肯定也是胸有成竹;然而,对于如何用VB来编写字符界面的控制台程序(Console-Mode Applications),知道的人恐怕不多。有人甚至认为这是不可能的,因为VB对编写控制台程序并无内在的支持,在VB的“新建工程”对话框里没有“控制台程序”这一选项。实际上,利用Windows提供的应用程序编程接口(API),VB是能够建立控制台程序的。控制台程序与图形界面的标准Windows程序不同,它没有Windows程序所通行的窗口,其与用户的交互是基于字符界面,外观类似于“MS-DOS方式”,同标准的Windows程序相比,控制台程序具有界面简单、占内存少、生成的可执行文件小的优点,因而在某些场合还有用武之地。
由于VB对建立控制台程序并无内在支持,全部工作都是依靠调用API函数来完成,故首先要用VB建立一个新的“标准EXE”工程,并删除其默认窗体(Form1),添加一标准模块(Module1),将其改名为VBConsole.bas,后续的所有工作都是在此模块中完成的。
下面按功能分类逐一介绍本文用到的API函数。
1.创建和销毁控制台窗口(consol window)用VB创建控制台程序的第一步就是为VB程序创建一个console window,并在程序结束时销毁它。这分别用到AllocConsole和FreeConsole函数。- Private Declare Function AllocConsole Lib "kernel32"() As Long
复制代码 功能:为VB程序创建一个 console window。- Private Declare Function FreeConsole Lib "kernel32"() AS Long
复制代码 功能:销毁为VB程序创建的 console window。
2.取得所建立的 console window 的句柄(Handle)
DOS程序有三个标准文件:标准输入文件(stdin),标准输出文件(stdout),标准错误文件(siderr)。与此类似,控制台程序窗口有三个句柄:
输入句柄(input handle) — 指向控制台程序的输入缓冲区
输出句柄(output handle)、错误句柄(error handle)— 指向控制台程序的屏幕输出缓冲区
在能够进行输入/输出操作之前,必须用 GetstdHandle 函数取得 console window 的这三个句柄。- Private Declare Function GetStdHandle Lib "kernel32" (ByVal nStdHandle As Long) As Long
复制代码 功能:返回 console window 的三个句柄之一。
说明:参数nStdHandle决定此函数返回的是哪一个句柄,它可以取如下值之一:- Private Const STD_INPUT_HANDLE = -10& ''返回 input handle
- Private Const TD_OUTPUT_HANDLE = - 11& ''返回 output handle
- Private Const STD_ERROR_HANDLE = -12& ''返回 error handle
复制代码 3.控制台输入/输出创建了
console window 并获得其 input/output handle 后,就可以利用WriteConsole和ReadConsole进行输入/输出了。- Private Declare Function WriteConsole Lib "kernel32" Alias "WriteConsoleA" _
- (ByVal hConsoleoutput As Long,ByVal lpBuffer As Any, ByVal nNumberofCharsTowrite _
- As Long, IpNumberofCharsWritten As Long, lpReserved As Any) As Long
复制代码 功能:向控制台窗口输出字符串。
说明:hConsoleOutput—控制台的outputhandle。 lpBuffer—要输出的字符串。 nNumberOfCharsToWrite—要输出的字符串的长度。 lpNumberofCharsWritten—实际输出的字符串的长度,可置为vbNull。 lpReserved—保留,必须置为vbNul。- 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
复制代码 功能:从输入缓冲区输入字符串。
说明:此函数是以块方式输入信息。在本文的示例中,只有用户按了Enter(回车)键后,此函数才返回。
hConsoleInput—console window的input handle。 lpBuffer—输入缓冲区地址。 nNumberOfCharsToRead—输入缓冲区的长度。 lpNumberOfCharsRead—实际读入的字符数,可置为vbNull。 lpReserved—保留,必须置为vbNull。- Private Declare Function SetConsoleMode Lib "kernel32" (ByVal hConsoleHandle _
- As Long, dwMode As Long) As Long
复制代码 功能:设置控制台输入缓冲区的输人模式或屏幕输出缓冲区的输出模式。
说明:在用 ReadConsole和 WriteConsole函数行输入/输出前,要用此函数设置好输入/输出模式。
hConsoleHandle—console window的Input handle或output handle。
dwMode是要设置的输入或输出模式值。hConsoleHandle是Input handle时, dwMode可取如下值的组合:- 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
复制代码 当 hConsoleHandle 是 output handle 时,dwMode可取如下值的组合:- Private Const ENABLE_PROCESSED_OUTPUT = &H1
- Private Const ENABLE_WRAP_AT_EOL_OUTPUT = &H2
复制代码 这些取值的具体意义,请参见 WINDOWS SDK 文档,此处不再详述。
注意:VB的API浏览器对WriteConsole和ReadConsole两函数的声明是不对的。尽管lpBuffer为长指针,它仍然应为传值调用,这是由于VB和API对字符串的存储和处理方式不一致造成的。
4.其他API函数
有了l、2、3所述的API函数,就可以创建一个基本的控制台程序了。当然,我们还可以用如下的API函数再“修饰”一下呆板的控制台窗口。- Private Declare Function SetConsoleTitle_Lib "kernel32"Alias "SetConsoleTitleA" _
- (ByVal lpConsoleTitle As String) As Long
复制代码 功能:设置控制台窗口的标题。
说明:lpConsoeTitle—要设置的窗口标题(字符串)。- Private Declare Functon SetConsoleTextAttribute Lib "hernel32" _
- (ByVal hConsoleOutput As Long, ByVal wAttributes As Long) As Long
复制代码 功能:设置要在控制台窗口输出的字符的前景色和背景色
说明:hConsoleOutput—控制台窗口的output handle wAttributes—决定了console window的前景色和背景色,可以是如下数值的组合:- 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 ''背景:高亮度
复制代码 例如,要设置前景色为黄色,可定义如下的常量并将其赋值给 wAttributes。- Private Const FOREGROUND_YELLOW = FOREGROUND_RED Or FOREGROUND_GREEN
复制代码 程序清单
示例程序将创建一个控制台窗口,并输出提示信息,要用户输入自己的名字。用户输入名字后,程序输出问候信息,并等待用户按键返回。本文的示例程序在VB6.0中文版下调试通过。- Option Explicit
- '' API函数声明
- 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, lpNumherOfCharsRead As Long, lpReserved As Any) 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
- Private Declare Function SetConsoleMode Lib "kernel32" (ByVal hConsoleOutput As Long, _
- dwMode As Long) As Long
- Private Declare Function SetConsoleTitle Lib "kernel32" Alias "SetConsoleTitleA" _
- (ByVal lpConsoleTitle As String) As Long
- Private Declare Function SetConsoleTextAttribute Lib "kernel32" _
- (ByVal hConsoleOutput As Long, ByVal wAttributes As Long) As Long
- ''定义API函数中用到的所有常量
- ''GetStdHandle函数的 nStdHandle参数的取值
- Private Const STD_INPUT_HANDLE = -10&
- Private Const STD_OUTPUT_HANDLE = -11&
- Private Const STD_ERROR_HANDLE = -12&
- ''SetConsoleTextAttribute函数的wAttributes参数的取值(按RGB方式组合)
- 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的输入模式
- 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的输出模式
- Private Const ENABLE_PROCESSED_OUTPUT = &H1
- Private Const ENABLE_WRAP_AT_EOL_OUTPUT = &H2
- Private hConsoleIn As Long ''控制台窗口的 input handle
- Private hConsoleOut As Long ''控制台窗口的output handle
- Private hConsoleErr As Long ''控制台窗口的error handle
- ''主程序
- Private Sub Main()
- Dim szUserInput As String
- AllocConsole ''创建 console window
- SetConsoleTitle "VB控制台应用程序"
- ''设置console window的标题
- ''取得console window的三个句柄
- hConsoleIn = GetStdHandle(STD_INPUT_HANDLE)
- hConsoleOut = GetStdHandle(STD_OUTPUT_HANDLE)
- hConsoleErr = GetStdHandle(STD_ERROR_HANDLE)
- SetConsoleTextAttribute hConsoleOut, FOREGROUND_GREEN Or FOREGROUND_INTENSITY
- ''前景:亮绿;背景:黑
- ConsolePrint "What''s your name?"
- szUserInput = ConsoleRead()
- If Not szUserInput = vbNullString Then
- ConsolePrint "Hello, " & szUserInput & "!" & vbCrLf
- Else
- ConsolePrint "You don''t have a name?" & vbCrLf
- End If
- ConsolePrint vbCrLf & "Press enter to exit!"
- Call ConsoleRead
- FreeConsole ''销毁 console window
- 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)
- ''截掉字符串结尾的&H00和回车、换行符
- ConsoleRead = Left$(sUserInput, InStr(sUserInput, Chr$(0)) - 3)
- End Function
复制代码 |
|