您的位置:首页 > 其它

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

2015-08-03 16:08 429 查看
本博文由CSDN博主zuishikonghuan所作,版权归zuishikonghuan所有,转载请注明出处:/article/9672522.html
上两篇分别介绍了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消息我已经处理了,你那儿凉快哪儿玩去吧。


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



完整源码:

</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);//其他消息交给系统处理
}




内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: