MFC绘图

文章目录

  • 消息组成
  • 消息的作用
  • 获取消息
  • 翻译消息
  • 常见消息
    • WM_DESTROY
    • WM_SYSCOMMAND
  • 消息循环的阻塞
  • 发送消息
  • 字符串资源
  • 加速键资源
  • GDI绘图对象-画笔
  • 位图绘制
  • 文本绘制
  • 字体
  • 模式对话框
  • 动态库特点
  • 线程
    • 创建线程
  • 互斥
  • 事件
  • 信号量

消息组成

  • 窗口句柄
  • 消息ID
  • 消息的两个参数
  • 消息产生的时间
  • 消息产生时的鼠标位置

消息的作用

  • 当系统通知窗口工作时,就采用消息的方式派发给窗口
//显示窗口
ShowWindow(hWnd,SW_SHOW);
UpdateWindow(hWnd);
//消息循环
MSG nMsg = {0}while(GetMessage(&nMsg,NULL,0,0)){TranslateMessage(&nMsg);DispatchMessage(&nMsg);
}
return 0;

获取消息

BOOL GetMessage(LPMSG lpMsg, //存取获取到的消息BUFFHWND hWnd, // 窗口句柄UINT wMsgFilterMin,//获取消息的最小IDUINT wMsgFilterMax,//获取消息的最大ID)
  • lpMsg–当获取到的消息后,将消息的参数存放到MSG结构中
  • hWnd–获取到hWnd所指定窗口的消息
  • wMsgFilterMin和wMsgFilterMsx—只能获取到由他们指定的消息,如果都为0,则表示没有范围

翻译消息

TranslateMessage–翻译消息,按键消息,翻译成字符消息

BOOL TranslateMessage{CONST MSG * lpMsg;//要翻译的消息地址
}
  • 检查消息是否是按键的消息,如果不是按键消息,不做任何处理,继续执行。

常见消息

WM_DESTROY

  • 产生时间:窗口被销毁时的消息
  • 附带信息:wParam为0 lParam 为0
  • 一般用法:常用于在窗口被销毁之前,做相应的善后处理,例如资源、内存等

WM_SYSCOMMAND

  • 产生时间:当点击窗口的最大化,最小化,关闭等
  • 附带消息:wParam:具体点击的位置,例如关闭SC_CLOSE等 lParam:鼠标光标的位置,LOWORD(lParam);//水平位置 HIWORD(lParam);//垂直位置
  • 一般用法:常用在窗口关闭时,提示用户处理

消息循环的阻塞

在这里插入图片描述

while(1){if(PeekMessage(&nMsg,NULL,0,0,PM_NOREMOVE)){if(GetMessage(&nMsg,NULL,0,0)){TranslateMessage(&nMsg);DisPatchMessage(&nMsg);}}
}

发送消息

  • SendMessage–发送消息,会等候消息处理的结果
  • PostMessage–投递消息,消息发出后立刻返回并不会等候消息执行结果
BOOL SendMessage/PostMessage{HWND hWnd;//消息发送的目的窗口UINT msg;//消息IDWPARAM wParam;//消息参数LPARAM lParam;//消息参数
}

自定义消息:

  • 系统消息:0x000-0x03ff 由系统定义好的消息,可以在程序中直接使用
  • 用户自定义消息–ID范围(0x0400-0x7fff) 由用户自己定义,满足用户自己的需求,由用户自己发出消息,并相应处理
#define WM_USER 0X0400+1
SendMessage(hWnd,msg,1,2);

字符串资源

  • 添加字符串资源:添加字符串表,在表中增加字符串
  • 字符串资源的使用
int LoadString(HINSTANCE hInstance;UINT uID,LPTSTR lpBuffer,int nBufferMax
);成功返回字符串长度,失败0

加速键资源

GDI绘图对象-画笔

  • 画笔作用:线的颜色、线型、线粗;HPEN-画笔句柄
  • 画笔使用:创建画笔
HPEN CreatePen(int fnPenStyle, //画笔的样式int nWidth, //画笔的粗细COLORREF crColor //画笔的颜色
)创建成功返回句柄
  • 其他:可以使用GetStockObject函数获取系统维护的画刷、画笔等,如果不使用画刷填充,需要使用NULL_BRUSH参数,获取不填充的GetStockObject返回的画刷不需要DeleteObject
HANDLE g_hOutput = 0;
void DrawPit(HDC hdc) {for (int i = 0; i < 256; i++) {for (int j = 0; j < 256; j++) {SetPixel(hdc, i, j, RGB(i, j, 0));}}
}void DrawLine(HDC hdc) {MoveToEx(hdc, 100, 100, NULL);LineTo(hdc, 300, 300);
}void DrawRect(HDC hdc) {Rectangle(hdc, 100, 100, 300, 300);
}
void DrawEll(HDC hdc) {Ellipse(hdc, 100, 100, 300, 300);
}
void OnPaint(HWND hWnd) {PAINTSTRUCT ps = { 0 };HDC hdc = BeginPaint(hWnd, &ps);//DrawPit(hdc);//DrawLine(hdc);//DrawRect(hdc);HPEN hPen = CreatePen(PS_DASH, 1, RGB(255, 0, 0));HGDIOBJ nOldPen = SelectObject(hdc, hPen);//HBRUSH hBrush = CreateSolidBrush(RGB(0, 255, 0));HGDIOBJ hBrush = GetStockObject(NULL_BRUSH);//透明颜色HGDIOBJ nOldBrush = SelectObject(hdc, hBrush);DrawEll(hdc);//DeleteObject(hBrush);SelectObject(hdc, nOldBrush);//SelectObject(hdc, nOldPen);//DeleteObject(hPen);EndPaint(hWnd, &ps);
}

位图绘制

- 位图

在这里插入图片描述
在这里插入图片描述

void DrawBmp(HDC hdc) {//添加位图资源(不需要代码)HBITMAP hBmp = LoadBitmap(g_hInstance, (char *)IDB_BITMAP1);HDC hMemdc = CreateCompatibleDC(hdc);//创建一个内存DC,并构建一个虚拟区域,并且内存DC在虚拟区域中绘图HGDIOBJ nOldBmp = SelectObject(hMemdc, hBmp);//将位图数据送给内存DC,内存DC在虚拟区域中将位图绘制出来BitBlt(hdc, 100, 100, 48, 48, hMemdc, 0, 0, SRCCOPY);//将虚拟区域中绘制好的图像城成像到窗口中StretchBlt(hdc, 200, 200, 24, 24, hMemdc, 0, 0, 48, 48, SRCCOPY);//缩放成像SelectObject(hMemdc, nOldBmp);DeleteObject(hBmp);DeleteDC(hMemdc);
}

文本绘制

在这里插入图片描述
在这里插入图片描述

void OnPaint(HWND hWnd) {PAINTSTRUCT ps = { 0 };HDC hdc = BeginPaint(hWnd, &ps);char szText[] = "hello txt";SetTextColor(hdc, RGB(255, 0, 0));SetBkColor(hdc, RGB(0, 255, 0));SetBkMode(hdc, TRANSPARENT);TextOut(hdc, 100, 100, szText, strlen(szText));RECT rc;rc.left = 100;rc.top = 150;rc.right = 200;rc.bottom = 200;Rectangle(hdc, 100, 150, 200, 200);DrawText(hdc, szText, strlen(szText), &rc, DT_LEFT | DT_TOP | DT_WORDBREAK);EndPaint(hWnd, &ps);
}

字体

在这里插入图片描述
在这里插入图片描述

void OnPaint(HWND hWnd) {PAINTSTRUCT ps = { 0 };HDC hdc = BeginPaint(hWnd, &ps);SetTextColor(hdc, RGB(255, 0, 0));SetBkColor(hdc, RGB(0, 255, 0));SetBkMode(hdc, TRANSPARENT);HFONT hFont = CreateFont(30, 0, 45, 0, 900, 1, 1, 1, GB2312_CHARSET, 0, 0, 0, 0, "黑体");HGDIOBJ nOldFont = SelectObject(hdc, hFont);char szText[] = "hello txt";TextOut(hdc, 100, 100, szText, strlen(szText));RECT rc;rc.left = 100;rc.top = 150;rc.right = 200;rc.bottom = 200;Rectangle(hdc, 100, 150, 200, 200);DrawText(hdc, szText, strlen(szText), &rc, DT_LEFT | DT_TOP | DT_WORDBREAK);SelectObject(hdc, nOldFont);DeleteObject(hFont);EndPaint(hWnd, &ps);
}

模式对话框

在这里插入图片描述
在这里插入图片描述

HINSTANCE g_hInstance = 0;
void OnCommand(HWND hWnd,WPARAM wParam){switch(LOWORD(wParam)){case ID_MODEL:{DialogBox(g_hInstance,(char*)IDD_DIALOG1,hWnd,DlgProc);}}
}INT CALLBACK DlgProc(HWND hwndlg,UINT msgID, WPARAM wParam,LPARAM lParam){if(wParam == SC_CLOSE){EndDialog(hwndlg,100);}break;return FALSE;
}

动态库特点

动态库特点

  • 运行时独立存在
  • 源码不会连接到执行程序
  • 使用时加载(使用动态库必须动态库执行)

与静态库比较:

  1. 由于静态库是将代码嵌入

线程

创建线程

HANDLE CreateThread(LPSECURITY_ATTRIBUTES lpThreadAttributes,//安全属性SIZE_T dwStackSize,  //线程栈的大小LPTHREAD_START_ROUTINE lpStartAddress, //线程处理函数的函数地址LPVOID lpParameter,   //传递给线程处理函数的参数DWORD dwCreationFlags, //线程的创建方式LPDWORD lpThread //创建成功,返回线程的ID
);创建成功,返回线程句柄

定义线程处理函数

DWORD WINAPI ThreadProc(LPVOID lpParameter //创建线程时,传递给线程的参数
)

互斥

相关的问题:
多线程下代码或资源的贡献使用
互斥的使用:
1、创建互斥

HANDLE CreateMutex(LPSECURITY_ATTRIBUTES lpMutexAttributes,//安全属性BOOL bInitialOwner, //初始的拥有者 true/falseLPCTSTR lpName //命名
);创建成功或返回互斥句柄

2、等候互斥
WaitFor… 互斥的等候遵循谁先等候谁先获取
3、释放互斥

BOOL ReleaseMutex(HANDLE hMutex //handle to mutex
);

3、关闭互斥句柄

#include<Windows.h>
#include<stdio.h>HANDLE g_hMutex;
DWORD CALLBACK TestProc(LPVOID pParam) {char* pszText = (char *)pParam;while (1) {WaitForSingleObject(g_hMutex, INFINITE);for (int i = 0; i < strlen(pszText); i++) {printf("%c", pszText[i]);Sleep(125);}printf("\n");ReleaseMutex(g_hMutex);}return 0;
}
DWORD CALLBACK TestProc2(LPVOID pParam) {char* pszText = (char *)pParam;while (1) {WaitForSingleObject(g_hMutex, INFINITE);for (int i = 0; i < strlen(pszText); i++) {printf("%c", pszText[i]);Sleep(125);}printf("\n");ReleaseMutex(g_hMutex);}return 0;
}
int main() {g_hMutex = CreateMutex(NULL, FALSE, NULL);DWORD nID = 0;char *pszText = "**********";HANDLE hThread = CreateThread(NULL, 0, TestProc, pszText, 0, &nID);char *pszText2 = "----------";HANDLE hThread2 = CreateThread(NULL, 0, TestProc2, pszText2, 0, &nID);getchar();getchar();return 0;}

事件

相关问题:
程序之间的通知的问题
事件的使用
1、创建事件

HANDLE CreateEvent(LPSECURITY_ATTRIBUTES lpEventAttributes,//安全属性BOOL bManualReset,//事件重置方式,true手动,false自动BOOL bInitialState, //事件初始状态,true有信号LPCTSTR lpName //事件命名
);创建成功返回事件句柄

2、等候事件

WaitForSingleObject/WaitForMUltipleObjects

3、触发事件(将事件设置成有信号状态)

BOOL SetEvent(HANDLE hEvent //handle to event
);

4、复位事件(将事件设置成无信号状态)

BOOL ResetEvent(HANDLE hEvent //handle to evnet
);

5、关闭事件 CloseHandle

小心事件的死锁

#include<Windows.h>
#include<stdio.h>
HANDLE g_hEvent = 0;
DWORD CALLBACK PrintProc(LPVOID pParam) {while (1) {WaitForSingleObject(g_hEvent, INFINITE);ResetEvent(g_hEvent);printf("********\n");}
}
DWORD CALLBACK CtrlProc(LPVOID pParam) {while (1) {Sleep(1000);SetEvent(g_hEvent);}
}
int main() {g_hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);DWORD nID = 0;HANDLE hThread[2] = { 0 };hThread[0] = CreateThread(NULL, 0, PrintProc, NULL, 0, &nID);hThread[1] = CreateThread(NULL, 0, CtrlProc, NULL, 0, &nID);WaitForMultipleObjects(2, hThread,TRUE, INFINITE);CloseHandle(g_hEvent);return 0;
}

信号量

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

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

相关文章

公路建设中边坡监测规范解析

边坡是山区公路或高速公路建设中的重要工程&#xff0c;但由于地形、地质等原因&#xff0c;边坡往往存在较高的塌方、滑坡、泥石流等风险。因此&#xff0c;边坡监测成为了十分必要的工作。本文将介绍边坡监测规范&#xff0c;希望能对相关工作者提供一些帮助。 点击输入图片描…

618这些卷王显示器,彻底杀疯了

该说不说&#xff0c;今年取消预售模式的第一个 618 终于让我看到了一些年中购物节该有的样子。 小忆估摸着不少同学的钱包君都有在这段时间被狠狠搜刮一番吧。 趁着活动热度还在&#xff0c;咱们今天再给大家添一把火&#xff0c;带来一期有关显示器的专题。 众所周知&#…

littlefs性能分析提升

littlefs性能分析 分析的目的很简单&#xff1a;希望支持掉电安全&#xff0c;或者说具有奔溃一致性特性的文件系统&#xff0c;他的读写速度能得到提升。如果了解了瓶颈所在&#xff0c;也可触类旁通。 本次分析&#xff0c;使用了大量的对比测试&#xff1a; littlefs读&a…

在Visual Studio Code中使用pytest进行AWS Lambda函数测试的最佳实践

