win32 API编程之GDI绘图

win32 API编程之GDI绘图

一、GDI简介

二、获取DC的3种方法

三、绘图函数

四、双缓冲绘图技术

五、绘制位图

一、GDI简介

1)什么是设备上下文

2)设备上下文类型

3)常见的GDI对象

4)windows坐标系

5)GDI绘图步骤

二、获取DC的3种方法

1)获取DC的3种方法

2)PAINTSTRUCT结构

3)BeginPaint函数

4)EndPaint函数

5)GetDC函数

6)GetWindowDC函数

7)三种方式的区别

8)代码实例

#include

//自定义的窗口过程

LRESULT CALLBACK MyWindowProc(HWND hWnd, UINT Msg,

WPARAM wParam, LPARAM lParam)

{

switch (Msg)

{

case WM_DESTROY:

PostQuitMessage(0);//可以使GetMessage返回0

return 0;

case WM_PAINT:

{

//1.使用BeginPaint,它能将无效区域变成有效(如果存在无效区域,系统会一直发送WM_PAINT)

/*PAINTSTRUCT ps;

HDC hdc = BeginPaint(hWnd, &ps);

TextOut(hdc, 0, 0, L"你好啊!", lstrlen(L"你好啊!"));

EndPaint(hWnd, &ps);*/

//2.使用GetDC获取客户区DC,它并不能将无效区域变成有效,所以WM_PAINT一直发送,文字一直闪烁

/*

HDC hdc = GetDC(hWnd);

TextOut(hdc, 0, 0, L"你好啊!", lstrlen(L"你好啊!"));

ReleaseDC(hWnd, hdc);

//return 0; //去掉之后交给默认DefWindowProc处理WM_PAINT消息,会调用BeginPaint,EndPaint

*/

}

break;

case WM_NCPAINT:

{

//3.获取整个窗口的DC,包括标题栏,工具条等

HDC hdc = GetWindowDC(hWnd);

RECT r = {0,0,400,20};

HBRUSH brh = CreateSolidBrush(RGB(255, 0, 0));

FillRect(hdc, &r, brh);

DeleteObject(brh);

ReleaseDC(hWnd, hdc);//释放掉DC

return true;

}break;

}

return DefWindowProc(hWnd, Msg, wParam, lParam);

}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,

LPSTR lpCmdLine, int nShowCmd)

{

//1.注册窗口类

WNDCLASS wnd;

wnd.cbClsExtra = 0;

wnd.cbWndExtra = 0;

wnd.hbrBackground = (HBRUSH)(GetStockObject(GRAY_BRUSH));//背景色

wnd.hCursor = LoadCursor(NULL, IDC_ARROW);//光标

wnd.hIcon = LoadIcon(NULL, IDI_APPLICATION);//图标

//wnd.lpfnWndProc = DefWindowProc;//默认窗口过程函数,用于处理消息

wnd.lpfnWndProc = MyWindowProc;//自定义的窗口过程函数

wnd.lpszClassName = L"MrHuang";//窗口类名

wnd.lpszMenuName = NULL;//菜单资源名称

wnd.style = CS_HREDRAW | CS_DBLCLKS;//窗口类、样式

wnd.hInstance = hInstance;//实例句柄

RegisterClass(&wnd);

//创建窗口(返回之前发送WM_CREATE)

HWND hWnd = CreateWindow(L"MrHuang", L"第一个窗口程序",

WS_OVERLAPPEDWINDOW, 100, 100, 400, 400, NULL, NULL, hInstance, NULL);

//显示窗口

ShowWindow(hWnd, nShowCmd);

//更新窗口(发送WM_PAINT)

UpdateWindow(hWnd);

//消息循环(收到WM_QUIT消息退出)

MSG msg;

while (GetMessage(&msg, NULL, 0, 0))

{

TranslateMessage(&msg);//翻译消息

DispatchMessage(&msg);//分发消息到窗口过程

}

}

三、绘图函数

1)创建画笔

2)选择一个对象到数据上下文

3)画直线

4)画矩形

5)创建画刷

6)DeleteObject函数

7)GetStockObject函数

8)画椭圆

9)画饼图

10)写入字符串

11)SetBkColor函数

12)SetBkMode函数

13)DrawText函数

14)SetTextAlign函数

15)代码实例

①绘制直线、矩形、椭圆、饼图

#include

//自定义的窗口过程

LRESULT CALLBACK MyWindowProc(HWND hWnd, UINT Msg,

WPARAM wParam, LPARAM lParam)

