GdiplusFlat(3)GdipCreateFromHDC函数 和 画笔(Pen)

本博文由CSDN博主zuishikonghuan所作,版权归zuishikonghuan所有,转载请注明出处: http://blog.csdn.net/zuishikonghuan/article/details/47251225

上两篇分别介绍了GDI+Flat编程是什么,意义和实现方法,以及对WM_PAINT,子类化和GDI编程中的DC做了简单介绍。今天,我们来看看用GDI+Flat如何进行绘图,在开始之前,首先给大家介绍一种新的颜色,ARGB颜色!

想必大家都知道RGB()宏,一种颜色占8位,用RGB宏可以更直观的生成类似0x00??????这样的整数,但是一个int有32位,处了红绿蓝三种颜色以外还有8位没有使用呢,其实,如果把这8位当作颜色的透明度,那就是ARGB颜色了。

没错,GDI+是使用的ARGB颜色,也就是说,通过GDI+可以很方便的实现透明,GDI+Flat也不例外。

GDI+是对GDI的封装吗,GDI不支持透明并不是绝对的,GDI+其实就是取了某一像素点的颜色,通过ARGB颜色中的透明度和ARGB中的颜色进行一定的运算,算出了一个新颜色,再用他封装GDI绘制的。

不过,好像并没有ARGB宏,不过不要紧,用0x??000000和RGB宏做位或运算,或者直接用十六进制:0x????????。

下面,进入重点:

使用设备上下文创建Graphics对象

我在上一篇里就已经说过了GDI+不再像GDI那样使用设备上下文了,但是GDI+是GDI的封装,作为GDI+的平面API,还真是离不开设备上下文,在GDI+Flat中,我们需要使用设备上下文创建Graphics对象,具体的方法是:

创建Graphics:GdipCreateFromHDC

销毁Graphics:GdipDeleteGraphics

还是和以前一样,我们必须自己声明GDI+Flat函数,自己定义GDI+Flat的数据结构。自己动手,丰衣足食。~~

我们把这两个函数自己声明出来!不用那些GDI+类的东西!只用C和Win32的最基本的数据类型!

extern "C" int WINAPI GdipCreateFromHDC(HDC hdc,int* graphics);
extern "C" int WINAPI GdipDeleteGraphics(int graphics);

GdipCreateFromHDC的第一个参数是设备上下文,第二个参数是一个指针,用于接受graphics对象。

GdipDeleteGraphics的参数是要销毁的graphics对象。

返回值:0成功,非0失败

画笔

还是和以前一样,我们必须自己声明GDI+Flat函数,自己定义GDI+Flat的数据结构。自己动手,丰衣足食。~~

对于画笔的创建和销毁,其实是GDI+调用的GDI+Flat的这两个函数:GdipCreatePen1和GdipDeletePen

我们把这两个函数自己声明出来!不用那些GDI+类的东西!只用C和Win32的最基本的数据类型!

extern "C" int WINAPI GdipCreatePen1(unsigned int argb_color, float width, int unit, int** pen);
extern "C" int WINAPI GdipDeletePen(int* pen);

GdipCreatePen1:创建画笔

参数1:ARGB颜色

参数2:画笔宽度

参数3:单位(0到6分别代表:UnitWorld = 0,UnitDisplay= 1,UnitPixel= 2,UnitPoint= 3,UnitInch= 4,UnitDocument= 5,UnitMillimeter= 6 )MSDN:https://msdn.microsoft.com/en-us/library/ms534405(v=vs.85).aspx

反正我只知道2是像素。

参数4:指向一个画笔的指针,用于接收返回的画笔,画笔是int*

GdipDeletePen:销毁画笔

参数:要销毁的画笔

返回值:0成功,非0失败

之后我们就可以通过画笔画图了,这里只介绍画矩形和画直线:

画矩形:GdipDrawRectangle

画直线:GdipDrawLine

还是和以前一样,我们必须自己声明GDI+Flat函数,自己定义GDI+Flat的数据结构。自己动手,丰衣足食。~~

我们把这两个函数自己声明出来!不用那些GDI+类的东西!只用C和Win32的最基本的数据类型!

extern "C" int WINAPI GdipDrawRectangle(int graphics, int* pen, float x, float y, float width, float height);
extern "C" int WINAPI GdipDrawLine(int graphics, int* pen, float x1, float y1, float x2, float y2);

参数没啥好说的,一个Graphics对象,然后是画笔,最后四个是坐标
例子:

	case WM_PAINT:
		HDC hdc;
		PAINTSTRUCT ps;
		hdc = BeginPaint(hwnd, &ps);

		int graphics;
		GdipCreateFromHDC(hdc, &graphics);//创建Graphics对象
		GdipCreatePen1(0x60FF2015, 1, 2, &pen);//创建画笔
		GdipDrawRectangle(graphics, pen, 20, 20, 120, 120);//画矩形
		GdipDrawLine(graphics, pen, 50, 60, 170, 340);//画直线

		GdipDeletePen(pen);//销毁画笔
		GdipDeleteGraphics(graphics);//销毁Graphics对象

		EndPaint(hwnd, &ps);
		return 0;//告诉系统,WM_PAINT消息我已经处理了,你那儿凉快哪儿玩去吧。

效果图:(看出来透明了吗)

GdiplusFlat(3)GdipCreateFromHDC函数 和 画笔(Pen)_第1张图片

完整源码:

</pre><pre class="cpp" name="code">#include "stdafx.h"
#include <gdiplus.h>
#include <gdiplusflat.h>
#pragma comment(lib,"gdiplus.lib")//very important

#include <windows.h>
#include <windowsx.h>
#pragma comment(lib,"user32.lib")
#pragma comment(lib,"gdi32.lib")

