当前位置: 首页 > news >正文

win32-鼠标消息、键盘消息、计时器消息、菜单资源



承接前文:

  1. win32窗口编程
  2. windows 开发基础
  3. win32-注册窗口类、创建窗口
  4. 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_SYSKEYDOWNWM_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-鼠标消息、键盘消息、计时器消息、菜单资源

承接前文&#xff1a; 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&#xff1a;Self-Supervised Image Retrieval with Open-Ended Instructions MagicLens: 自监督图像检索与开放式指令 作者&#xff1a;Kai Zhang&#xff0c; Yi Luan&#xff0c; Hexiang Hu&#xff0c; Kenton Lee&#xff0c; Siyuan Qiao&#xff0c; Wenhu …...

[9] CUDA性能测量与错误处理

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

Java学习四

Random 随机数 数组 静态初始化数组 数组在计算机中的基本原理 数组的访问 什么是遍历 数组的动态初始化 动态初始化数组元素默认值规则 Java内存分配介绍 数组在计算机中的执行原理 使用数组时常见的一个问题 案例求数组元素最大值 public class Test1 {public static void ma…...

Vue 父组件使用refs来直接访问和修改子组件的属性或调用子组件的方法

步骤 1: 在子组件中定义要被修改的属性或方法 首先&#xff0c;在子组件中定义你想要父组件能够修改或调用的属性或方法。例如&#xff0c;我们有一个名为MyChildComponent的子组件&#xff0c;它有一个名为childData的数据属性和一个名为updateData的方法。 // 子组件 MyChi…...

范罗士、希喂、安德迈爆款宠物空气净化器哪款好?深度对比测评

作为一名深受养猫过敏困扰的铲屎官&#xff0c;我经常提醒新手铲屎官重视家里的空气环境。宠物的浮毛和皮屑不仅会引发过敏&#xff0c;还可能传播细菌和病毒。很多人以为普通空气净化器能解决问题&#xff0c;但这些产品并未针对宠物家庭的特殊需求。经过多次研究和测试&#…...

SAP OBYC自动记账 详解

在MM模块的许多操作都能实现在FI模块自动过账,如PO收货、发票验证、工单发料、向生产车间发料等等。不用说,一定需要在IMG中进行配置才可以实现自动处理。但SAP实现的这种自动配置的机制是怎样的呢?其实也并不复杂,让我们先以一种最简单的情况来了解实现原理和实现流程,然…...

《NoSQL数据库技术与应用》 MongoDB副本集

《NoSQL数据库技术与应用》 教学设计 课程名称&#xff1a;NoSQL数据库技术与应用 授课年级&#xff1a; 20xx年级 授课学期&#xff1a; 20xx学年第一学期 教师姓名&#xff1a; 某某老师 2020年5月6日 课题 名称 第4章 MongoDB副本集 计划学时 8课时 内容 分析 独立模式可…...

Flutter 中的 DropdownButtonFormField 小部件:全面指南

Flutter 中的 DropdownButtonFormField 小部件&#xff1a;全面指南 在Flutter中&#xff0c;DropdownButtonFormField是一个特殊的表单字段小部件&#xff0c;它结合了下拉选择框&#xff08;DropdownButton&#xff09;和表单字段&#xff08;FormField&#xff09;的功能。…...

哈希算法教程(个人总结版)

背景 哈希算法&#xff08;Hash Algorithm&#xff09;是一种将任意长度的输入&#xff08;也称为消息&#xff09;转换为固定长度的输出&#xff08;也称为哈希值、散列值、摘要&#xff09;的算法。哈希算法在计算机科学中有着广泛的应用&#xff0c;包括数据存储、数据检索…...

Nocobase快速上手 -第一个collection

本文记录Nocobase中如何创建collection&#xff0c;以及如何将collection展示到页面中&#xff0c;并且配置CRUD相应的操作. Collection 在NocoBase中&#xff0c;collection&#xff08;集合&#xff09;是用来组织和存储各种数据的容器&#xff0c;如订单、产品、用户、评论…...

吴恩达2022机器学习专项课程C2W2:2.19 sigmoid函数的替代方案 2.20如何选择激活函数 2.21 激活函数的重要性

这里写目录标题 引言sigmoid激活函数的局限1.回顾需求案例2.ReLU激活函数 常用的激活函数1.线性激活函数的解释 如何选择激活函数&#xff1f;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中&#xff0c;可以方便地定义和使用数组&#xff0c;对于已经定义的数组&#xff0c;怎样查看其值呢&#xff1f; 看下面的示例&#xff0c;并运行它。 上面的示例中&#xff0c;标签不完整&#xff0c;请补充完整再试运行。你知道少了什么标签么&#xff1f; 注…...

强化学习学习笔记-李宏毅

Policy Gradient actorenvreward function&#xff0c;env和reward是不能控制的&#xff0c;唯一可以变的是actor&#xff0c;Policy π \pi π是一个网络&#xff0c;参数为 θ \theta θ&#xff0c;输入是当前的观察&#xff0c;输出是采取的行为&#xff0c;例如游戏中输…...

吴恩达深度学习笔记:超 参 数 调 试 、 Batch 正 则 化 和 程 序 框 架(Hyperparameter tuning)3.8-3.9

目录 第二门课: 改善深层神经网络&#xff1a;超参数调试、正 则 化 以 及 优 化 (Improving Deep Neural Networks:Hyperparameter tuning, Regularization and Optimization)第三周&#xff1a; 超 参 数 调 试 、 Batch 正 则 化 和 程 序 框 架&#xff08;Hyperparameter …...

SQL 语言:数据控制

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

『ZJUBCA Weekly Feed 07』MEV | AO超并行计算机 | Eigen layer AVS生态

一文读懂MEV&#xff1a;区块链的黑暗森林法则 01 &#x1f4a1;TL;DR 这篇文章介绍了区块链中的最大可提取价值&#xff08;MEV&#xff09;概念&#xff0c;MEV 让矿工和验证者通过抢先交易、尾随交易和三明治攻击等手段获利&#xff0c;但也导致网络拥堵和交易费用增加。为了…...

正点原子延时函数delay_ms延时失效的原因

1、问题陈述 今天在测试小车程序的时候使用了如下代码&#xff0c;发现延时并没有达到期望的4s&#xff0c;而是仅仅延时了0.4s左右&#xff0c;本来以为少加了个0&#xff0c;最后在我多次测试下来&#xff0c;发现在延时大约超过2s的时候就会失效。 while(1){Set_Pwm(6000,60…...

MySQL 满足条件函数中使用查询最大值函数

在实际的数据库操作中&#xff0c;我们常常需要根据某些条件找到最大值并据此进行下一步的操作。例如&#xff0c;在一个包含订单信息的表中&#xff0c;可能需要找到特定客户的最大订单金额&#xff0c;并据此进行某些统计或决策。MySQL 提供了多种函数和查询方法&#xff0c;…...

Java | Leetcode Java题解之第101题对称二叉树

题目&#xff1a; 题解&#xff1a; class Solution {public boolean isSymmetric(TreeNode root) {return check(root, root);}public boolean check(TreeNode u, TreeNode v) {Queue<TreeNode> q new LinkedList<TreeNode>();q.offer(u);q.offer(v);while (!q.…...

【区块链】智能合约漏洞测试

打开Ganache vscode打开智能合约漏洞工程 合约内容 pragma solidity >0.8.3;contract EtherStore {mapping(address > uint) public balances;function deposit() public payable {balances[msg.sender] msg.value;emit Balance(balances[msg.sender]);}function with…...

大模型主流 RAG 框架TOP10

节前&#xff0c;我们组织了一场算法岗技术&面试讨论会&#xff0c;邀请了一些互联网大厂朋友、今年参加社招和校招面试的同学。 针对大模型技术趋势、大模型落地项目经验分享、新手如何入门算法岗、该如何准备面试攻略、面试常考点等热门话题进行了深入的讨论。 总结链接…...

第八次javaweb作业

我们小组课程设计的题目是&#xff1a;超市管理系统&#xff0c;我认领的模块是&#xff1a;商品信息管理 controller package com.example.supermarker.controller;import com.example.supermarker.pojo.MerchInfo; import com.example.supermarker.pojo.PageBean; import c…...

js积累四 (读json文件)

function ReadRadioJson() {var url "../radio.json" //json文件url&#xff0c;本地的就写本地的位置&#xff0c;如果是服务器的就写服务器的路径var request new XMLHttpRequest();request.open("get", url, false); //设置请求方法与路径request.sen…...

关于我转生从零开始学C++这件事:升级Lv.25

❀❀❀ 文章由不准备秃的大伟原创 ❀❀❀ ♪♪♪ 若有转载&#xff0c;请联系博主哦~ ♪♪♪ ❤❤❤ 致力学好编程的宝藏博主&#xff0c;代码兴国&#xff01;❤❤❤ OK了老铁们&#xff0c;又是一个周末&#xff0c;大伟又来继续给大家更新我们的C的内容了。那么根据上一篇博…...

mysql中text,longtext,mediumtext区别

文章目录 一.概览二、字节限制不同三、I/O 不同四、行迁移不同 一.概览 在 MySQL 中&#xff0c;text、mediumtext 和 longtext 都是用来存储大量文本数据的数据类型。 TEXT&#xff1a;TEXT 数据类型可以用来存储最大长度为 65,535(2^16-1)个字符的文本数据。如果存储的数据…...

IP协议说明

文章目录 前言一、IP协议的简介二、IP数据报1.IP 数据报结构2.IP 数据报的分片解析3.IP 数据报的分片重装 三、IP 数据报的输出四、IP 数据报的输入 前言 IP 指网际互连协议&#xff0c; Internet Protocol 的缩写&#xff0c;是 TCP/IP 体系中的网络层协议。设计 IP 的目的是…...

第13章 层次式架构设计理论与实践

层次式架构的核心思想是将系统组成为一种层次结构&#xff0c;每一层为上层服务&#xff0c;并作为下层客户。其实不管是分层还是其他的架构都是为了解耦&#xff0c;更好的复用&#xff0c;只要秉承着这种思想去理解一切都迎刃而解了。 13.1 层次上体系结构概述 回顾一下软件…...