Windows API窗口绘图程序设计

news/2024/11/13 1:57:02/文章来源:https://www.cnblogs.com/wa2211lq/p/18540588

目录
  • Windows API窗口绘图程序设计
    • 1、窗口过程函数
    • 2、WM_LBUTTONDOWN:处理鼠标左键按下的消息
      • 鼠标消息相关知识点
        • 基本鼠标消息
        • 双击消息
        • 附带信息
        • 滚轮消息
          • 附带信息:
    • 3、WM_PAINT:处理窗口重绘的消息
      • 窗口绘图相关知识点
        • 窗口绘图基本流程
        • 开始绘画
          • 绘制封闭图形(能使用画刷填充的图形)
          • GDI绘图对象
    • 实验结果
    • 实验小结
    • 相关链接
      • win32窗口创建流程
      • win32绘图

Windows API窗口绘图程序设计

设计一个简单的Windows 窗口程序,在程序窗口内任意位置按下鼠标左键,可绘制范围在10-100之间随机大小的正方形。并且显示的正方形用红色填充。

1、窗口过程函数

本次实验涉及主要消息类型:
1、WM_CREATE:初始化全局变量
2、WM_LBUTTONDOWN:处理鼠标左键按下的消息
3、WM_PAINT:处理窗口重绘的消息

//窗口过程函数:处理窗口接收的消息
LRESULT CALLBACK MainWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{switch (uMsg){//关闭窗口case WM_DESTROY:PostQuitMessage(0);break;//通知窗口需要重绘case WM_PAINT: {DrawRect(hwnd);break;}case WM_CREATE:// 初始化全局变量start.x = 0;start.y = 0;squareSize = 0;break;//鼠标左键case WM_LBUTTONDOWN:OnLButtonDown(hwnd,lParam);break;//都不符合default:return DefWindowProc(hwnd, uMsg, wParam, lParam);//转给windows处理,默认的窗口过程}return 0;
}

2、WM_LBUTTONDOWN:处理鼠标左键按下的消息

期望得到鼠标左键单击时的坐标作为绘制正方形的起始坐标,因此可以使用LOWORD(lParam)获得x坐标,HIWORD(lParam)获得y坐标,然后随机生成正方形的边长,通过全局变量RECT rect存储矩形的边界信息,然后InvalidateRect(hwnd, NULL, TRUE);通知窗口立即重绘。

void OnLButtonDown(HWND hwnd, LPARAM lParam)
{start.x= LOWORD(lParam);//鼠标X坐标start.y = HIWORD(lParam);//鼠标Y坐标squareSize = rand() % 91 + 10;//正方形的边长rect = { start.x, start.y, start.x + squareSize, start.y + squareSize };//正方形的边界信息InvalidateRect(hwnd, NULL, TRUE);
}

鼠标消息相关知识点

基本鼠标消息

WM_LBUTTONDOWN:鼠标左键按下
WM_LBUTTONUP:鼠标左键抬起
WM_RBUTTONDOWN:鼠标右键按下
WM_RBUTTONUP:鼠标右键抬起
WM_MOUSEMOVE:鼠标移动消息

双击消息

使用时要在注册窗口类时添加CS_DBLCLKS风格

WM_LBUTTONDBLCLK:鼠标左键双击
WM_RBUTTONDBLCLK:鼠标右键双击

消息产生顺序(左键双击):WM_LBUTTONDOWN->WM_LBUTTONUP->WM_LBUTTONDBLCLK->WM_LBUTTONUP

附带信息

wPARAM:其他按键的状态,如CTRl(包括鼠标本身按键)
lPARAM:鼠标的位置,窗口客户窗坐标系LOWORD(lPARAM) X坐标HIWORD(lPARAM)  Y坐标

滚轮消息

WM_MOUSEWHEEL:鼠标滚轮消息
附带信息:
wPARAM:LOWORD(wPARAM) 其他按键的状态,如CTRl(包括鼠标本身按键)HIWORD(wPARAM) 滚轮的偏移量,正:向前滚动;负:向后滚动
lPARAM:鼠标当前的位置,屏幕坐标系LOWORD(lPARAM) X坐标HIWORD(lPARAM)  Y坐标

3、WM_PAINT:处理窗口重绘的消息

我们要使用红色实线画笔和红色画刷根据rect存储的正方形信息绘制一个红色实心正方形Rectangle(hdc, rect.left, rect.top, rect.right, rect.bottom);//根据获得的矩形绘制一个矩形。

void DrawRect(HWND hwnd)
{PAINTSTRUCT ps;//存储绘画操作的信息。HDC hdc = BeginPaint(hwnd, &ps);//得到绘图设备if (squareSize > 0) {HPEN hPen = CreatePen(PS_SOLID, 1, RGB(255, 0, 0));//创建红色实心画笔HGDIOBJ hOldPen = SelectObject(hdc,hPen);//应用画笔到DCHBRUSH hBrush = CreateSolidBrush(RGB(255, 0, 0));//创建红色画刷HGDIOBJ hOldBrush = SelectObject(hdc, hBrush);//应用画刷到DC//绘图Rectangle(hdc, rect.left, rect.top, rect.right, rect.bottom);//根据获得的矩形绘制一个矩形SelectObject(hdc, hOldPen);//取出画笔SelectObject(hdc, hOldBrush);//取出画刷DeleteObject(hPen);//释放画笔DeleteObject(hBrush);//释放画刷}//结束绘画操作,将绘画结果提交到屏幕上。EndPaint(hwnd, &ps);
}

窗口绘图相关知识点

窗口绘图基本流程

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

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

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

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

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

开始绘画

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

矩形: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;
} ;
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绘图对象句柄(画笔句柄、画刷句柄));