{

switch (Msg)

{

case WM_DESTROY:

PostQuitMessage(0);//可以使GetMessage返回0

return 0;

case WM_PAINT:

{

PAINTSTRUCT ps;

//获取设备上下文句柄

HDC hdc = BeginPaint(hWnd, &ps);

//创建画笔

HPEN hPen = CreatePen(PS_DASHDOT, 1, RGB(255, 0, 0));

//将笔选入到设备上下文(使用这支笔)

SelectObject(hdc, hPen);

//1.画直线(两个点)

MoveToEx(hdc, 100, 100, NULL);

LineTo(hdc, 200, 100);

//创建画刷

HBRUSH hBsh = CreateSolidBrush(RGB(0, 255, 0));

//将画刷选入到设备上下文(使用这支画刷)

SelectObject(hdc, hBsh);

//2.画矩形(正方形)

Rectangle(hdc, 200, 200, 400, 400);

//获取透明画刷

HGDIOBJ hBsh2 =GetStockObject(NULL_BRUSH);

SelectObject(hdc, hBsh2);

Rectangle(hdc, 100, 100, 200, 150);

//3.画椭圆(圆形)

Ellipse(hdc, 200, 200, 400, 400);

Ellipse(hdc, 100, 100, 200, 150);

//4.画饼图

/*

//饼图产生的步骤分解

Ellipse(hdc, 500, 100, 800, 400);

//从圆心到第一个点的连线

MoveToEx(hdc, 650, 250, NULL);

LineTo(hdc,1000, 300);

//从圆心到第二个点的连线

MoveToEx(hdc, 650, 250, NULL);

LineTo(hdc, 400, 400);

*/

Pie(hdc, 500, 100, 800, 400, 1000, 300,400, 400);

//删除GDI对象

DeleteObject(hPen);

DeleteObject(hBsh);

EndPaint(hWnd, &ps);

}

break;

}

return DefWindowProc(hWnd, Msg, wParam, lParam);

}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,

LPSTR lpCmdLine, int nShowCmd)

{

//1.注册窗口类

WNDCLASS wnd;

wnd.cbClsExtra = 0;

wnd.cbWndExtra = 0;

wnd.hbrBackground = (HBRUSH)(GetStockObject(GRAY_BRUSH));//背景色

wnd.hCursor = LoadCursor(NULL, IDC_ARROW);//光标

wnd.hIcon = LoadIcon(NULL, IDI_APPLICATION);//图标

//wnd.lpfnWndProc = DefWindowProc;//默认窗口过程函数,用于处理消息

wnd.lpfnWndProc = MyWindowProc;//自定义的窗口过程函数

wnd.lpszClassName = L"MrHuang";//窗口类名

wnd.lpszMenuName = NULL;//菜单资源名称

wnd.style = CS_HREDRAW | CS_DBLCLKS;//窗口类、样式

wnd.hInstance = hInstance;//实例句柄

RegisterClass(&wnd);

//创建窗口(返回之前发送WM_CREATE)

HWND hWnd = CreateWindow(L"MrHuang", L"第一个窗口程序",

WS_OVERLAPPEDWINDOW, 100, 100, 1000, 700, NULL, NULL, hInstance, NULL);

//显示窗口

ShowWindow(hWnd, nShowCmd);

//更新窗口(发送WM_PAINT)

UpdateWindow(hWnd);

//消息循环(收到WM_QUIT消息退出)

MSG msg;

while (GetMessage(&msg, NULL, 0, 0))

{

TranslateMessage(&msg);//翻译消息

DispatchMessage(&msg);//分发消息到窗口过程

}

}

②写入字符串

#include

//自定义的窗口过程

LRESULT CALLBACK MyWindowProc(HWND hWnd, UINT Msg,

WPARAM wParam, LPARAM lParam)

{

switch (Msg)

{

case WM_DESTROY:

PostQuitMessage(0);//可以使GetMessage返回0

return 0;

case WM_PAINT:

{

PAINTSTRUCT ps;

//获取设备上下文句柄

HDC hdc = BeginPaint(hWnd, &ps);

//改变文本的背景色

SetBkColor(hdc, RGB(255, 0, 0));

//设置文本背景模式

SetBkMode(hdc, TRANSPARENT);//透明

//设置文本的颜色

SetTextColor(hdc, RGB(255, 0, 0));

//设置文本的参考点

SetTextAlign(hdc, TA_TOP);

//1.界面上画文本

TextOut(hdc,250, 200, L"你好啊,这是画的文本!", lstrlen(L"你好啊,这是画的文本!"));

//2.在矩形范围中画文本

RECT r = {250,400,300,500};

Rectangle(hdc, r.left, r.top, r.right, r.bottom);

DrawText(hdc, L"你好啊,这是画的文本!", lstrlen(L"你好啊,这是画的文本!")

, &r, DT_BOTTOM|DT_SINGLELINE);

EndPaint(hWnd, &ps);

}

break;

}

return DefWindowProc(hWnd, Msg, wParam, lParam);

}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,

