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的最基本的数据类型!
GdipCreateFromHDC的第一个参数是设备上下文,第二个参数是一个指针,用于接受graphics对象。
GdipDeleteGraphics的参数是要销毁的graphics对象。
返回值:0成功,非0失败
画笔
还是和以前一样,我们必须自己声明GDI+Flat函数,自己定义GDI+Flat的数据结构。自己动手,丰衣足食。~~
对于画笔的创建和销毁,其实是GDI+调用的GDI+Flat的这两个函数:GdipCreatePen1和GdipDeletePen
我们把这两个函数自己声明出来!不用那些GDI+类的东西!只用C和Win32的最基本的数据类型!
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的最基本的数据类型!
参数没啥好说的,一个Graphics对象,然后是画笔,最后四个是坐标
例子:
效果图:(看出来透明了吗)
完整源码:
上两篇分别介绍了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);//其他消息交给系统处理
}
相关文章推荐
- Hibernate事务与并发问题处理(乐观锁与悲观锁)
- Java NIO系列教程(七) DatagramChannel
- Json网络解析
- Ubuntu使用技巧
- duBand源码分析-底层通讯部分
- 【数据库学习】耿建玲视频章节导图
- Json网络解析
- SpringMVC + Spring 3.2.14 + Hibernate 3.6.10 集成详解
- Linux根目录
- Java NIO系列教程(六) ServerSocketChannel
- Java NIO系列教程(五) SocketChannel
- twisted的单元测试
- Android String.xml Html格式化方法
- poj1679.The Unique MST(最小生成树是否唯一)
- 杭电OJ-1000-(A + B Problem)
- Struts2知识点总结
- Android OpenGL ES 2.0之开发流程
- Aircrack-ng设置监听模式异常
- Java NIO系列教程(四) Selector
- 解决iOS中调用系统中的相机,显示英文标题