背景/引言 在现代软件开发中&#xff0c;自动化测试已经成为保证代码质量的重要一环。对于AWS Lambda函数开发者来说&#xff0c;使用pytest进行单元测试和集成测试是一个高效且可靠的方法。本文将介绍在Visual Studio Code中使用pytest测试AWS Lambda函数的最佳实践&#xff…

RESTful API最佳实践:Python构建指南

目录 一、引言 二、RESTful API设计原则 三、Python构建RESTful API的技术栈 四、Flask构建RESTful API实践 安装Flask 定义路由和资源 处理HTTP方法 错误处理 数据验证和序列化 使用Flask扩展 五、最佳实践案例 七、结论 一、引言 在当今的软件开发领域&#…

SpringBoot 项目创建和 IDEA 常见问题

1、 Cannot save Files 问题(无法自动保存项目文件) Cannot save ....../HelloWord.java. Unable to create a backup file (HelloWord.java~). The file left unchanged. 原因&#xff1a;DIEA无法在保存前备份文件 解决办法&#xff1a;找到 Files --> Settings... -->…

谁是最会写作文的AI“考生”?“阅卷老师”ChatGPT直呼惊艳!

文章推荐 粽叶飘香&#xff0c;端午安康&#xff01;AI视频送祝福啦~ AI日报&#xff5c;文生语音大模型国内外均有突破&#xff0c;Pika完成6亿新融资&#xff0c;视频大模型也不远了&#xff01; ⭐️搜索“可信AI进展“关注公众号&#xff0c;获取当日最新AI资讯 一年一…

