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

【PB案例学习笔记】-24创建一个窗口图形菜单

写在前面

这是PB案例学习笔记系列文章的第24篇,该系列文章适合具有一定PB基础的读者。

通过一个个由浅入深的编程实战案例学习,提高编程技巧,以保证小伙伴们能应付公司的各种开发需求。

文章中设计到的源码,小凡都上传到了gitee代码仓库https://gitee.com/xiezhr/pb-project-example.git

gitee代码仓库

需要源代码的小伙伴们可以自行下载查看,后续文章涉及到的案例代码也都会提交到这个仓库【pb-project-example

如果对小伙伴有所帮助,希望能给一个小星星⭐支持一下小凡。

一、小目标

继上一个案例之后,这个案例我们将制作一个图形菜单。案例中需要用到图形菜单技术,制作图形菜单可以使界面变得

更加友好美观。最终效果如下图所示

图形菜单最终效果

二、创作思路

要实现图形菜单,我们需要用到LoadImageA()SetMenuItemBitmaps()GetMenuItemID()ModifyMenu()等函数。

利用这些函数来加载一个图片,给菜单设置图标。

三、创建程序基本框架

① 新建examplework工作区

② 新建exampleapp应用

③ 新建菜单,保存为m_mymenu

④ 新建w_main窗口,将Title属性设置为"图形菜单",将MenuName属性设置为m_mymenu

由于文章篇幅原因,以上步骤不再赘述。如果忘记怎么操作得小伙伴可以翻一翻该系列之前文章

四、设置Menu菜单

① 创建菜单基本框架。如下图所示

创建菜单基本框架

② 保存菜单

五、编写代码

① 定义扩展函数

Declare Local External Functions 选项卡中添加如下代码

FUNCTION ulong LoadImageA(ulong hintance, string filename,uint utype,int x,int y,uint fload)  LIBRARY "USER32.DLL"
FUNCTION boolean SetMenuItemBitmaps(ulong hmenu,uint upos,uint flags,ulong handle_bm1,ulong handle_bm2)  LIBRARY "USER32.DLL"
FUNCTION int GetSystemMetrics(  int nIndex ) LIBRARY "USER32.DLL"
FUNCTION ulong GetMenuItemID(ulong hMenu,uint uItem) LIBRARY "USER32.DLL"
FUNCTION int GetSubMenu(ulong hMenu,int pos) LIBRARY "USER32.DLL"
FUNCTION ulong GetMenu(ulong hWindow) LIBRARY "USER32.DLL"
FUNCTION boolean ModifyMenu(ulong  hMnu, ulong uPosition, ulong uFlags, ulong uIDNewItem, long lpNewI) alias for ModifyMenuA LIBRARY "USER32.DLL"

② 准备图片

在应用根目录下准备好如下两张图片,图片格式为bmp。注:这里的图片格式必须是bmp格式,否则没法设置

准备图片

③ 在w_main窗口的Open事件中输入如下代码

