首页 > 其他分享 >win32窗口绘制

win32窗口绘制

时间:2024-11-11 21:43:12浏览次数:1  
标签:窗口 int 句柄 DC win32 绘图 GDI 绘制

目录

win32窗口绘制

win32在WM_PAINT消息类型中绘制窗口

//5、窗口过程函数:处理窗口接收的消息
LRESULT CALLBACK MainWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    switch (uMsg)
    {
        //关闭窗口
    case WM_DESTROY:        
        PostQuitMessage(0);
        break;
        //通知窗口需要重绘
    case WM_PAINT: 
        Paint(hwnd);
        break;
        //都不符合
    default:
        return DefWindowProc(hwnd, uMsg, wParam, lParam);//转给windows处理,默认的窗口过程
    }
    return 0;
}

窗口绘图基本流程

绘图设备 DC(Device Context),绘图上下文,绘图描述表
HDC:DC句柄

绘图步骤:
1、得到绘图设备

HDC BeginPaint(
    HWND hWnd,               //窗口句柄
    LPPAINTSTRUCT lpPaint   //存储绘画操作的指针
    );

2、开始绘画
3、结束绘画,将绘画结果提交到屏幕上。

BOOL EndPaint(
     HWND hWnd,                  //窗口句柄
     CONST PAINTSTRUCT *lpPaint  //存储绘画操作的指针
);

开始绘画

基本图形绘制

1、画点 设置指定点的颜色

返回值为点原来的颜色
COLORREF SetPixel(
    HDC hdc,        //绘图设备句柄
    int x,          //点的X坐标
    int y,          //点的Y坐标
    COLORREF color  //点的颜色
    );

2、画线(直线、弧线)

当前点:上一次绘图时的最后一点,初始为(0,0)点
MoveToEx:指定窗口当前点

BOOL MoveToEx(
    HDC hdc,           //绘图设备句柄
    int x,             //指定当前点的X坐标
    int y,             //指定当前点的Y坐标
    LPPOINT lppt       //原本的当前点指针
);

LineTo:从窗口当前点到(LineTo)指定点绘制一条直线

BOOL LineTo(
    HDC hdc,       //绘图设备句柄
    int x,         //指定点的X坐标
    int y          //指定点的Y坐标
    );

3、绘制封闭图形(能使用画刷填充的图形)

矩形:Rectangle

BOOL Rectangle(
   HDC hdc,        //绘图设备句柄
   int left,       //矩形的左
   int top,        //矩形的上
   int right,      //矩形的右
   int bottom      //矩形的下
   );

通常和结构体RECT配合使用,RECT用于定义要绘制的矩形的边界,而Rectangle函数则根据这些边界信息在屏幕上绘制矩形。

typedef struct RECT {
    LONG left;
    LONG top;
    LONG right;
    LONG bottom;
} ;

圆形:Ellipse

BOOL Ellipse(
   HDC hdc,        //绘图设备句柄
   int left,       //外接矩形的左
   int top,        //外接矩形的上
   int right,      //外接矩形的右
   int bottom      //外接矩形的下
   );

GDI绘图对象

HGDIOBJ:GDI绘图对象句柄,兼容画笔句柄,画刷句柄等
HPEN:画笔句柄,描绘线的样式(虚线、点线、实线)、线粗、颜色
HBRUSH:画刷句柄,给封闭图形(不管线型)填充颜色和图案
步骤:
1、创建GDI绘图对象句柄(画笔、画刷)

// 画笔
 HPEN CreatePen(
    int iStyle,     //样式    PS_SOLID:实心线,可以支持多个像素宽,其他类型只能支持一个像素宽
    int cWidth,     //线粗
    COLORREF color  //颜色
 );
// 画刷
 HBRUSH CreateSolidBrush(   //创建实心画刷,填充单一颜色
    COLORREF color          //颜色
 );
 HBRUSH CreateHatchBrush(   //创建纹理画刷,填充纹理线
    int iHatch,             //纹理样式
    COLORREF color          //颜色
    );

