win32-鼠标消息、键盘消息、计时器消息、菜单资源
承接前文:
- win32窗口编程
- windows 开发基础
- win32-注册窗口类、创建窗口
- win32-显示窗口、消息循环、消息队列
本文目录
- 键盘消息
- 键盘消息的分类
- WM_CHAR 字符消息
- 鼠标消息
- 鼠标消息附带信息
- 定时器消息 WM_TIMER
- 创建销毁定时器
- 菜单资源
- 资源相关
- 菜单资源使用
- 命令消息的处理 WM_COMMAND
- 上下文菜单
键盘消息
键盘消息的分类
- WM_KEYDOWN :按键被按下时产生。
- WM_KEYUP :按键被放开时产生。
- WM_SYSKEYDOWN :系统按键被按下时产生,比如:ALT、F10等。
- WM_SYSKEYUP :系统按键放开时产生。
- 附带信息:
- WPARAM :按键的 Virtual Key Code(虚拟键码),虚拟键码是操作系统定义的一组唯一标识不同键的整数值,用来表示每个键盘键的抽象标识。虚拟键码与具体的物理键盘码(如扫描码)或字符不同,它不依赖于特定的键盘布局。应用程序通过检查wParam的值可以得知是哪个键被按下了,然后可以进行相应的处理逻辑。因为虚拟键码是统一的跨越不同键盘布局的标识符,这样设计帮助开发者编写跨平台和可移植的应用程序。
- LPARAM :按键的参数,例如按下的次数
- 附带信息:
- 按下一个按键并松开,会产生一个 WM_KEYDOWN 消息和一个 WM_KEYUP 消息(成对出现)。
- 按下一个按键不松开,会连续产生 WM_KEYDOWN 消息,知道松开时会产生 一个 WM_KEYUP 消息。
- 无论大小写锁定键是否被打开,按下相同的字母时键码值是一样的,意味着单凭键码值无法区分大小写,所以按键消息需要翻译,以区分大小写。
- 在Windows系统上,
Alt
键和F10
键,这俩按键是系统按键,需要用WM_SYSKEYDOWN
和WM_SYSKEYUP
。
WM_CHAR 字符消息
- TranslateMessage() 在转换
WM_KEYDOWN
消息时,对于可见字符可以产生WM_CHAR
消息,不可见字符无此消息。 - 附带信息:
- WPARAM :输入字符的 ASCII 码值。
- LPARAM :按键的相关参数。
//TranslateMessage伪代码
TranlateMessage(){if (nMsg.message != WM_KEYDOWN)return ...; //如果不是 WM_KEYDOWN 消息直接return//根据 nMsg.wParam (键码值) 可以获知哪个按键被按下if (不可见字符的按键)return ...;//查看CapsLock (大小写锁定键) 是否被打开if (打开)PostMessage(nMsg.hWnd, WM_CHAR, 按键的大写ASCII码值, ... );elsePostMessage(nMsg.hWnd, WM_CHAR, 按键的小写ASCII码值, ... );
}
- CapsLock 键没有打开时,按下键盘
A
键 产生的WM_CHAR
消息的 wParam 值为 小写字母a
的ASCII码值97
。按下 CapsLock 键(键码值20)后,再按下键盘A
键,产生的WM_CHAR
消息的 wParam 值为 大写字母A
的ASCII码值65
。
鼠标消息
鼠标基本消息:
- WM_LBUTTONDOWN :鼠标左键按下。
- WM_LBUTTONUP :鼠标左键抬起。
- WM_RBUTTONDOWN :鼠标右键按下。
- WM_RBUTTONUP :鼠标右键抬起。
- WM_MOUSEMOVE :鼠标移动消息。
双击消息:
- WM_LBUTTONDBLCLK :左键双击。
- WM_RBUTTONDBLCLK :鼠标右键双击。
使用双击消息需要在注册窗口类时增加 CS_DBLCLKS
风格,否则无论鼠标表点击得多么快都是多次单击。
滚轮消息:
- WM_MOUSEWHEEL
鼠标消息附带信息
-
wParam :其他按键的状态,例如Ctrl / Shift 等。
-
lParam :鼠标的位置,窗口客户区坐标系。
- LOWORD x坐标位置
- HIWORD y坐标位置
-
一般情况下鼠标按下 / 抬起 成对出现。在鼠标移动过程中,会根据移动速度产生一系列的 WM_MOUSEMOVE 消息。
case WM_LBUTTONDOWN:OnLButtonDown(hWnd, wParam, lParam);break;
case WM_LBUTTONUP:OnLButtonUp(hWnd, wParam, lParam);break;void OnLButtonDown(HWND hWnd, WPARAM wParam, LPARAM lParam) {char text[128] = { 0 };sprintf_s(text, "WM_LBUTTONDOWN:其他按键状态:%d,x = %d, y = %d\n", wParam, LOWORD(lParam), HIWORD(lParam));WriteConsole(g_dos_output, text, strlen(text), NULL, NULL);
}void OnLButtonUp(HWND hWnd, WPARAM wParam, LPARAM lParam) {char text[128] = { 0 };sprintf_s(text, "WM_LBUTTONUP:其他按键状态:%d,x = %d, y = %d\n", wParam, LOWORD(lParam), HIWORD(lParam));WriteConsole(g_dos_output, text, strlen(text), NULL, NULL);
}
鼠标左键按下时,wParam 值为1,按住 Ctrl 同时按下鼠标左键 wParam 值为 1+8 = 9,松开时 wParam 值为 9 - 1 = 8。
双击:
滚轮的附带信息:
- wParam
- LOWORD :其他键的状态。
- HIWORD :滚轮的偏移量,通过正负表示滚轮方向。
- lParam,坐标原点为屏幕原点下的鼠标当前位置。
- LOWORD :x 坐标。
- HIWORD :y坐标。
case WM_MOUSEWHEEL:OnWheel(hWnd, wParam, lParam);break;void OnWheel(HWND hWnd, WPARAM wParam, LPARAM lParam) {char text[128] = { 0 };short nDelta = HIWORD(wParam);sprintf_s(text, "WM_MOUSEWHEEL, 其他键状态:%d,偏移量 %d, x:%d,y:%d\n", LOWORD(wParam), nDelta, LOWORD(lParam), HIWORD(lParam));WriteConsole(g_dos_output, text, strlen(text), NULL, NULL);
}
滚轮的距离以 120 为单位,往前滚动是正数,往后滚动是负数。
定时器消息 WM_TIMER
- 产生时间:
在程序中创建定时器,当到达指定时间时,定时器会向程序发送一个WM_TIMER
消息。定时器的经度是毫秒级,但是准确度很低。例如设置的时间是1000ms后,但是可能会在非1000m后到达。 - 附带信息:
wParam :定时器ID。
lParam :定时器处理函数指针。
定时器消息其实由 GetMessage() 发送,在前面的文章中提到过,因为 GetMessage() 函数做的事情特别多,特别忙碌,所以定时器消息不是很准,但误差也不会太大,通常也就几毫秒。
WM_TIMER消息的应用范围如下:
定时器功能:WM_TIMER消息通常与SetTimer函数一起使用,用于创建定时器。当定时器到达设定的时间间隔时,系统会发送WM_TIMER消息给窗口,从而触发相应的处理逻辑。开发者可以在接收到WM_TIMER消息时进行特定的操作,比如更新UI界面、执行一段代码等。
动画效果:WM_TIMER消息可以用于实现一些简单的动画效果,例如平滑的滚动、闪烁等。通过定时器不断发送WM_TIMER消息,可以控制界面元素的变化,从而营造出动态的视觉效果。
定时任务:WM_TIMER消息也可以用于执行定时任务,比如定时检查网络连接状态、定时备份数据等。通过设置定时器并处理WM_TIMER消息,可以实现定时执行任务的功能。
总的来说,WM_TIMER消息主要用于定时器相关的功能,可以帮助开发者管理定时事件、实现动画效果以及执行定时任务等操作。
创建销毁定时器
- 创建定时器:
UINT_PTR SetTime(HWND hWnd, //定时器窗口句柄UINT_PTR nIDEvent, //定时器IDUINT uElapse, //时间间隔TIMERPROC lpTimerFunc //定时器处理函数指针(一般不使用,为NULL) }; //创建成功,返回非0
- 关闭定时器:
BOOL KillTimer(HWND hWnd, //定时器窗口句柄UINT_PTR uIDEvent //定时器ID };
实验:在窗口创建之后显示之前创建两个定时器,一个每隔1秒触发,一个每个两秒触发,每次触发打印定时器的ID。
case WM_CREATE: //WM_CREATE消息产生时间即窗口创建成功显示之前SetTimer(hWnd, 1, 1000, NULL);SetTimer(hWnd, 2, 2000, NULL); //定时器创建成功后开始计时,设定的时间之后就会触发WM_TIMER消息break;case WM_TIMER: //处理定时器触发OnTimer(hWnd, wParam); //调用OnTimer()函数处理break;//OnTimer()函数内容如下:
void OnTimer(HWND hWnd, WPARAM wParam) { //这里传进来的wParam是定时器的ID/*switch(wParam){case 1:break;case 2:break;}*/ //一般对定时器的ID wParam使用switch语句,对不同的定时器ID做不同的处理char txt[128] = { 0 };sprintf_s(txt, "WM_TIMER: 定时器ID=%d\n", wParam);WriteConsole(g_dos_output, txt, strlen(txt), NULL, NULL);
}
运行结果:每产生一个定时器2就会产生两个定时器1。
菜单资源
菜单分类:
- 窗口的顶层菜单(窗口顶层一长条,新建、编辑等)
- 弹出式菜单(右键点击弹出,顶层菜单被点击弹出)
- 系统菜单(点击窗口图标弹出)
HMENU 类型表示菜单句柄,ID表示菜单项。
资源相关
- 资源脚本文件 :*.rc 文件,描绘资源文件的脚本代码。
- 编译器:RC.exe,用来编译资源脚本文件。
.c
/ cpp
文件经过 CL.exe
编译器编译成 .obj
文件,.rc
文件经过 RC.exe
编译成 .res
文件,.obj
文件和 .res
文件经过链接器 LINK.exe
链接成最终可执行文件 .exe
。
菜单资源使用
-
添加菜单资源
-
加载菜单资源
- 注册窗口类时设置菜单
- 创建窗口传参设置菜单
- 在主窗口 WM_CREATE 消息中利用 SetMenu 函数设置菜单
加载菜单资源:
HMENU LoadMenu(HINSTANCE hInstance, //handle to moduleLPCTSTR lpMenuName //menu name or resource identifier );
添加资源文件:
添加资源:
编辑菜单:
顶层的 文件
编辑
视图
项目
帮助
这些并没有ID,因为点击它们就做一件事情——弹出下拉框,而下拉框里面的每一项都有一个 ID ,以区分鼠标点击的哪一个内容。
菜单资源ID:IDR_MENU1
。
Resource.rc 文件内容:
添加菜单到窗口中:
方法一:在注册窗口类时添加菜单。
#include "resource.h" //添加资源头文件//注册窗口类时添加菜单ID:
wc.lpszMenuName = (char*)IDR_MENU1;
wc.hCursor = LoadCursor(NULL, IDC_ARROW); //顺便添加一个默认鼠标资源,这样可以使鼠标在一些情况下正常显示
方法二:在创建窗口时添加菜单(倒数第三个参数,注意是菜单的句柄不是菜单ID)
//创建窗口时添加菜单:
HMENU hMenu = LoadMenu(hIns, (char*)IDR_MENU1);
HWND hWnd = CreateWindowEx(0, pClassName, "My Window",WS_CAPTION | WS_MINIMIZEBOX | WS_SYSMENU | WS_OVERLAPPEDWINDOW,200, 200, 640, 480, //窗口位置(200,200),大小长宽(640,480)。nullptr, hMenu, hIns, nullptr
);
使用 LoadMenu() 函数来加载菜单的句柄。项目编译成功后,菜单资源也就在可运行文件.exe 中,在运行该可执行文件时,可执行文件又被加载到内存,通过 hInstance 可以找到当前进程所在的内存,再用菜单资源的ID可以找到菜单所在内存的句柄。
方法三:在主窗口 WM_CREATE 消息中利用 SetMenu 函数设置菜单。
case WM_CREATE:{HMENU hMenu = LoadMenu(nullptr, (char*)IDR_MENU1);SetMenu(hWnd, hMenu);}break;
命令消息的处理 WM_COMMAND
附带信息:
LOWORD(wParam) 菜单项的ID。
//WndProc 的 switch语句添加以下代码:
case WM_COMMAND:OnCommand(hWnd, wParam);
break;//OnCommand() 函数代码:
void OnCommand(HWND hWnd, WPARAM wParam) {switch (LOWORD(wParam)) {case ID_40001:MessageBox(hWnd, "新建被点击", "Information", MB_OK);break;case ID_40002:MessageBox(hWnd, "打开被点击", "Information", MB_OK);break;case ID_40003:MessageBox(hWnd, "退出被点击", "Information", MB_OK);break;}
}
运行结果:
上下文菜单
- 显示上下文菜单:
BOOL TrackPopupMenu(HMENU hMenu, //菜单句柄UINT uFlags, //显示方式int x, //水平位置,屏幕坐标系下int y, //垂直位置,屏幕坐标系下int nReserved, //保留参数,必须为0HWND hWnd, //处理菜单消息的窗口句柄CONST RECT *prcRect //NULL 忽略 }; //TrackPopupMenu 是阻塞函数
使用:
case WM_RBUTTONUP: //右键弹起时显示上下文菜单OnRButtonUp(hWnd, lParam);break;void OnRButtonUp(HWND hWnd, LPARAM lParam) {HMENU hMenu = LoadMenu(nullptr, (char*)IDR_MENU1); //加载菜单资源,拿到菜单句柄HMENU hPopup = GetSubMenu(hMenu, 0); //获取顶层菜单的子菜单,0就是文件下的子菜单POINT clientPoint = { LOWORD(lParam), HIWORD(lParam) }; //创建客户区的坐标ClientToScreen(hWnd, &clientPoint); //将客户区的坐标位置转化为屏幕坐标系TrackPopupMenu(hPopup, TPM_CENTERALIGN | TPM_VCENTERALIGN, //菜单中心显示,水平居中、垂直居中clientPoint.x, clientPoint.y, 0, hWnd, NULL);
}
运行:
或者使用专门的显示上下文菜单的消息:
- WM_CONTEXTMENU :鼠标右键抬起来 WM_RBUTTONUP 消息之后产生。
- wParam :右键点击的窗口句柄。
- lParam :LOWORD,x 坐标,屏幕坐标系;HIWORD,y 坐标,屏幕坐标系。
#include <Windows.h>
#include <stdio.h>#include "resource.h"HANDLE g_dos_output = 0;void OnCommand(HWND hWnd, WPARAM wParam) {switch (LOWORD(wParam)) {case ID_40001:MessageBox(hWnd, "新建被点击", "Information", MB_OK);break;case ID_40002:MessageBox(hWnd, "打开被点击", "Information", MB_OK);break;case ID_40003:MessageBox(hWnd, "退出被点击", "Information", MB_OK);break;}
}void OnRButtonUp(HWND hWnd, LPARAM lParam) {HMENU hMenu = LoadMenu(nullptr, (char*)IDR_MENU1);HMENU hPopup = GetSubMenu(hMenu, 0);TrackPopupMenu(hPopup, TPM_LEFTALIGN | TPM_TOPALIGN, //左上角显示LOWORD(lParam), HIWORD(lParam), 0, hWnd, NULL);
}LRESULT CALLBACK WndProc(HWND hWnd, UINT msgID, WPARAM wParam, LPARAM lParam)
{switch (msgID){case WM_CLOSE:PostQuitMessage(0);break;case WM_COMMAND:OnCommand(hWnd, wParam);break;case WM_CONTEXTMENU:OnRButtonUp((HWND)wParam, lParam);break;}return DefWindowProc(hWnd, msgID, wParam, lParam);
}int CALLBACK WinMain(HINSTANCE hIns, HINSTANCE hPreIns, LPSTR lpCmdLine, int nCmdShow)
{AllocConsole();g_dos_output = GetStdHandle(STD_OUTPUT_HANDLE); //获得标准输出句柄const auto pClassName = "Main";WNDCLASSEX wc = { 0 };wc.cbClsExtra = 0;wc.cbWndExtra = 0;wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);wc.hCursor = LoadCursor(NULL, IDC_ARROW);wc.hIcon = nullptr;wc.hInstance = hIns;wc.lpfnWndProc = WndProc;wc.lpszClassName = pClassName;wc.lpszMenuName = (char*)IDR_MENU1;wc.hIconSm = nullptr;wc.style = CS_HREDRAW | CS_VREDRAW |CS_DBLCLKS;wc.cbSize = sizeof(wc);RegisterClassEx(&wc);HWND hWnd = CreateWindowEx(0, pClassName, "My Window",WS_CAPTION | WS_MINIMIZEBOX | WS_SYSMENU | WS_OVERLAPPEDWINDOW,200, 200, 640, 480, //窗口位置(200,200),大小长宽(640,480)。nullptr, nullptr, hIns, nullptr);ShowWindow(hWnd, SW_SHOW);UpdateWindow(hWnd);MSG nMsg = { 0 };BOOL gResult;while (1) //先进入死循环,循环体中进行判断是否退出循环{if (PeekMessage(&nMsg, NULL, 0, 0, PM_NOREMOVE)) //PeekMessage侦察兵侦察是否有消息,如果有消息{if ((gResult = GetMessage(&nMsg, NULL, 0, 0)) > 0) //gResult值大于零意味着GetMessage没有抓到 WM_QUIT(返回值为0) 也没有出错(出错返回值为-1){TranslateMessage(&nMsg);DispatchMessage(&nMsg);}else //如果抓到 WM_QUIT 或者 出错 退出while循环{break;}}else //如果PeekMessage()没有侦察到消息,空闲处理{//WriteConsole(g_dos_output, "No Message", strlen("No Message"), NULL, NULL);}}if (gResult == -1) //GetMessage()出错返回值 -1{//错误处理或直接退出程序 return -1;}else //抓到 WM_QUIT 消息,退出程序,返回 PostQuitMessage()的参数值{return nMsg.wParam; //此时 wParam 是 PostQuitMessage()的参数值}
}
后续更新… …
相关文章:

win32-鼠标消息、键盘消息、计时器消息、菜单资源
承接前文: win32窗口编程windows 开发基础win32-注册窗口类、创建窗口win32-显示窗口、消息循环、消息队列 本文目录 键盘消息键盘消息的分类WM_CHAR 字符消息 鼠标消息鼠标消息附带信息 定时器消息 WM_TIMER创建销毁定时器 菜单资源资源相关菜单资源使用命令消息的…...

springboot项目部署到linux服务器
springboot后端 修改前 修改后 vue前端 修改前 将地址中的 localhost改为 ip 重新生成war包 war上传到linux的tomcat的webapps下 其他环境配置和macOS大差不差 Tomcat安装使用与部署Web项目的三种方法_tomcat部署web项目-CSDN博客...

MagicLens:新一代图像搜索技术和产品形态
MagicLens:Self-Supervised Image Retrieval with Open-Ended Instructions MagicLens: 自监督图像检索与开放式指令 作者:Kai Zhang, Yi Luan, Hexiang Hu, Kenton Lee, Siyuan Qiao, Wenhu …...

[9] CUDA性能测量与错误处理
CUDA性能测量与错误处理 讨论如何通过CUDA事件来测量它的性能如何通过CUDA代码进行调试 1.测量CUDA程序的性能 1.1 CUDA事件 CPU端的计时器可能无法给出正确的内核执行时间CUDA事件等于是在你的CUDA应用运行的特定时刻被记录的时间戳,通过使用CUDA事件API&#…...

Java学习四
Random 随机数 数组 静态初始化数组 数组在计算机中的基本原理 数组的访问 什么是遍历 数组的动态初始化 动态初始化数组元素默认值规则 Java内存分配介绍 数组在计算机中的执行原理 使用数组时常见的一个问题 案例求数组元素最大值 public class Test1 {public static void ma…...
Vue 父组件使用refs来直接访问和修改子组件的属性或调用子组件的方法
步骤 1: 在子组件中定义要被修改的属性或方法 首先,在子组件中定义你想要父组件能够修改或调用的属性或方法。例如,我们有一个名为MyChildComponent的子组件,它有一个名为childData的数据属性和一个名为updateData的方法。 // 子组件 MyChi…...

范罗士、希喂、安德迈爆款宠物空气净化器哪款好?深度对比测评
作为一名深受养猫过敏困扰的铲屎官,我经常提醒新手铲屎官重视家里的空气环境。宠物的浮毛和皮屑不仅会引发过敏,还可能传播细菌和病毒。很多人以为普通空气净化器能解决问题,但这些产品并未针对宠物家庭的特殊需求。经过多次研究和测试&#…...
SAP OBYC自动记账 详解
在MM模块的许多操作都能实现在FI模块自动过账,如PO收货、发票验证、工单发料、向生产车间发料等等。不用说,一定需要在IMG中进行配置才可以实现自动处理。但SAP实现的这种自动配置的机制是怎样的呢?其实也并不复杂,让我们先以一种最简单的情况来了解实现原理和实现流程,然…...
《NoSQL数据库技术与应用》 MongoDB副本集
《NoSQL数据库技术与应用》 教学设计 课程名称:NoSQL数据库技术与应用 授课年级: 20xx年级 授课学期: 20xx学年第一学期 教师姓名: 某某老师 2020年5月6日 课题 名称 第4章 MongoDB副本集 计划学时 8课时 内容 分析 独立模式可…...
Flutter 中的 DropdownButtonFormField 小部件:全面指南
Flutter 中的 DropdownButtonFormField 小部件:全面指南 在Flutter中,DropdownButtonFormField是一个特殊的表单字段小部件,它结合了下拉选择框(DropdownButton)和表单字段(FormField)的功能。…...
哈希算法教程(个人总结版)
背景 哈希算法(Hash Algorithm)是一种将任意长度的输入(也称为消息)转换为固定长度的输出(也称为哈希值、散列值、摘要)的算法。哈希算法在计算机科学中有着广泛的应用,包括数据存储、数据检索…...

Nocobase快速上手 -第一个collection
本文记录Nocobase中如何创建collection,以及如何将collection展示到页面中,并且配置CRUD相应的操作. Collection 在NocoBase中,collection(集合)是用来组织和存储各种数据的容器,如订单、产品、用户、评论…...

吴恩达2022机器学习专项课程C2W2:2.19 sigmoid函数的替代方案 2.20如何选择激活函数 2.21 激活函数的重要性
这里写目录标题 引言sigmoid激活函数的局限1.回顾需求案例2.ReLU激活函数 常用的激活函数1.线性激活函数的解释 如何选择激活函数?1.选择输出层的激活函数2.选择隐藏层的激活函数 选择激活函数的总结1.输出层总结2.隐藏层总结3.TensorFlow设置激活函数 激活函数多样…...
循序渐进Docker Compose
文章目录 1.概述1.1 Docker Compose 定义1.2 Docker Compose背景1.3 Docker Compose核心概念 2.安装2.1 Official Repos2.2 Manual Installation2.3 v1.x 兼容性 3. YAML 配置说明3.1 Services3.2 Volumes & Networks 4. 解析 Service4.1 Pulling一个Image4.2 Building一个…...

怎样查看JavaScript中没有输出结果的数组值?
在JavaScript中,可以方便地定义和使用数组,对于已经定义的数组,怎样查看其值呢? 看下面的示例,并运行它。 上面的示例中,标签不完整,请补充完整再试运行。你知道少了什么标签么? 注…...
强化学习学习笔记-李宏毅
Policy Gradient actorenvreward function,env和reward是不能控制的,唯一可以变的是actor,Policy π \pi π是一个网络,参数为 θ \theta θ,输入是当前的观察,输出是采取的行为,例如游戏中输…...

吴恩达深度学习笔记:超 参 数 调 试 、 Batch 正 则 化 和 程 序 框 架(Hyperparameter tuning)3.8-3.9
目录 第二门课: 改善深层神经网络:超参数调试、正 则 化 以 及 优 化 (Improving Deep Neural Networks:Hyperparameter tuning, Regularization and Optimization)第三周: 超 参 数 调 试 、 Batch 正 则 化 和 程 序 框 架(Hyperparameter …...

SQL 语言:数据控制
文章目录 概述授权(GRANT)销权(REVOKE)总结 概述 SQL语言中的数据控制权限分配是数据库管理的重要组成部分,它涉及到如何合理地为用户分配对数据库资源的访问和使用权限。 权限类型:在SQL中,权限主要分为…...

『ZJUBCA Weekly Feed 07』MEV | AO超并行计算机 | Eigen layer AVS生态
一文读懂MEV:区块链的黑暗森林法则 01 💡TL;DR 这篇文章介绍了区块链中的最大可提取价值(MEV)概念,MEV 让矿工和验证者通过抢先交易、尾随交易和三明治攻击等手段获利,但也导致网络拥堵和交易费用增加。为了…...
正点原子延时函数delay_ms延时失效的原因
1、问题陈述 今天在测试小车程序的时候使用了如下代码,发现延时并没有达到期望的4s,而是仅仅延时了0.4s左右,本来以为少加了个0,最后在我多次测试下来,发现在延时大约超过2s的时候就会失效。 while(1){Set_Pwm(6000,60…...

云启出海,智联未来|阿里云网络「企业出海」系列客户沙龙上海站圆满落地
借阿里云中企出海大会的东风,以**「云启出海,智联未来|打造安全可靠的出海云网络引擎」为主题的阿里云企业出海客户沙龙云网络&安全专场于5.28日下午在上海顺利举办,现场吸引了来自携程、小红书、米哈游、哔哩哔哩、波克城市、…...

安宝特方案丨XRSOP人员作业标准化管理平台:AR智慧点检验收套件
在选煤厂、化工厂、钢铁厂等过程生产型企业,其生产设备的运行效率和非计划停机对工业制造效益有较大影响。 随着企业自动化和智能化建设的推进,需提前预防假检、错检、漏检,推动智慧生产运维系统数据的流动和现场赋能应用。同时,…...
Qwen3-Embedding-0.6B深度解析:多语言语义检索的轻量级利器
第一章 引言:语义表示的新时代挑战与Qwen3的破局之路 1.1 文本嵌入的核心价值与技术演进 在人工智能领域,文本嵌入技术如同连接自然语言与机器理解的“神经突触”——它将人类语言转化为计算机可计算的语义向量,支撑着搜索引擎、推荐系统、…...

2021-03-15 iview一些问题
1.iview 在使用tree组件时,发现没有set类的方法,只有get,那么要改变tree值,只能遍历treeData,递归修改treeData的checked,发现无法更改,原因在于check模式下,子元素的勾选状态跟父节…...
linux 下常用变更-8
1、删除普通用户 查询用户初始UID和GIDls -l /home/ ###家目录中查看UID cat /etc/group ###此文件查看GID删除用户1.编辑文件 /etc/passwd 找到对应的行,YW343:x:0:0::/home/YW343:/bin/bash 2.将标红的位置修改为用户对应初始UID和GID: YW3…...

vue3+vite项目中使用.env文件环境变量方法
vue3vite项目中使用.env文件环境变量方法 .env文件作用命名规则常用的配置项示例使用方法注意事项在vite.config.js文件中读取环境变量方法 .env文件作用 .env 文件用于定义环境变量,这些变量可以在项目中通过 import.meta.env 进行访问。Vite 会自动加载这些环境变…...
大学生职业发展与就业创业指导教学评价
这里是引用 作为软工2203/2204班的学生,我们非常感谢您在《大学生职业发展与就业创业指导》课程中的悉心教导。这门课程对我们即将面临实习和就业的工科学生来说至关重要,而您认真负责的教学态度,让课程的每一部分都充满了实用价值。 尤其让我…...

HDFS分布式存储 zookeeper
hadoop介绍 狭义上hadoop是指apache的一款开源软件 用java语言实现开源框架,允许使用简单的变成模型跨计算机对大型集群进行分布式处理(1.海量的数据存储 2.海量数据的计算)Hadoop核心组件 hdfs(分布式文件存储系统)&a…...
k8s从入门到放弃之HPA控制器
k8s从入门到放弃之HPA控制器 Kubernetes中的Horizontal Pod Autoscaler (HPA)控制器是一种用于自动扩展部署、副本集或复制控制器中Pod数量的机制。它可以根据观察到的CPU利用率(或其他自定义指标)来调整这些对象的规模,从而帮助应用程序在负…...

机器学习复习3--模型评估
误差与过拟合 我们将学习器对样本的实际预测结果与样本的真实值之间的差异称为:误差(error)。 误差定义: ①在训练集上的误差称为训练误差(training error)或经验误差(empirical error&#x…...