实验结果

实验小结

本次实验主要处理WM_LBUTTONDOWNWM_PAINT这两类消息类型,通过获得鼠标左击时的坐标作为正方形的起始坐标,通过随机数获取正方形的边长,然后在窗口重绘时使用红色画笔和画刷绘制并填充矩形。

相关链接

win32窗口创建流程

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

win32绘图

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/832013.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Matlab常用的图像属性

线型、标记和颜色 线型、标记和颜色,指定为包含符号的字符串或字符向量。符号可以按任意顺序显示。不需要同时指定所有三个特征(线型、标记和颜色)。例如,如果忽略线型,只指定标记,则绘图只显示标记,不显示线条。以下是 MATLAB 在许多类型的绘图中使用的默认颜色的 RGB …

jvm Java虚拟机栈——栈内存溢出

----------- ---------------------- -----------------

学习笔记(三十五):ArkTs-@ohos.util.ArrayList (线性容器ArrayList)

概述: 一种线性数据结构,底层基于数组实现一、导入import { ArrayList } from @kit.ArkTS; 二、定义let arrayList: ArrayList<string | number> = new ArrayList(); 三、常用函数 1、 add,在ArrayList尾部插入元素 2、insert,在长度范围内任意位置插入指定元素3、…

Scrum冲刺-第一篇

这个作业属于哪个课程 广工计院计科34班这个作业要求在哪里 作业要求这个作业的目标 小队各成员的任务确认和项目期望一、团队简介: 队名:edg.gdut 成员:姓名 学号罗祖文 3121004537郑志涛 3122004547陈恺麟 3122004515许凌铎 3122004540邓茗骏 3122004517李晓彬 3122004531…

(1) Pytorch深度学习—数值处理

(1)Pytorch——数值处理参考于李沐“动手学深度学习”系列以及网上各路大佬的博客资料,感谢大家的分享,如错改,如侵删。torch中的数值处理 数值处理是深度学习中极其重要的一部分,张量(tensor)是后续进行处理和计算的基本单位。张量表示一个由数值组成的数组,这个数组…

904. 水果成蓝

题目 自己第一次写的,结果超时了 class Solution { public:int totalFruit(vector<int> &fruits){int r = 1;int res = 1;while (r < fruits.size()){int l = r - 1;int n = 1; // 代表不同的种类个数int second = -1;while (n <= 2 && l >= 0){i…

Lift, Splat, Shoot, LSS代码详尽分析与解读

LSS是英伟达在ECCV2020上发表的文章《Lift, Splat, Shoot: Encoding Images from Arbitrary Camera Rigs by Implicitly Unprojecting to 3D》中提出的一个BEV感知算法,后续很多BEV感知算法如CaDDN、BEVDet都是在LSS的基础上实现的。本文将结合论文和代码详细解读LSS的原理。鸟…

【Playwright + Python】系列(九)Playwright 调用 Chrome 插件,小白也能事半功倍

哈喽,大家好,我是六哥!今天我来给大家分享一下如何使用playwight调用chrome插件,面向对象为功能测试及零基础小白,我尽量用大白话的方式举例讲解,力求所有人都能看懂,建议大家先收藏,以免后面找不到。😎 什么是chrome插件? 就是辅助你工作生活的助手,会让你事半功倍…

基于Java+SpringBoot+Mysql在线课程学习教育系统功能设计与实现四

技术点:SpringBoot+SpringDataJPA+Mysql+Freemaker+Bootstrap+JS+CSS+HTML 部分功能:课程分类信息数据层Dao、课程信息数据层Dao、课程订单信息数据层Dao、课程评价信息数据层Dao、课程视频信息数据层Dao、课程小节信息数据层Dao、课程试题信息数据层Dao、课程试卷信息数据层…

极限limit

The Limit 两个重要极限\[\displaystyle\lim_{x\to 0}\frac{sinx}{x}=1 \]\[\displaystyle\lim_{x\to \infty}(1+x)^{\frac{1}{x}}=e \]间断点 1.第一类间断点 第一类间断点是指在该点附近的函数值存在,但在该点的极限不存在。具体来说,若 $ f(x) $ 在 $ x = c $ 附近的左极限…

基于Java+SpringBoot+Mysql在线课程学习教育系统功能设计与实现三

该系统总共24张表,代码整洁,每个功能、接口上都有注释说明。 运行环境:jdk1.8、mysql5.x、eclipse/idea、maven3.5/3.6 包远程运行的哦。 特色功能:发布课程、学习课程、分享资料、资料讨论等。 部分功能:关于我们信息实体类Entity、评论信息实体类Entity、课程资料信息实…

SpringBoot+Thyemleaf开发环境正常,打jar包发到服务器就报错Template might not exist or might not ..

前言 前几天,我在开发前后端一体的项目时候,遇到了一个巨大的坑。这个是关于SpringBoot+Thyemleaf的。现象就是,我在本地开发环境是好的,正常访问某个页面,但是到了打成jar包后,部署到服务器之后,再访问那个页面,总是报错。这个报错是类似于Template might not exist o…