2、将创建的GDI绘图对象句柄应用到DC(绘图设备)中,此时自动取出原来的GDI绘图对象句柄
只能置换同种GDI绘图对象,即画刷换画刷,画笔换画笔

 HGDIOBJ SelectObject(      //返回值为原来的GDI绘图对象句柄
    HDC hdc,                //绘图设备句柄
    HGDIOBJ hgdiobj         //GDI绘图对象句柄(画笔句柄、画刷句柄)
 );

3、绘图
4、取出DC(绘图设备)中的GDI绘图对象句柄
使用SelectObject(hdc,原来的GDI绘图对象句柄),即可将之前创建的GDI绘图对象句柄(画笔、画刷)取出
且不需要接收返回值,因为之前创建GDI绘图对象时已有此对象句柄,此时只是将此GDI绘图对象从DC中取出
5、释放GDI绘图对象句柄
只能删除现在不被DC使用的GDI绘图对象,所以释放前要取出创建的GDI绘图对象

 BOOL DeleteObject(
    HGDIOBJ hgdiobj         //GDI绘图对象句柄(画笔句柄、画刷句柄)
 );

可以使用GetStockObject函数获取系统维护的画刷、画笔等
GetStockObject返回的画刷只要取出DC即可,不需要释放,因为是向操作系统借的

HGDIOBJ GetStockObject( 
int i      //NULL_BRUSH:获取透明的画刷,如果没有使用透明画刷,封闭图形内部颜色为白色
);

位图绘制

光栅图像:记录图像中每一点的颜色等信息
矢量图像:记录图像算法、绘图指令等
HBITMAP:位图句柄,既是一种GDI绘图对象,又是一种资源
步骤:
1、添加位图资源
资源文件->添加->资源->Bitmap->绘制保存后,硬盘中保存有该资源文件,程序启动时进程进入内存,内存中有该资源文件
2、加载位图资源LoadBitmap
在本进程的内存中找到该位图资源

     HBITMAP LoadBitmap(        //返回值为该位图资源句柄
        HINSTANCE hInstance,    //当前实例句柄
        LPCWSTR lpBitmapName    //位图ID
        );

3、创建一个与当前DC(在屏幕上绘画)相匹配的DC(内存DC:在内存的一个虚拟区域中绘画)和内存中的虚拟区域

     HDC CreateCompatibleDC(    //返回创建好的内存DC句柄
        HDC hdc                 //当前DC句柄,可为NULL(使用屏幕DC)
     )

4、将位图数据放入内存DC,内存DC在虚拟区中将图像绘制出来

     HGDIOBJ SelectObject(      //返回值为原来的GDI绘图对象句柄,初始时没有原来的位图也要接收这个对象为假位图,之后才能换出来
        HDC hdc,                //绘图设备句柄(内存DC)
        HGDIOBJ hgdiobj         //GDI绘图对象句柄(位图句柄)
     );

5、屏幕成像

//1:1成像
 BOOL BitBlt(
     HDC hdc,       //目的DC
     int x,         //目的左上X坐标
     int y,         //目的左上Y坐标
     int cx,        //目的宽度
    int cy,        //目的高度
     HDC hdcSrc,    //源DC
     int x1,        //源左上X坐标
     int y1,        //源左上Y坐标
     DWORD rop      //成像方法 SRCCOPY:原样成像
 );
 //缩放成像
 BOOL StretchBlt(
     HDC hdc,       //目的DC
     int x,         //目的左上X坐标
     int y,         //目的左上Y坐标
     int cx,        //目的宽度
     int cy,        //目的高度
     HDC hdcSrc,    //源DC
     int x1,        //源左上X坐标
     int y1,        //源左上Y坐标
     int wSrc,      //源DC宽
     int hSrc,      //源DC高
     DWORD rop      //成像方法 SRCCOPY:原样成像
 );