//GDI+Flat
typedef struct _GdiplusStartupInput{
	unsigned int GdiplusVersion;
	unsigned int DebugEventCallback;
	BOOL SuppressBackgroundThread;
	BOOL SuppressExternalCodecs;
}GdiplusStartupInput;

extern "C" int WINAPI GdiplusStartup(int* token, GdiplusStartupInput *input, int *output);
extern "C" void WINAPI GdiplusShutdown(int token);
extern "C" int WINAPI GdipCreateFromHDC(HDC hdc, int* graphics);
extern "C" int WINAPI GdipDeleteGraphics(int graphics);
//画笔
extern "C" int WINAPI GdipCreatePen1(unsigned int argb_color, float width, int unit, int** pen);
extern "C" int WINAPI GdipDeletePen(int* pen);
extern "C" int WINAPI GdipDrawRectangle(int graphics, int* pen, float x, float y, float width, float height);
extern "C" int WINAPI GdipDrawLine(int graphics, int* pen, float x1, float y1, float x2, float y2);
int token;
int* pen;

//*************************************************************
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);

WNDCLASS wc;
const TCHAR* AppName = TEXT("MyWindowClass1");
HWND hwnd1;

int APIENTRY _tWinMain(_In_ HINSTANCE hInstance,
	_In_opt_ HINSTANCE hPrevInstance,
	_In_ LPTSTR    lpCmdLine,
	_In_ int       nCmdShow)
{
	//GDI+开启
	GdiplusStartupInput StartupInput = { 0 };
	StartupInput.GdiplusVersion = 1;
	if (GdiplusStartup(&token, &StartupInput, NULL))MessageBox(0, TEXT("GdiPlus开启失败"), TEXT("错误"), MB_ICONERROR);

	//这里是在构建窗口类结构
	wc.style = CS_HREDRAW | CS_VREDRAW;
	wc.lpfnWndProc = WndProc;//窗口回调函数指针
	wc.cbClsExtra = 0;
	wc.cbWndExtra = 0;
	wc.hInstance = hInstance;//实例句柄
	wc.hIcon = LoadIcon(hInstance, TEXT("ICON_1"));
	wc.hCursor = LoadCursor(NULL, IDC_ARROW);//默认指针
	wc.hbrBackground = (HBRUSH)(COLOR_WINDOW);//默认背景颜色
	wc.lpszMenuName = NULL;
	wc.lpszClassName = AppName;//窗口类名

	//注册窗口类
	if (!RegisterClass(&wc))
	{
		MessageBox(NULL, TEXT("注册窗口类失败!"), TEXT("错误"), MB_ICONERROR);
		return 0;
	}

	//创建窗口
	int style = WS_OVERLAPPEDWINDOW;
	hwnd1 = CreateWindowEx(NULL, AppName, TEXT("窗口标题"), style, 50, 50, 500, 500, 0, LoadMenu(hInstance, TEXT("MENU1")), hInstance, 0);
	if (hwnd1 == NULL)
	{
		MessageBox(NULL, TEXT("创建窗口失败!"), TEXT("错误"), MB_ICONERROR);
		return 0;
	}
	//无边框窗口
	SetWindowLong(hwnd1, GWL_STYLE, WS_OVERLAPPED | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS);

	//显示、更新窗口
	ShowWindow(hwnd1, nCmdShow);
	UpdateWindow(hwnd1);

	//消息循环
	MSG msg;
	while (GetMessage(&msg, NULL, 0, 0))
	{
		TranslateMessage(&msg);
		DispatchMessage(&msg);
	}

	//GDI+关闭
	GdiplusShutdown(token);//可以把这个写在消息循环后面,程序退出就销毁,或者在不需要GDI+时调用,比如GDI+窗口的WM_DESTROY消息里调用
	return msg.wParam;
}

LRESULT CALLBACK WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	switch (uMsg){

	case WM_PAINT:
		HDC hdc;
		PAINTSTRUCT ps;
		hdc = BeginPaint(hwnd, &ps);

		int graphics;
		GdipCreateFromHDC(hdc, &graphics);//创建Graphics对象
		GdipCreatePen1(0x60FF2015, 1, 2, &pen);//创建画笔
		GdipDrawRectangle(graphics, pen, 20, 20, 120, 120);//画矩形
		GdipDrawLine(graphics, pen, 50, 60, 170, 340);//画直线

		GdipDeletePen(pen);//销毁画笔
		GdipDeleteGraphics(graphics);//销毁Graphics对象

		EndPaint(hwnd, &ps);
		return 0;//告诉系统,WM_PAINT消息我已经处理了,你那儿凉快哪儿玩去吧。
	case WM_CREATE:
		break;
	case WM_DESTROY://窗口已经销毁
		PostQuitMessage(0);//退出消息循环,结束应用程序
		return 0;
		break;
	case WM_LBUTTONDOWN://鼠标左键按下
		//让无边框窗口能够拖动(在窗口客户区拖动)
		PostMessage(hwnd, WM_SYSCOMMAND, 61458, 0);
		break;
		/*case WM_MOUSEMOVE://鼠标移动
			int xPos, yPos;
			xPos = GET_X_LPARAM(lParam);//鼠标位置X坐标
			yPos = GET_Y_LPARAM(lParam);//鼠标位置Y坐标
			//不要用LOWORD和HIWORD获取坐标,因为坐标有可能是负的
			break;*/
	default:
		break;
	}
	return DefWindowProc(hwnd, uMsg, wParam, lParam);//其他消息交给系统处理
}




你可能感兴趣的:(windows,api,Desktop,GDI+,gdiplus)