Claude3 注册及升级教程(包含封号解决方法)

前言 最近大家呼声很高的 Claude3 &#xff0c;它的 注册以及升级 教程来了&#xff01;&#xff01;&#xff01; &#xff08;还有封号情况的解决方式放在了后面&#xff09; 废话不多说&#xff0c;直接进入教程。 Claude 3 注册 前期准备工作 一个国外的邮箱账号&#…

HarmonyOS Next 系列之HTTP请求封装和Token持久化存储(四)

系列文章目录 HarmonyOS Next 系列之省市区弹窗选择器实现&#xff08;一&#xff09; HarmonyOS Next 系列之验证码输入组件实现&#xff08;二&#xff09; HarmonyOS Next 系列之底部标签栏TabBar实现&#xff08;三&#xff09; HarmonyOS Next 系列之HTTP请求封装和Token…

windows上修改Podman的镜像配置源加速

目录 前言解决办法1. 打开window的Powershell 2. 修改registries.conf3. 重启podman即可 扩展内容1. 国内镜像源地址2. 阿里加速地址 前言 今天在电脑上准备通过podman安装mysql&#xff0c;结果执行安装命令后&#xff0c;网络不通没法下载镜像。 解决办法 将默认镜像源修改…

释放创意潜力:AI写作助手如何助力内容创作?

