最近和别人聊天,聊到了控制台绘图,曾经学了一些windows的API编程,却没想到直接在控制台窗口上进行绘图

今天有时间,便把代码写了出来

#include

#include

/************************************************************************/

/* 函数 DrawCircle

/* 参数 HDC hdc 绘图的句柄

/* int x

/*int y圆心的x,y坐标

/*int r圆的半径

/*COLORREF color圆的填充颜色

/* 功能 在(x, y)处画一个半径为r的圆,用color的颜色填充

/************************************************************************/

void DrawCircle(HDC hdc, int x, int y, int r, COLORREF color)

{

HBRUSH brush = (HBRUSH)CreateSolidBrush (color);//新建一个画刷

SelectObject(hdc, (HGDIOBJ)brush);//选择画刷

Ellipse(hdc, x-r, y-r, x+r, y+r);//画一个圆

DeleteObject(brush);//删除画刷

}

int main()

{

HWND console = GetConsoleWindow();//获取控制台窗口句柄

HDC console_hdc = GetDC(console);//获取绘图dc

RECT rect;//保存绘图区域大小的结构体

int x,

y,//小球的xy坐标

dx = 3,//x的增量

dy = 3;//y的增量

int r = 0, g = 0, b = 0;//小球颜色

int speed;//小球速度

COORD pos={0,4};//光标位置

HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);

GetClientRect(console, &rect);//首先获取绘图区域的大小

x = 10 + rand() % (rect.right);

y = 10 + rand() % (rect.bottom);

printf("当前窗口宽度 %d\n当前窗口高度 %d\n请输入小球颜色(r g b):", rect.right, rect.bottom);

scanf("%d %d %d", &r, &g, &b);

printf("请输入小球运动速度(1~10)");

scanf("%d", &speed);

//rgb 的范围分别是0~255

//255 255 255为白色

if (speed <1 || speed > 10 || r >255 || r < 0 || g >255 || g < 0 || b >255 || g <0)

{

printf("无效的输入");

return 0;

}

while (1)

{

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

printf("当前小球位置 x= %d \ty=%d ", x, y);

DrawCircle(console_hdc, x, y, 10, RGB(r, g, b));//画一个白色的圆

Sleep(200/speed);

DrawCircle(console_hdc, x, y, 10, RGB(0, 0, 0));//画一个黑色的圆(擦除)

if (x > rect.right - 10 || x < 10)

dx = -dx;

if (y > rect.bottom - 10 || y < 10)

dy = -dy;

x += dx;

y += dy;

}

ReleaseDC(console, console_hdc);

return 0;

}

要实现绘图就需要先获取控制台窗口的句柄

句柄说的高大上,其实它就是一个数字而已,它标记了一种资源,根据这个数字,我们就可以找到这个窗口。不然在绘图函数绘图的时候,就可能写到别的窗口上了

获取了控制台句柄之后,我们需要获取HDC,HDC是设备上下文,名字变得更加玄乎了,其实它就是用来绘图的。

GetStdHandle这个API又是获取句柄的,不过这一次不是窗口了,而是标准输出,因为我们程序中需要直接定位光标的位置,因此需要使用到标准输出的句柄

GetClientRect能获取绘图的范围,知道了绘图的范围后,我们能让画出来的圆“碰到”边框后自动的“弹回”

因为printf会在每次画圆之后输出圆的坐标,因此我们需要在每次输出前将光标放到指定的位置

SetConsoleCursorPosition便发挥了这个作用,它将光标定位到第三行第一个字符的位置

DrawCircle是我们自己封装的一个函数,它的具体功能注释中已经明确的写了出来

DrawCircle中我们先新建了一个画刷,因为我们需要用指定的颜色去画圆

SelectObject选择画刷,这样下面的作图就会变成我们所指定的颜色

Ellipse是一个画椭圆的函数,它的后四个参数分别是椭圆的外界矩形的坐标,如果我们使矩形的边长相等,那么它画出来的自然就是圆形了

最后别忘了把画刷用DeleteObject删除,因为画刷也是需要占用资源的

下面就是实现小球的运动过程了,其实实现起来很简单。由于“视觉暂留”效应,我们只需要先画一个圆,再删除,接着立即在他的旁边画一个圆,人眼便会形成一种错觉,小球在运动!

那么怎么擦除呢,很简单啦,在我们画出的圆上再画一个圆,它的颜色和背景颜色相同,这样不就把刚才的圆给覆盖了吗?

小球的运动速度由每次画圆到擦除之前的延时时间决定,根据你的输入,每次延时的值将在200ms – 20ms之间变化

这样,我们便实现了控制台版本的运动的小球程序了

运行效果

运行效果

