C语言控制台窗口界面编程修正版.docx

上传人:b****4 文档编号:4790967 上传时间:2022-12-09 格式:DOCX 页数:41 大小:172.61KB
下载 相关 举报
C语言控制台窗口界面编程修正版.docx_第1页
第1页 / 共41页
C语言控制台窗口界面编程修正版.docx_第2页
第2页 / 共41页
C语言控制台窗口界面编程修正版.docx_第3页
第3页 / 共41页
C语言控制台窗口界面编程修正版.docx_第4页
第4页 / 共41页
C语言控制台窗口界面编程修正版.docx_第5页
第5页 / 共41页
点击查看更多>>
下载资源
资源描述

C语言控制台窗口界面编程修正版.docx

《C语言控制台窗口界面编程修正版.docx》由会员分享,可在线阅读,更多相关《C语言控制台窗口界面编程修正版.docx(41页珍藏版)》请在冰豆网上搜索。

C语言控制台窗口界面编程修正版.docx

C语言控制台窗口界面编程修正版

控制台窗口界面编程控制

〇、摘要 

一、概述

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

三、控制台窗口操作 

四、文本属性操作 

五、文本输出 

六、文本操作示例

七、滚动和移动

八、光标操作

九、读取键盘信息

十、读取鼠标信息 

十一、结语

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

摘要:

文本界面的控制台应用程序开发是深入学习C++、掌握交互系统的实现方法的最简单的一种手段。

然而,VisualC++的C++专用库却没有TC所支持的文本(字符)屏幕控制函数,为此本系列文章从一般控制步骤、控制台窗口操作、文本(字符)控制、滚动和移动光标、键盘和鼠标等几个方面讨论控制台窗口界面的编程控制方法。

在众多C++开发工具中,由于Microsoft本身的独特优势,选用VisualC++已越来越被众多学习者所接受。

显然,现今如果还再把TC作为开发环境的话,不仅没有必要,而且也不利于向Windows应用程序开发的过渡。

然而,VisualC++的C++专用库却没有TC所支持的文本屏幕(控制台窗口)控制函数(相应的头文件是conio.h)。

这必然给C++学习者在文本界面设计和编程上带来诸多不便。

要知道,文本界面设计是一种深入学习C++、掌握交互系统的实现方法的最简单的一种手段,它不像C++的Windows图形界面应用 程序,涉及知识过多。

为此,本系列文章来讨论在Visual C++ 6.0开发环境中,如何编写具有美观清晰的控制台窗口界面的C++应用程序。

(一)概述操作

所谓控制台应用程序,就是指那些需要与传统DOS操作系统保持某种程序的兼容,同时又不需要为用户提供完善界面的程序。

简单地讲,就是指在Windows环境下运行的DOS程序。

一旦控制台应用程序在Windows操作系统中运行后,就会弹出一个窗口。

例如下列代码:

#include

int main(intargc,char *argv[])