LPSTR lpCmdLine, int nShowCmd)

{

//1.注册窗口类

WNDCLASS wnd;

wnd.cbClsExtra = 0;

wnd.cbWndExtra = 0;

wnd.hbrBackground = (HBRUSH)(GetStockObject(GRAY_BRUSH));//背景色

wnd.hCursor = LoadCursor(NULL, IDC_ARROW);//光标

wnd.hIcon = LoadIcon(NULL, IDI_APPLICATION);//图标

//wnd.lpfnWndProc = DefWindowProc;//默认窗口过程函数,用于处理消息

wnd.lpfnWndProc = MyWindowProc;//自定义的窗口过程函数

wnd.lpszClassName = L"MrHuang";//窗口类名

wnd.lpszMenuName = NULL;//菜单资源名称

wnd.style = CS_HREDRAW | CS_DBLCLKS;//窗口类、样式

wnd.hInstance = hInstance;//实例句柄

RegisterClass(&wnd);

//创建窗口(返回之前发送WM_CREATE)

HWND hWnd = CreateWindow(L"MrHuang", L"第一个窗口程序",

WS_OVERLAPPEDWINDOW, 100, 100, 1000, 700, NULL, NULL, hInstance, NULL);

//显示窗口

ShowWindow(hWnd, nShowCmd);

//更新窗口(发送WM_PAINT)

UpdateWindow(hWnd);

//消息循环(收到WM_QUIT消息退出)

MSG msg;

while (GetMessage(&msg, NULL, 0, 0))

{

TranslateMessage(&msg);//翻译消息

DispatchMessage(&msg);//分发消息到窗口过程

}

}

四、双缓冲绘制技术

1)什么是双缓冲绘制技术

2)步骤

3)CreateCompatiableDC函数

4)CreateCompatiableBitmap函数

5)BitBlt函数

6)StretchBlt函数

7)代码实例

#include

#include

//自定义的窗口过程

LRESULT CALLBACK MyWindowProc(HWND hWnd, UINT Msg,

WPARAM wParam, LPARAM lParam)

{

switch (Msg)

{

case WM_DESTROY:

PostQuitMessage(0);//可以使GetMessage返回0

return 0;

case WM_PAINT:

{

PAINTSTRUCT ps;

HDC hdc = BeginPaint(hWnd, &ps);

//1.创建兼容内存DC,此时它的大小时1X1,很小,不能绘制

HDC hMemDC=CreateCompatibleDC(hdc);

//2.创建兼容位图,提供绘画区域

HBITMAP hMemBmp = CreateCompatibleBitmap(hdc, 100, 100);

//3.把兼容位图选到兼容内存DC中,此刻DC的大小与位图一致,可以绘制

SelectObject(hMemDC, hMemBmp);

//4.在兼容内存DC上进行绘图操作

SetTextColor(hMemDC, RGB(255, 0, 0));

TextOut(hMemDC, 0, 0, L"双缓冲技术绘制!", lstrlen(L"双缓冲技术绘制!"));

Rectangle(hMemDC, 30, 30, 80, 80);

//5.把内存DC中的图像一次性画到窗口DC上

//不拉伸

BitBlt(hdc, 0, 0, 100, 100, hMemDC, 0, 0, SRCCOPY);

//拉伸(目标矩形大于源矩形)

StretchBlt(hdc, 0, 0, 400, 400, hMemDC, 0, 0,100,100, SRCCOPY);

//压缩(目标矩形小于源矩形)

StretchBlt(hdc, 0, 0, 50, 50, hMemDC, 0, 0, 100, 100, SRCCOPY);

//释放资源

DeleteDC(hMemDC);

DeleteObject(hMemBmp);

EndPaint(hWnd, &ps);

}

break;

}

return DefWindowProc(hWnd, Msg, wParam, lParam);

}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,

LPSTR lpCmdLine, int nShowCmd)

