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, //存取获取到的消息BUFF
	HWND hWnd, // 窗口句柄
	UINT wMsgFilterMin,//获取消息的最小ID
	UINT 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;//消息ID
	WPARAM 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/false
	LPCTSTR 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;
}

信号量

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

PGConf.dev 2024 |@PGer 你的问题已出海,来看看 Tom Lane 如何回复?

2024 PostgreSQL 开发大会&#xff08;pgconf.dev&#xff09;于5月8日在温哥华召开。瀚高IvorySQL发起留言互动活动——#PGConf.dev 2024数据世界因你不同#&#xff0c;已将部分用户想问的问题传递到PGConf.dev现场。 与会的大佬们对每一个问题都给予了认真的回复和解答。来看…

ABB机器人修改IO信号的具体方法介绍

ABB机器人修改IO信号的具体方法介绍 具体步骤可从参考以下内容: 导出IO配置文件 打开【控制面板】-【配置】-【I/O System】-【文件】-【‘EIO’另存为】,就可以保存IO配置文件【EIO.cfg】用RobotStudio软件打开EIO.cfg文件在软件界面,鼠标右击,选择【I/O信号数据编辑器】选…

Flutter 实现dispose探测控件

文章目录 前言一、什么是dispose探测控件&#xff1f;1、通常情况2、使用dispose探测控件 二、如何实现1、继承StatefulWidget2、定义dipose回调3、定义child4、重载Dispose方法5、build child 三、完整代码四、使用示例1、基本用法2、设置定义数据 总结 前言 开发flutter一般…

单片机多个中断源时的设计思路,(51为例)工作寄存器R0-R7

51单片机中四组工作寄存器&#xff08;R0-R7&#xff09; 参考 可以看出每个工作寄存器区有8个字节即为R0-R7&#xff0c;当不指定使用哪个工作寄存器区的时候默认0区。其他工作区作为普通的RAM使用。特殊功能寄存器中有可以位寻址和不能位寻址的区域 下面文字引用 通过修改…

晶泰科技即将登陆港交所:三年亏近55亿,二级市场信心待考

《港湾商业观察》黄懿 有着“AI制药”之称的深圳晶泰科技有限公司&#xff08;以下简称&#xff0c;晶泰科技&#xff1b;02228.HK&#xff09;即将登陆港交所。 据日前消息&#xff0c;晶泰科技于2024年6月4日至6月7日招股&#xff0c;拟全球发售股份1.87373亿股&#xff0c…

ES8.13 _bulk报错Malformed content, found extra data after parsing: START_OBJECT解决

在使用elaticsearch8.13.0使用批量创建索引时&#xff0c;根据谷粒中说的es7.9方法去批量操作请求&#xff1a; http://127.0.0.1:9200/shop/_doc/_bulk 注意1&#xff1a;设置header为Content-Type:application/x-ndjson,否则请求报错&#xff1a; {"error": &qu…

LeetCode | 2022.将一维数组转变为二维数组

这道题思路比较简单&#xff0c;比较容易想到的是先判断m和n构成的二维数组在形式上是否可以由原来的数组转变而成&#xff0c;若不可以返回空数组&#xff0c;若可以直接用一个二重循环遍历一遍即可&#xff0c;时间复杂度 O ( n 2 ) O(n^2) O(n2) class Solution(object):de…

史上最全,呕心沥血总结oracle推进SCN方法(六)

作者介绍&#xff1a;老苏&#xff0c;10余年DBA工作运维经验&#xff0c;擅长Oracle、MySQL、PG数据库运维&#xff08;如安装迁移&#xff0c;性能优化、故障应急处理等&#xff09; 公众号&#xff1a;老苏畅谈运维 欢迎关注本人公众号&#xff0c;更多精彩与您分享。前面介…

tmux 移植到ARM板端运行环境搭建

tmux源码下载&#xff1a; Home tmux/tmux Wiki GitHub 依赖的库代码下载&#xff1a; libevent&#xff1a; ncurses: 第一步&#xff1a;将以上三个代码解压放在同一个目录下&#xff0c;逐个编译 1. cd ./libevent-2.1.12-stable ./configure --host"arm-nextvp…

北斗位置服务管理平台

