GDI 画笔(9)
使用现有画笔
Windows 提供三种备用画笔(Stock Pen):BLACK_PEN(黑色画笔)、WHITE_PEN(白色画笔)、NULL_PEN(不绘制任何图形的画笔)。
调用 GetStockObject 函数可以获取备用画笔的句柄(HPEN),调用 SelectObject 函数可以将指定的画笔选入设备环境,并返回之前选入设备环境的画笔句柄:
// 定义画笔句柄
HPEN hPen, hPrevPen; // 获取备用画笔的句柄
hPen = GetStockObject(WHITE_PEN); // 将画笔选入设备环境,函数返回之前选入设备环境的画笔的句柄
hPrevPen = SelectObject(hdc, hPen);
GDI 对象使用规则
- 最终应当删除所有由用户创建的 GDI 对象
- 当 GDI 对象被选入一个有效的设备环境时,不可删除它
- 不可删除备用对象(Stock Object)
创建画笔
调用 CreatePen 函数可以创建一个画笔,画笔句柄将作为返回值返回:
HPEN CreatePen(
int fnPenStyle, // 画笔样式(决定绘制的是实线、虚线或点线)
int nWidth, // 画笔宽度(为 0 时,将设为 1 个像素。虚线或点线只能为 1 个像素,否则将被设为实线)
COLORREF crColor // 画笔颜色(COLORREF 值,可以通过 RGB 宏指定)
);
调用 CreatePenIndirect 函数可以根据 LOGPEN(逻辑画笔)结构来建立一个画笔,画笔句柄将作为返回值返回:
LOGPEN 结构:
typedef struct tagLOGPEN {
UINT lopnStyle; // 画笔样式
POINT lopnWidth; // 画笔宽度(Windows 仅使用 x 字段)
COLORREF lopnColor; // 画笔颜色
} LOGPEN, *PLOGPEN;
CreatePenIndirect 函数:
HPEN CreatePenIndirect(
CONST LOGPEN *lplgpn // LOGPEN 结构的地址
);
选择画笔
调用 SelectObject 函数,可以将刚刚创建的画笔选入设备环境,并返回之前选入设备环境的画笔句柄:
HGDIOBJ SelectObject(
HDC hdc, // 设备环境句柄
HGDIOBJ hgdiobj // GDI 对象句柄(这里指画笔句柄)
);
删除画笔
调用 DeleteObject 函数,可以将使用完的画笔删除:
BOOL DeleteObject(
HGDIOBJ hObject // GDI 对象句柄(这里指画笔句柄)
);
注:不要删除已被选入设备环境的当前画笔
获取创建的画笔
调用 GetObject 函数可以从指定画笔句柄中,得到关于此画笔的 LOGPEN 结构的各个字段的值:
GetObject(hPen, sizeof(LOGPEN), (LPVOID)&logpen);
调用 GetCurrentObject 函数可以获取当前被选入设备环境的画笔句柄:
hPen = GetCurentObject(hdc, OBJ_PEN);
填充空隙
空隙的颜色由设备环境的背景模式和背景颜色所决定,默认的背景模式是 OPAQUE(不透明),即用背景颜色(默认为白色)填充。
调用 SetBkColor 函数可以改变 Windows 填充空隙的背景颜色:
COLORREF SetBkColor(
HDC hdc, // 设备环境句柄
COLORREF crColor // 背景颜色值(COLORREF)
);
调用 GetBkColor 函数可以得到 Windows 填充空隙的背景颜色,函数将它作为返回值返回:
COLORREF GetBkColor(
HDC hdc // 设备环境句柄
);
调用 SetBkMode 函数可以设置背景模式,设置成 TRANSPARENT 可以阻止 Windows 填充空隙:
int SetBkMode(
HDC hdc, // 设备环境句柄
int iBkMode // 背景模式,可选 QPAQUE(不透明)和 TRANSPARENT(透明)两种模式
);
绘图模式
二元光栅操作(ROP2,raster operation 2):Windows 绘制直线时,将画笔的像素颜色和目标显示表面的像素颜色按位进行布尔运算
默认情况下,绘图模式是 R2_COPYPEN,像素的简单复制。
- R2_NOTCOPYPEN 像素复制为画笔颜色的反色
- R2_BLACK 总是绘制为黑色
- R2_WHITE 总是绘制为白色
- R2_NOP 不操作
- R2_NOT 将目标颜色取反,来获取绘制颜色
调用 SetROP2 函数可以设置一种新的绘图模式:
int SetROP2(
HDC hdc, // 设备环境句柄
int fnDrawMode // 绘图模式(以 R2 为前缀的标志)
);
调用 GetROP2 函数可以获取当前的绘图模式,作为返回值返回:
int GetROP2(
HDC hdc // 设备环境句柄
);
PENDEMO 示例程序
#include <windows.h>
#include <math.h> #define NUMS 1000
#define TWOPI 6.283185307179586476925286766559 LRESULT CALLBACK WindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { HDC hdc;
PAINTSTRUCT ps;
static LOGPEN logpen;
static HPEN hRedPen;
static HPEN hBluePen;
static int cxClient, cyClient;
POINT apt[NUMS];
int i; switch (message) { case WM_CREATE: logpen.lopnColor = RGB(255, 0, 0);
logpen.lopnStyle = PS_DASH;
logpen.lopnWidth.x = 1;
hRedPen = CreatePenIndirect(&logpen); logpen.lopnColor = RGB(0, 0, 255);
logpen.lopnStyle = PS_INSIDEFRAME;
logpen.lopnWidth.x = 3;
hBluePen = CreatePenIndirect(&logpen); return 0; case WM_SIZE:
cxClient = LOWORD(lParam);
cyClient = HIWORD(lParam); return 0; case WM_PAINT:
hdc = BeginPaint(hwnd, &ps); SelectObject(hdc, hRedPen);
MoveToEx(hdc, 0, cyClient / 2, NULL);
LineTo(hdc, cxClient, cyClient / 2); SelectObject(hdc, hBluePen);
for (i = 0; i < NUMS; i++) {
apt[i].x = i * cxClient / NUMS;
apt[i].y = (int)(( 1 - sin(TWOPI * i / NUMS)) * cyClient / 2);
} SetTextAlign(hdc, TA_TOP | TA_RIGHT);
TextOut(hdc, cxClient - 12, 12, TEXT("y = sin x"), 12);
TextOut(hdc, cxClient / 2 - 12, cyClient / 2 + 12, TEXT("( π, 0 )"), 9);
TextOut(hdc, cxClient - 12, cyClient / 2 + 12, TEXT("( 2 π, 0 )"), 11); SetTextAlign(hdc, TA_TOP | TA_LEFT);
TextOut(hdc, 12, cyClient / 2 + 12, TEXT("( 0, 0 )"), 9); PolyBezier(hdc, apt, NUMS); EndPaint(hwnd, &ps);
return 0; case WM_DESTROY:
DeleteObject(hRedPen);
DeleteObject(hBluePen);
PostQuitMessage(0);
return 0;
} return DefWindowProc(hwnd, message, wParam, lParam);
} int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { LPCTSTR lpszClassName = TEXT("PenDemo");
LPCTSTR lpszWindowName = TEXT("Pen Demo Program"); WNDCLASS wndclass;
wndclass.cbClsExtra = 0;
wndclass.cbWndExtra = 0;
wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wndclass.hInstance = hInstance;
wndclass.lpfnWndProc = WindowProc;
wndclass.lpszClassName = lpszClassName;
wndclass.lpszMenuName = NULL;
wndclass.style = CS_HREDRAW | CS_VREDRAW; if (!RegisterClass(&wndclass)) {
MessageBox(NULL, TEXT("This program requires Windows NT!"), lpszWindowName, MB_ICONERROR);
return 0;
} HWND hwnd = CreateWindow(
lpszClassName,
lpszWindowName,
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
NULL,
NULL,
hInstance,
NULL
); ShowWindow(hwnd, nCmdShow);
UpdateWindow(hwnd); MSG msg;
while (GetMessage(&msg, NULL, 0, 0)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
} return msg.wParam;
}
GDI 画笔(9)的更多相关文章
- {Reship}{C#}{GDI+}GDI+画笔,线,区域类型
=================================================================================== This article is ...
- GDI编程
图形设备接口(GDI)是一个可执行程序,它接受Windows应用程序的绘图请求(表现为GDI函数调用),并将它们传给相应的设备驱动程序,完成特定于硬件的输出,象打印机输出和屏幕输出.GDI负责Wind ...
- GDI编程小结
图形设备接口(GDI)是一个可运行程序,它接受Windows应用程序的画图请求(表现为GDI函数调用),并将它们传给对应的设备驱动程序,完毕特定于硬件的输出,象打印机输出和屏幕输出.GDI负责Wind ...
- VC++学习之GDI概述
VC++学习之GDI概述 图形设备接口(GDI)是一个可执行程序,它接受Windows应用程序的绘图请求(表现为GDI函数调用),并将它们传给相应的设备驱动程序,完成特定于硬件的输出,象打印机输出和屏 ...
- MFC绘图相关GDI工具对象和函数介绍
在利用MFC进行界面编程时,除了需要熟悉各种类型控件的操作外,还会经常遇到图形绘制和显示的问题,比如时频分析界面.图像处理界面等.处理这些软件界面开发问题时,不可避免地需要用到一系列GDI工具对象和相 ...
- c# -- 对象销毁和垃圾回收
有些对象需要显示地销毁代码来释放资源,比如打开的文件资源,锁,操作系统句柄和非托管对象.在.NET中,这就是所谓的对象销毁,它通过IDisposal接口来实现.不再使用的对象所占用的内存管理,必须在某 ...
- DWM 窗体玻璃效果实现
我一直盼望着 Windows 新版本的发布.令人感兴趣的事情莫过于浏览 MSDN® 和 SDK 文档,查找一些可以利用和依赖的最新创新,然后让朋友和同事以及您的老板(如果幸运的话)大开眼界.Windo ...
- MFC编程基础
http://www.cnblogs.com/lzmfywz/archive/2012/03/15/2399403.html 一.MFC类库概述 MFC(Microsoft Foundation cl ...
- 【转】DWM 窗体玻璃效果实现
我一直盼望着 Windows 新版本的发布.令人感兴趣的事情莫过于浏览 MSDN® 和 SDK 文档,查找一些可以利用和依赖的最新创新,然后让朋友和同事以及您的老板(如果幸运的话)大开眼界.Windo ...
随机推荐
- php 数组 array()
定义和用法 array() 创建数组,带有键和值.如果在创建数组时省略了键,则生成一个整数键,默认从 0 开始,然后以 1 进行递增. 用 array() 创建一个数组,可使用 => 来分隔键和 ...
- Android Studio第一次启动的Fetching android sdk component information的问题
1)进入刚安装的Android Studio文件夹下的bin文件夹.找到idea.properties文件,用文本编辑器打开. 2)在idea.properties文件末尾加入一行: disable. ...
- 2017 Multi-University Training Contest - Team 2&&hdu 6047 Maximum Sequence
Maximum Sequence Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) ...
- NOIP2013--火柴排队(树状数组)
转载: 树状数组,具体的说是 离散化+树状数组.这也是学习树状数组的第一题. 算法的大体流程就是: 1.先对输入的数组离散化,使得各个元素比较接近,而不是离散的, 2.接着,运用树状数组的标准操作来累 ...
- poj1041 John's trip——字典序欧拉回路
题目:http://poj.org/problem?id=1041 求字典序欧拉回路: 首先,如果图是欧拉图,就一定存在欧拉回路,直接 dfs 即可,不用 return 判断什么的,否则TLE... ...
- word文档去掉复制过来的背景颜色
选择清除格式
- 利用windbg获取dump的dll文件
根据堆栈对应的地址查找其对应的Module ID,然后将对应的Module保存. !IP2MD 命令从托管函数中获取 MethodDesc 结构地址. !dumpmodule 1caa50 下面的命令 ...
- MVC微信浏览器图片上传(img转Base64)
因公司业务需要,需要做一个微信公众号里的图片上传功能,主要用到的技术就是 img转base64 上到服务器 话不多说, 贴代码 先看前端显示出来的东西 OK 图片不重要,看代码 <!--微信图片 ...
- python3爬取豆瓣排名前250电影信息
#!/usr/bin/env python # -*- coding: utf-8 -*- # @File : doubanmovie.py # @Author: Anthony.waa # @Dat ...
- MTD 门店统计
DROP TABLE #MTD ' ,@endDate date = cast(getdate() as date) CREATE TABLE #MTD(bydate date) DECLARE @c ...