说三道四技术文摘-感悟人生的经典句子
说三道四 > 文档快照

用VB建立字符界面的控制台程序

HTML文档下载 WORD文档下载 PDF文档下载
用VB建立字符界面的控制台程序


邓双成

一、概述
  即使是初学VB的人,对于如何用它来建立一个GUI界面的标准Windows应用程序,肯定也是胸有成竹;然而,对于如何用VB来编写字符界面的控制台程序(Console-Mode Applications),知道的人恐怕不多。有人甚至认为这是不可能的,因为VB对编写控制台程序并无内在的支持,在VB的“新建工程”对话框里没有“控制台程序”这一选项。实际上,利用Windows提供的应用程序编程接口(API),VB是能够建立控制台程序的。控制台程序与图形界面的标准Windows程序不同,它没有Windows程序所通行的窗口,其与用户的交互是基于字符界面,外观类似于“MS-DOS方式”,如图1所示。


图1 本文示例程序的运行结果

  同标准的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

三、程序清单
  示例程序将创建一个控制台窗口,并输出提示信息,要用户输入自己的名字。用户输入名字后,程序输出问候信息,并等待用户按键返回。本文的示例程序在VB5.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
 
技术人员组团参加SDCC 2013的十个理由 继BAT之后 第四大巨头是谁 如果传统IT部门真的消亡,你该何去何从? 闪存突袭,混合储存是否已步入黄昏 Cloudera发布Hadoop开源组件Sentry:提供细粒度基于角色的安全控制 我从其他Shell脚本中学到了什么? 10个调试和排错的小建议 机器学习的时代来临,人类应该做点什么? 云端测试破1500万 Testin已为开发者省2亿 智能腕表inWatch:已发售近3600台 Bingo!微软证实Windows 8.1将捆绑安装Skype IBM宣布收购以色列网络安全公司Trusteer 约10亿美元 如何才能运作好一个开源项目? 为什么JavaScript有能力成为未来企业级编程语言? Red Hat CEO:拥抱开源 拥抱克隆 小米手机-HAXLR8on硬件黑客马拉松 开团了! 移动周报:雷军做红米的N个理由 Pangea Software CEO:08年App Store游戏降价大战的真相 揭秘MongoDB最新Java驱动:更好的JVM支持,指日可期的异步 不仅只有IE Mozilla将于发布Win8平台Metro版Firefox 360搜索发布新产品“我的搜索” 引入网民评价和网站名片功能 AppScale:Google App Engine的开源实现 近期十大优秀jQuery插件推荐 通过语音识别来编程 速度远超键盘 BrowserStack:多系统跨浏览器兼容性测试工具API发布 更加开放?Path向13家应用开发商开放API 重金力邀开发者 联想智能桌面应用开发大赛开幕 SDCC 2013大会讲师名单议题出炉 8月20日五折票价最后一天 程序员困境:底层编码能力正逐步丧失 寓教于乐 给代码审查者的几点建议 裁员4千、总裁员人数超过7.5万,难掩思科锋芒 救命!如何用 cable modem 上宽带网 在VC里如何实现QQ的界面啊,急急急急急急急急急急急? web如何实现连接点的回调功能? 新闻系统建模? 如何去掉release版exe文件中export的___CppdebugHook? 用标准C++开发的时候最常用的工具是什么? 到哪里能载到一些编游戏用的2D、3D图象文件啊? 招聘asp.net工程師(深圳) windows关机的问题,把我搞得好惨 请问高手如何判断保存上传图片的字段是否有数据?谢谢! 急!告急了。 学Java与Vc哪个更有实力,更有前途? 有关J2EE部署文件? 请问谁有《微型计算机原理与汇编》潘峰著,电子工业出版社的!!谢谢 一个简单的问题(VFP中) 请问OnKeyPress 和 OnKeyDown 这两个事件有什么区别? 哪里有可视化的jCheckTree组件? 关于译码器的问题,急!! *******在red hat linux下怎么设置DNS?网络设置里没有嘛 help 一个简单的问题 怎样删除干净OCX控件? 我用QQ的自定义查找输入一个QQ号码,但现在忘了我输入的是哪个号码,能不能找回? 框架制作!! 框架的问题 提个弱问! 使用treeview控件,我想给它们的节点图标都换一下,可它默认图标都在上面,怎么去掉默认的。 有牛人吗?准考证英文怎么说? 请大家帮我看看,我的机器是怎么回事?我的机器很不稳定!!! 我为大家共享的资源.找我的人太多了,我吃不消.在这里列BILL.大家看看,书不算太多。 很傻的问题,在线等 ★★如何实现按一下按钮可以终止一个正在运行中的循环?请举个例子,谢谢! 谁能帮我提供一点资料或文档! 告急?(在线等待) 用正则表达式,怎么验证日期(yyyy-mm-dd)的输入啊? kao~ 请教有关MSWORD9.OLB的帮助文档是哪个? 怎样知道一个调度执行失败或没有执行???(MSSQL7)上火呀~~~ 如何将自己定义的记录类型转化成Tmemorystream对象? c++builder5的下载地址? 做个调查,来者有分。 ODBC下的数据库查询,急!急! 初学者的问题--com dll服务器如何在客户程序中使用? 如何统计 DBGrid 中记录的个数???? 请教:m_fLogfile.Read(pBuffer , sizeof(VNumAndPassWord)); 错在哪? 谁能替我做一张图片啊? 气死人了,安装红帽子在输入根口令时遇到的尴尬:( 奇怪的oracle数据库错误? 公布我的软件了——网络邮盘,国内日下载量>1000,国外<10 关于堆和栈的队! 请问,准考证的英文怎么说? Both Alice and Linda speak English fluently.是speak 还是speaking? Linda can't speak English 改为肯定句 He went to bed after his father came bake home改为同义句 Bob never does his homework_________Mary.He makes lots of mistakes.选A.as carefully as,为什么?为什么不选as careful as 《世说新语,德行》中的古文“荀巨伯探友”的意思? 1.When father was young ,he__from morning till night.答案是was made to work 为什么?什么类型的动词复制搜索 ______carefully the boy does his homework!A.HOW B.HOW AN C.WHAT D .WHAT AN ( )Linda___________(speak)English? his father died when he was young ,when后面是状语从句么 Jack does his homework carefully.Lucy does her hJack does his homework carefully.Lucy does her homework carefully ,too保持原句意思Jack does his homework__carefully___Lucy 世说新语·德行里,荀巨伯探友这篇文章是什么意思? (七年级下英语) she does her homework in the evening.(改为(七年级下英语)she does her homework in the evening.(改为同义句)she _____ _____ her homework in the evening. 英语A级多少分才能过?如果没过下次是从B级考么 He can speak (English)括号部份提问()() he speak? 求英文抒情歌曲~类似于Air Supply的Every Woman In The World旋律一定要好听 下次考英语三级怎么办呢?自己考不了,想打小抄.但小抄的答案也不一定对啊提前一个星期在那有答案,百度么。知道有的真有的假 Meimei can (speak English).对括号部分提问 there is/are a variety of rooms 这里用is 还是are 英语三级不考行不行 红可以组什么词?我不知道呀! 是There is no book还是There is no books?或There are no books He can speak english,这句是第三人称单数为什么speak不加s? 锨组词 我不知道不知道 there ____ a kind of books.是is 还是are? 《世说新语.德行》 荀巨伯远看友人疾 我不知道诗换偏旁组词 ( )is the rabbit?It's in the box.A what B whose C where 世说新语 德行第9荀巨伯远看友人疾,值胡贼攻郡,友人语巨伯曰:“吾今死矣,子可去.”巨伯曰:“远来相视,子令吾去,败义以求生,岂荀巨伯所行邪!”贼既至,谓巨伯曰:“大军至,一郡尽空,汝 ____________is a celebration Jesus Christ back to life 填节日 初三的英语作文,帮忙看一下有没有什么错误. Little John does his homework every day.对does his homework提问. ()is a celebration Jesus Christ coming to life 祈使句的练习题和答案 世说新语 德行3求翻译,最好有重点字的单独翻译, 英语的阅读理解题 祈使句练习题及答案?祈使句练习题及答案分别是什么?有谁知道吗? 英语A级和英语三级是不是一样的?有人说是一样的,只是叫法不同有些人又说不一样,说A级是二级三级比A级难都糊涂了 英语练习阅读理解 语文祈使句练习题?暂时没分了!下次给你昂! 一些单词麻烦造句1.用afford造句2.用allow造句3.用behave造句4.用commute造句5.用enroll造句6.用expect造句7.用hide造句8.用kiss造句 阅读理解.英语练习 德语祈使句的相关练习和答案 一.仿句.1.例:弯弯下垂的月亮,浮在水一样的天上.仿写:2.故乡的歌是一支清远的笛,总是在有月亮的晚上响起.仿写:3.机舱的密封条件又不好,"高处不胜寒".乘客们不得不穿着皮大衣,戴上皮手套, 英语练习,阅读理解 英语翻译You choose the long road,But well be waiting bye bye beautif!尤其是BYE BYE BEAUTIF! 英语翻译 上课不能做小动作的英文怎么讲?我的女儿问我,我不知道该怎么说, 英语练习题~阅读题 "我会一直和你在一起"用英语怎么翻译 我要上课讲英语,请问开头怎么讲.尽量多些.类似look at the blackbord .我将给你们讲一些单词的重要用法(请给我翻译).thanks for listening.等 一篇关于明星的英语作文 请问:礼轻情意重 英语怎么翻译? 《世说新语·德行》之荀巨伯原文+翻译` When he was young,he often _(fly)a kite with his father要用过去式还是用一般现在,为什么 【夏日绝句】是一首{ }言诗. 英语翻译differentiation of exponential functions xiaolei went to bed after his father came back改为同义句xiaolei ________ go to bed________his father came back 谁知道夏日绝句全诗的意思是什么意思 《世说新语,德行》中的古文“荀巨伯探友”的翻译? His father_____when he was very young.有选项初一的练习:His father_____when he was very young.选项:A died B dead并说明为什么,如果句意不变,用dead的话,怎么改呢
备案号:鲁ICP备13029499号-2 说三道四 www.s3d4.cn 说三道四技术文摘