控制台_控制台命令 - CSDN
控制台 订阅
控制台可以指:控制室内的专业家具;控制面板,Windows图形用户界面的一部分;命令行界面(CLI),也有人称之为字符用户界面(CUI);机械控制台,如交通工具的驾驶舱; 展开全文
控制台可以指:控制室内的专业家具;控制面板,Windows图形用户界面的一部分;命令行界面(CLI),也有人称之为字符用户界面(CUI);机械控制台,如交通工具的驾驶舱;
信息
外文名
Console
领    域
工程
中文名
控制台
控制台控制台
控制台(英语:Console),在运行关键任务的控制室当中,根据特殊的人体工程学设计制造的,为操作和调度人员提供可以承载各种办公设备和专用设备的专业家具。控制台应用范围非常广泛,涵盖电力生产和电力调度中心,核工业设施运行中心,能源生产中心,交通运行监控中心,航空航天任务监控中心,公共安全任务监控中心,金融交易中心监控中心,广播电视监控中心,工厂中控室等等非常多的应用场景,这些类型的控制室,监控中心,控制中心都属于关键任务控制环境(Mission Critical Control Environment),影响着经济与社会的有序运作。
收起全文
精华内容
参与话题
  • 控制台

    2019-10-10 20:22:27
    控制台(Console)是JS开发里最重要的面板,主要作用是显示网页加载过程中产生各类信息。 之前的开发经常用Firebug进行JS代码调试,Firebug是firefox下的一个扩展,能够调试所有网站语言,如Html,Css等,最吸引人的...

    console简介

    控制台(Console)是JS开发里最重要的面板,主要作用是显示网页加载过程中产生各类信息。

    之前的开发经常用Firebug进行JS代码调试,Firebug是firefox下的一个扩展,能够调试所有网站语言,如Html,Css等,最吸引人的就是javascript调试功能,使用起来非常方便,而且在各种浏览器下正常使用,但是目前为止Firebug 官网宣布已停止开发更新。

    但目前的浏览器自带的开发者工具类似于FireBug,一样可以使用。
    console对象,提供5种方法,用来显示信息
    日志信息console.log()、一般信息console.info()
    除错信息console.debug()、警告提示console.warn()
    错误提示console.error()
    console对象,提供5种方法,用来显示信息
    日志信息console.log()、一般信息console.info()
    除错信息console.debug()、警告提示console.warn()
    错误提示console.error()

    在这里插入图片描述

    chrome浏览器

    在这里插入图片描述

    Firefox浏览器

    在这里插入图片描述

    占位符

    console对象的上面5种方法,都可以使用printf(格式化输出)风格的占位符。不过,占位符的种类比较少,只支持字符(%s)、整数(%d或%i)、浮点数(%f)和对象(%o)、CSS格式化样式(%c)五种。
    在这里插入图片描述
    在这里插入图片描述
    %o占位符,可以用来查看一个对象内部情况。比如,有这样一个对象,对它使用o%占位符:
    在这里插入图片描述

    丰富样式输出

    可以使用%c进行css样式格式化输出。常见的富样式输出有两种:文字样式、图片输出。
    (1)文字样式
    在这里插入图片描述

    (2)%c可以写在任何地方,不限于开头,然后%c后面所有的输出会应用我们指定的样式。如果想单独对中间某几个字进行样式处理呢?
    在这里插入图片描述
    在这里插入图片描述
    如果信息太多,可以分组显示,用到的方法是console.group()和console.groupEnd()。

    在这里插入图片描述
    在这里插入图片描述

    注意:点击组标题,该组信息会折叠或展开;可以用console.groupEnd()引起来,也可以不引起来或者最后引起。

    console.dir()可以显示一个对象所有的属性和方法。
    在这里插入图片描述
    在这里插入图片描述

    console.dirxml()用来显示网页的某个节点(node)所包含的html/xml代码。
    在这里插入图片描述
    在这里插入图片描述

    console.clear()清空控制台内容
    在这里插入图片描述
    在这里插入图片描述

    计时器

    console.time(),console.timeEnd()方法计算一个操作的执行的时间console.time()是开始,console.timeEnd()是结束。
    可以传一个参数,参数为计时器的名称。
    在这里插入图片描述
    在这里插入图片描述

    计数器

    console.count()方法用于计数,输出它被调用了多少次。
    在这里插入图片描述
    在这里插入图片描述

    表格化

    console.table()方法可以将传入的对象或数组这些复合数据以表格形式输出。
    在这里插入图片描述
    在这里插入图片描述

    控制台快捷键

    1、方向键盘的上下键,一用就知晓。比如用上键就相当于使用上次在控制台的输入符号。
    2、$_命令返回最近一次表达式执行的结果,功能跟按向上的方向键再回车是一样的

    在这里插入图片描述

    3、Chrome 控制台中原生支持类jQuery的选择器,也就是说你可以用cssDOM加上熟悉的css选择器来选择DOM节点。例如(‘body’)
    4、$ 简单理解就是 document.querySelector 。
    5、$$ 简单理解就是 document.querySelectorAll 。
    6、$_ 是上一个表达式的值
    7、dir 就是 console.dir

    展开全文
  • 认识控制台-什么是控制台

    千次阅读 2006-04-29 21:43:00
    控制台管理字符模式程序的输入和输出(程序不需要提供他们自己的图形用户界面)。 控制台函数使访问不同级别的控制台成为可能。高级控制台 I/O 函数使程序可以从标准输入来重新得到存储在控制台输入缓冲区中的键盘...

    控制台管理字符模式程序的输入和输出(程序不需要提供他们自己的图形用户界面)。

    控制台函数使访问不同级别的控制台成为可能。高级控制台 I/O 函数使程序可以从标准输入来重新得到存储在控制台输入缓冲区中的键盘输入;这些函数也能够是程序可以向标准输出写或将错误显示在标准的控制台缓冲区中。高级别的控制台函数也支持重定向标准的句柄和不同 I/O 功能的控制台模式。低级别的 I/O 函数能够使程序接收详细的键盘输入和鼠标事件,以及控制台窗口和用户交互的事件。低级函数也是输出到屏幕较大的控制。
    控制台对简单字符模式程序提供高级的支持,其通过读写标准输入和输出以及标准错误函数来和用户交互。控制台也提供复杂低级支持,例如:直接访问控制台屏幕缓冲区以及接收额外输入信息(例如鼠标输入)。

    什么是控制台?

    控制台是一个用来提供字符模式 I/O 的接口。这种处理器独立的机制使导入一个存在的字符模式程序或创建一个新的字符模式工具和程序变的容易。

    控制由输入缓冲区和一到多哥屏幕缓冲区组成。输入缓冲区包含一个输入记录的序列,序列中是输入事件的信息。输入队列也包含键按下和松开键事件。它也能包括鼠标事件(指针移动和鼠标键按下或释放)以及用来影响活动屏幕区域大小的用户动作。屏幕缓冲区是一个控制台窗口的二维的字符数组和彩色数据。所有的处理能共享一个控制台。

    系统在启动一个控制台程序的时候创建一个控制台,控制台程序是一个字符模式的程序,入口是 main 函数。例如,系统在其他命令处理器是会创建一个新的控制台。当命令处理器开始一个新的控制台程序时,用户能指定系统是否为新的程序创建一个新的控制台还是从命令处理器控制台继承。

    一个程序可以使用下面的方法来创建一个控制台:

    1.  GUI 或控制台程序可以使用 CreateProcess 函数并带有 CREATE_NEW_CONSOLE 来创建一个带有新控制台的控制台程序。(默认的,控制台程序从它的父控制台中继承并且不能保证输出可以被程序接收)

    2.  GUI 或控制台进程没有附着到一个控制台上的,可以使用 AllocConsole 函数来创建一个新的控制台( GUI 程序在创建的时候不附着到控制台上,控制台进程在使用 DETACHED_PROCESS 标志的 CreateProcess 函数创建的时候也不附着到控制台上。

    典型的情况,一个程序在错误发生并请求用户交互的时候使用 AllocConsole 来创建一个控制台。例如,一个 GUI 程序在阻止使用正常图形接口程序错误发生的时候能创建一个控制台,或一个控制台进程没有正常地和用户交互可以创建一个控制台来显示错误。

    进程可以在调用 CreateProcess 的时候指定 CREATE_NEW_COSOLE 标志来创建一个控制台。这个方法创建一个控制对子进程可访问,而对父进程不可访问。独立的控制台对于是父子进程与用户不冲突的交互成为可能。如果这个标志在一个控制台进程创建的时候没有指定,两个进程都附着到相同的控制台上,并且不能保证正确的进程能接收到提供给他的输入。程序可以在创建子进程的时候不继承输入缓冲区的句柄来避免这种迷惑的情况,或者同时只有一个子进程继承输入缓冲区句柄来组织父亲进程在子进程没有完成的时候读控制台输入。

    创建一个新的控制台结果是一个新的控制台窗口,同时也包括独立的屏幕缓冲区。和新控制台关联的进程可以使用 GetStdHandle 函数来得到新的控制台输入和屏幕缓冲区的句柄。这些句柄使进程可以访问控制台。

    当一个进程使用 CreateProcess ,它可以指定一个 STARTUPINFO 结构,该结构的成员控制为子进程创建的第一个新控制台的特性。如果 CREATE_NEW_CONSOLE 标志被指定, STARTUPINFO 结构在调用 CreateProcess 时候影响一个控制台的创建;它也影响子进程后来使用 AllocConsole 来创建控制台。下面的控制台特性可以指定:

    1.  新控制台窗口的大小,字符单元

    2.  新控制台窗口的位置,屏幕像素坐标

    3.  新控制台屏幕缓冲区的文本和背景颜色属性

    4.  新控制台窗口的 TITLE BAR 上的显示名字

    如果 STARTUPINFO 值没有指定,系统使用默认的值。子进程可以使用 GetStartupInfo 函数来判断 STARTUPINFO 结构中的值。

    进程不能改变控制台窗口在屏幕上的位置,但下面的控制台函数可以用来设置和获得 STARTUPINFO 结构的其他属性。

    函数

    描述

    GetConsoleScreenBufferInfo

    返回窗口大小、屏幕缓冲区大小和颜色属性

    SetConsoleWindowInfo

    改变控制台窗口的大小

    SetConsoleScreenBufferSize

    该表控制台屏幕缓冲区的大小

    SetConsoleTextAttribute

    设置颜色属性

    SetConsoleTitle

    设置控制台窗口的标题

    GetConsoleTitle

    获得控制窗口的标题

    进程可以使用 FreeConsole 函数来分离继承的控制台或通过 AllocConsole 创建的控制台。

    展开全文
  • C++控制台操作(基本操作的代码)

    万次阅读 多人点赞 2012-06-08 13:35:03
    控制台窗口界面编程控制 〇、摘要 一、概述 二、控制台文本窗口的一般控制步骤 三、控制台窗口操作 四、文本属性操作 五、文本输出 六、文本操作示例 七、滚动和移动 八、光标操作 九、读取键盘...

    控制台窗口界面编程控制

    〇、摘要

    一、概述

    二、控制台文本窗口的一般控制步骤

    三、控制台窗口操作

    四、文本属性操作

    五、文本输出

    六、文本操作示例

    七、滚动和移动

    八、光标操作

    九、读取键盘信息

    十、读取鼠标信息

    十一、结语

    补充篇--经典程序(Internet资源)

    摘要:

    文本界面的控制台应用程序开发是深入学习C++、掌握交互系统的实现方法的最简单的一种手段。然而,Visual C++的C++专用库却没有TC所支持的文本(字符)屏幕控制函数,为此本系列文章从一般控制步骤、控制台窗口操作、文本(字符)控制、滚动和移动光标、键盘和鼠标等几个方面讨论控制台窗口界面的编程控制方法。

    在众多C++开发工具中,由于Microsoft本身的独特优势,选用 Visual C++已越来越被众多学习者所接受。显然,现今如果还再把TC作为开发环境的话,不仅没有必要,而且也不利于向Windows应用程序开发的过渡。然而,Visual C++的C++专用库却没有TC所支持的文本屏幕(控制台窗口)控制函数(相应的头文件是conio.h)。这必然给C++学习者在文本界面设计和编程上带来诸多不便。要知道,文本界面设计是一种深入学习C++、掌握交互系统的实现方法的最简单的一种手段,它不像C++的Windows图形界面应用 程序,涉及知识过多。为此,本系列文章来讨论在Visual C++ 6.0开发环境中,如何编写具有美观清晰的控制台窗口界面的C++应用程序。


    (一) 概述操作

    所谓控制台应用程序,就是指那些需要与传统DOS操作系统保持某种程序的兼容,同时又不需要为用户提供完善界面的程序。简单地讲,就是指在Windows环境下运行的DOS程序。一旦控制台应用程序在Windows操作系统中运行后,就会弹出一个窗口。例如下列代码:

    #include <stdio.h>

    int main(int argc,char *argv[])

    {

           printf("Hello, Console!\n");

           return 0;

    }

    单击小型编译工具栏中的“Build”按钮或按F7键,系统出现一个对话框,询问是否将此项目的工作文件夹设定源文件所在的文件夹,单击[是]按钮,系统开始编译。 单击小型编译工具栏中的“Execute Program”按钮或按Ctrl+F5键,运行刚才的程序。 程序运行后,弹出下图的窗口:

     

    这就是控制台窗口,与传统的DOS屏幕窗口相比最主要的区别有:

    (1) 默认的控制台窗口有系统菜单和标题,它是一个内存缓冲区窗口,缓冲区大小取决于Windows操作系统的分配;而DOS屏幕是一种物理窗口,不具有Windows窗口特性,其大小取决于ROM BIOS分配的内存空间。

    (2) 控制台窗口的文本操作是调用低层的Win32 APIs,而DOS屏幕的文本操作是通过调用BIOS的16(10h)中断而实现的。

    (3) 默认的控制台窗口可以接收键盘和鼠标的输入信息,设备驱动由Windows管理,而DOS屏幕窗口接收鼠标时需要调用33h中断,且鼠标设备驱动程序由自己安装。


    (二)    控制台文本窗口的一般控制步骤

    在Visual C++ 6.0中,控制台窗口界面的一般编程控制步骤如下:调用GetStdHandle获取当前的标准输入(STDIN)和标准输出(STDOUT)设备句柄。函数原型为:

    HANDLE GetStdHandle( DWORD nStdHandle );

    其中,nStdHandle可以是STD_INPUT_HANDLE(标准输入设备句柄)、STD_OUTPUT_HANDLE(标准输出设备句柄)和 STD_ERROR_HANDLE(标准错误句柄)。

    需要说明的是,“句柄”是Windows最常用的概念。它通常用来标识Windows资源(如菜单、 图标、窗口等)和设备等对象。虽然可以把句柄理解为是一个指针变量类型,但它不是对象所在的地址指针,而是作为Windows系统内部表的索引值来使用 的。调用相关文本界面控制的API函数。这些函数可分为三类。一是用于控制台窗口操作的函数(包括窗口的缓冲区大小、窗口前景字符和背景颜色、窗口标题、大小和位置等);二是用于控制台输入输出的函数(包括字符属性操作函数);其他的函数并为最后一类。 调用CloseHandle()来关闭输入输出句柄。 注意,在程序中还必须包含头文件windows.h。下面看一个程序:

    #include <windows.h>

    #include <stdio.h>

    #include <conio.h>

    int main(void)

    {

           HANDLE hOut;

           CONSOLE_SCREEN_BUFFER_INFO bInfo; // 存储窗口信息

           COORD pos = {0, 0};

           // 获取标准输出设备句柄

           hOut = GetStdHandle(STD_OUTPUT_HANDLE);

           // 获取窗口信息

           GetConsoleScreenBufferInfo(hOut, &bInfo );

           printf("\n\nThe soul selects her own society\n");

           printf("Then shuts the door\n");

           printf("On her devine majority\n");

           printf("Obtrude no more\n\n");

           _getch();

           // 向窗口中填充字符以获得清屏的效果

           FillConsoleOutputCharacter(hOut,' ', bInfo.dwSize.X * bInfo.dwSize.Y, pos, NULL);

           // 关闭标准输出设备句柄

           CloseHandle(hOut);

           return 0;

    }

     

    程序中,COORD和CONSOLE_SCREEN_BUFFER_ INFO是wincon.h定义的控制台结构体类型,其原型如下:

    // 坐标结构体

    typedef struct _COORD {

    SHORT X;

    SHORT Y;

    } COORD;

    // 控制台窗口信息结构体

    typedef struct _CONSOLE_SCREEN_BUFFER_INFO {

    COORD dwSize; // 缓冲区大小

    COORD dwCursorPosition; // 当前光标位置

    WORD wAttributes; // 字符属性

    SMALL_RECT srWindow; // 当前窗口显示的大小和位置

    COORD dwMaximumWindowSize; // 最大的窗口缓冲区大小

    } CONSOLE_SCREEN_BUFFER_INFO ;

    还需要说明的是,虽然在C++中,iostream.h定义了cin和cout的标准输入和输出流对象。但它们只能实现基本的输入输出 操作,对于控制台窗口界面的控制却无能为力,而且不能与stdio.h和conio.h友好相处,因为iostream.h和它们是C++两套不同的输入 输出操作方式,使用时要特别注意。


    (三)   控制台窗口操作操作

    用于控制台窗口操作的API函数如下:

    GetConsoleScreenBufferInfo 获取控制台窗口信息

    GetConsoleTitle 获取控制台窗口标题

    ScrollConsoleScreenBuffer 在缓冲区中移动数据块

    SetConsoleScreenBufferSize 更改指定缓冲区大小

    SetConsoleTitle 设置控制台窗口标题

    SetConsoleWindowInfo 设置控制台窗口信息

    此外,还有窗口字体、显示模式等控制函数,这里不再细说。下列举一个示例,程序如下:

    #include <windows.h>

    #include <stdio.h>

    #include <conio.h>

    int main(void)

    {

           char strTitle[255];

           CONSOLE_SCREEN_BUFFER_INFO bInfo; // 窗口缓冲区信息

           COORD size = {80, 25};

           HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE); // 获取标准输出设备句柄

           GetConsoleScreenBufferInfo(hOut, &bInfo ); // 获取窗口缓冲区信息

           GetConsoleTitle(strTitle, 255); // 获取窗口标题

           printf("当前窗口标题是:\n%s\n", strTitle);

           _getch();

           SetConsoleTitle("控制台窗口操作"); // 设置窗口标题

           GetConsoleTitle(strTitle, 255);

           printf("当前窗口标题是:\n%s\n", strTitle);

           _getch();

           SetConsoleScreenBufferSize(hOut,size); // 重新设置缓冲区大小

           _getch();

           SMALL_RECT rc = {0,0, 80-1, 25-1}; // 重置窗口位置和大小

           SetConsoleWindowInfo(hOut,true ,&rc);

           CloseHandle(hOut); // 关闭标准输出设备句柄

           return 0;

    }

    需要说明的是,控制台窗口的原点坐标是(0, 0),而最大的坐标是缓冲区大小减1,例如当缓冲区大小为80*25时,其最大的坐标是(79, 24)。


    (四) 文本属性操作操作

    与DOS字符相似,控制台窗口中的字符也有相应的属性。这些属性分为:文本的前景色、背景色和双字节字符集(DBCS)属性三种。事实上,我们最关心是文本颜色,这样可以构造出美观的界面。颜色属性都是一些预定义标识:

    FOREGROUND_BLUE 蓝色

    FOREGROUND_GREEN 绿色

    FOREGROUND_RED 红色

    FOREGROUND_INTENSITY 加强

    BACKGROUND_BLUE 蓝色背景

    BACKGROUND_GREEN 绿色背景

    BACKGROUND_RED 红色背景

    BACKGROUND_INTENSITY 背景色加强

    COMMON_LVB_REVERSE_VIDEO 反色

    与文本属性相关的主要函数有:

    BOOL FillConsoleOutputAttribute( // 填充字符属性

    HANDLE hConsoleOutput, // 句柄

    WORD wAttribute, // 文本属性

    DWORD nLength, // 个数

    COORD dwWriteCoord, // 开始位置

    LPDWORD lpNumberOfAttrsWritten // 返回填充的个数

    );

    BOOL SetConsoleTextAttribute( // 设置WriteConsole等函数的字符属性

    HANDLE hConsoleOutput, // 句柄

    WORD wAttributes // 文本属性

    );

    BOOL WriteConsoleOutputAttribute( // 在指定位置处写属性

    HANDLE hConsoleOutput, // 句柄

    CONST WORD *lpAttribute, // 属性

    DWORD nLength, // 个数

    COORD dwWriteCoord, // 起始位置

    LPDWORD lpNumberOfAttrsWritten // 已写个数

    );

    另外,获取当前控制台窗口的文本属性是通过调用函数GetConsoleScreenBufferInfo后,在CONSOLE_SCREEN_ BUFFER_INFO结构成员wAttributes中得到。


    (五) 文本输出

    操作文本输出函数有:

    BOOL FillConsoleOutputCharacter( // 填充指定数据的字符

    HANDLE hConsoleOutput, // 句柄

    TCHAR cCharacter, // 字符

    DWORD nLength, // 字符个数

    COORD dwWriteCoord, // 起始位置

    LPDWORD lpNumberOfCharsWritten);// 已写个数

    BOOL WriteConsole( // 在当前光标位置处插入指定数量的字符

    HANDLE hConsoleOutput, // 句柄

    CONST VOID *lpBuffer, // 字符串

    DWORD nNumberOfCharsToWrite, // 字符个数

    LPDWORD lpNumberOfCharsWritten, // 已写个数

    LPVOID lpReserved);// 保留

     

    BOOL WriteConsoleOutput( // 向指定区域写带属性的字符

    HANDLE hConsoleOutput, // 句柄

    CONST CHAR_INFO *lpBuffer, // 字符数据区

    COORD dwBufferSize, // 数据区大小

    COORD dwBufferCoord, // 起始坐标

    PSMALL_RECT lpWriteRegion );// 要写的区域

     

    BOOL WriteConsoleOutputCharacter( // 在指定位置处插入指定数量的字符

    HANDLE hConsoleOutput, // 句柄

    LPCTSTR lpCharacter, // 字符串

    DWORD nLength, // 字符个数

    COORD dwWriteCoord, // 起始位置

    LPDWORD lpNumberOfCharsWritten); // 已写个数

     

    可以看出:WriteConsoleOutput函数功能相当于SetConsoleTextAttribute和WriteConsole 的功能。而WriteConsoleOutputCharacter函数相当于SetConsoleCursorPosition(设置光标位置)和 WriteConsole的功能。不过在具体使用要注意它们的区别。


    (六) 文本操作示例操作

    下面看一个示例程序:

    // 在具有阴影效果的窗口中显示一行字符

    #include <windows.h>

    HANDLE hOut;

    void ShadowWindowLine(char *str);

    void DrawBox(bool bSingle, SMALL_RECT rc); // 绘制边框

    int main(void)

    {

           hOut = GetStdHandle(STD_OUTPUT_HANDLE); // 获取标准输出设备句柄

           SetConsoleOutputCP(437); // 设置代码页,这里如果设置成936(简体中文),那么程序会怎样?那样的话,将画不出边框。

           ShadowWindowLine("Display a line of words, and center the window with shadow.");

           CloseHandle(hOut); // 关闭标准输出设备句柄

           return 0;

    }

    void ShadowWindowLine(char *str)

    {

           SMALL_RECT rc;

           CONSOLE_SCREEN_BUFFER_INFO bInfo; // 窗口缓冲区信息

           WORD att0,att1,attText;

           int i, chNum = strlen(str);

           GetConsoleScreenBufferInfo( hOut, &bInfo ); // 获取窗口缓冲区信息

           // 计算显示窗口大小和位置

           rc.Left = (bInfo.dwSize.X - chNum)/2 - 2;

           rc.Top = 8; // 原代码段中此处为bInfo.dwSize.Y/2 - 2,但是如果您的DOS屏幕有垂直滚动条的话,还需要把滚动条下拉才能看到,为了方便就把它改为10

           rc.Right = rc.Left + chNum + 4;

           rc.Bottom = rc.Top + 4;

           att0 = BACKGROUND_INTENSITY; // 阴影属性

           att1 = FOREGROUND_RED |FOREGROUND_GREEN |FOREGROUND_BLUE | FOREGROUND_INTENSITY | BACKGROUND_RED | BACKGROUND_BLUE;// 文本属性

           attText = FOREGROUND_RED |FOREGROUND_INTENSITY; // 文本属性

           // 设置阴影然后填充

           COORD posShadow = {rc.Left+1, rc.Top+1}, posText = {rc.Left, rc.Top};

           for (i=0; i<5; i++)

           {

                  FillConsoleOutputAttribute(hOut, att0, chNum + 4, posShadow, NULL);

                  posShadow.Y++;

           }

           for (i=0;i<5;i++)

           {

                  FillConsoleOutputAttribute(hOut, att1,chNum + 4, posText, NULL);

                  posText.Y++;

           }

           // 写文本和边框

           posText.X = rc.Left + 2;

           posText.Y = rc.Top + 2;

           WriteConsoleOutputCharacter(hOut, str, strlen(str), posText, NULL);

           DrawBox(true, rc);

           SetConsoleTextAttribute(hOut, bInfo.wAttributes); // 恢复原来的属性

    }

    void DrawBox(bool bSingle, SMALL_RECT rc) // 函数功能:画边框

    {

           char chBox[6];

           COORD pos;

           if (bSingle)

           {

                  chBox[0] = (char)0xda; // 左上角点

                  chBox[1] = (char)0xbf; // 右上角点

                  chBox[2] = (char)0xc0; // 左下角点

                  chBox[3] = (char)0xd9; // 右下角点

                  chBox[4] = (char)0xc4; // 水平

                  chBox[5] = (char)0xb3; // 坚直

           } else {

                  chBox[0] = (char)0xc9; // 左上角点

                  chBox[1] = (char)0xbb; // 右上角点

                  chBox[2] = (char)0xc8; // 左下角点

                  chBox[3] = (char)0xbc; // 右下角点

                  chBox[4] = (char)0xcd; // 水平

                  chBox[5] = (char)0xba; // 坚直

           }

           // 画边框的上 下边界

           for(pos.X = rc.Left+1;pos.X<rc.Right-1;pos.X++)

           {    

                  pos.Y = rc.Top;

                  // 画上边界

                  WriteConsoleOutputCharacter(hOut, &chBox[4], 1, pos, NULL);

                  // 画左上角

                  if(pos.X == rc.Left+1)

                  {

                         pos.X--;

                         WriteConsoleOutputCharacter(hOut, &chBox[0],1, pos, NULL);

                         pos.X++;

                  }

                  // 画右上角

                  if(pos.X == rc.Right-2)

                  {

                         pos.X++;

                         WriteConsoleOutputCharacter(hOut, &chBox[1], 1, pos, NULL);

                         pos.X--;

                  }

                  pos.Y = rc.Bottom;

                  // 画下边界

                  WriteConsoleOutputCharacter(hOut, &chBox[4], 1, pos, NULL);

                  // 画左下角

                  if(pos.X == rc.Left+1)

                  {

                         pos.X--;

                         WriteConsoleOutputCharacter(hOut, &chBox[2], 1, pos, NULL);

                         pos.X++;

                  }

                  // 画右下角

                  if(pos.X==rc.Right-2)

                  {

                         pos.X++;

                         WriteConsoleOutputCharacter(hOut, &chBox[3], 1, pos, NULL);

                         pos.X--;

                  }

           }

           // 画边框的左右边界

           for (pos.Y = rc.Top+1; pos.Y<=rc.Bottom-1; pos.Y++)

           {

                  pos.X = rc.Left;

                  // 画左边界

                  WriteConsoleOutputCharacter(hOut, &chBox[5], 1, pos, NULL);

                  pos.X = rc.Right-1;

                  // 画右边界

                  WriteConsoleOutputCharacter(hOut, &chBox[5], 1, pos, NULL);

           }

    }

    程序运行结果如下图所示:

     

    需要说明的是:

    ①在上述例子中,如果调用DrawBox函数时,传递的第一个参数不是true而是false,那么画出来的边框将是双线的。运行结果如下:

     

    ②如果在上述程序无法编译通过,您可以这样修改,即程序中调用WriteConsoleOutputCharacter和FillConsoleOutputAttribute函数的时候,最后一个参数不用NULL,而是先定义一个变量:

    DWORD written;

    然后把 &written作为最后一个参数。

    ③上述程序在不同的字符代码页面(code page)下显示的结果是不同的。例如,中文Windows操作系统的默认代码页是简体中文(936),在该代码页面下值超过128的单字符在Windows NT/XP是显示不出来的。下表列出了可以使用的代码页。

    代码页(Code page)   说明

    1258       越南文

    1257       波罗的海文

    1256       阿拉伯文

    1255       希伯来文

    1254       土耳其语

    1253       希腊文

    1252       拉丁文(ANSI)

    1251       斯拉夫文

    1250       中欧文

    950  繁体中文

    949  韩文

    936  简体中文

    932  日文

    874  泰文

    850  使用多种语言(MS-DOS拉丁文)

    437  MS-DOS美语/英语

     

    (七) 滚动和移动操作

    ScrollConsoleScreenBuffer是实现文本区滚动和移动的API函数。它可以将指定的一块文本区域移动到另一个区域,被移空的那块区域由指定字符填充。函数的原型如下:

    BOOL ScrollConsoleScreenBuffer(

    HANDLE hConsoleOutput, // 句柄

    CONST SMALL_RECT* lpScrollRectangle, // 要滚动或移动的区域

    CONST SMALL_RECT* lpClipRectangle, // 裁剪区域

    COORD dwDestinationOrigin, // 新的位置

    CONST CHAR_INFO* lpFill // 填充字符

    );

    利用这个API函数还可以实现删除指定行的操作。下面来举一个例子,程序如下:

    #include <windows.h>

    #include <stdio.h>

    #include <conio.h>

    HANDLE hOut;

    void DeleteLine(int row); // 删除一行

    void MoveText(int x, int y, SMALL_RECT rc); // 移动文本块区域

    void ClearScreen(void); // 清屏

    int main(void)

    {

           hOut = GetStdHandle(STD_OUTPUT_HANDLE); // 获取标准输出设备句柄

           WORD att = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_INTENSITY | BACKGROUND_BLUE;// 背景是蓝色,文本颜色是黄色

           SetConsoleTextAttribute(hOut, att);

           ClearScreen();

           printf("\n\nThe soul selects her own society\n");

           printf("Then shuts the door;\n");

           printf("On her devine majority;\n");

           printf("Obtrude no more.\n\n");

           COORD endPos = {0, 15};

           SetConsoleCursorPosition(hOut, endPos); // 设置光标位置

           SMALL_RECT rc = {0, 2, 40, 5};

           _getch();

           MoveText(10, 5, rc);

           _getch();

           DeleteLine(5);

           CloseHandle(hOut); // 关闭标准输出设备句柄

           return 0;

    }

    void DeleteLine(int row)

    {

           SMALL_RECT rcScroll, rcClip;

           COORD crDest = {0, row - 1};

           CHAR_INFO chFill;

           CONSOLE_SCREEN_BUFFER_INFO bInfo;

           GetConsoleScreenBufferInfo( hOut, &bInfo );

           rcScroll.Left = 0;

           rcScroll.Top = row;

           rcScroll.Right = bInfo.dwSize.X - 1;

           rcScroll.Bottom = bInfo.dwSize.Y - 1;

           rcClip = rcScroll;

           chFill.Attributes = bInfo.wAttributes;

           chFill.Char.AsciiChar = ' ';

           ScrollConsoleScreenBuffer(hOut, &rcScroll, &rcClip, crDest, &chFill);

    }

    void MoveText(int x, int y, SMALL_RECT rc)

    {

           COORD crDest = {x, y};

           CHAR_INFO chFill;

           CONSOLE_SCREEN_BUFFER_INFO bInfo;

           GetConsoleScreenBufferInfo( hOut, &bInfo );

           chFill.Attributes = bInfo.wAttributes;

           chFill.Char.AsciiChar = ' ';

           ScrollConsoleScreenBuffer(hOut, &rc, NULL, crDest, &chFill);

    }

    void ClearScreen(void)

    {

           CONSOLE_SCREEN_BUFFER_INFO bInfo;

           GetConsoleScreenBufferInfo( hOut, &bInfo );

           COORD home = {0, 0};

           WORD att = bInfo.wAttributes;

           unsigned long size = bInfo.dwSize.X * bInfo.dwSize.Y;

           FillConsoleOutputAttribute(hOut, att, size, home, NULL);

           FillConsoleOutputCharacter(hOut, ' ', size, home, NULL);

    }

    程序中,实现删除行的操作DeleteLine的基本原理是:首先将裁剪区域和移动区域都设置成指定行row(包括该行)以下的控制台窗口区域,然后将移动的位置指定为(0, row-1)。这样,超出裁剪区域的内容被裁剪掉,从而达到删除行的目的。

    需要说明的是,若裁剪区域参数为NULL,则裁剪区域为整个控制台窗口。


    (八) 光标操作操作

    控制台窗口中的光标反映了文本插入的当前位置,通过SetConsoleCursorPosition函数可以改变这个“当前”位置,这样就能控制字符(串)输出。事实上,光标本身的大小和显示或隐藏也可以通过相应的API函数进行设定。例如:

    BOOL SetConsoleCursorInfo( // 设置光标信息

    HANDLE hConsoleOutput, // 句柄

    CONST CONSOLE_CURSOR_INFO *lpConsoleCursorInfo // 光标信息

    );

    BOOL GetConsoleCursorInfo( // 获取光标信息

    HANDLE hConsoleOutput, // 句柄

    PCONSOLE_CURSOR_INFO lpConsoleCursorInfo // 返回光标信息

    );

    这两个函数都与CONSOLE_CURSOR_INFO结构体类型有关,其定义如下:

    typedef struct _CONSOLE_CURSOR_INFO {

    DWORD dwSize; // 光标百分比大小

    BOOL bVisible; // 是否可见

    } CONSOLE_CURSOR_INFO, *PCONSOLE_CURSOR_INFO;

    需要说明的是,dwSize值反映了光标的大小,它的值范围为1-100;当为1时,光标最小,仅是一条最靠下的水平细线,当为100,光标最大,为一个字符大小的方块。

    (九) 读取键盘信息操作

      键盘事件通常有字符事件和按键事件,这些事件所附带的信息构成了键盘信息。它是通过API函数ReadConsoleInput来获取的,其原型如下:

    BOOL ReadConsoleInput(

    HANDLE hConsoleInput, // 输入设备句柄

    PINPUT_RECORD lpBuffer, // 返回数据记录

    DWORD nLength, // 要读取的记录数

    LPDWORD lpNumberOfEventsRead // 返回已读取的记录数

    );

    其中,INPUT_RECORD定义如下:

    typedef struct _INPUT_RECORD {

    WORD EventType; // 事件类型

    union {

    KEY_EVENT_RECORD KeyEvent;

    MOUSE_EVENT_RECORD MouseEvent;

    WINDOW_BUFFER_SIZE_RECORD WindowBufferSizeEvent;

    MENU_EVENT_RECORD MenuEvent;

    FOCUS_EVENT_RECORD FocusEvent;

    } Event;

    } INPUT_RECORD;

    与键盘事件相关的记录结构KEY_EVENT_RECORD定义如下:

    typedef struct _KEY_EVENT_RECORD {

    BOOL bKeyDown; // TRUE表示键按下,FALSE表示键释放

    WORD wRepeatCount; // 按键次数

    WORD wVirtualKeyCode; // 虚拟键代码

    WORD wVirtualScanCode; // 虚拟键扫描码

    union {

    WCHAR UnicodeChar; // 宽字符

    CHAR AsciiChar; // ASCII字符

    } uChar; // 字符

    DWORD dwControlKeyState; // 控制键状态

    } KEY_EVENT_RECORD;

    我们知道,键盘上每一个有意义的键都对应着一个唯一的扫描码,虽然扫描码可以作为键的标识,但它依赖于具体设备的。因此,在应用程序中,使用的往往是与具体设备无关的虚拟键代码。这种虚拟键代码是与设备无关的键盘编码。在Visual C++中,最常用的虚拟键代码已被定义在Winuser.h中,例如:VK_SHIFT表示SHIFT键,VK_F1表示功能键F1等。上述结构定义中,dwControlKeyState用来表示控制键状态,它可以是CAPSLOCK_ON(CAPS LOCK灯亮)、ENHANCED_KEY(按下扩展键)、LEFT_ALT_PRESSED(按下左ALT键)、 LEFT_CTRL_PRESSED(按下左CTRL键)、NUMLOCK_ON (NUM LOCK灯亮)、RIGHT_ALT_PRESSED(按下右ALT键)、RIGHT_CTRL_PRESSED(按下右CTRL键)、 SCROLLLOCK_ON(SCROLL LOCK灯亮)和SHIFT_PRESSED(按下SHIFT键)中的一个或多个值的组合。下面的程序是将用户按键的字符输入到一个控制台窗口的某个区域中,并当按下NUM LOCK、CAPS LOCK和SCROLL LOCK键时,在控制台窗口的最后一行显示这些键的状态。

    #include <windows.h>

    HANDLE hOut;

    HANDLE hIn;

    void DrawBox(bool bSingle, SMALL_RECT rc); // 这个自定义函数在第六章用过

    void ClearScreen(void);

    void CharWindow(char ch, SMALL_RECT rc); // 将ch输入到指定的窗口中

    void ControlStatus(DWORD state); // 在最后一行显示控制键的状态

    void DeleteTopLine(SMALL_RECT rc); // 删除指定窗口中最上面的行并滚动

    int main(void)

    {

           hOut = GetStdHandle(STD_OUTPUT_HANDLE); // 获取标准输出设备句柄

           hIn = GetStdHandle(STD_INPUT_HANDLE); // 获取标准输入设备句柄

           WORD att = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_INTENSITY | BACKGROUND_BLUE ; // 背景是蓝色,文本颜色是黄色

           SetConsoleTextAttribute(hOut, att);

           ClearScreen(); // 清屏

           INPUT_RECORD keyRec;

           DWORD state = 0, res;

           char ch;

           SMALL_RECT rc = {20, 2, 40, 12};

           DrawBox(false, rc);

           COORD pos = {rc.Left+1, rc.Top+1};

           SetConsoleCursorPosition(hOut, pos); // 设置光标位置

           for(;;) // 循环

           {

                  ReadConsoleInput(hIn, &keyRec, 1, &res);

                  if (state != keyRec.Event.KeyEvent.dwControlKeyState)

                  {

                         state = keyRec.Event.KeyEvent.dwControlKeyState;

                         ControlStatus(state);

                  }

                  if (keyRec.EventType == KEY_EVENT)

                  {

                         if (keyRec.Event.KeyEvent.wVirtualKeyCode == VK_ESCAPE)

                                break;

                         // 按ESC键退出循环

                         if (keyRec.Event.KeyEvent.bKeyDown)

                         {

                                ch = keyRec.Event.KeyEvent.uChar.AsciiChar;

                                CharWindow(ch, rc);

                         }

                  }

           }

           pos.X = 0; pos.Y = 0;

           SetConsoleCursorPosition(hOut, pos); // 设置光标位置

           CloseHandle(hOut); // 关闭标准输出设备句柄

           CloseHandle(hIn); // 关闭标准输入设备句柄

           return 0;

    }

     

    void CharWindow(char ch, SMALL_RECT rc) // 将ch输入到指定的窗口中

    {

           static COORD chPos = {rc.Left+1, rc.Top+1};

           SetConsoleCursorPosition(hOut, chPos); // 设置光标位置

           if ((ch<0x20)||(ch>0x7e)) // 如果是不可打印的字符,具体查看ASCII码表

                  return;

           WriteConsoleOutputCharacter(hOut, &ch, 1, chPos, NULL);

           if (chPos.X >= (rc.Right-2))

           {

                  chPos.X = rc.Left;

                  chPos.Y++;

           }

           if (chPos.Y>(rc.Bottom-1))

           {

                  DeleteTopLine(rc);

                  chPos.Y = rc.Bottom-1;

           }

           chPos.X++;

           SetConsoleCursorPosition(hOut, chPos); // 设置光标位置

    }

     

    void ControlStatus(DWORD state) // 在第一行显示控制键的状态

    {

           CONSOLE_SCREEN_BUFFER_INFO bInfo;

           GetConsoleScreenBufferInfo( hOut, &bInfo );

           COORD home = {0, 24}; // 原来此处为bInfo.dwSize.Y-1,但为了更便于观察,我把这里稍微修改了一下

           WORD att0 = BACKGROUND_INTENSITY ;

           WORD att1 = FOREGROUND_GREEN | FOREGROUND_INTENSITY | BACKGROUND_RED;

           FillConsoleOutputAttribute(hOut, att0, bInfo.dwSize.X, home, NULL);

           FillConsoleOutputCharacter(hOut, ' ', bInfo.dwSize.X, home, NULL);

           SetConsoleTextAttribute(hOut, att1);

           COORD staPos = {bInfo.dwSize.X-16,24}; // 原来此处为bInfo.dwSize.Y-1

           SetConsoleCursorPosition(hOut, staPos);

           if (state & NUMLOCK_ON)

                  WriteConsole(hOut, "NUM", 3, NULL, NULL);

           staPos.X += 4;

           SetConsoleCursorPosition(hOut, staPos);

           if (state & CAPSLOCK_ON)

                  WriteConsole(hOut, "CAPS", 4, NULL, NULL);

           staPos.X += 5;

           SetConsoleCursorPosition(hOut, staPos);

           if (state & SCROLLLOCK_ON)

                  WriteConsole(hOut, "SCROLL", 6, NULL, NULL);

           SetConsoleTextAttribute(hOut, bInfo.wAttributes); // 恢复原来的属性

           SetConsoleCursorPosition(hOut, bInfo.dwCursorPosition); // 恢复原来的光标位置

    }

    void DeleteTopLine(SMALL_RECT rc)

    {

           COORD crDest;

           CHAR_INFO chFill;

           SMALL_RECT rcClip = rc;

           rcClip.Left++;

           rcClip.Right -= 2;

           rcClip.Top++;

           rcClip.Bottom--;

           crDest.X = rcClip.Left;

           crDest.Y = rcClip.Top - 1;

           CONSOLE_SCREEN_BUFFER_INFO bInfo;

           GetConsoleScreenBufferInfo( hOut, &bInfo );

           chFill.Attributes = bInfo.wAttributes;

           chFill.Char.AsciiChar = ' ';

           ScrollConsoleScreenBuffer(hOut, &rcClip, &rcClip, crDest, &chFill);

    }

    void ClearScreen(void)

    {

           CONSOLE_SCREEN_BUFFER_INFO bInfo;

           GetConsoleScreenBufferInfo( hOut, &bInfo );

           COORD home = {0, 0};

           WORD att = bInfo.wAttributes;

           unsigned long size = bInfo.dwSize.X * bInfo.dwSize.Y;

           FillConsoleOutputAttribute(hOut, att, size, home, NULL);

           FillConsoleOutputCharacter(hOut, ' ', size, home, NULL);

    }

    // 函数功能:画边框

    void DrawBox(bool bSingle, SMALL_RECT rc)

    {

           char chBox[6];

           COORD pos;

           if (bSingle)

           {

                  chBox[0] = (char)0xda; // 左上角点

                  chBox[1] = (char)0xbf; // 右上角点

                  chBox[2] = (char)0xc0; // 左下角点

                  chBox[3] = (char)0xd9; // 右下角点

                  chBox[4] = (char)0xc4; // 水平

                  chBox[5] = (char)0xb3; // 坚直

           }

           else

           {

                  chBox[0] = (char)0xc9; // 左上角点

                  chBox[1] = (char)0xbb; // 右上角点

                  chBox[2] = (char)0xc8; // 左下角点

                  chBox[3] = (char)0xbc; // 右下角点

                  chBox[4] = (char)0xcd; // 水平

                  chBox[5] = (char)0xba; // 坚直

           }

           // 画边框的上 下边界

           for(pos.X = rc.Left+1;pos.X<rc.Right-1;pos.X++)

           {    

                  pos.Y = rc.Top;

                  // 画上边界

                  WriteConsoleOutputCharacter(hOut, &chBox[4], 1, pos, NULL);

                  // 画左上角

                  if(pos.X == rc.Left+1)

                  {

                         pos.X--;

                         WriteConsoleOutputCharacter(hOut, &chBox[0],1, pos, NULL);

                         pos.X++;

                  }

                  // 画右上角

                  if(pos.X == rc.Right-2)

                  {

                         pos.X++;

                         WriteConsoleOutputCharacter(hOut, &chBox[1], 1, pos, NULL);

                         pos.X--;

                  }

                  pos.Y = rc.Bottom;

                  // 画下边界

                  WriteConsoleOutputCharacter(hOut, &chBox[4], 1, pos, NULL);

                  // 画左下角

                  if(pos.X == rc.Left+1)

                  {

                         pos.X--;

                         WriteConsoleOutputCharacter(hOut, &chBox[2], 1, pos, NULL);

                         pos.X++;

                  }

                  // 画右下角

                  if(pos.X==rc.Right-2)

                  {

                         pos.X++;

                         WriteConsoleOutputCharacter(hOut, &chBox[3], 1, pos, NULL);

                         pos.X--;

                  }

     

           }

           // 画边框的左右边界

           for (pos.Y = rc.Top+1; pos.Y<=rc.Bottom-1; pos.Y++)

           {

                  pos.X = rc.Left;

                  // 画左边界

                  WriteConsoleOutputCharacter(hOut, &chBox[5], 1, pos, NULL);

                  pos.X = rc.Right-1;

                  // 画右边界

                  WriteConsoleOutputCharacter(hOut, &chBox[5], 1, pos, NULL);

           }

    }

    当你输入画面中句子时,运行结果如下图:

     


    (十) 读取鼠标信息操作

    与读取键盘信息方法相似,鼠标信息也是通过ReadConsoleInput来获取的,其MOUSE_EVENT_RECORD具有下列定义:

    typedef struct _MOUSE_EVENT_RECORD {

    COORD dwMousePosition; // 当前鼠标位置

    DWORD dwButtonState; // 鼠标按钮状态

    DWORD dwControlKeyState; // 键盘控制键状态

    DWORD dwEventFlags; // 事件状态

    } MOUSE_EVENT_RECORD;

    其中,dwButtonState反映了用户按下鼠标按钮的情况,它可以是:

    FROM_LEFT_1ST_BUTTON_PRESSED(最 左边按钮)、RIGHTMOST_BUTTON_PRESSED(最右边按钮)、FROM_LEFT_2ND_BUTTON_PRESSED(左起第二个 按钮)、FROM_LEFT_3RD_BUTTON_PRESSED(左起第三个按钮)和FROM_LEFT_4TH_BUTTON_PRESSED (左起第四个按钮)。而dwEventFlags表示鼠标 的事件,如DOUBLE_CLICK(双击)、MOUSE_MOVED(移动)和 MOUSE_WHEELED(滚轮滚动,只适用于Windows 2000/XP)。dwControlKeyState的含义同前。

    下面举一个例子。这个例子能把鼠标的当前位置显示在控制台窗口的最后一行上,若单击鼠标左键,则在当前位置处写一个字符‘A’,若双击鼠标任一按钮,则程序终止。具体代码如下:

    #include <windows.h>

    #include <stdio.h>

    #include <string.h>

    HANDLE hOut;

    HANDLE hIn;

    void ClearScreen(void);

    void DispMousePos(COORD pos); // 在第24行显示鼠标位置

    int main()

    {

           hOut = GetStdHandle(STD_OUTPUT_HANDLE); // 获取标准输出设备句柄

           hIn = GetStdHandle(STD_INPUT_HANDLE); // 获取标准输入设备句柄

           WORD att = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_INTENSITY | BACKGROUND_BLUE ;

           // 背景是蓝色,文本颜色是黄色

           SetConsoleTextAttribute(hOut, att);

           ClearScreen(); // 清屏

           INPUT_RECORD mouseRec;

           DWORD state = 0, res;

           COORD pos = {0, 0};

           for(;;) // 循环

           {

                  ReadConsoleInput(hIn, &mouseRec, 1, &res);

                  if (mouseRec.EventType == MOUSE_EVENT)

                  {

                         if (mouseRec.Event.MouseEvent.dwEventFlags == DOUBLE_CLICK)

                                break; // 双击鼠标退出循环       

                         pos = mouseRec.Event.MouseEvent.dwMousePosition;

                         DispMousePos(pos);

                         if (mouseRec.Event.MouseEvent.dwButtonState == FROM_LEFT_1ST_BUTTON_PRESSED)

                                FillConsoleOutputCharacter(hOut, 'A', 1, pos, NULL);

                  }

           }

           pos.X = pos.Y = 0;

           SetConsoleCursorPosition(hOut, pos); // 设置光标位置

           CloseHandle(hOut); // 关闭标准输出设备句柄

           CloseHandle(hIn); // 关闭标准输入设备句柄

    }

    void DispMousePos(COORD pos) // 在第24行显示鼠标位置

    {

           CONSOLE_SCREEN_BUFFER_INFO bInfo;

           GetConsoleScreenBufferInfo( hOut, &bInfo );

           COORD home = {0, 24};

           WORD att0 = BACKGROUND_INTENSITY ;

           FillConsoleOutputAttribute(hOut, att0, bInfo.dwSize.X, home, NULL);

           FillConsoleOutputCharacter(hOut, ' ', bInfo.dwSize.X, home, NULL);

           char s[20];

           sprintf(s,"X = %2lu, Y = %2lu",pos.X, pos.Y);

           SetConsoleTextAttribute(hOut, att0);

           SetConsoleCursorPosition(hOut, home);

           WriteConsole(hOut, s, strlen(s), NULL, NULL);

           SetConsoleTextAttribute(hOut, bInfo.wAttributes); // 恢复原来的属性

           SetConsoleCursorPosition(hOut, bInfo.dwCursorPosition); // 恢复原来的光标位置

    }

    void ClearScreen(void)

    {

           CONSOLE_SCREEN_BUFFER_INFO bInfo;

           GetConsoleScreenBufferInfo( hOut, &bInfo );

           COORD home = {0, 0};

           unsigned long size = bInfo.dwSize.X * bInfo.dwSize.Y;

           FillConsoleOutputAttribute(hOut, bInfo.wAttributes, size, home, NULL);

           FillConsoleOutputCharacter(hOut, ' ', size, home, NULL);

    }

    如果你尝试在屏幕上写一个“Hello!”,将看到如下运行结果:

     


    (十一) 结语

    综上所述,利用控制台窗口的Widows API函数可以设计简洁美观的文本界面,使得用Visual C++ 6.0开发环境深入学习C++以及文本界面设计成为一件比较容易的事件。当然文本界面的设计还需要一定的方法和技巧,限于篇幅,这里不再阐述。

    补充篇--经典控制台程序

    下面是我在网上找到的几个经典代码,供大家学习!

    ①    输出各种彩带。来源:百度文库《在控制台窗口中输出彩带(含倾斜彩带)》

    源代码:

    #include <windows.h>

    #include <stdio.h>

    void shuiping();

    void chuizhi();

    void zuoqingxie();

    void youqingxie();

    void jiantou();

    void SetColor(unsigned short ForeColor,unsigned short BackGroundColor);

    int main()

    {

           int a;

           SMALL_RECT rc = {0,0,20,10};

           HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);

           SetConsoleOutputCP(936);

           SetColor(14,3);

           printf("0:水平彩带,\n1:垂直彩带,\n2:右倾斜彩带,\n3:左倾斜彩带,\n4:箭头状彩带,\n5:水纹状彩带,\n其他输入退出\n");

           scanf("%d",&a);

           while(a==0||a==1||a==2||a==3||a==4||a==5)

           {

                  if(a==0)//实现水平彩带输出

                  {

                         shuiping();

                         SetColor(14,3); //刷新缓冲区,使字迹可见

                  }    

                  else if(a==1)//实现垂直彩带输出

                  {

                         chuizhi();

                         SetColor(14,3);

                  }

                  else if(a==2)//实现右倾斜彩带输出

                  {

                         youqingxie();

                         SetColor(14,3);

                  }

                  else if(a==3)//实现左倾斜彩带输出

                  {

                         zuoqingxie();

                         SetColor(14,3);

                  }

                  else if(a==4)//实现箭头状彩带输出

                  {

                         jiantou();

                         SetColor(14,3);

                  }

                  else if(a==5)//实现水纹状彩带输出

                  {

                         jiantou();

                         jiantou();

                         SetColor(14,3);

                  }

                  fflush(stdin);

                  printf("0:水平彩带,\n1:垂直彩带,\n2:右倾斜彩带,\n3:左倾斜彩带,\n4:箭头状彩带,\n5:水纹状彩带,\n其他输入退出\n");

                  scanf("%d",&a);

           }

           return 0;

          

    }

    void SetColor(unsigned short ForeColor,unsigned short BackGroundColor)

    {

           HANDLE hCon=GetStdHandle(STD_OUTPUT_HANDLE);

           SetConsoleTextAttribute(hCon,ForeColor+BackGroundColor*0x10);

    }

    //水平彩带函数

    void shuiping()

    {

           int i,j,k;

           for(i=0;i<25;++i)

           {

                  for(j=0;j<=79;++j)

                  {

                         k=i%16;

                         SetColor(k,k);

                         putchar('A');

                  }

           }

    }

     

    //垂直彩带函数

    void chuizhi()

    {

           int i,j,k;

           for(i=0;i<25;++i)

           {

                  for(j=0;j<40;++j)

                  {

                         k=j%16;

                         SetColor(k,k);

                         putchar('A');

                         putchar('A');

            }

                 

           }

    }

     

    //右倾斜彩带函数

    void youqingxie()

    {

           int i,j,k;

           for(i=0;i<25;++i)

           {

                  for(j=0;j<40;++j)

                  {

                         if(j-i>=0)

                                k=(j-i)%16;

                         else

                                k=(j-i)%16+16;

                         SetColor(k,k);

                         putchar('A');

                         putchar('A');

                  }

           }

    }

     

    //左倾斜彩带函数

    void zuoqingxie()

    {

           int i,j,k;

           for(i=0;i<25;++i)

           {

                  for(j=0;j<40;++j)

                  {

                         k=(i+j)%16;

                         SetColor(k,k);

                         putchar('A');

                         putchar('A');

                  }

           }

    }

    //箭头状彩带函数

    void jiantou()

    {

           int i,j,k;

           for(i=0;i<16;++i)

           {

                  for(j=0;j<40;++j)

                  {

                         k=(i+j)%16;

                         SetColor(k,k);

                         putchar('A');

                         putchar('A');

                  }

           }

           for(i=0;i<16;++i)

           {

                  for(j=0;j<40;++j)

                  {

                         if(j-i>=0)

                                k=(j-i)%16;

                         else

                                k=(j-i)%16+16;

                         SetColor(k,k);

                         putchar('A');

                         putchar('A');

                  }

           }

    }

    运行结果展示:

    水平彩带

          竖直彩带

    左倾斜彩带

          右倾斜彩带

    箭头状彩带

          水波状彩带

     


    ②输出颜色方阵

    出处: 百度知道《在控制台窗口中输出颜色方阵》

    作者:AlphaBlend

    #include <windows.h>

    #include <stdio.h>

    #include <conio.h>

     

    #define getrandom( min, max ) ((rand() % (int)(((max)+1) - (min))) + (min))

     

    void Init(void);

    void gotoxy(int x, int y);

    void regularcolor(void);

    void randomcolor(void);

    void Cls(HANDLE hConsole);

     

    HANDLE hOut;

    int forecolor[16];

    int backcolor[16];

     

    int main(void)

    {

           int i;

           int a;

          

           for (i = 0; i < 16; i++)

           {

                  forecolor[i] = i;

                  backcolor[i] = i << 4;

           }

           hOut = GetStdHandle(STD_OUTPUT_HANDLE);

          

           Init();

           while(1)

           {

                  a = getch();

                  if (a == 48)

                  {

                         Cls(hOut);

                         regularcolor();

                         getch();

                  } else if (a == 49) {

                         Cls(hOut);

                         randomcolor();

                         getch();

                  }  else {

                         Cls(hOut);

                         break;

                  }

                  Cls(hOut);

                  Init();

           }

          

          

           CloseHandle(hOut);

           return 0;

    }

    //---------------------------------------------------------------------------

     

    void gotoxy(int x, int y)

    {

           COORD pos = {x, y};

           SetConsoleCursorPosition(hOut, pos);

    }

     

    void regularcolor(void)

    {

           int i, j, x, y;

           int l = 8, t = 5;

           for (y = 0; y < 16; y++)

           {

                  gotoxy(l - 3, y + t);

                  SetConsoleTextAttribute(hOut, forecolor[15]|backcolor[0]);

                  printf("%d", y);

                  for (x = 0; x < 16; x++)

                  {

                         gotoxy(x * 4 + l, y + t);

                         SetConsoleTextAttribute(hOut, forecolor[y]|backcolor[x]);

                         printf("ZZZ");

                         if (y == 15)

                         {

                                gotoxy(x * 4 + l, 17 + t);

                                SetConsoleTextAttribute(hOut, forecolor[15]|backcolor[0]);

                                printf("%d", x);

                         }

                  }

           }

    }

     

    void randomcolor(void)

    {

           int i, j, x, y;

           int l = 8, t = 5;

           char s[4] = {"012"};

           rand();

           for (y = 0; y < 16; y++)

           {

                  for (x = 0; x < 16; x++)

                  {

                         s[0] = getrandom(32, 127);

                         s[1] = getrandom(32, 127);

                         s[2] = getrandom(32, 127);

                         gotoxy(x * 4 + l, y + t);

                         SetConsoleTextAttribute(hOut, forecolor[getrandom(0, 15)]|backcolor[getrandom(0, 15)]);

                         printf("%c", s[0]);

                         gotoxy(x * 4 + l + 1, y + t);

                         SetConsoleTextAttribute(hOut, forecolor[getrandom(0, 15)]|backcolor[getrandom(0, 15)]);

                         printf("%c", s[1]);

                         gotoxy(x * 4 + l + 2, y + t);

                         SetConsoleTextAttribute(hOut, forecolor[getrandom(0, 15)]|backcolor[getrandom(0, 15)]);

                         printf("%c", s[2]);

                  }

           }

    }

     

    void Cls(HANDLE hConsole)

    {

           COORD coordScreen = {0, 0};

          

           BOOL   bSuccess;

           DWORD  cCharsWritten;

           CONSOLE_SCREEN_BUFFER_INFO csbi;

           DWORD  dwConSize;

          

           SetConsoleTextAttribute(hOut, 0x0f|0);

           bSuccess = GetConsoleScreenBufferInfo(hConsole, &csbi);

           dwConSize = csbi.dwSize.X * csbi.dwSize.Y;

          

           bSuccess = FillConsoleOutputCharacter(hConsole, (TCHAR) '   ', dwConSize, coordScreen, &cCharsWritten);

           bSuccess = GetConsoleScreenBufferInfo(hConsole, &csbi);

           bSuccess = FillConsoleOutputAttribute(hConsole, csbi.wAttributes, dwConSize, coordScreen, &cCharsWritten);

           bSuccess = SetConsoleCursorPosition(hConsole, coordScreen);

    }

     

    void Init(void)

    {

           gotoxy(30, 10);

           printf("0. Regular Color Array");

           gotoxy(30, 11);

           printf("1. Random Color Array");

           gotoxy(30, 12);

           printf("2. Quit");

    }

    展开全文
  • 控制台程序隐藏方法总结(四种)

    千次阅读 2018-09-04 20:26:48
    学习计算机,往往先从Windows环境下学习编程,学习编程,往往从C学起,学习C,往往又从控制台程序学习,何为控制台,就是那个黑框白字的界面。对于这样一个最初认为奇陋无比而现在认为无所不能的编程平台,有时候...

    学习计算机,往往先从Windows环境下学习编程,学习编程,往往从C学起,学习C,往往又从控制台程序学习,何为控制台,就是那个黑框白字的界面。对于这样一个最初认为奇陋无比而现在认为无所不能的编程平台,有时候需要将界面隐藏起来。那么如何做呢?

    方法1:
    在头文件下加上一句预处理命令:

    #pragma comment( linker, "/subsystem:\"windows\" /entry:\"mainCRTStartup\"" ) // 设置入口地址

    完整程序为:

    
    #include<windows.h>
    #pragma comment( linker, "/subsystem:\"windows\" /entry:\"mainCRTStartup\"" ) // 设置入口地址
    int main()
    {
        MessageBox(NULL,"Hello","Notice",NULL);
        return 0;
    }

    在编译器下运行时仍会出现黑框,但直接运行编译好的exe程序就不会显示黑框了

    方法2:
    使用API函数隐藏自身窗口,但会有黑框快速闪过的痕迹。代码如下:

    #include<windows.h>
    int main()
    {
        HWND hwnd;
        hwnd=FindWindow("ConsoleWindowClass",NULL); //处理顶级窗口的类名和窗口名称匹配指定的字符串,不搜索子窗口。
        if(hwnd)
        {
            ShowWindow(hwnd,SW_HIDE);               //设置指定窗口的显示状态
        }
        MessageBox(NULL,"Hello","Notice",MB_OK);
        system("pause");
        return 0;
    }

    运行效果:在编译器下运行和直接运行exe文件,都会有黑屏闪烁一下。

    方法3:
    一个人自身的力量毕竟有限,所有有时候需要借助外力,自己办不到的可以让好朋友帮忙,程序也同样如此,内部实现不了的功能可以让外部程序帮自己实现。

    再用C\C++写一个引导程序,让引导程序隐藏调用该程序。假设要隐藏运行记事本程序,代码如下:

    
    #include<windows.h>
    int main()
    {
        WinExec("notepad.exe",SW_HIDE);     //隐藏执行其他程序
        return 0;
    }

    运行效果:完全隐藏

    方法4:
    既然思路以及不再局限到程序自身,那么其实就有了很多很多中外部隐藏调用的方法,只要你的知识面足够宽那么解决方法就会足够多。比如,C#、Java、Python、Ruby、VB、Delphi等等都可以。最后再用VBScript写一个吧。代码如下:

    set objShell=wscript.createObject("wscript.shell")  
    iReturn=objShell.Run("你的程序.exe", 0, FALSE)  
    
    'Run()
    '第一个参数是你要执行的程序的路径,亦可传参
    '第二个参数是窗口的形式,0后台运行;1正常运行;2最小化;3最大化;缺省的话表示正常运行
    '第三个参数是表示这个脚本是等待还是继续执行,如果设为了True,脚本就会等待调用的程序退出后再向后执行。

    运行效果:完全隐藏

    展开全文
  • 控制台和终端的区别

    千次阅读 2017-10-26 00:04:29
    直接连接到电脑上的键盘和显示器叫控制台,可显示系统消息; 控制台是基本设备,终端是附加设备,一台电脑可以有多个终端,但只有一个控制台控制台/终端:可输入命令行并显示程序运行过程的信息及程序运行结果的...
  • js控制台使用详解

    千次阅读 2018-08-11 20:09:58
    一 实例图解   四种不同的console输出函数,输出信息前显示不同的图标;   $查看某个元素;   console.dir()可以显示一个对象所有的属性和方法;   分组显示信息; ...con...
  • 控制台程序的两种结束方式 1、Ctrl+Z,然后按enter键  这是在程序内部并没有输入是否结束的判定时,可以采用的一种结束输入的方式。 2、添加判断结束代码段  一般会设置一个字符用来判定输入是否结束,代码段...
  • VS显示控制台窗口

    万次阅读 2018-09-27 09:03:03
    有的时候我们在完成编程后, 运行发现没有控制台窗口, 比如我们用Qt编写的界面软件, 又想看到我们在代码中添加的打印日志信息,这个时候加上控制台窗口就能实现 方法: 项目–&gt; 属性–&gt;链接器–&...
  • 终端与控制台的区别? 最近开始接触Linux,终端、虚拟终端、shell、控制台、tty等概念让我很混乱,有必要认识清楚。 今天看到有人问终端和控制台的区别,而且这个问题比较有普遍性,因此想抽出一点时间来解释一下...
  • [DEBUG] 2018-01-18 00:57:05,517 method:org.apache.ibatis.io.DefaultVFS.list(DefaultVFS.java:102) Reader entry: ���� 3 b [DEBUG] 2018-01-18 00:57:05,522 method:org.apache.ibatis.io.DefaultVFS.find...
  • 关于IDEA启动tomcat报错��Ϣ

    千次阅读 2019-08-20 10:52:29
    这里写自定义目录标题欢迎使用Markdown编辑器新的改变功能快捷键合理的创建标题,有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、...
  • 带w:窗口 带f:全屏
  • 解决IntelliJ IDEA控制台输出中文乱码问题

    万次阅读 多人点赞 2018-07-18 14:07:25
    IntelliJ IDEA 控制台输出中文乱码部分如图所示: 二、解决方法: 1.打开tomcat配置页面,Edit Configurations。 2.选择项目部署的tomcat,在配置项VM options文本框中输入-Dfile.encoding=UTF-8,点击Apply...
  • CSGO控制台与常用指令

    万次阅读 2019-07-19 12:02:36
    这篇文章我会详细的介绍CSGO控制台、指令系统、设置方面的知识,有点晦涩,希望各位能在阅读的过程中时不时昏睡过去( ͡° ͜ʖ ͡°)。 控制台 V社(Valve)的Source起源引擎制作的游戏都可以开发者控制台,简称...
  • 编写 Java 程序,在控制台中输入日期,计算该日期是对应年份的第几天。 实现思路: (1)声明变量 year、month和 date,用于存储日期中的年、月、日。 (2)声明变量 days,用于存储累加的天数。 (3)通过 ...
  • 终端与控制台

    万次阅读 2018-12-14 20:53:41
    终端与控制台的区别? 最近开始接触Linux,终端、虚拟终端、shell、控制台、tty等概念让我很混乱,有必要认识清楚。 今天看到有人问终端和控制台的区别,而且这个问题比较有普遍性,因此想抽出一点时间来解释一下...
  • IDEA控制台Console里没有查找快捷键

    万次阅读 多人点赞 2020-04-10 17:08:38
    IntelliJ IDEA版本:2016.2.1 问题描述: ...发现在控制台Console里没有查找快捷键功能。 解决: 在网上找了好久也没有发现有效的信息,只好自己耐心的逐项对比了,发现在Keymap为Eclipse方式下,
  • IDEA中Tomcat在控制台乱码问题以及IDEA编码设置UTF-8

    万次阅读 多人点赞 2020-02-22 22:41:15
    在idea中经常遇到jsp的乱码问题,原因是编码不是UTF-8的问题,这次来彻底解决idea的编码问题首先设置idea编辑器的编码:File-Setting...8:上面设置完后控制台还会乱码:打开idea安装目录-bin用记事本打开idea.exe....
  • Java图书管理系统(控制台程序)

    千次阅读 多人点赞 2019-05-25 22:32:19
    这是Java练手的一个小项目,适合初学者,用的技术是Java和MySQL。主要功能包括 (1)用户登录 (2)增加图书 (3)修改图书信息 (4)删除图书信息 (5)查询图书 (6)查看所有的图书 下面是源码 ...
  • Sentinel 控制台

    千次阅读 2020-09-05 17:17:24
    Sentinel 控制台 1. 概述 Sentinel 提供一个轻量级的开源控制台,它提供机器发现以及健康情况管理、监控(单机和集群),规则管理和推送的功能。另外,鉴权在生产环境中也必不可少。这里,我们将会详细讲述如何通过...
1 2 3 4 5 ... 20
收藏数 888,722
精华内容 355,488
关键字:

控制台