一.实现控制台绘图
这两天正在看一本书,无意中需要在控制台程序中绘图,当时觉得有点困难,当然还抱着侥幸心理。我们都知道windows程序的输出都是图形,而图形是面向窗口的。在windows程序中绘图当然很简单。而控制台程序的输出是面向整个屏幕的,在它上面真的能够绘图吗?我就上网查阅了一些资料,发现确实可以在控制台程序中绘图。控制台程序运行结果也是在窗口中进行的,虽然该窗口比较丑,但是它依然是窗口。是窗口就有窗口句柄,当然也可以得到窗口句柄了。那么如何得到窗口句柄呢?我们可以使用下面的方法:
//如果是C语言,则
WINBASEAPI HWND WINAPI GetConsoleWindow ();
//
如果是C++语言,则
extern "C" WINBASEAPI HWND WINAPI GetConsoleWindow ();
C有一套图形接口函数在graphic.h中定义,而C++的编译器一般都没有带上这套库,
因此才会出现上边的分情况讨论。得到了窗口句柄,就可以开始绘图了。来看下面的代码:
#include<stdio.h>
#include<stdlib.h>
#include<tchar.h>
#include<windows.h>

extern "C" WINBASEAPI HWND WINAPI GetConsoleWindow ();

int main(int argc,char *argv[])
{
  HWND hwnd;
  HDC hdc;
  hwnd = GetConsoleWindow();
  hdc = GetDC(hwnd);
  MoveToEx(hdc,20,20,NULL);
  LineTo(hdc,200,300);
  ReleaseDC(hwnd,hdc);
  getchar();
  return 0;
}
 
   
运行一下上面的程序,发现窗口中什么都没有啊,难道控制台程序真的不能绘图。大胆尝试一下,再看下面的程序:
#include<stdio.h>
#include<stdlib.h>
#include<tchar.h>
#include<windows.h>

extern "C" WINBASEAPI HWND WINAPI GetConsoleWindow ();

int main(int argc,char *argv[])
{
  HDC hdc;
  hdc=GetDC(NULL);
  MoveToEx(hdc,20,20,NULL);
  LineTo(hdc,200,300);
  ReleaseDC(hwnd,hdc);
  getchar();
  return 0;
}
 
   
运行一下这个程序,发现在你的显示屏幕左上角有一条黑色的线,这条线就是你希望显示在控制台窗口中的线,那它怎么跑到显示屏幕上了呢?这是因为我们获得的是父窗口句柄,所以就出现了这种结果。既然能在显示器屏幕上显示,那为什么就不能显示在控制台窗口中呢,你有没有注意到这条线是黑色的,而控制台窗口背景也是黑色的,就算真的显示了,你能看得到吗?那我们再大胆尝试一下,来看下面的代码:
#include<stdio.h>
#include<stdlib.h>
#include<tchar.h>
#include<windows.h>

extern "C" WINBASEAPI HWND WINAPI GetConsoleWindow ();

int main(int argc,char *argv[])
{
  HWND hwnd;
  HDC hdc;
  hwnd = GetConsoleWindow();
  hdc = GetDC(hwnd);
  system("color 3d");
  MoveToEx(hdc,20,20,NULL);
  LineTo(hdc,200,300);
  ReleaseDC(hwnd,hdc);
  getchar();
  return 0;
}
 
   
运行一下这个程序,是不是就看到了我们想要的结果啊,给控制台窗口换一个背景色就可以了。这只是简单的画了一条线,既然能画线,肯定也可以画诸如矩形、圆等图形。
二.还有其他办法吗?
换一个角度思考,既然可以通过改变背景色来显示我们绘制的图形,表明控制台上确实可以绘图,只是显示的问题。那么我们可不可以不改变背景色,而改变画笔的颜色呢。我尝试了一下,结果失败了,代码如下所示:
#include<stdio.h>
#include<stdlib.h>
#include<tchar.h>
#include<windows.h>

extern "C" WINBASEAPI HWND WINAPI GetConsoleWindow ();

int main(int argc,char *argv[])
{
  HWND hwnd;
  HDC hdc;
  HPEN hPen;
  hwnd = GetConsoleWindow();
  hdc = GetDC(hwnd);
  hPen=CreatePen(PS_INSIDEFRAME,0,RGB(100,120,150));
  system("color 3d");
  MoveToEx(hdc,50,50,NULL);
  LineTo(hdc,80,200);
        DeleteObject(hPen);
  ReleaseDC(hwnd,hdc);
  getchar();
  return 0;
}
 
   
三.控制台绘图存在的问题
比如我绘制了一个矩形,通过运行结果观察到矩形内部被填充成了白色,但是我并没有填充啊。看一下代码:

extern "C" WINBASEAPI HWND WINAPI GetConsoleWindow ();

int main(int argc,char *argv[])
{
  HWND hwnd;
  HDC hdc;    
  hwnd = GetConsoleWindow();
  hdc = GetDC(hwnd);
  system("color 3d");    
  Rectangle(hdc,100,100,300,300);    
  ReleaseDC(hwnd,hdc);
  getchar();
  return 0;
}
 
   
虽然用这种方法可以绘图,通过仔细观察可以发现:如果所画直线是水平的、垂直的或沿45度角方向,这时候画出来的线还是很平滑的,但是若沿任意其他方向画线的话,这时候画出来的线周围有很多小锯齿,不是很平滑。我不知道控制台绘图有什么意义,但是如果真遇到了,不妨试一下上面的方法。