Long		ll_MainHandle
long		ll_SubMenuHandle
integer	li_MenuItemID
long		ll_X
long		ll_Y
long		ll_BitmapHandleA
long		ll_BitmapHandleB
// Win32 常量
Integer IMAGE_BITMAP	   = 0
Integer LR_LOADFROMFILE = 16
Integer SM_CXMENUCHECK  = 71
Integer SM_CYMENUCHECK	= 72
Integer MF_BITMAP			= 4
Integer MF_BYCOMMAND		= 0
Integer MF_BYPOSITION	= 1024
// 获取菜单句柄
ll_MainHandle = GetMenu(Handle(this))
//获取第一个菜单的句柄
ll_SubMenuHandle = GetSubMenu(ll_MainHandle,0)
//以原始大小装入图片
ll_BitmapHandleA = LoadImageA(0,'1.bmp',0,0,0,LR_LOADFROMFILE)
ll_BitmapHandleB = LoadImageA(0,'2.bmp',0,0,0,LR_LOADFROMFILE)
li_MenuItemID = GetMenuItemID(ll_SubMenuHandle,0)
ModifyMenu(ll_SubMenuHandle,li_MenuItemID,MF_BITMAP,li_MenuItemId,ll_BitmapHandleA)
li_MenuItemID = GetMenuItemID(ll_SubMenuHandle,1)
ModifyMenu(ll_SubMenuHandle,li_MenuItemID,MF_BITMAP,li_MenuItemId,ll_BitmapHandleB)
ll_SubMenuHandle = GetSubMenu(ll_SubMenuHandle,2)
li_MenuItemID = GetMenuItemID(ll_SubMenuHandle,0)
ModifyMenu(ll_SubMenuHandle,li_MenuItemID,MF_BITMAP,li_MenuItemId,ll_BitmapHandleA)
li_MenuItemID = GetMenuItemID(ll_SubMenuHandle,1)
ModifyMenu(ll_SubMenuHandle,li_MenuItemID,MF_BITMAP,li_MenuItemId,ll_BitmapHandleB)// back to the top//Now get the handle of the second submenu..
ll_SubMenuHandle = GetSubMenu(ll_MainHandle,1)// Get sizes for the pictures, use winapi for the bitmaps sizes
ll_x = GetSystemMetrics(SM_CXMENUCHECK) 
ll_y = GetSystemMetrics(SM_CYMENUCHECK) // Load the images using the dimensions for the checked state
ll_BitmapHandleA = LoadImageA(0,'1.bmp',  IMAGE_BITMAP	,ll_x,ll_y,LR_LOADFROMFILE)
ll_BitmapHandleB = LoadImageA(0,'2.bmp',IMAGE_BITMAP	,ll_x,ll_y,LR_LOADFROMFILE)SetMenuItemBitmaps(ll_SubMenuHandle,0,MF_BYPOSITION,ll_BitmapHandleA,ll_BitmapHandleB)
SetMenuItemBitmaps(ll_SubMenuHandle,1,MF_BYPOSITION,ll_BitmapHandleB,ll_BitmapHandleA) 
// Get a handle the third submenu menu item
ll_SubMenuHandle = GetSubMenu(ll_SubMenuHandle,2)
SetMenuItemBitmaps(ll_SubMenuHandle,0,MF_BYPOSITION,ll_BitmapHandleA,ll_BitmapHandleB)
SetMenuItemBitmaps(ll_SubMenuHandle,1,MF_BYPOSITION,ll_BitmapHandleB,ll_BitmapHandleA) 

以下是代码的详细解释和注释:

  1. 定义了一些Win32常量,包括加载位图、菜单项标识、菜单项位置等。
  2. 获取主菜单的句柄。
  3. 获取主菜单中第一个子菜单的句柄。
  4. 使用LoadImageA函数加载两个位图文件(1.bmp和2.bmp)。
  5. 获取第一个子菜单中第一个菜单项的标识。
  6. 使用ModifyMenu函数将第一个菜单项的位图替换为加载的第一个位图。
  7. 获取第一个子菜单中第二个菜单项的标识。
  8. 使用ModifyMenu函数将第二个菜单项的位图替换为加载的第二个位图。
  9. 获取第一个子菜单中第三个菜单项的句柄。
  10. 重复步骤6和7,将第三个菜单项的位图替换为加载的位图。
  11. 获取第二个子菜单的句柄。
  12. 获取位图的大小。
  13. 使用LoadImageA函数再次加载位图,但这次使用了位图的大小。
  14. 使用SetMenuItemBitmaps函数将加载的位图设置为第二个子菜单中的菜单项的位图。
  15. 重复步骤14,将第二个子菜单中第二个菜单项的位图设置为加载的位图。
  16. 获取第二个子菜单中第三个菜单项的句柄。
  17. 重复步骤14和15,将第三个菜单项的位图替换为加载的位图。

这段代码的目的是在菜单项中插入位图,以增强用户界面的视觉效果。通过加载并设置位图,可以为菜单项添加图像,使菜单看起来更加生动和吸引人。

④ 在开发界面左边的System Tree窗口中双击exampleapp,并在其Open事件中添加如下代码

open(w_main)

六、运行程序

代码都添加完了,我们来验证下劳动成果,看看能不能达到预期效果。

最终效果