内容为王&#xff0c;在内容创作的世界中尤为重要。然而&#xff0c;面对写作时常常感到无从下手&#xff1a;有时缺乏灵感&#xff0c;有时难以表达清楚自己的想法。AI写作助手的出现&#xff0c;为这些问题提供了创新的解决方案&#xff0c;极大地改变了内容创作的过程。 今…

C++: shared_ptr是线程安全的吗

导读 C面试中有时会有这样一个问题&#xff0c;shared_ptr是线程安全的吗&#xff1f;对此问题&#xff0c;我们需要从三个并发场景进行考虑&#xff0c;拷贝shared_ptr的安全性、对shared_ptr赋值的安全性和读写shared_ptr指向内存区域的安全性。 对于以上问题&#xff0c;首…

奥特曼28亿「投资帝国」曝光!不要OpenAI股份,当CEO最不赚钱

Sam Altman十几年来建立的庞大投资帝国&#xff0c;让我们终于理解了他为什么可以不要OpenAI的股权。 内容提要 作为一家曾经的小型非盈利组织&#xff0c;OpenAI以创纪录的速度迅速成长为估值860亿美元的独角兽。 虽然这大多归功于Sam Altman和微软达成的商业合作&#xff…

超强 BAAS 神器:支持自动生成API、对象存储、静态托管,云函数!

想象一下&#xff0c;你是一名开发者&#xff0c;你有一种强大的神器&#xff0c;可以让你摆脱繁琐的服务搭建和接口开发&#xff0c;免费使用众多第三方认证服务、对象存储、云函数和静态部署。这就是MemFire Cloud&#xff01; MemFire Cloud是懒人开发者的福音&#xff0c;一…

开源VisualFbeditor中文版,vb7 IDE,VB6升级64位跨平台开发安卓APP,Linux程序

吴涛老矣&#xff0c;社区苦无64位易语言&#xff0c;用注入DLL增强菜单&#xff0c;做成VS一样的界面 终归是治标不治本&#xff0c;一来会报毒&#xff0c;二来闭源20年没更新了 开源的VB7&#xff0c;欢迎易语言的铁粉进群&#xff1a;1032313876 【Freebasic编程语言】编绎…

Transformer论文解读

目录 写在前面 一、Transformer要解决的问题 1.长距离依赖问题 2.序列处理瓶颈 二、整体结构 三、自注意力机制 1.Scaled Dot-Product Attention 2.Multi-Head Attention 四、Position-wise Feed-Forward Networks&#xff08;FFN&#xff09; 五、位置编码 六、总结…

数组双指针经典习题

合并两个有序数组 class Solution {public void merge(int[] nums1, int m, int[] nums2, int n) {int p1m-1,p2n-1;int p3nums1.length-1;while(p1>0&&p2>0){//放完一个数组if(nums1[p1]>nums2[p2]){nums1[p3--]nums1[p1];p1--;}else{nums1[p3--]nums2[p2];p…

iOS调整collectionViewCell顺序

效果图 原理 就是设置collectionView调整顺序的代理方法&#xff0c;这里要注意一点 调整过代理方法之后&#xff0c;一定要修改数据源&#xff0c;否则导致错乱。 还有就是在collectionView上面添加一个长按手势&#xff0c;在长按手势的不同阶段&#xff0c;调用collectionV…

第18篇 Intel FPGA Monitor Program的使用<一>

Q&#xff1a;Intel FPGA Monitor Program开发工具可以支持Terasic的FPGA开发板使用吗&#xff1f; A&#xff1a;Intel FPGA Monitor Program 是Intel提供的适用于 ARM* Cortex*-A9 处理器和 Nios II 处理器的完整软件开发环境&#xff0c;它包括编译工具以及完整的调试功能&…

全国电力变压器数据

全国共10330个电力变压器 属性部分并不是很全&#xff0c;比如说一次电压&#xff0c;二次电压只有200条是全的 不过以我做电力采集时的经验&#xff0c;其实变压器的数量和位置是最难采集的数据&#xff0c;反而电压、电流、功率这些专业数据可以直接找设备台账补充或利用移动…