linux上c语言hdc句柄,控制台窗口的绘图相关推荐

  1. linux窗口切换快捷键_分配快捷键以在Linux上激活打开的应用程序窗口

    linux窗口切换快捷键 We've already shown you how to customize shortcut keys in any Linux application, but fo ...

  2. c mysql linux,linux上C语言连接mysql

    linux下C语言连接mysql 环境:fedora16 1)安装:# yum install mysql mysql-devel   //mysql-devel同样需要安装,开发中要用到/usr/i ...

  3. Linux上C语言程序编译过程详解

    点击蓝字 关注我们 因公众号更改推送规则,请点"在看"并加"星标"第一时间获取精彩技术分享 来源于网络,侵删 本文将介绍如何将高层的C/C++语言编写的程序转换 ...

  4. Windows上C语言实现设置控制台的颜色

    这里设置只要调用system();这个函数就行了,参数是字符串,想要设置终端的颜色,按照以下格式可以设置: //数字表示前景色,字母表示背景色//color 0=黑色 1蓝色 2 绿色 3湖蓝色 4红 ...

  5. linux上C语言的编译流程

    本文将介绍如何从C/C++文本到二进制可执行文件的过程.该过程需要经过预处理->编译->链接三个步骤,文件内容从普通文本->汇编->二进制的变化. 预处理(Preprocess ...

  6. 深入浅出CChart 每日一课——快乐高四第四十九课 旧石器时代,老血狂喷之控制台窗口绘图

    前面快乐高四第三十三课,介绍了在控制台程序中怎么利用CChart绘制曲线,那里的方法呢,很简单,就是创建一个弹出窗口,然后在这个弹出窗口上绘图,其实技术含量比较低. 这一课呢,笨笨想给大家介绍一下怎么 ...

  7. 为Linux安装Mac图标主题,在Linux上安装macOS Catalina图标主题的方法

    想改变你无聊的Linux系统图标吗?以匹新款Apple macOS Catalina吗?如果是这样,本文适合你,我们将介绍如何在Linux上安装和设置macOS Catalina图标主题. 下载mac ...

  8. 【C语言】控制台窗口图形界面编程(一)句柄和文本属性

    00. 目录 文章目录 00. 目录 01. 句柄 02. GetStdHandle函数 03. CloseHandle函数 04. SetConsoleTextAttribute函数 05. 十进制 ...

  9. C语言控制台窗口界面编程:printf格式化显示-修改字符字体、颜色和背景

    环境:cygwin-Linux+GCC PS:windows的cmd下不能实现. 在linux终端中一个ls指令得出的显示结果文件夹.文件以及不同操作权限的文件的显示颜色是不同的,那么这个是如何实现的 ...

最新文章

  1. JDBC连接mysql数据的7个步骤(讲解+源码)
  2. 百度AI“杀入”新领域,我举双手支持!
  3. c语言实践 1/1+1/2+1/3+1/4+...+1/n
  4. 太阳系八大行星碰撞的视频_高中地理——太阳系与地球
  5. Java中的守护线程和非守护线程(转载)
  6. 编程语言的发展趋势及未来方向(2):声明式编程与DSL
  7. 饥荒海难创建显示专用服务器,饥荒创建世界时一直显示启动服务器 | 手游网游页游攻略大全...
  8. 的级联选择_级联接收机的计算及Y因子噪声因子测量法
  9. 下拉式菜单在GridView编辑时联动选择
  10. css删除li 圆点_CSS中li圆点样式
  11. fastica java_发一篇CCF-C论文有多难?
  12. 未来是计算机科学的天下,美国留学信息与计算机科学发展方向
  13. 塔菲尔曲线斜率的大小_中国第一塔,与埃菲尔铁塔齐名,到底有多强悍?
  14. 计算机做减法运算的过程,32位汇编基础_计算机做加减乘除
  15. 11-11 11:11
  16. 20155339 《信息安全系统设计基础》课程总结
  17. InstallShield 取消特定安装步骤
  18. 中控考勤机重置考勤机密码方法
  19. 微信公众号开发框架讲解
  20. Unity 如何获取安卓设备的SN号

热门文章

  1. 不为人知的 35 个 More Effective C++ 改善编程与设计的最佳方法 | 原力计划
  2. 如何伪装成一个彻头彻尾的程序员?
  3. IBM 推出全球首台计算性能最强悍的 53 位量子计算机
  4. 程序员破解推荐系统瓶颈,带来超百亿收入增量!
  5. 开源正在蚕食 500 亿美元的数据库行业!
  6. 快播王欣再做视频;Apple Watch 非法雇佣学生;ofo 进军电单车 | 极客头条
  7. linux sd卡空间,充分利用树莓派中的SD卡空间
  8. java 生成多叉树_java中多叉树(tree)的生成与显示 | 学步园
  9. java语言入门要多久,王者笔记!
  10. 移动平均滤波器 matlab,移动平均滤波的原理---matlab函数的实现smooth