{

printf("Hello,Console!

\n");

ﻩreturn0;

}

单击小型编译工具栏中的“Build”按钮或按F7键,系统出现一个对话框,询问是否将此项目的工作文件夹设定源文件所在的文件夹,单击[是]按钮,系统开始编译。

单击小型编译工具栏中的“ExecuteProgram”按钮或按Ctrl+F5键,运行刚才的程序。

程序运行后,弹出下图的窗口:

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

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

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

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

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

在VisualC++ 6.0中,控制台窗口界面的一般编程控制步骤如下:

调用GetStdHandle获取当前的标准输入(STDIN)和标准输出(STDOUT)设备句柄。

函数原型为:

HANDLEGetStdHandle(DWORDnStdHandle);

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

需要说明的是,“句柄”是Windows最常用的概念。

它通常用来标识Windows资源(如菜单、图标、窗口等)和设备等对象。

虽然可以把句柄理解为是一个指针变量类型,但它不是对象所在的地址指针,而是作为Windows系统内部表的索引值来使用的。

调用相关文本界面控制的API函数。

这些函数可分为三类。

一是用于控制台窗口操作的函数(包括窗口的缓冲区大小、窗口前景字符和背景颜色、窗口标题、大小和位置等);二是用于控制台输入输出的函数(包括字符属性操作函数);其他的函数并为最后一类。

 调用CloseHandle()来关闭输入输出句柄。

注意,在程序中还必须包含头文件windows.h。

下面看一个程序:

#include

#include

#include<conio.h>

intmain(void)

{

ﻩHANDLEhOut;

ﻩCONSOLE_SCREEN_BUFFER_INFObInfo; //存储窗口信息

COORDpos={0, 0};

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

hOut=GetStdHandle(STD_OUTPUT_HANDLE);

ﻩ// 获取窗口信息

ﻩGetConsoleScreenBufferInfo(hOut,&bInfo); 

printf("\n\nThesoul selects herown society\n");

printf("Thenshutsthe door\n");

ﻩprintf("On herdevinemajority\n");

ﻩprintf("Obtrudeno 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定义的控制台结构体类型,其原型如下:

//坐标结构体

typedefstruct_COORD{ 

SHORTX; 

SHORTY;

} COORD;

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

typedefstruct_CONSOLE_SCREEN_BUFFER_INFO{ 

COORD dwSize;// 缓冲区大小

COORDdwCursorPosition;//当前光标位置

WORDwAttributes;//字符属性

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

COORDdwMaximumWindowSize;//最大的窗口缓冲区大小

}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>

intmain(void)

{

char strTitle[255];

ﻩCONSOLE_SCREEN_BUFFER_INFObInfo;//窗口缓冲区信息

ﻩCOORD size ={80,25};

HANDLEhOut=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_RECTrc= {0,0,80-1, 25-1};//重置窗口位置和大小

SetConsoleWindowInfo(hOut,true,&rc);

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

return0;

}

需要说明的是,控制台窗口的原点坐标是(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反色

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

BOOLFillConsoleOutputAttribute(//填充字符属性

HANDLEhConsoleOutput, // 句柄

WORD wAttribute,//文本属性

DWORDnLength,//个数

COORDdwWriteCoord, //开始位置

LPDWORDlpNumberOfAttrsWritten// 返回填充的个数

);

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

HANDLEhConsoleOutput, //句柄

WORDwAttributes//文本属性

);

BOOLWriteConsoleOutputAttribute( //在指定位置处写属性

HANDLEhConsoleOutput,//句柄

CONSTWORD*lpAttribute,//属性

DWORDnLength,//个数

COORDdwWriteCoord,//起始位置

LPDWORD lpNumberOfAttrsWritten//已写个数

);

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

(五)文本输出

操作文本输出函数有:

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

HANDLEhConsoleOutput, // 句柄

TCHAR cCharacter,//字符

DWORD nLength, //字符个数

COORDdwWriteCoord,//起始位置

LPDWORDlpNumberOfCharsWritten // 已写个数

);

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

HANDLE hConsoleOutput,//句柄

CONSTVOID *lpBuffer, //字符串

DWORDnNumberOfCharsToWrite,//字符个数

LPDWORDlpNumberOfCharsWritten,//已写个数

LPVOIDlpReserved//保留

);

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

HANDLEhConsoleOutput,//句柄

CONSTCHAR_INFO*lpBuffer, // 字符数据区

COORD dwBufferSize,// 数据区大小

COORDdwBufferCoord,//起始坐标

PSMALL_RECTlpWriteRegion //要写的区域

);

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

HANDLEhConsoleOutput,//句柄

LPCTSTRlpCharacter,// 字符串

DWORDnLength,//字符个数

COORDdwWriteCoord, //起始位置

LPDWORD lpNumberOfCharsWritten//已写个数

);

可以看出:

WriteConsoleOutput函数功能相当于SetConsoleTextAttribute和WriteConsole 的功能。

而WriteConsoleOutputCharacter函数相当于SetConsoleCursorPosition(设置光标位置)和 WriteConsole的功能。

不过在具体使用要注意它们的区别。

(六)文本操作示例操作

下面看一个示例程序:

 

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

#include 

HANDLE hOut;

voidShadowWindowLine(char*str);

voidDrawBox(boolbSingle,SMALL_RECTrc);//绘制边框

int main(void)

{

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

ﻩSetConsoleOutputCP(437);// 设置代码页,这里如果设置成936(简体中文),那么程序会怎样?

那样的话,将画不出边框。

ShadowWindowLine("Displayaline ofwords,andcenterthewindow withshadow.");

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

return0;

}

void ShadowWindowLine(char*str)

{

ﻩSMALL_RECT rc;

CONSOLE_SCREEN_BUFFER_INFObInfo;//窗口缓冲区信息

ﻩWORDatt0,att1,attText;

ﻩinti,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;// 文本属性

// 设置阴影然后填充

COORDposShadow={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);//恢复原来的属性

}

voidDrawBox(boolbSingle, SMALL_RECT rc) //函数功能:

画边框

{

charchBox[6];

ﻩCOORDpos;

ﻩ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作为最后一个参数。

③上述程序在不同的字符代码页面(codepage)下显示的结果是不同的。

例如,中文Windows操作系统的默认代码页是简体中文(936),在该代码页面下值超过128的单字符在Windows NT/XP是显示不出来的。

下表列出了可以使用的代码页。

代码页(Codepage)

说明

1258

越南文

1257

波罗的海文

1256

阿拉伯文

1255

希伯来文

1254

土耳其语

1253

希腊文

1252

拉丁文(ANSI)

1251

斯拉夫文

1250

中欧文

950

繁体中文

949

韩文

936

简体中文

932

日文

874

泰文

850

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

437

MS-DOS美语/英语

(七)滚动和移动操作

ScrollConsoleScreenBuf

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 求职职场 > 职业规划

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1