{

//1.注册窗口类

WNDCLASS wnd;

wnd.cbClsExtra = 0;

wnd.cbWndExtra = 0;

wnd.hbrBackground = (HBRUSH)(GetStockObject(GRAY_BRUSH));//背景色

wnd.hCursor = LoadCursor(NULL, IDC_ARROW);//光标

wnd.hIcon = LoadIcon(NULL, IDI_APPLICATION);//图标

//wnd.lpfnWndProc = DefWindowProc;//默认窗口过程函数,用于处理消息

wnd.lpfnWndProc = MyWindowProc;//自定义的窗口过程函数

wnd.lpszClassName = L"MrHuang";//窗口类名

wnd.lpszMenuName = NULL;//菜单资源名称

wnd.style = CS_HREDRAW | CS_DBLCLKS;//窗口类、样式

wnd.hInstance = hInstance;//实例句柄

RegisterClass(&wnd);

//创建窗口(返回之前发送WM_CREATE)

HWND hWnd = CreateWindow(L"MrHuang", L"第一个窗口程序",

WS_OVERLAPPEDWINDOW, 100, 100, 400, 400, NULL, NULL, hInstance, NULL);

//显示窗口

ShowWindow(hWnd, nShowCmd);

//更新窗口(发送WM_PAINT)

UpdateWindow(hWnd);

//消息循环(收到WM_QUIT消息退出)

MSG msg;

while (GetMessage(&msg, NULL, 0, 0))

{

TranslateMessage(&msg);//翻译消息

DispatchMessage(&msg);//分发消息到窗口过程

}

}

五、绘制位图

1)什么是位图

2)位图绘制的步骤

3)LoadImage函数

4)SetStrechBltMode函数

5)代码实例

#include

#include

//自定义的窗口过程

LRESULT CALLBACK MyWindowProc(HWND hWnd, UINT Msg,

WPARAM wParam, LPARAM lParam)

{

switch (Msg)

{

case WM_DESTROY:

PostQuitMessage(0);//可以使GetMessage返回0

return 0;

case WM_PAINT:

{

PAINTSTRUCT ps;

HDC hdc = BeginPaint(hWnd, &ps);

//1.创建内存兼容DC(1px X 1px)

HDC hMemDC = CreateCompatibleDC(hdc);

//2.加载位图资源

HBITMAP hBmp= (HBITMAP)LoadImage(NULL, L"bg.bmp", IMAGE_BITMAP, 800, 800, LR_LOADFROMFILE);

//3.把位图选入到兼容内存DC

SelectObject(hMemDC, hBmp);

//添加水印

TextOut(hMemDC, 100, 100, L"乱涂乱画", lstrlen(L"乱涂乱画"));

//设置图像拉伸模式

//SetStretchBltMode(hdc, COLORONCOLOR);//删除多余像素

SetStretchBltMode(hdc, HALFTONE);

//4.将兼容DC中的图像一次性拷贝到窗口DC上

//BitBlt(hdc, 0, 0, 800, 800, hMemDC, 0, 0, SRCCOPY);

//完整显示

StretchBlt(hdc, 0, 0, 400, 400, hMemDC, 0, 0, 800,800,SRCCOPY);

//5.释放DC与位图资源

DeleteObject(hBmp);

DeleteDC(hMemDC);

EndPaint(hWnd, &ps);

}

break;

}

return DefWindowProc(hWnd, Msg, wParam, lParam);

}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,

LPSTR lpCmdLine, int nShowCmd)

{

//1.注册窗口类

WNDCLASS wnd;

wnd.cbClsExtra = 0;

wnd.cbWndExtra = 0;

wnd.hbrBackground = (HBRUSH)(GetStockObject(GRAY_BRUSH));//背景色

wnd.hCursor = LoadCursor(NULL, IDC_ARROW);//光标

wnd.hIcon = LoadIcon(NULL, IDI_APPLICATION);//图标

//wnd.lpfnWndProc = DefWindowProc;//默认窗口过程函数,用于处理消息

wnd.lpfnWndProc = MyWindowProc;//自定义的窗口过程函数

wnd.lpszClassName = L"MrHuang";//窗口类名

wnd.lpszMenuName = NULL;//菜单资源名称

wnd.style = CS_HREDRAW | CS_DBLCLKS;//窗口类、样式

wnd.hInstance = hInstance;//实例句柄

RegisterClass(&wnd);

//创建窗口(返回之前发送WM_CREATE)

HWND hWnd = CreateWindow(L"MrHuang", L"第一个窗口程序",

WS_OVERLAPPEDWINDOW, 100, 100, 400, 400, NULL, NULL, hInstance, NULL);

//显示窗口

ShowWindow(hWnd, nShowCmd);

//更新窗口(发送WM_PAINT)

UpdateWindow(hWnd);

//消息循环(收到WM_QUIT消息退出)

MSG msg;

while (GetMessage(&msg, NULL, 0, 0))

{

TranslateMessage(&msg);//翻译消息

DispatchMessage(&msg);//分发消息到窗口过程

}

}

相关数据流

交易猫交易平台怎么样 交易猫平台交易靠谱吗
365bet体育35元

交易猫交易平台怎么样 交易猫平台交易靠谱吗

⌚ 10-04 👁️‍🗨️ 5708
聚砜PSF有哪些特性和用途?
365bet体育35元

聚砜PSF有哪些特性和用途?

⌚ 09-05 👁️‍🗨️ 1415