平台简介 一直想做一款后台管理系统&#xff0c;同时可以管理人&#xff0c;车&#xff0c;物品&#xff0c;猫&#xff0c;狗&#xff0c;牛羊等一切可以移动的室外事物进行集中化管理&#xff0c;最初的需求聚焦——谁在哪儿&#xff01; 系统框架是基于当前最常用的RuoYi框架…

68页 | 2024体育赛事网络安全保障实践蓝皮书(免费下载)

以上是资料简介和目录&#xff0c;如需下载&#xff0c;请前往星球获取&#xff1a;

短剧片源火爆,千金难求好剧源

前言 在当今快节奏的生活中&#xff0c;短剧以其精悍的篇幅、吸睛的剧情和便捷的观看方式&#xff0c;异军突起&#xff0c;吸引了大量观众的关注和喜爱。这些短剧不仅让人们在忙碌的间隙轻松娱乐&#xff0c;更以其高潮迭起的情节设计&#xff0c;让观众在短时间内便能体验到…

“百变换装师”之证照之星

拍证件照是一件很麻烦的事吗&#xff1f;证件照编辑是一件复杂的事吗&#xff1f;只有专业人员才能对证件照进行编辑吗&#xff1f;以前可能是&#xff0c;但今天小编将给大家分享一个证件照编辑软件证照之星&#xff0c;它将使每一个人都能具备简单的证件照编辑技能。 证照之星…

Failed to start gdm.servide - GNOME Display manager

启动虚拟机时&#xff0c;卡在Failed to start gdm.servide - GNOME Display manager不动。 解决方法: 1.重新启动Ubuntu&#xff0c;在进度条未结束之前&#xff0c;长按shift直到界面跳转到选项菜单。 2.选择第二个&#xff0c;按enter进入 3.选择最新版本&#xff08;后面…

使用charles做域名代理

目的&#xff1a;访问http://abcdefg:8099/时&#xff0c;指向本地http://localhost:8090/ 1、tools > Map Remote 2、tools > Rewrite 3、help > SSL Proxying > Install Charles Root Certificate 全部信任

基于Ascend C的FlashAttention算子性能优化最佳实践

LLM的Attention部分处理给计算系统带来巨大的计算和访存压力。业界先后出现FlashAttention、FlashAttention2等算法&#xff0c;通过计算等价和切分有效降低HBM数据访问量。 昇腾异构计算架构CANN针对昇腾AI处理器的片上内存和缓存大小&#xff0c;以及数据搬运通路&#xff0…

xLua(一) 环境安装笔记

为了方便查阅记录一下xLua的安装地址及方法 1.登录地址下载: https://github.com/Tencent/xLua 2.解压文件 将文件中的这些内容拷贝到项目中的Asset文件夹中 注意 : 工程项目路径不得含有中文 3.将Tools复制到Asset同级目录下 4.导入后会发现有Bug,需要导入工程 5.还有另…

AI科普 | 什么是人工智能的本质?

我们将以科普的角度深入探讨AI的本质&#xff0c;揭示其内在的基本逻辑。 我希望能够为读者提供一个简单清晰的认识&#xff0c;所以我摒弃晦涩的专用名词&#xff0c;用大白话的方式让小白也能轻松看懂&#xff0c;让大家更加了解这位改变世界的“魔法师”。 通过这篇文章&a…

Fyndiq买家号下单:自养号测评如何打造本土物理环境系统?

Fyndiq 是一个瑞典电子商务平台&#xff0c;我们通过该平台为渴望讨价还价的购物者提供一系列产品。该公司为希望以可访问的方式提高销售额的所有类型的零售商提供销售渠道。Fyndiq几乎是瑞典家喻户晓的存在&#xff0c;是瑞典折扣促销平台。以销售质优价廉的商品吸引了大量忠实…

14年后 苹果终于推出iPad原生计算器应用

迄今为止&#xff0c;在WWDC 2024大会上&#xff0c;新增的计算器应用获得了最热烈的掌声。iOS 官方计算器应用程序终于要登陆大屏幕了。该功能利用额外的屏幕空间带来了公司无法在 iPhone 上实现的新功能。其中最大的亮点是新增了"数学笔记"功能。新增的功能可以帮你…