6、取出位图
SelectObject(hdc,原来的GDI绘图对象句柄(位图句柄))
7、释放位图
DeleteObject(位图句柄)
8、释放内存DC
DeleteDC

文本绘制

TextOut:将文字绘制在指定坐标位置,只能绘制单行字符串,不能换行

BOOL TextOut(
    HDC hdc,                //绘图设备句柄
    int x                   //绘制位置,x坐标
    int y,                  //绘制位置,y坐标
    LPCWSTR lpString,       //绘制内容(字符串)
    int c                   //绘制内容(字符串)长度
    );

DrawText:在矩形范围内画字符串,可以绘制多行字符串

int DrawText(
    HDC hdc,                //绘图设备句柄
    LPCWSTR lpchText,       //字符串
    int cchText,            //字符数量
    LPRECT lprc,            //绘制文字的矩形框
    UINT format             //绘制的方式
    );

文字颜色:SetTextColor

COLORREF SetTextColor(
   HDC hdc
   COLORREF color
   );

文字背景色:SetBkColor

COLORREF SetBkColor(
   HDC hdc,
   COLORREF color
   );

文字背景模式:SetBkMode

SetBkMode(OPAQUE/TRANSPARENT):不透明背景/透明背景

字体

HFONT:字体句柄,GDI绘图对象之一
步骤:
1、创建GDI绘图对象句柄(字体)

HFONT CreateFont(
   int cHeight,                //字体高度
   int cWidth,                 //字体宽度
   int cEscapement,            //字符串倾斜角度     单位:0.1度
   int cOrientation,           //字符旋转角度
   int cWeight,                //字体粗细
   DWORD bItalic,              //斜体               1/0
   DWORD bUnderline,           //字符下划线         1/0
   DWORD bStrikeOut,           //删除线             1/0
   DWORD iCharSet,             //字符集             GB231
   DWORD iOutPrecision,        //输出精度             0
   DWORD iClipPrecision,       //剪切精度             0
   DWORD iQuality,             //输出质量             0
   DWORD iPitchAndFamily,      //匹配字体             0
   LPCWSTR pszFaceName         //字体名称
   );

2、将创建的GDI绘图对象句柄应用到DC(绘图设备)中,此时自动取出原来的GDI绘图对象句柄
只能置换同种GDI绘图对象,即画刷换画刷,画笔换画笔

HGDIOBJ SelectObject(      //返回值为原来的GDI绘图对象句柄(原字体句柄)
   HDC hdc,                //绘图设备句柄
   HGDIOBJ hgdiobj         //GDI绘图对象句柄(字体句柄)
);

3、绘制文本
TextOut/DrawText
4、取出DC(绘图设备)中的GDI绘图对象句柄
使用SelectObject(hdc,原来的GDI绘图对象句柄),即可将之前创建的GDI绘图对象句柄(字体)取出,
且不需要接收返回值,因为之前创建GDI绘图对象时已有此对象句柄,此时只是将此GDI绘图对象从DC中取出
5、释放GDI绘图对象句柄
只能删除现在不被DC使用的GDI绘图对象,所以释放前要取出创建的GDI绘图对象

BOOL DeleteObject(
   HGDIOBJ hgdiobj         //GDI绘图对象句柄(字体句柄)
);

相关链接

创建窗口

https://www.cnblogs.com/wa2211lq/p/18540536

标签:窗口,int,句柄,DC,win32,绘图,GDI,绘制
From: https://www.cnblogs.com/wa2211lq/p/18540637

