您的位置:首页 > 编程语言

走进windows编程的世界-----绘图相关

2014-07-13 10:35 375 查看
 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 ); //默认画笔颜色

// 此代码模块中包含的函数的前向声明:
ATOM MyRegisterClass(HINSTANCE hInstance);
BOOL InitInstance(HINSTANCE, int);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
INT_PTR CALLBACK About(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;

//命令ID
wmId = 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_PAINT
break;

case ID_32790://绘制画笔红色

//保存图形绘制类型
g_nPenColor = RGB(255,0,0);
InvalidateRect(hWnd,NULL,TRUE);//刷新窗口,会触发WM_PAINT
break;

case ID_32792://画笔样式
g_nPenStyle = PS_SOLID;
InvalidateRect(hWnd,NULL,TRUE);//刷新窗口,会触发WM_PAINT
break;
case ID_32794://画笔样式
g_nPenStyle = PS_DASH;
InvalidateRect(hWnd,NULL,TRUE);//刷新窗口,会触发WM_PAINT
break;
case ID_32796://画笔样式
g_nPenWdith = 1;
InvalidateRect(hWnd,NULL,TRUE);//刷新窗口,会触发WM_PAINT
break;
case ID_32797://画笔样式
g_nPenWdith = 5;
InvalidateRect(hWnd,NULL,TRUE);//刷新窗口,会触发WM_PAINT
break;
case ID_32799://画刷颜色
g_nBrushColor = RGB(255,0,0);
InvalidateRect(hWnd,NULL,TRUE);//刷新窗口,会触发WM_PAINT
break;
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);

//设置画刷到当前DC
HBRUSH 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 0
wmId = 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);
}
#endif
break;
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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: