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

用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
 
[探讨] 用户体验设计师现在面临怎样的机遇和挑战? PPT集萃(二):淘宝、CloudStack等分享的架构经验与最佳实践 2013中国云计算榜单之二:64家云主机+云存储,错综复杂! 看Java技术基础的eBay如何评价他们的Node.js首次尝鲜 Jolla发布首款Sailfish系统手机 无缝兼容Android应用 NPD:全球智能手机出货量2013年将首次超过功能手机 聚合数据左磊:不走寻常路 做国内最好的数据聚合平台 从程序员到软件商 需要注意些什么? 共享软件海外营销策略与实战(上海站) 直接拿来用!最火的Android开源项目(完结篇) 一步加入云生态系统 参加第五届中国云计算大会的十大理由 传苹果iOS7将深度整合Flickr 用户受益最大 Chrome 27来了:页面加载快5% 可同步数据到Google Drive 微软发布新一代游戏主机Xbox One 搭配全新Kinect 2.0体感系统 Unity游戏引擎向iOS与Android开发者免费 Twitter获“下拉刷新”专利 开发者仍可自由使用 复杂产品的响应式设计【流程篇】 使用Javassist库为Bytecode Instrumentation开发JVM Agent 内容解析创业公司Stremor推出4款API 2013中国云计算榜单之三:174家云应用服务商,繁花似锦! 盘点各大云服务提供商:麦当劳=AWS,汉堡王=? BlackBerry Jam亚洲开发者大会9月将在香港开幕 把服务器搬进来:Splashtop在中国搭建Bridging Cloud Web框架全对比第五期 新增Windows环境 前Tumblr首席开发者回忆录:一个人也能开发出好产品 测试者和开发者,为何我们不能友好地相处? 讲师秀之11:何刚谈京东的云机遇 讲师秀之10:武汉大学张焕国教授,可信计算是云计算之成败关键 【上海直播】Windows Azure+世纪互联:中国云计算“烈火烹油” 最新版Chrome浏览器推出全新语音搜索功能 惠普第二财季净利润同比下滑32% PC和服务器销售不佳 请教有关类的扩展 请问WIN2000专业版IIS为什么连接限制是10 急,为什么我的数据库会出现这样的错误? 寻求一个好的全屏翻译软件(在线等候,在线给分) 寻找《编译原理与时间》电子文档下载url 升级了,散分小庆.认识的朋友进来捧个场,不认识的也进来热闹热闹!忠心感谢:-) 奇怪的问题 如何解决在一个表单中多个提交按钮的问题? 请问怎样关闭135端口 Photoshop7.0的一个简单问题,大师们帮帮忙! 关于动态查询的问题? 请问如何验证代理服务器? 超过半个小时不作任何操作就把这个连接KILL掉,改如何做呢? 如何才能做出只存在于托盘栏的程序! 搜集VB绘图源代码,多多益善 北京市里有没有支持asp.net的服务器空间提供吗? GGJJDDMM 帮帮我啊~~~~ 新手的问题--如何作到点击页面中的提交按钮,只刷该页面的DataGrid部分,而其它部分控件值不变?(在线给分) 大家帮忙,要取得客户端的信任,用服务器控件对客户端进行读写文件的资料? 谁说我们要和兄弟会和解了? 一直都是你们在攻击我们,靠还和解?道歉差不多。 版本的差异造成的问题,ADO连接SQL Server。求教!!! 海宜派(NSU Pie) 为什么insert into语句不能完成添加? 在线等一个简单的问题! 能用DOS盘启动然后用GHOST 备分LINUX分区吗?我想备份我的LINUX系统。 SQL中能否用CopyMemory这样的函数??? 我的猫竟拨不上号 一个菜问题 type和typedef有什么区别? 100分问题,在线等,本地XSL,XML,使用VB脚本,使用MSChart生成图形,刷新几次后IE崩溃,高分求解 socket.setSoTimeout() BCB使用ClientDataSet调用Sybase存储过程的问题 趟过“地雷阵”的铁面总理 (转载) 我的电脑为何会自动开机? emf是什么打印格式? 小偷 请问我以后删贴、结贴是不是要先向EA、ginger、大师申请? 如何实现这种查询?急!!!! 高分求救:Dos下控制(HP等)打印机打印汉字的编程,请各位帮帮我好吗? 能否将下面的代码简化呢?? 请大家给介绍几本C++学习的入门书籍,好吗? type和typedef有什么区别? 本人姓刘,现在正在给自己的孩子起名,希望大家多多帮忙! 大力好~~~~~~~~~~~~~~ 如何用数组操作的方法对控件组操作? 谁有需求分析文档?明天结帖。 各位大哥,有没有网络监控方面的控件,小弟有急用。 免费空间广告去除~! Delphi对文件的操作 简单的问题,先解决先给分了 后台服务加载,在线等待,高分求解! 北京迈达斯技术有限公司 怎么样 三面投影图中,形体投影规律为____,____,____. 《昆虫记》的读后感与读书心得 迈达斯中的tonf/m^2什么意思?tong是哪个国家的单位,什么意思? 例句:海上的夜是柔和的,是静寂的,是梦幻的.城市的夜是…… 早晨的雾是…… 先天下之忧而忧的下一句 迈达斯中选择 5to222by54 是什么意思 怎么样来计算配煤的配比呢?感谢各位的帮助~! 昆虫记读书笔记(要好句和读后感,不要别的)记住,只要好句和读后感,不要主要内容, 关于下丘脑功能的叙述 正确的事①可参与血糖平衡的调节 ②有调节躯体运动的高级中枢 ③可合成和分泌促甲状腺激素释放激素 ④垂体通过下丘脑控制性腺的生长发育A.①②B.②③C. 1投影的形成需要哪些要素?2.平行正投影有哪些基本性质?3.土木工程上常用的投影图有哪些? 什么化学剂或药剂能破除蛋白质由于一种油水液体因温度过高导致里面生成蛋白,现在我想让这些蛋白消失,希望大家给个答复我!谢谢,请大家帮帮忙!本人万分感谢 自然光在玻璃、水面、木质桌面等表面反射时,反射光和折射光都是偏振光,为什么,我就是理解不了,还反射光折射光,这都没有通过偏振片啊.当我们直接观察、拍摄橱窗、水中的物体时,有些时 一个有关桥的故事 先天下之忧而忧,的下一句 迈达斯定义结构组的时候为什么选择不到单元?不管怎么选择都是“节点数=0,单元数=0'. 高中生物神经调节这个知识点怎么提高 哪些试剂可以除去蛋白质中的脂 迈达斯FEA和CIVIL区别 具体说下 怎么感觉不出来? 这两个词的意思? 我喜欢你里约热内卢语怎么写? 下丘脑的功能下丘脑控制哪些功能 谁可以给我初二上的生物各章知识点啊?生物老师给我布置了一项寒假作业,让我把初二上学期的生物各章知识点归纳一下, 蒙古语我喜欢你的写法不要拼音要确切的怎么写就是能贴图的最好贴图那种长得像钥匙一样的文字(咳咳,不好意思,那文字被我形容成那样了)恩我邮箱834077646@qq .com恩.发给我吧.给了讲一声 为什么感觉迈达斯之手很少有人出呢?除了可以加快攻速啊 很适合DPS的过度啊 难道是我玩的太少了? 闻一多先生说了什么做了什么? 广东语我喜欢你怎么说? 改反意疑问句:Nobody wants to go there,----- ----?为什么是does he?我觉得是does it? 为什么自然光经过介质反射后可以成为偏振光?请介绍一下其中的原理, "先天下之忧而忧"下句是什么? 什么是下丘脑?作用是什么呢? 做脂质体用什么显微镜比较好 先天下之忧而忧的下一句是什么?如题! 下丘脑的作用是什么 《生日感慨》作文怎么写 只说 方法就可以 先天下之忧而忧,下一句是什么? 肾调节酸碱平衡的机制? 如何给自己写生日感言 先天下之忧而忧,的下一句是什么? 下丘脑有哪些功能? 求迈达斯软件的用法有没有迈达斯软件的电子书教程? 闻一多先生 说与做有何特点 下丘脑有什么作用 迈达斯分配功能如何使用 上联是:先天下之忧而忧忧得其所 求下联、拜托了、 为什么说体内酸碱平衡的稳定是由化学缓冲剂通过呼吸作用和肾脏来调节的 例句:海上的夜市柔和的,是静寂的,是梦幻的依照例句的格式各造一句乡村的夜( )城市的夜( ) 先天下之忧而忧的下句是? 如何在Microsoft Office Word 2003制作条形统计图如题 例句 海上的夜是柔和的,是寂静的,是梦幻的.仿照例句,选择一个事物造句 问一下感慨历史沧桑无常的诗句像“人生天地间,忽如远行客”这样的 迈达斯+截面显示不了质心也不能计算截面特性怎样回事 我爱你你爱我吗?你嫁给我好吗?越南语怎么写 英语翻译 关于桥的故事?简洁的语言. 大气压强减小液体沸点减小你们那么固体的呢? 关于桥的谚语故事传说多点 校园生活中的感悟快加上写人的开头结尾, 电大建筑制图基础形成性考核 根据所给形体的三面投影,绘制形体的正等轴测图? 歇后语里的故事名称( )——自欺欺人( )——巧用天时( )——颠倒是非古代文人勤奋读书的故事很多,流传甚广得有( )( )(写成语) 长沙飞杭州航班受炸弹威胁备降南昌医生举报副县长公款旅游 开发商10万第九届杭州市十大道德模范(平民英雄)每天倾倒80吨工业垃圾 温州双岙村遭默克尔遭美国监听 德议员称斯诺登愿协杭州发布十大产业高层次人才需求榜爱心的哥往返江山衢州接送尿毒症患者只叙利亚按期销毁化武设施台风“罗莎”进入南海 局部海域将现5长沙机场4个航班受炸弹威胁 其中两个战士吐槽办证难:户口20年没办好 参三位工人井底昏倒 德清民警王天辰冒死联合国称叙利亚完成对化武生产设施功能今起杭州地铁1号线周末末班车延迟至2楼盘装饰柱挡业主家窗户 屋顶外沿成小外交部对“世维会”质疑“10·28”男同事抽烟20多年对面办公桌女同事查美前高官督促安倍 克制“拜鬼”美医改网站频瘫痪奥巴马承诺负全责俄突击检查战略核力量智利沿海发生6.6级地震 圣地亚哥房批判竞争最狠的话:竞争属于失败者Windows Logo的30年进化张震:这世界欠你一部好电影当梦想照进现实——魅族第五代梦想MX9 本影响乔布斯一生的书南充市检察院调研营山县社区矫正工作贾大方专栏|粉丝教我如何做人:“呵呵相濡以沫,不如相望于江湖辽宁高层:保级很难,换帅未必管用白岩松:读书读久了,你总会信仰些什么从北京到武汉只有一家书店那么远森绘梨佳妆容示范:暖暖的、妩媚的、随焦作市装备制造技术研究中心揭牌Air Jordan 1 “Lase市政府召开第九次市长议事会议真实的日本是这样的,没去过的来看看吧市领导调研基层宣传思想文化工作愿它抹去我自身的神话,用它的火遮住我庞福水:救死扶伤五十载红包大战:背后是对银行的绞杀新常态下,科技如何引领经济发展
备案号:鲁ICP备13029499号-2 说三道四 www.s3d4.cn 说三道四技术文摘