windows程式畫圖,大體上有3種方法:
(1)你告訴系統點的座標和顏色,系統通過SetPixel來畫。類似的,通過GetPixel來擷取某一點像素值。
(2)使用MoveToEx、LineTo來劃線,MoveToEx設定起點座標,LineTo設定終點座標,或者使用Polyline函數,這個函數接受一個POINT類型的數組,通過數組裡的點連線。
(3)windows提供了一些基本圖形繪製的函數供我們直接調用,比如Rectangle繪製矩形,Ellipse繪製橢圓,RoundRect繪製圓角橢圓。
下面看看程式中如何使用它們:(還是那本windows程式設計裡的)
#include <windows.h>#include <math.h>#define NUM 1000#define TWOPI (2*3.14159)LRESULT CALLBACK WndProc (HWND,UINT,WPARAM,LPARAM);int WINAPI WinMain(HINSTANCE hInstance,//當前執行個體控制代碼 HINSTANCE hPrevInstance, //先前執行個體控制代碼 LPSTR lpCmdLine,//命令列 int iCmdShow)//顯示狀態{static TCHAR szAppName[] = TEXT("畫圖");//視窗控制代碼HWND hwnd;//訊息MSG msg;//視窗類別WNDCLASS wndclass;//視窗風格:當移動視窗或者改變大小時重繪視窗wndclass.style = CS_HREDRAW | CS_VREDRAW;//指明回呼函數wndclass.lpfnWndProc = WndProc;//額外的位元用來確認下一個視窗類別的位置,暫時不用wndclass.cbClsExtra = 0;//額外的位元用來確認下一個視窗執行個體的位置,暫時不用wndclass.cbWndExtra = 0;//執行個體控制代碼wndclass.hInstance = hInstance;//裝載表徵圖wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);//裝載游標wndclass.hCursor = LoadCursor(NULL,IDC_ARROW);//背景為白色wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH);//菜單:暫時沒有wndclass.lpszMenuName = NULL;//視窗類別名wndclass.lpszClassName = szAppName;//註冊視窗if(!RegisterClass(&wndclass)){return -1;}//建立視窗hwnd = CreateWindow(szAppName,//視窗類別的名稱,必須是已經註冊的TEXT("我的畫圖"),//視窗標題WS_OVERLAPPEDWINDOW,//視窗風格CW_USEDEFAULT,//X座標CW_USEDEFAULT,//Y座標CW_USEDEFAULT,//寬度CW_USEDEFAULT,//高度NULL,//父視窗控制代碼NULL,//菜單視窗控制代碼hInstance,//進階版本的windos忽略NULL);//顯示視窗//ShowWindow(hwnd,SW_SHOWNA);ShowWindow (hwnd, iCmdShow);//更新視窗UpdateWindow(hwnd);//訊息迴圈while(GetMessage(&msg,NULL,0,0)){TranslateMessage(&msg);//將訊息給視窗DispatchMessage(&msg);}return msg.wParam;}LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam){HDC hdc;PAINTSTRUCT ps;int i,j;static int cxClient,cyClient;POINT apt[NUM];switch(message){case WM_SIZE:cxClient = LOWORD(lParam);cyClient = HIWORD(lParam);return 0;case WM_PAINT:hdc = BeginPaint(hwnd,&ps);/*//畫出漸層的顏色for(i = 0;i < 500;i++){for(j = 0; j < 26;j++){SetPixel(hdc,200+i,200+j,RGB(i,j*10,0));}}*///劃線/*//用點劃線for(i = 0; i < 500;i++){SetPixel(hdc,0+i,200,RGB(0,0,0));}*//*//用函數劃線MoveToEx(hdc,0,cyClient/2,NULL);LineTo(hdc,cxClient,cyClient/2);for(int i = 0; i< NUM;i++){//把x軸等分成1000份apt[i].x = i * cxClient / NUM;apt[i].y = (int) (cyClient / 2 * (1-sin(TWOPI * i /NUM)));//LineTo(hdc,apt[i].x,apt[i].y);}//Polyline繪製,速度快於在for迴圈內LineToPolyline(hdc,apt,NUM);*///繪製矩形Rectangle(hdc,cxClient / 8,cyClient / 8,7 * cxClient / 8,7 * cyClient / 8);//繪製對角線MoveToEx(hdc,0,0,NULL);LineTo(hdc,cxClient,cyClient);MoveToEx(hdc,0,cyClient,NULL);LineTo(hdc,cxClient,0);//繪製橢圓Ellipse(hdc,cxClient / 8,cyClient / 8,7 * cxClient / 8,7 * cyClient / 8);//繪製圓角矩形RoundRect(hdc,cxClient / 4,cyClient / 4,3 * cxClient / 4,3 * cyClient / 4,//最後兩個參數是圓角矩形的圓角形成的橢圓的長和寬cxClient / 4,cyClient / 4);EndPaint(hwnd,&ps);return 0;case WM_DESTROY:PostQuitMessage(0);return 0;}return DefWindowProc(hwnd,message,wParam,lParam);}
有幾點需要說明:
(1)事實上畫橢圓也是先畫矩形,然後計算內接橢圓得出的。
(2)畫矩形(橢圓)時都是指定左上方和右下角畫圖,這與我們平時使用的畫圖軟體(畫圖、visio)裡是同樣的,可以想象,他們實現的畫圖的方法應該與這裡相同。
(3)程式啟動並執行結果,使得對角線被橢圓遮擋住了。如果改變順序,最後畫對角線,就沒有遮擋發生。這說明,畫出的圖,是“實心的”,不能簡單的理解為只有輪廓。