C语言控制台窗口图形编程

C语言控制台窗口图形编程

设备句柄与窗口信息

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

在Windows操作系统下用C语言编写控制台的窗口界面首先

需要获取当前标准输入和标准输出设备的的句柄。通过调用函数

GetStdHandle可以获取当前标准输入以及输出设备的句柄。函数原型:

HANDLE GetStdHandle(DWORD nStdHandle);
/*
其中,nStdHandle可以是
STD_INPUT_HANDLE    标准输入设备句柄
STD_OUTPUT_HANDLE   标准输出设备句柄
STD_ERROR_HANDLE    标准错误设备句柄
*/

示例程序

#include <stdio.h>
#include <windows.h>
#include <conio.h>
 
int main(int argc,char *argv[])
{
    HANDLE handle_out;                              //定义一个句柄
    CONSOLE_SCREEN_BUFFER_INFO screen_info;         //定义窗口缓冲区信息结构体
    COORD pos = {0, 0};                             //定义一个坐标结构体
    handle_out = GetStdHandle(STD_OUTPUT_HANDLE);   //获得标准输出设备句柄
    GetConsoleScreenBufferInfo(handle_out, &screen_info);   //获取窗口信息
    _getch();   //输入一个字符,不会显示到屏幕上
    /*
    向整个缓冲区填充字符'A'
    其中填充的开始处为pos,坐标为{0, 0},也就是屏幕最左上角的字符处
    填充个数为screen_info.dwSize.X(缓冲区宽度,也就是横坐标最大值加1) * screen_info.dwSize.Y(缓冲区高度,也就是纵坐标最大值加1)
    因此可以达到向整个缓冲区填充字符'A'的效果
    */
    FillConsoleOutputCharacter(handle_out, 'A', screen_info.dwSize.X * screen_info.dwSize.Y, pos, NULL);
    CloseHandle(handle_out);    //关闭标准输出设备句柄
    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;

窗口缓冲区的设置

几个控制台窗口操作的API函数,如下:

//获取控制台窗口信息
GetConsoleScreenBufferInfo();
 
//获取控制台窗口标题
GetConsoleTitle();
 
//更改指定缓冲区大小
SetConsoleScreenBufferSize();
 
//设置控制台窗口标题
SetConsoleTitle();
 
//设置控制台窗口信息
SetConsoleWindowInfo();

示例程序

#include <stdio.h>
#include <stdlib.h>
#include <Windows.h>
#include <conio.h>
#define N 255
 
int main()
{
	HANDLE handle_out;	//定义一个句柄
	CONSOLE_SCREEN_BUFFER_INFO scbi;	//定义一个窗口缓冲区信息结构体
	COORD size = {80, 25};		//定义一个坐标结构体
	char strtitle[N];
	handle_out = GetStdHandle(STD_OUTPUT_HANDLE);	//获得标准输出设备句柄
	GetConsoleScreenBufferInfo(handle_out, &scbi);	//获得窗口缓冲区信息
	GetConsoleTitle(strtitle, N);	//获得当前窗口标题
	printf("当前窗口标题为:%s\n", strtitle);
	_getch();
	SetConsoleTitle("控制台窗口操作");		//设置窗口标题为“控制台窗口操作”
	GetConsoleTitle(strtitle, N);			//获得当前窗口标题
	printf("当前窗口标题为:%s\n", strtitle);
	_getch();
	SetConsoleScreenBufferSize(handle_out, size);	// 重新设置缓冲区大小
	_getch();
	SMALL_RECT rc = {0, 0, 80-1, 25-1};		// 重置窗口位置和大小
	SetConsoleWindowInfo(handle_out, 1, &rc);
	CloseHandle(handle_out);	//关闭标准输出设备句柄
	return 0;
}

文本属性

设置文本属性的函数,原型如下

BOOL SetConsoleTextAttribute(   // 设置WriteConsole等函数的字符属性
HANDLE hConsoleOutput,          // 句柄
WORD wAttributes                // 文本属性
);

示例程序

#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <conio.h>
/*
基本文本属性
FOREGROUND_BLUE 蓝色
FOREGROUND_GREEN 绿色
FOREGROUND_RED 红色
FOREGROUND_INTENSITY 加强
BACKGROUND_BLUE 蓝色背景
BACKGROUND_GREEN 绿色背景
BACKGROUND_RED 红色背景
BACKGROUND_INTENSITY 背景色加强
COMMON_LVB_REVERSE_VIDEO 反色
*/
 
const WORD FORE_BLUE   = FOREGROUND_BLUE;           //蓝色文本属性
const WORD FORE_GREEN  = FOREGROUND_GREEN;          //绿色文本属性
const WORD FORE_RED    = FOREGROUND_RED;            //红色文本属性
const WORD FORE_PURPLE = FORE_BLUE | FORE_RED;      //紫色文本属性
const WORD FORE_CYAN   = FORE_BLUE | FORE_GREEN;    //青色文本属性
const WORD FORE_YELLOW = FORE_RED | FORE_GREEN;     //黄色文本属性
const WORD FORE_GRAY   = FOREGROUND_INTENSITY;      //灰色文本属性
const WORD BACK_BLUE   = BACKGROUND_BLUE;           //蓝色背景属性
const WORD BACK_GREEN  = BACKGROUND_GREEN;          //绿色背景属性
const WORD BACK_RED    = BACKGROUND_RED;            //绿色背景属性
const WORD BACK_PURPLE = BACK_BLUE | BACK_RED;      //紫色背景属性
const WORD BACK_CYAN   = BACK_BLUE | BACK_GREEN;    //青色背景属性
const WORD BACK_YELLOW = BACK_RED | BACK_GREEN;     //黄色背景属性
const WORD BACK_GRAY   = BACKGROUND_INTENSITY;      //灰色背景属性
 
int main()
{
    HANDLE handle_out = GetStdHandle(STD_OUTPUT_HANDLE);    //获得标准输出设备句柄
    CONSOLE_SCREEN_BUFFER_INFO csbi;                        //定义窗口缓冲区信息结构体
    GetConsoleScreenBufferInfo(handle_out, &csbi);          //获得窗口缓冲区信息
    SetConsoleTextAttribute(handle_out, FORE_BLUE);
    printf("蓝色字符\n");
    SetConsoleTextAttribute(handle_out, FORE_RED);
    printf("红色字符\n");
    SetConsoleTextAttribute(handle_out, FORE_GREEN);
    printf("绿色字符\n");
    SetConsoleTextAttribute(handle_out, FORE_PURPLE);
    printf("紫色字符\n");
    SetConsoleTextAttribute(handle_out, FORE_CYAN);
    printf("青色字符\n");
    SetConsoleTextAttribute(handle_out, FORE_YELLOW);
    printf("黄色字符\n");
    SetConsoleTextAttribute(handle_out, FORE_GRAY);
    printf("灰色字符\n");
    SetConsoleTextAttribute(handle_out, FORE_GREEN | FORE_BLUE | FORE_RED);
    printf("白色字符\n");
    SetConsoleTextAttribute(handle_out, BACK_BLUE);
    printf("蓝色背景\n");
    SetConsoleTextAttribute(handle_out, BACK_RED);
    printf("红色背景\n");
    SetConsoleTextAttribute(handle_out, BACK_GREEN);
    printf("绿色背景\n");
    SetConsoleTextAttribute(handle_out, BACK_PURPLE);
    printf("紫色背景\n");
    SetConsoleTextAttribute(handle_out, BACK_CYAN);
    printf("青色背景\n");
    SetConsoleTextAttribute(handle_out, BACK_YELLOW);
    printf("黄色背景\n");
    SetConsoleTextAttribute(handle_out, BACK_GRAY);
    printf("灰色背景\n");
    SetConsoleTextAttribute(handle_out, BACK_BLUE | BACK_RED | BACK_GREEN);
    printf("白色背景\n");
    SetConsoleTextAttribute(handle_out, BACK_GREEN | FORE_RED); //示例:绿色背景红色字符
    printf("绿色背景与红色字符的混合\n");
    SetConsoleTextAttribute(handle_out, FOREGROUND_INTENSITY | FORE_RED);   //示例:亮红色字符
    printf("亮色的生成,与加强色融合\n");
    return 0;
}

文本输出

文本输出函数:

BOOL FillConsoleOutputAttribute(    // 填充字符属性
HANDLE hConsoleOutput,              // 句柄
WORD wAttribute,                    // 文本属性
DWORD nLength,                      // 个数
COORD dwWriteCoord,                 // 开始位置
LPDWORD lpNumberOfAttrsWritten      // 返回填充的个数
);
BOOL FillConsoleOutputCharacter(    // 填充指定数据的字符
HANDLE hConsoleOutput,              // 句柄
TCHAR cCharacter,                   // 字符
DWORD nLength,                      // 字符个数
COORD dwWriteCoord,                 // 起始位置
LPDWORD lpNumberOfCharsWritten      // 已写个数
);
BOOL WriteConsoleOutputCharacter(   // 在指定位置处写指定数量的字符
HANDLE hConsoleOutput,              // 句柄
LPCTSTR lpCharacter,                // 字符串
DWORD nLength,                      // 字符个数
COORD dwWriteCoord,                 // 起始位置
LPDWORD lpNumberOfCharsWritten      // 已写个数
);

表示区域的结构体

typedef struct _SMALL_RECT  //表示矩形区域的结构体
{
  SHORT Left;       //左边界
  SHORT Top;        //上边界
  SHORT Right;      //右边界
  SHORT Bottom;     //下边界
} SMALL_RECT;
/*
微软官方的说法是
Left    区域的左上顶点的X坐标
Top     区域的左上顶点的Y坐标
Right   区域的右下顶点的X坐标
Bottom  区域的右下顶点的Y坐标
*/

示例程序

#include <stdio.h>
#include <stdlib.h>
#include <Windows.h>
#include <conio.h>
 
int main()
{
    char *str = "Hello World!";     //定义输出信息
    int len = strlen(str), i;
    WORD shadow = BACKGROUND_INTENSITY;     //阴影属性
    WORD text = BACKGROUND_GREEN | BACKGROUND_INTENSITY;    //文本属性
    HANDLE handle_out = GetStdHandle(STD_OUTPUT_HANDLE);    //获得标准输出设备句柄
    CONSOLE_SCREEN_BUFFER_INFO csbi;    //定义窗口缓冲区信息结构体
    GetConsoleScreenBufferInfo(handle_out, &csbi);  //获得窗口缓冲区信息
    SMALL_RECT rc;      //定义一个文本框输出区域
    COORD posText;      //定义文本框的起始坐标
    COORD posShadow;    //定义阴影框的起始坐标
    //确定区域的边界
    rc.Top = 8;     //上边界
    rc.Bottom = rc.Top + 4;     //下边界
    rc.Left = (csbi.dwSize.X - len) / 2 - 2;    //左边界,为了让输出的字符串居中
    rc.Right = rc.Left + len + 4;   //右边界
    //确定文本框起始坐标
    posText.X = rc.Left;
    posText.Y = rc.Top;
    //确定阴影框的起始坐标
    posShadow.X = posText.X + 1;
    posShadow.Y = posText.Y + 1;
    for (i=0; i<5; ++i)     //先输出阴影框
    {
        FillConsoleOutputAttribute(handle_out, shadow, len + 4, posShadow, NULL);
        posShadow.Y++;
    }
    for (i=0; i<5; ++i)     //在输出文本框,其中与阴影框重合的部分会被覆盖掉
    {
        FillConsoleOutputAttribute(handle_out, text, len + 4, posText, NULL);
        posText.Y++;
    }
    //设置文本输出处的坐标
    posText.X = rc.Left + 2;
    posText.Y = rc.Top + 2;
    WriteConsoleOutputCharacter(handle_out, str, len, posText, NULL);   //输出字符串
    SetConsoleTextAttribute(handle_out, csbi.wAttributes);   // 恢复原来的属性
    CloseHandle(handle_out);
    return 0;
}

文本移动

控制文本移动的函数

BOOL ScrollConsoleScreenBuffer(             //文本移动函数
    HANDLE hConsoleOutput,                  //句柄
    const SMALL_RECT *lpScrollRectangle,    //移动区域
    const SMALL_RECT *lpClipRectangle,      //裁剪区域,如果为NULL,那么将代表整个屏幕缓冲区
    COORD dwDestinationOrigin,              //移动到的位置,这个点将成为移动区域的左上顶点
    const CHAR_INFO *lpFill                 //空出区域的填充字符
);

示例函数

#include <stdio.h>
#include <conio.h>
#include <Windows.h>
#include <stdlib.h>
 
int main()
{
    HANDLE handle_out = GetStdHandle(STD_OUTPUT_HANDLE);    //获得标准输出设备句柄
    CONSOLE_SCREEN_BUFFER_INFO csbi;        //定义窗口缓冲区信息结构体
    SMALL_RECT scroll;      //定义移动区域
    COORD pos = {0, 5};     //移动位置
    CHAR_INFO chFill;       //定义填充字符
    GetConsoleScreenBufferInfo(handle_out, &csbi);  //获得窗口缓冲区信息
    //定义填充字符的各个参数及属性
    chFill.Char.AsciiChar = ' ';
    chFill.Attributes = csbi.wAttributes;
    //输出文本
    printf("00000000000000000000000000000\n");
    printf("11111111111111111111111111111\n");
    printf("22222222222222222222222222222\n");
    printf("33333333333333333333333333333\n");
    //确定区域
    scroll.Left = 1;
    scroll.Top = 1;
    scroll.Right = 10;
    scroll.Bottom = 2;
    ScrollConsoleScreenBuffer(handle_out, &scroll, NULL, pos, &chFill); //移动文本
    return 0;
}

光标操作

控制光标位置的函数

BOOL SetConsoleCursorPosition(  //设置光标位置
    HANDLE hConsoleOutput,      //句柄
    COORD dwCursorPosition      //坐标
);      //若函数调用成功则返回非0值

光标结构体原型、获得与设置光标信息的函数

typedef struct _CONSOLE_CURSOR_INFO     //光标信息结构体
{
    DWORD dwSize;       //光标尺寸大小,范围是1~100
    BOOL  bVisible;     //表示光标是否可见,true表示可见
} CONSOLE_CURSOR_INFO, *PCONSOLE_CURSOR_INFO;
 
BOOL GetConsoleCursorInfo(      //获得光标信息
    HANDLE hConsoleOutput,      //句柄
    PCONSOLE_CURSOR_INFO lpConsoleCursorInfo    //光标信息,注意这是个指针类型
);
 
BOOL SetConsoleCursorInfo(      //设置光标信息
    HANDLE hConsoleOutput,      //句柄
    const CONSOLE_CURSOR_INFO *lpConsoleCursorInfo  //光标信息
);

示例程序

#include <stdio.h>
#include <Windows.h>
#include <conio.h>
#include <stdlib.h>
 
int main()
{
    HANDLE handle_out = GetStdHandle(STD_OUTPUT_HANDLE);    //获得标准输出设备句柄
    CONSOLE_CURSOR_INFO cci;        //定义光标信息结构体
    GetConsoleCursorInfo(handle_out, &cci);     //获得当前光标信息
    _getch();
    cci.dwSize = 1;     //设置光标尺寸为1
    SetConsoleCursorInfo(handle_out, &cci);
    _getch();
    cci.dwSize = 50;    //设置光标尺寸为50
    SetConsoleCursorInfo(handle_out, &cci);
    _getch();
    cci.dwSize = 100;   //设置光标尺寸为100
    SetConsoleCursorInfo(handle_out, &cci);
    _getch();
    cci.bVisible = false;       //设置光标为不可见
    SetConsoleCursorInfo(handle_out, &cci);
    _getch();
    return 0;
}

  • 1
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值