一.實現控制檯繪圖
這兩天正在看一本書,無意中需要在控制檯程序中繪圖,當時覺得有點困難,當然還抱着僥倖心理。我們都知道windows程序的輸出都是圖形,而圖形是面向窗口的。在windows程序中繪圖當然很簡單。而控制檯程序的輸出是面向整個屏幕的,在它上面真的能夠繪圖嗎?我就上網查閱了一些資料,發現確實可以在控制檯程序中繪圖。控制檯程序運行結果也是在窗口中進行的,雖然該窗口比較醜,但是它依然是窗口。是窗口就有窗口句柄,當然也可以得到窗口句柄了。那麼如何得到窗口句柄呢?我們可以使用下面的方法:
//如果是C語言,則
WINBASEAPI HWND WINAPI GetConsoleWindow ();
//如果是C++語言,則
extern "C" WINBASEAPI HWND WINAPI GetConsoleWindow ();
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<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<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<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;
}
#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度角方向,這時候畫出來的線還是很平滑的,但是若沿任意其他方向畫線的話,這時候畫出來的線周圍有很多小鋸齒,不是很平滑。我不知道控制檯繪圖有什麼意義,但是如果真遇到了,不妨試一下上面的方法。