【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 (●’◡’●)

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

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

相关文章

Django 表单使用示例:添加角色

在本文中,我们将使用 Django 的表单(Forms)功能来创建一个添加角色的页面。 创建 Django 项目和应用 首先,我们创建一个名为 ​​form_demo​​​ 的 Django 项目和一个名为 ​​app01​​ 的应用: django-admin startproject form_demo cd form_demo python manage.py…

在Ubuntu 18.04上安装和配置Ansible的方法

前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站。 简介 配置管理系统旨在简化对大量服务器的控制,适用于管理员和运维团队。它们允许您从一个中央位置以自动化的方式控制许多…

Matplotlib中文显示解决方案:字体渲染机制与font.sans-serif设置

在Matplotlib中,设置font.sans-serif参数为中文字体如SimHei,可以使图表支持中文显示的原因在于Matplotlib的字体渲染机制。以下是详细解释: 1. **字体支持**: Matplotlib默认使用的字体可能不支持中文字符。大多数西方字体只包含…

Golang - 90天从新手到大师

开篇 最近有很多小伙伴都在寻找go语言完整学习资料,我整理了一些Golang方面的知识,方便大家学习。内容从最基础的入门到项目设计,希望帮助更多想了解和学习Go语言的伙伴。 因为是持续创作,所以也会持续更新。有些章节目录还没有…

mysql高并发环境解决方案有那些?

1、硬件和基础设施优化 1、使用高性能的服务器硬件,如更快的CPU、更大的内存和高速的存储设备。 2、确保网络带宽和延迟不会对数据库性能产生负面影响。 3、使用负载均衡器将请求分发到多个MySQL服务器上,以实现水平扩展。 2、数据库架构优化 1、读…

免费APP分发平台:小猪APP分发如何解决开发者的痛点

你是否曾为自己开发的APP找不到合适的分发平台而烦恼?你是否因为高昂的分发费用而望而却步?放心吧,你并不是一个人。很多开发者都面临同样的问题。但别担心,小猪APP分发来了,它可以帮你解决这些问题。 小猪app封装www…

面试题--MongoDB

MongoDb MongoDB 是什么? mongodb 是属于文档型的非关系型数据库,是开源、高性能、高可用、可扩展的 数据逻辑层次关系:文档>集合>数据库 在关系型数据库中每一行的数据对应 mongodb 里是一个文档。mongodb 的文档 是以 BSON&…

条件断点在找call中的应用

以TLBB为例,在2024.6.24附近左右的时间段,游戏窗口切换时就会有两个左右的call,在x64dbg下断点之后切换回游戏窗口,很难分辨出哪个是我们需要的动作引起的call,因此在send函数处下条件断点:$breakpointcoun…

FFMPEG 流媒体推流收流基本命令

FFmpeg可用来进行音视频的编解码、转码、剪辑、合成等操作。在流媒体领域,FFmpeg也是一个非常重要的工具,可以用来进行RTSP推流、HLS推流、RTMP推流等操作。 FFmpeg推流,以RTSP推流示例: RTSP推流是指将本地的音视频流通过RTSP协…

数据库课程知识点总结

数据库概述 数据库基本特点:数据结构化,数据独立性,数据冗余小,易扩充,统一管理和控制,永久存储,有组织,可共享 三级模式 模式:一个数据库只有一个模式,是对…

大屏可视化

<!DOCTYPE html> <!-- 这个font-size:20px UI给的字体大小--> <html lang"en" style"font-size: 20px;"> <head> <meta charset"UTF-8"> <meta name"viewport" content"widthdevice-width…

Java中的流处理框架:Kafka Streams与Flink

Java中的流处理框架&#xff1a;Kafka Streams与Flink 大家好&#xff0c;我是免费搭建查券返利机器人省钱赚佣金就用微赚淘客系统3.0的小编&#xff0c;也是冬天不穿秋裤&#xff0c;天冷也要风度的程序猿&#xff01;今天我们将深入探讨Java中两个强大的流处理框架&#xff…

在线可调试IDE

replit: replit官网

Github 2024-06-26 C开源项目日报 Top10

根据Github Trendings的统计,今日(2024-06-26统计)共有10个项目上榜。根据开发语言中项目的数量,汇总情况如下: 开发语言项目数量C项目10Python项目2jq:轻量灵活的命令行JSON处理器 创建周期:4207 天开发语言:C协议类型:OtherStar数量:27698 个Fork数量:1538 次关注人…

秋招Java后端开发冲刺——关系型数据库篇(Mysql)

本文介绍关系型数据库及其代表Mysql数据库&#xff0c;并介常见面试题目。 一、数据库概述 1. 数据库&#xff08;Database, DB&#xff09;&#xff1a;是长期储存在计算机内的、有组织的、可共享的数据集合。 2. 数据库管理系统&#xff08;Database Management System, D…

服务器数据恢复—异常断电导致RAID6阵列中磁盘出现坏扇区的数据恢复案例

服务器存储数据恢复环境&#xff1a; 一台存储中有一组由12块SAS硬盘组建的RAID6磁盘阵列&#xff0c;划分为一个卷&#xff0c;分配给几台Vmware ESXI主机做共享存储。该卷中存放了大量Windows虚拟机&#xff0c;这些虚拟机系统盘是统一大小&#xff0c;数据盘大小不确定&…

【Linux】静态库、动态库

动静态库里面包含的是源文件通过汇编阶段生成的后缀为.o的可重定位目标文件。我们在使用C语言&#xff0c;包含一个stdio.h头文件就可以使用scanf方法&#xff0c;其实都是系统调用了相应的头文件和库&#xff0c;库里面有开发者已经写好各种方法。也就是说我们在使用C语言时&a…

在MySQL中,定义字段为TINYINT(1)、TINYINT(2) 和 INT(2)的区别

在MySQL中&#xff0c;定义字段为 TINYINT(1)、TINYINT(2) 和 INT(2) 的区别&#xff1a; 1. TINYINT(1) 和 TINYINT(2) 范围&#xff1a; TINYINT 是一个 1 字节&#xff08;8 位&#xff09;的整数类型。它的取值范围是 -128 到 127&#xff08;有符号&#xff09;或者 0 到…

RabbitMQ实践——Stream队列的使用方法

大纲 什么是Stream队列创建Stream发布消息消费从第一条消息开始读取从最后一条消息开始读取从某个时间戳开始读取从某个偏移量开始读取 样例长度控制长度控制时间控制服务端筛选消息发布方设定过滤值消费方设置服务端过滤&#xff0c;且要二次过滤 工程代码参考资料 在 《Rabb…

Lua网站开发之文件表单上传

这个代码示例演示如何上传文件或图片&#xff0c;获取上传信息及保存文件到本地。 local fw require("fastweb") local request require("fastweb.request") local response require("fastweb.response") local cjson require("cjson&q…