標籤:des style blog color 使用 os
Windows繪圖
1 圖形繪製
1.1 圖形繪製的方式
擷取到繪圖控制代碼-裝置描述表(DC),使用相應的繪圖的API,在裝置上繪製圖形.
1.2 顏色
R\G\B三色, 每種顏色8位, 共24位顏色.
32位顏色: 顏色數量24位顏色, 多出來的8位表示灰階.
16位: 顏色數量2的16次方.
Win32下,顏色的定義 COLORREF(DWORD), RGB宏定義顏色
COLORREF nColor = RGB( 0, 0, 0 );
COLORREF nColor = RGB( 255,255,255 );
COLORREF nColor = RGB( 255,0, 0 );
從一個顏色中擷取RGB三色:
int nBlue = GetBValue( nColor );
int nRed = GetRValue( nColor );
int nGreen= GetGValue( nColor );
下面是具體的代碼
// winDraw.cpp.cpp : 定義應用程式的進入點。//#include "stdafx.h"#include "winDraw.cpp.h"#include <stdio.h>#define MAX_LOADSTRING 100// 全域變數:HINSTANCE hInst;// 當前執行個體TCHAR szTitle[MAX_LOADSTRING];// 標題列文本TCHAR szWindowClass[MAX_LOADSTRING];// 主視窗類名int g_nDrawType = 0; //繪圖命令COLORREF g_nPenColor = RGB( 0, 0, 0 ); //預設畫筆顏色int g_nPenStyle = PS_SOLID; //預設畫筆類型int g_nPenWdith = 1; //預設畫筆寬度COLORREF g_nBrushColor = RGB( 255, 255, 255 ); //預設畫筆顏色// 此代碼模組中包含的函數的前向聲明:ATOMMyRegisterClass(HINSTANCE hInstance);BOOLInitInstance(HINSTANCE, int);LRESULT CALLBACKWndProc(HWND, UINT, WPARAM, LPARAM);INT_PTR CALLBACKAbout(HWND, UINT, WPARAM, LPARAM);int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow){UNREFERENCED_PARAMETER(hPrevInstance);UNREFERENCED_PARAMETER(lpCmdLine); // TODO: 在此放置代碼。MSG msg;HACCEL hAccelTable;// 初始化全域字串LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);LoadString(hInstance, IDC_WINDRAWCPP, szWindowClass, MAX_LOADSTRING);MyRegisterClass(hInstance);// 執行應用程式初始化:if (!InitInstance (hInstance, nCmdShow)){return FALSE;}hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_WINDRAWCPP));// 主訊息迴圈:while (GetMessage(&msg, NULL, 0, 0)){if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg)){TranslateMessage(&msg);DispatchMessage(&msg);}}return (int) msg.wParam;}//// 函數: MyRegisterClass()//// 目的: 註冊視窗類別。//// 注釋://// 僅當希望// 此代碼與添加到 Windows 95 中的“RegisterClassEx”// 函數之前的 Win32 系統相容時,才需要此函數及其用法。調用此函數十分重要,// 這樣應用程式就可以獲得關聯的// “格式正確的”小表徵圖。//ATOM MyRegisterClass(HINSTANCE hInstance){WNDCLASSEX wcex;wcex.cbSize = sizeof(WNDCLASSEX);wcex.style= CS_HREDRAW | CS_VREDRAW;wcex.lpfnWndProc= WndProc;wcex.cbClsExtra= 0;wcex.cbWndExtra= 0;wcex.hInstance= hInstance;wcex.hIcon= LoadIcon(hInstance, MAKEINTRESOURCE(IDI_WINDRAWCPP));wcex.hCursor= LoadCursor(NULL, IDC_ARROW);wcex.hbrBackground= (HBRUSH)(COLOR_WINDOW+1);/*載入功能表項目 也可以在建立windows的時候載入菜單*/wcex.lpszMenuName= MAKEINTRESOURCE(IDC_WINDRAWCPP);wcex.lpszClassName= szWindowClass;wcex.hIconSm= LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));return RegisterClassEx(&wcex);}//// 函數: InitInstance(HINSTANCE, int)//// 目的: 儲存執行個體控制代碼並建立主視窗//// 注釋://// 在此函數中,我們在全域變數中儲存執行個體控制代碼並// 建立和顯示主程式視窗。//BOOL InitInstance(HINSTANCE hInstance, int nCmdShow){ HWND hWnd; hInst = hInstance; // 將執行個體控制代碼儲存在全域變數中 hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL); if (!hWnd) { return FALSE; } ShowWindow(hWnd, nCmdShow); UpdateWindow(hWnd); return TRUE;}void OnCommand(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam){int wmId, wmEvent;//命令IDwmId = LOWORD(wParam);wmEvent = HIWORD(wParam);// 分析菜單選擇:switch (wmId){case ID_32774://繪製點case ID_32775:case ID_32772:case ID_32776://繪製圓弧case ID_32777://繪製折線 case ID_32780://繪製曲線case ID_32781://繪製多樣式曲線case ID_32782://繪製矩形case ID_32783://繪製圓case ID_32785://繪製餅case ID_32786://繪製炫case ID_32787://繪製多邊形//儲存圖形繪製類型g_nDrawType = wmId;InvalidateRect(hWnd,NULL,TRUE);//重新整理視窗,會觸發WM_PAINTbreak;case ID_32790://繪製畫筆紅色//儲存圖形繪製類型g_nPenColor = RGB(255,0,0);InvalidateRect(hWnd,NULL,TRUE);//重新整理視窗,會觸發WM_PAINTbreak;case ID_32792://畫筆樣式g_nPenStyle = PS_SOLID;InvalidateRect(hWnd,NULL,TRUE);//重新整理視窗,會觸發WM_PAINTbreak;case ID_32794://畫筆樣式g_nPenStyle = PS_DASH;InvalidateRect(hWnd,NULL,TRUE);//重新整理視窗,會觸發WM_PAINTbreak;case ID_32796://畫筆樣式g_nPenWdith = 1;InvalidateRect(hWnd,NULL,TRUE);//重新整理視窗,會觸發WM_PAINTbreak;case ID_32797://畫筆樣式g_nPenWdith = 5;InvalidateRect(hWnd,NULL,TRUE);//重新整理視窗,會觸發WM_PAINTbreak;case ID_32799://畫刷顏色g_nBrushColor = RGB(255,0,0);InvalidateRect(hWnd,NULL,TRUE);//重新整理視窗,會觸發WM_PAINTbreak;case IDM_ABOUT:DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);break;case IDM_EXIT:DestroyWindow(hWnd);break;default: DefWindowProc(hWnd, message, wParam, lParam); break;}}//點的繪製void DrawPixel(HDC hDC){COLORREF nColor = RGB(255,0,0);/* *繪製: COLORREF SetPixel( * HDC hdc, //DC控制代碼 * int X, //x座標 * int Y, //y座標 * COLORREF crColor ); // 點的顏色 */SetPixel(hDC,100,100,nColor);}void GetPixelColor(HDC hDC){DrawPixel(hDC);/*擷取點的顏色 *擷取: COLORREF GetPixel( * HDC hdc, //DC控制代碼 * int XPos, //x座標 * int nYPos ); //y座標 * 返回指定座標位置的點的顏色 */ COLORREF nColor = GetPixel( hDC, 100, 100 ); //擷取顏色的三色值 int nRed = GetRValue( nColor ); int nGreen = GetGValue( nColor ); int nBlue = GetBValue( nColor ); CHAR szText[260] = { 0 };sprintf_s( szText, "COLOR=%08X, RED=%d GREEN=%d BLUE=%d", nColor, nRed, nGreen, nBlue ); MessageBox( NULL, szText, "GetPixelColor", MB_OK );}//繪製直線void DrawLine( HDC hDC ){ MoveToEx( hDC, 0, 0, NULL ); LineTo( hDC, 500, 500 ); MoveToEx( hDC, 500, 0, NULL ); LineTo( hDC, 0, 500 );}//繪製圓弧void DrawArc(HDC hDC ){//逆時針的方式 SetArcDirection( hDC, AD_COUNTERCLOCKWISE ); //通過外切矩形和切割線/*BOOL Arc( HDC hdc, * int nLeftRect, // 外切矩形的座標 * int nTopRect,//外切矩形的座標 * int nRightRect,//外切矩形的座標 * int nBottomRect,//外切矩形的座標 * int nXStartArc,//起始切割半徑的X座標 * int nYStartArc,//起始切割半徑的Y座標 * int nXEndArc, //終止切割半徑的X座標 * int nYEndArc ); //終止切割半徑的X座標 * 可以使用SetArcDirection函數,設定Arc函數 * 切割方向:順時針和逆時針 */ Arc( hDC, 400, 200, 500, 300,500, 200, 400, 200); //順時針的方式 SetArcDirection( hDC, AD_CLOCKWISE ); Arc( hDC, 500, 200, 600, 300,600, 200, 500, 200);/*沒有這個話會出現0,0 到200,200 的一條直線*/MoveToEx( hDC, 200, 200, NULL );/* 另一種繪製圓的方法, *BOOL AngleArc( * HDC hdc, // handle to device context * int X, //圓心的X座標 * int Y, //圓心的Y座標 * DWORD dwRadius,//圓的半徑 * FLOAT eStartAngle,//開始角度 * FLOAT eSweepAngle );//夾角 */AngleArc(hDC,200,200,100,60,120);LineTo( hDC, 200, 200 );}//繪製折線void DrawPolyLine(HDC hDC){POINT ptPolyLine[7] = { 0 }; ptPolyLine[0].x = 100; ptPolyLine[0].y = 100; ptPolyLine[1].x = 200; ptPolyLine[1].y = 100; ptPolyLine[2].x = 200; ptPolyLine[2].y = 200; ptPolyLine[3].x = 300; ptPolyLine[3].y = 200; ptPolyLine[4].x = 300; ptPolyLine[4].y = 300; ptPolyLine[5].x = 400; ptPolyLine[5].y = 300; ptPolyLine[6].x = 400; ptPolyLine[6].y = 400;/* *BOOL Polyline( * HDC hdc, //DC控制代碼 * CONST POINT *lppt,//Polyline頂點的座標數組 * int cPoints ); //頂點數組的長度 * PolylineTo 與Polyline類似, 只是在繪製Polyline前 * ,從當前點使用LineTo繪製直線到Polyline的第一個頂點 */ Polyline( hDC, ptPolyLine, 7 ); //PolylineTo( hDC, ptPolyLine, 3 );/* *繪製多組折線 PolyPolyline * BOOL PolyPolyline( HDC hdc, * CONST POINT *lppt,//所有點的數組 * CONST DWORD *lpdwPolyPoints,//每組點的數量 * DWORD cCount );//分組的數量 */ //DWORD nGroup[] = { 4, 3 }; //PolyPolyline( hDC, ptPolyLine,nGroup, 2 );}void DrawBizer( HDC hDC ){ POINT ptBizer[7] = { 0 }; ptBizer[0].x = 100; //端點 ptBizer[0].y = 100; // ptBizer[1].x = 100; //控制點 ptBizer[1].y = 50; // ptBizer[2].x = 300; //控制點 ptBizer[2].y = 150; // ptBizer[3].x = 300; //端點 ptBizer[3].y = 100; // ptBizer[4].x = 300; //控制點 ptBizer[4].y = 400; ptBizer[5].x = 400; //控制點 ptBizer[5].y = 200; ptBizer[6].x = 500; //端點 ptBizer[6].y = 300; /* Bezier曲線 BOOL PolyBezier(HDC hdc, CONST POINT *lppt,//點數組,最少4個點 DWORD cPoints );//點的數量 4個點: 1和4是端點,2.3點是控制點 7個點: 1.4.7是端點,其餘是控制點 */ PolyBezier( hDC, ptBizer, 7 ); MoveToEx( hDC, ptBizer[0].x, ptBizer[0].y, NULL ); LineTo( hDC, ptBizer[1].x, ptBizer[1].y ); MoveToEx( hDC, ptBizer[3].x, ptBizer[3].y, NULL ); LineTo( hDC, ptBizer[2].x, ptBizer[2].y );}//多樣式線void DrawPolyDraw( HDC hDC ){ POINT ptDraw[4] = { 0 }; ptDraw[0].x = 100; ptDraw[0].y = 100; ptDraw[1].x = 200; ptDraw[1].y = 100; ptDraw[2].x = 200; ptDraw[2].y = 200; ptDraw[3].x = 300; ptDraw[3].y = 200; BYTE ptType[4] = {0}; ptType[0] = PT_MOVETO; ptType[1] = PT_LINETO;ptType[2] = PT_LINETO; ptType[3] = PT_LINETO;/** BOOL PolyDraw( HDC hdc, * CONST POINT *lppt,//各個點的數組 * CONST BYTE *lpbTypes, //從某點到下一點的繪製方式 pointer to line and curve identifiers * int cCount); //點的數量 * * lpbTypes - PT_MOVETO 移動到該點 * PT_LINETO 繪直線 * PT_BIZERTO Biezer曲線 */ PolyDraw( hDC, ptDraw, ptType, 4 );}void DrawRect( HDC hDC ){ //矩形 Rectangle( hDC, 100, 100, 200, 200 ); //帶圓角矩形/* 帶圓角的矩形 BOOL RoundRect( HDC hdc, int nLeftRect, //左上X座標 int nTopRect, //左上Y座標 int nRightRect,//右下X座標 int nBottomRect, //右下Y座標 int nWidth, //產生圓角的橢圓的寬度 int nHeight );//產生圓角的橢圓的高度*/ RoundRect( hDC, 300, 100, 400, 200, 50, 50 );}void DrawEllipse( HDC hDC ){ //圓/*BOOL Ellipse( HDC hdc, int nLeftRect, //外切矩形左上X座標 int nTopRect,//外切矩形左上Y座標 int nRightRect, //外切矩形右下X座標 int nBottomRect); //外切矩形右下Y座標*/ Ellipse( hDC, 100, 100, 200, 200 ); //橢圓 Ellipse( hDC, 300, 100, 500, 200 );}void DrawPie( HDC hDC ){ Pie( hDC, 100, 100, 500, 400, 500, 100, 100, 100 );}void DrawChord( HDC hDC ){/* 弦 * BOOL Chord( HDC hdc, * int nLeftRect, //外切矩形左上X座標 * int nTopRect, //外切矩形左上Y座標 * int nRightRect, //外切矩形右下X座標 * int nBottomRect, //外切矩形右下Y座標 * int nXRadial1,//切割起始半徑X座標 * int nYRadial1,//切割起始半徑Y座標 * int nXRadial2,//切割終止半徑X座標 * int nYRadial2 );//切割終止半徑Y座標 */ Chord( hDC, 100, 100, 500, 400, 500, 100, 100, 100 );}void DrawPloygon( HDC hDC ){ POINT ptPloygon[4] = { 0 }; ptPloygon[0].x = 100; ptPloygon[0].y = 100; ptPloygon[1].x = 200; ptPloygon[1].y = 100; ptPloygon[3].x = 600; ptPloygon[3].y = 300; ptPloygon[2].x = 500; ptPloygon[2].y = 300;/* 多邊形 * BOOL Polygon( HDC hdc, * CONST POINT *lpPoints, //多邊形的頂點 * int nCount ); //頂點的數量 * PolyPolygon 可以繪製多組多邊形 */ Polygon( hDC, ptPloygon, 4 );}void OnPaint(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam){HDC hDC;PAINTSTRUCT ps;hDC = BeginPaint(hWnd,&ps);/*建立畫筆 * HPEN CreatePen( * int fnPenStyle, //畫筆的樣式 * int nWidth, //畫筆的寬度 * COLORREF crColor);//畫筆的顏色 */HPEN hPen = CreatePen(g_nPenStyle,g_nPenWdith,g_nPenColor);/*設定畫筆到當前DC * HGDIOBJ SelectObject( * HDC hdc, // 當前DC的控制代碼 * HGDIOBJ hgdiobj );//要使用的GDI物件控點 * 返回當前DC原來使用的同類型的GDI物件控點。 */HPEN hOldPen = (HPEN)SelectObject(hDC,hPen);//建立畫刷,畫刷只對填充物有效果,圓,多邊形,矩形等HBRUSH hBrush = CreateSolidBrush(g_nBrushColor);//設定畫刷到當前DCHBRUSH hOldBrush = (HBRUSH)SelectObject(hDC,hBrush);// 根據不同的繪製類型,來做不同的指令 switch(g_nDrawType){case ID_32774://繪製點DrawPixel(hDC);break;case ID_32775://擷取點顏色GetPixelColor(hDC);break;case ID_32772://繪製直線DrawLine(hDC);break;case ID_32776://繪製圓弧DrawArc(hDC);break;case ID_32777://繪製折線DrawPolyLine(hDC);break;case ID_32780://繪製曲線DrawBizer( hDC );break;case ID_32781://繪製多樣式曲線DrawPolyDraw( hDC );break;case ID_32782://繪製矩形DrawRect( hDC );break;case ID_32783://繪製圓和橢圓DrawEllipse( hDC );break;case ID_32785://繪製餅絲DrawPie( hDC );break;case ID_32786://繪製炫DrawChord( hDC );break;case ID_32787://繪製多邊形DrawPloygon( hDC );break;default:break;}//取出畫刷 SelectObject( hDC, hOldBrush ); //刪除畫刷 DeleteObject( hBrush ); //取出畫筆,舊畫筆放進去,新畫筆就會釋放 SelectObject( hDC, hOldPen ); //銷毀畫筆 DeleteObject( hPen );EndPaint(hWnd,&ps);}//// 函數: WndProc(HWND, UINT, WPARAM, LPARAM)//// 目的: 處理主視窗的訊息。//// WM_COMMAND- 處理應用程式菜單// WM_PAINT- 繪製主視窗// WM_DESTROY- 發送退出訊息並返回////LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam){switch (message){case WM_COMMAND:/*菜單的資訊處理*/OnCommand(hWnd,message,wParam,lParam);#if 0wmId = LOWORD(wParam);wmEvent = HIWORD(wParam);// 分析菜單選擇:switch (wmId){case IDM_ABOUT:DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);break;case IDM_EXIT:DestroyWindow(hWnd);break;default:return DefWindowProc(hWnd, message, wParam, lParam);}#endifbreak;case WM_PAINT:/*繪圖指令*/OnPaint(hWnd, message, wParam, lParam);break;case WM_DESTROY:PostQuitMessage(0);break;default:return DefWindowProc(hWnd, message, wParam, lParam);}return 0;}// “關於”框的訊息處理常式。INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam){UNREFERENCED_PARAMETER(lParam);switch (message){case WM_INITDIALOG:return (INT_PTR)TRUE;case WM_COMMAND:if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL){EndDialog(hDlg, LOWORD(wParam));return (INT_PTR)TRUE;}break;}return (INT_PTR)FALSE;}