本期内容到这儿就结束了,★,°:.☆( ̄▽ ̄)/$:.°★ 。 希望对您有所帮助

我们下期再见 ヾ(•ω•`)o (●’◡’●)

相关文章:

【PB案例学习笔记】-24创建一个窗口图形菜单

写在前面 这是PB案例学习笔记系列文章的第24篇,该系列文章适合具有一定PB基础的读者。 通过一个个由浅入深的编程实战案例学习,提高编程技巧,以保证小伙伴们能应付公司的各种开发需求。 文章中设计到的源码,小凡都上传到了gite…...

环境配置的相关问题

一、shap安装踩坑 遇到错误: A module that was compiled using NumPy 1.x cannot be run in NumPy 2.0.0 as it may crash. To support both 1.x and 2.x versions of NumPy, modules must be compiled with NumPy 2.0. Some module may need to rebuild instead…...

github配置可拉取项目到本地

首先配置用户名和邮箱: git config --global user.name 自己的名字git config --global user.email 自己的邮箱配置完之后检查一下: git config --global user.namegit config --global user.email如果提示的是自己配置好的名字和邮箱就Ok 然后拉取githu…...

Snippet-AndroidFontWeight

常用FontWeight值 <?xml version"1.0" encoding"utf-8"?> <resources><integer name"font_weight_Thin">100</integer><integer name"font_weight_ExtraLight">200</integer><integer name…...

选择合适的分类评价指标:传统指标与自定义指标的权衡

这里写目录标题 选择合适的分类评价指标&#xff1a;传统指标与自定义指标的权衡传统评价指标**准确率&#xff08;Accuracy&#xff09;****精确度&#xff08;Precision&#xff09;和召回率&#xff08;Recall&#xff09;****F1分数&#xff08;F1 Score&#xff09;** 自定…...

数据结构-线性表的链式表示

目录 前言一、线性表的链式表示和实现1.1 线性表的表示1.2 基本操作的实现1.3 线性表的链式表示的优缺点 总结 前言 本篇文章主要介绍线性表的链式表示 一、线性表的链式表示和实现 1.1 线性表的表示 线性表的链式表示又称为链式存储结构或链式映像 链式存储定义&#xff1…...

DDL-表操作-数据类型

一.DDL-表操作-数据类型 MySQL中的数据类型有很多,主要分为三类:数值类型,字符串类型,日期类型。 二.关系表 注意: 无符号和有符号的取值范围不是一样的,无符号需要加上UNSIGNED范围。 BLOB&#xff1a;用来描述二进制数据 TEXT:用来描述字符串 三.定长字符串和变长字符串 c…...

python实例代码 - 多层感知机预测销售情况

多层感知器预测销售情况 将一种广告投放到TV、newspaper、radio上时不同组合的情况会对应不同的销售量。 # -*- coding:utf-8 -*- # PredicateAdvertise.py # 多层感知器预测销售情况 # 将一种广告投放到TV、newspaper、radio上时不同组合的情况会对应不同的销售量。 import …...

JVM专题十:JVM中的垃圾回收机制

在JVM专题九&#xff1a;JVM分代知识点梳理中&#xff0c;我们主要介绍了JVM为什么采用分代算法&#xff0c;以及相关的概念&#xff0c;本篇我们将详细拆分各个算法。 垃圾回收的概念 垃圾回收&#xff08;Garbage Collection&#xff0c;GC&#xff09;确实是计算机编程中的…...

MySQL入门学习-索引.创建索引

索引是 MySQL 中用于加速查询的一种数据结构。它通过在表的列上创建索引来加快数据的检索速度。 一、索引的概念 索引类似于书的目录&#xff0c;可以快速定位到表中的数据。当在表中的列上创建索引后&#xff0c;MySQL 会根据索引列的值对数据进行排序&#xff0c;并建立一个…...

ChatGPT智能对话绘画系统 带完整的安装源代码包以及搭建教程

系统概述 ChatGPT 智能对话绘画系统是一款集智能语言处理和绘画创作于一体的综合性系统。它利用了深度学习和自然语言处理技术&#xff0c;能够理解用户的意图和需求&#xff0c;并通过与用户的交互&#xff0c;生成富有创意的绘画作品。该系统的核心是一个强大的人工智能模型…...

巴中市红色旅游地管理系统

摘 要 随着红色旅游的兴起&#xff0c;越来越多的人开始对巴中市的红色旅游地产生兴趣。巴中市作为中国革命的重要发源地之一&#xff0c;具有丰富的红色旅游资源。然而&#xff0c;目前巴中市红色旅游地的管理仍然存在许多问题&#xff0c;如信息不对称、资源利用效率低等。为…...

ROS2从入门到精通2-2:详解机器人3D可视化工具Rviz2与案例分析

目录 0 专栏介绍1 什么是Rviz2&#xff1f;2 Rviz2基本界面3 Rviz2基本数据类型4 数据可视化案例4.1 实例1&#xff1a;显示USB摄像头数据4.2 实例2&#xff1a;显示球体 0 专栏介绍 本专栏旨在通过对ROS2的系统学习&#xff0c;掌握ROS2底层基本分布式原理&#xff0c;并具有…...

国企:2024年6月中国铁路相关招聘信息,6.27截止

中国铁路济南局集团有限公司2024年度 招聘普通高校本科及以上学历毕业生公告(三) 中国铁路济南局集团有限公司根据企业发展需要,拟招聘普通高等院校本科及以上学历毕业生,现将有关事项公告如下: 一、招聘计划 本次招聘岗位均为生产一线操作技能岗位,具体岗位、专业要求…...

React+TS前台项目实战(十九)-- 全局常用组件封装:带加载状态和清除等功能的Input组件实现

文章目录 前言Input组件1. 功能分析2. 代码详细注释3. 使用方式4. 效果展示 总结 前言 今天我们来封装一个input输入框组件&#xff0c;并提供一些常用的功能&#xff0c;你可以选择不同的 尺寸、添加前缀、显示加载状态、触发回调函数、自定义样式 等等。这些功能在这个项目中…...

php composer 报错

引用文章&#xff1a; Composer设置国内镜像_composer 国内源-CSDN博客 php composer.phar require --prefer-dist yiidoc/yii2-redactor "*" A connection timeout was encountered. If you intend to run Composer without connecting to the internet, run the …...

数据安全如何防护?迅软加密软件保护企业数据资产

前言&#xff1a;加密软件是一种重要的工具&#xff0c;可以帮助企业保护其数据资产的安全。通过使用加密算法&#xff0c;加密软件可以将敏感数据转化为无法理解的密文&#xff0c;只有授权的用户才能解密并访问这些数据。 一、迅软加密软件保护企业数据资产的关键方面 1、数…...

Android 11 ,默认授予预置应用/APK 需要的权限,解决permission denied for window type 2003 问题。

写这篇文章的原因是解决了一个APP闪退的问题&#xff0c;闪退的原因是插拔U盘时&#xff0c;注册的广播接收者接收到广播需要弹出一个Dialog询问是否需要打开U盘&#xff0c;这个Dialog设置的是系统级别悬浮窗&#xff0c;没有这个权限&#xff0c;报错导致闪退&#xff0c;下面…...

RabbitMQ(消息队列)

RabbitMQ 它是消息中间件&#xff0c;是在消息的传输过程中保存消息的容器&#xff0c;实现应用程序和应用程序之间通信的中间产品。目前主流消息队列通讯协议是AMQP&#xff08;二进制传输&#xff0c;支持多种语言&#xff09;、JMS&#xff08;HTTP传输&#xff0c;只支持J…...

LeetCode-数组/回溯-No40组合总和II

题目&#xff1a; 给定一个候选人编号的集合 candidates 和一个目标数 target &#xff0c;找出 candidates 中所有可以使数字和为 target 的组合。candidates 中的每个数字在每个组合中只能使用一次 。 注意&#xff1a;解集不能包含重复的组合。 示例 1: 输入: ca…...

【杂谈】-递归进化:人工智能的自我改进与监管挑战

递归进化&#xff1a;人工智能的自我改进与监管挑战 文章目录 递归进化&#xff1a;人工智能的自我改进与监管挑战1、自我改进型人工智能的崛起2、人工智能如何挑战人类监管&#xff1f;3、确保人工智能受控的策略4、人类在人工智能发展中的角色5、平衡自主性与控制力6、总结与…...

SCAU期末笔记 - 数据分析与数据挖掘题库解析

这门怎么题库答案不全啊日 来简单学一下子来 一、选择题&#xff08;可多选&#xff09; 将原始数据进行集成、变换、维度规约、数值规约是在以下哪个步骤的任务?(C) A. 频繁模式挖掘 B.分类和预测 C.数据预处理 D.数据流挖掘 A. 频繁模式挖掘&#xff1a;专注于发现数据中…...

系统设计 --- MongoDB亿级数据查询优化策略

系统设计 --- MongoDB亿级数据查询分表策略 背景Solution --- 分表 背景 使用audit log实现Audi Trail功能 Audit Trail范围: 六个月数据量: 每秒5-7条audi log&#xff0c;共计7千万 – 1亿条数据需要实现全文检索按照时间倒序因为license问题&#xff0c;不能使用ELK只能使用…...

STM32标准库-DMA直接存储器存取

文章目录 一、DMA1.1简介1.2存储器映像1.3DMA框图1.4DMA基本结构1.5DMA请求1.6数据宽度与对齐1.7数据转运DMA1.8ADC扫描模式DMA 二、数据转运DMA2.1接线图2.2代码2.3相关API 一、DMA 1.1简介 DMA&#xff08;Direct Memory Access&#xff09;直接存储器存取 DMA可以提供外设…...

《C++ 模板》

目录 函数模板 类模板 非类型模板参数 模板特化 函数模板特化 类模板的特化 模板&#xff0c;就像一个模具&#xff0c;里面可以将不同类型的材料做成一个形状&#xff0c;其分为函数模板和类模板。 函数模板 函数模板可以简化函数重载的代码。格式&#xff1a;templa…...

使用Spring AI和MCP协议构建图片搜索服务

目录 使用Spring AI和MCP协议构建图片搜索服务 引言 技术栈概览 项目架构设计 架构图 服务端开发 1. 创建Spring Boot项目 2. 实现图片搜索工具 3. 配置传输模式 Stdio模式&#xff08;本地调用&#xff09; SSE模式&#xff08;远程调用&#xff09; 4. 注册工具提…...

【Linux】Linux 系统默认的目录及作用说明

博主介绍&#xff1a;✌全网粉丝23W&#xff0c;CSDN博客专家、Java领域优质创作者&#xff0c;掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域✌ 技术范围&#xff1a;SpringBoot、SpringCloud、Vue、SSM、HTML、Nodejs、Python、MySQL、PostgreSQL、大数据、物…...

MySQL 索引底层结构揭秘:B-Tree 与 B+Tree 的区别与应用

文章目录 一、背景知识&#xff1a;什么是 B-Tree 和 BTree&#xff1f; B-Tree&#xff08;平衡多路查找树&#xff09; BTree&#xff08;B-Tree 的变种&#xff09; 二、结构对比&#xff1a;一张图看懂 三、为什么 MySQL InnoDB 选择 BTree&#xff1f; 1. 范围查询更快 2…...

PHP 8.5 即将发布:管道操作符、强力调试

前不久&#xff0c;PHP宣布了即将在 2025 年 11 月 20 日 正式发布的 PHP 8.5&#xff01;作为 PHP 语言的又一次重要迭代&#xff0c;PHP 8.5 承诺带来一系列旨在提升代码可读性、健壮性以及开发者效率的改进。而更令人兴奋的是&#xff0c;借助强大的本地开发环境 ServBay&am…...

适应性Java用于现代 API:REST、GraphQL 和事件驱动

在快速发展的软件开发领域&#xff0c;REST、GraphQL 和事件驱动架构等新的 API 标准对于构建可扩展、高效的系统至关重要。Java 在现代 API 方面以其在企业应用中的稳定性而闻名&#xff0c;不断适应这些现代范式的需求。随着不断发展的生态系统&#xff0c;Java 在现代 API 方…...