相关文章

  • Windows API窗口绘图程序设计
    目录WindowsAPI窗口绘图程序设计1、窗口过程函数2、WM_LBUTTONDOWN:处理鼠标左键按下的消息鼠标消息相关知识点基本鼠标消息双击消息附带信息滚轮消息附带信息:3、WM_PAINT:处理窗口重绘的消息窗口绘图相关知识点窗口绘图基本流程开始绘画绘制封闭图形(能使用画刷填充的图形)GDI绘图......
  • 【优选算法 — 滑动窗口】水果成篮 & 找到字符串中所有字母异位词
         水果成篮  水果成篮  题目描述  因为只有两个篮子,每个篮子装的水果种类相同,如果从0开始摘,则只能摘0和1两个种类;因为当我们在两个果篮都装有水果的情况下,如果再走到下一颗果树,果树的水果种类不是果篮中的任意一种,则停止采摘;所以就是要找......
  • leetcode刷题笔记--最大滑动窗口
    classSolution{publicintlongestOnes(int[]nums,intk){intl=0,r=0;while(r<nums.length){if(nums[r++]==0){k--;}if(k<0&&nums[l++]==0){......
  • 在线性坐标系中绘制指数函数图象
    本文记述了用Matplotlib在线性坐标系中绘制指数函数图象的例子。代码主体内容如下:...defmain():fig,ax=plt.subplots(figsize=(8,8))#1ax=configure_axes(ax,'ExponentialFunction',3,8,1,0.25,1,0.25)#2x=np.linspace(......
  • 代码随想录算法训练营第十一天 | 150. 逆波兰表达式求值+ 239. 滑动窗口最大值+347.前
    今天接着补上周末的栈与队列的part2,下午继续完成今天的任务。150.逆波兰表达式求值 给你一个字符串数组 tokens ,表示一个根据 逆波兰表示法 表示的算术表达式。请你计算该表达式。返回一个表示表达式值的整数。注意:有效的算符为 '+'、'-'、'*' 和 '/' 。每个......
  • 滑动窗口最大值
    滑动窗口最大值题目给你一个整数数组nums,有一个大小为k的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑动窗口内的k个数字。滑动窗口每次只向右移动一位。返回滑动窗口中的最大值。示例示例1:输入:nums=[1,3,-1,-3,5,3,6,7],k=3输出:[3,3,5,5,6......
  • 代码随想录之滑动窗口、Java日期api、集合(11.4-11.11)
    代码1、长度最小的子数组⭐使用滑动窗口的思想,外层循环控制结束位置j,内层循环控制起始位置i,看似是双层循环,但时间复杂度是o(2n)。 2、水果成篮自己想法:使用backet1和backet2表示篮子1和篮子2;使用backet1Account和backet2Account分别表示两个篮子里水果的数量,内层循环将i指针......
  • windows环境下cmd窗口打开就进入到对应目录,一般人都不知道~
    前言很久以前,我还在上一家公司的时候,有一次我看到我同事打开cmd窗口的方式,瞬间把我惊呆了。原来他打开cmd窗口的方式,不是一般的在开始里面输入cmd,然后打开cmd窗口。而是另外一种方式。我这个同事是个技术控,喜欢研究新的技术,研究一些提高效率的小窍门。这一方面,我看来还是要向他......
  • 实现qt 窗口无边框拖拽
    无边框拖拽是参考Qt实战6.万能的无边框窗口(FramelessWindow)-Qt小罗-博客园的文章,对其代码进行修改而来。本篇一共会提供本人写的无边框的代码以及Qt实战6.万能的无边框窗口(FramelessWindow)-Qt小罗-博客园里面的完整代码供大家参考.代码使用的话,我是直接让widget继承于fr......
  • 通过C++跨平台的预编译宏来区分不同的操作系统:Win32/Win64/Unix/Linux/MacOS
    因为C++具有跨平台的特性,所以有些需求一套代码就多端使用,比如我最近在学习的OpenGLES。但是,不同平台还是具有一定差异性,所以我们首先得判断出是什么平台?比如iOS系统和Android系统。那么如何判断呢?我们接着往下看!要检查C或C代码中主机的操作系统,我们需要检查编......