C++ 重载EditBox默认ContextMenu(含详细代码)

2023-10-14 04:59

本文主要是介绍C++ 重载EditBox默认ContextMenu(含详细代码),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

本人微信公众号:CPP进阶之旅
如果觉得这篇文章对您有帮助,欢迎关注 “CPP进阶之旅” 学习更多技术干货

C++ 重载EditBox默认ContextMenu

      • 问题背景
      • 自定义右键菜单
      • 重载系统默认右键菜单
      • 参考资料
      • 重要说明

问题背景

      在做windows下的C++客户端程序开发的时候,经常会遇到自定义右键菜单的功能点的开发。
      这时候,我们一般只需要在窗口的事件过程中处理WM_CONTEXTMENU消息。处理时,根据需要可以使用CreatePopupMenu创建弹出菜单,并插入指定的子菜单项,最后处理对应菜单项的消息这样的流程来实现一个自定义的右键菜单列表。也可以通过拿到菜单项的句柄,枚举并修改菜单列表的形式重载一些已经实现的或者已经定义的菜单列表。
      之前遇到一个需求,需要继承Edit默认的右键菜单,在此基础上添加一些自定义的右键菜单项。然而,按照之前的理解,写代码的过程中发现,WM_CONTEXTMENU消息触发的时候,不能获取到默认的右键菜单句柄信息,也就拿不到右键菜单中的菜单列表条目。因此也不能继续进行右键菜单项的自定义操作。下面用代码演示一下,一般自定义右键菜单的方法和在editbox中实现重载默认Context的方法。

自定义右键菜单

在这里用代码表示一般的右键菜单创建和处理的过程:

//编辑框事件处理
#define EDIT_NEW_MENU_ITEM WM_USER + 800
static LRESULT CALLBACK WndProcForEditCtrl(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) {switch (message) {case WM_CONTEXTMENU: {//创建菜单项列表HMENU popup = CreatePopupMenu();WCHAR temp[50] = {0};wcscpy(temp, L"自定义菜单");AppendMenu(popup, MF_STRING, (UINT_PTR)EDIT_NEW_MENU_ITEM, tmp);POINT pt = {GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)};TrackPopupMenu(popup, TPM_LEFTALIGN | TPM_LEFTBUTTON | TPM_RIGHTBUTTON, pt.x,pt.y, 0,hwnd, nullptr);return true;}break;case EDIT_NEW_MENU_ITEM:{//根据具体的需求处理消息}break;default:break;}return DefWindowProc(hwnd, message, wParam, lParam);
}

重载系统默认右键菜单

//获取列表中pos处的菜单项
MENUITEMINFO GetMenuInfoByPosition(HMENU menu, UINT nPos) {TCHAR szMenuStr[256] = {0};MENUITEMINFO mInfo = {0};mInfo.cbSize = sizeof(mInfo);mInfo.fMask = 0 |MIIM_CHECKMARKS | MIIM_DATA | MIIM_ID | MIIM_STATE | MIIM_SUBMENU| MIIM_TYPE| 0;mInfo.dwTypeData = szMenuStr;mInfo.cch = _countof(szMenuStr);GetMenuItemInfo(menu, nPos, TRUE, &mInfo);return mInfo;
}#define EDIT_NEW_MENU_ITEM WM_USER + 800
static bool isInitMenu = true;
static LRESULT CALLBACK WndProcForEditCtrl(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) {switch (message) {case WM_CONTEXTMENU: {isInitMenu = true;} break;case WM_ENTERIDLE: {if (wParam == MSGF_MENU) {//表示为菜单消息,当wParam为MSGF_DIALOGBOX表示的是对话框消息//这里表示菜单进入空闲状态if (isInitMenu) {isInitMenu = false;MENUBARINFO mbi;memset(&mbi, 0, sizeof(MENUBARINFO));mbi.cbSize = sizeof(MENUBARINFO);GetMenuBarInfo((HWND)lParam, OBJID_CLIENT, 0, &mbi);if (::IsMenu((HMENU)mbi.hMenu)) {for (int i = 0; i < GetMenuItemCount(mbi.hMenu) - 1; i++) {MENUITEMINFO menuInfo = GetMenuInfoByPosition(mbi.hMenu, i);auto aa = menuInfo.dwTypeData;if (str::Len(menuInfo.dwTypeData)) {WCHAR menuName[50] = {0};wcscpy(menuName, menuInfo.dwTypeData);win::menu::SetText(mbi.hMenu, menuInfo.wID, menuName);}}WCHAR menuStr[50] = {0};wcscpy(menuStr, L"自定义菜单");AppendMenu(mbi.hMenu, MF_STRING, (UINT_PTR)9000, menuStr);}}}} break;default:break;}return DefWindowProc(hwnd, message, wParam, lParam);
}

参考资料

https://stackoverrun.com/cn/q/1566456
https://docs.microsoft.com/en-us/troubleshoot/cpp/cannot-change-state-menu-item

重要说明

欢迎关注我的个人微信公众号,查看专业的客户端/服务端开发知识、笔试面试题目、程序员职场经验与心得分享。
在这里插入图片描述

这篇关于C++ 重载EditBox默认ContextMenu(含详细代码)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/208322

相关文章

在 Spring Boot 中连接 MySQL 数据库的详细步骤

《在SpringBoot中连接MySQL数据库的详细步骤》本文介绍了SpringBoot连接MySQL数据库的流程,添加依赖、配置连接信息、创建实体类与仓库接口,通过自动配置实现数据库操作,... 目录一、添加依赖二、配置数据库连接三、创建实体类四、创建仓库接口五、创建服务类六、创建控制器七、运行应用程序八

MySQL连表查询之笛卡尔积查询的详细过程讲解

《MySQL连表查询之笛卡尔积查询的详细过程讲解》在使用MySQL或任何关系型数据库进行多表查询时,如果连接条件设置不当,就可能发生所谓的笛卡尔积现象,:本文主要介绍MySQL连表查询之笛卡尔积查... 目录一、笛卡尔积的数学本质二、mysql中的实现机制1. 显式语法2. 隐式语法3. 执行原理(以Nes

Python跨文件实例化、跨文件调用及导入库示例代码

《Python跨文件实例化、跨文件调用及导入库示例代码》在Python开发过程中,经常会遇到需要在一个工程中调用另一个工程的Python文件的情况,:本文主要介绍Python跨文件实例化、跨文件调... 目录1. 核心对比表格(完整汇总)1.1 自定义模块跨文件调用汇总表1.2 第三方库使用汇总表1.3 导

使用Redis快速实现共享Session登录的详细步骤

《使用Redis快速实现共享Session登录的详细步骤》在Web开发中,Session通常用于存储用户的会话信息,允许用户在多个页面之间保持登录状态,Redis是一个开源的高性能键值数据库,广泛用于... 目录前言实现原理:步骤:使用Redis实现共享Session登录1. 引入Redis依赖2. 配置R

使用Python的requests库调用API接口的详细步骤

《使用Python的requests库调用API接口的详细步骤》使用Python的requests库调用API接口是开发中最常用的方式之一,它简化了HTTP请求的处理流程,以下是详细步骤和实战示例,涵... 目录一、准备工作:安装 requests 库二、基本调用流程(以 RESTful API 为例)1.

python使用Akshare与Streamlit实现股票估值分析教程(图文代码)

《python使用Akshare与Streamlit实现股票估值分析教程(图文代码)》入职测试中的一道题,要求:从Akshare下载某一个股票近十年的财务报表包括,资产负债表,利润表,现金流量表,保存... 目录一、前言二、核心知识点梳理1、Akshare数据获取2、Pandas数据处理3、Matplotl

Django开发时如何避免频繁发送短信验证码(python图文代码)

《Django开发时如何避免频繁发送短信验证码(python图文代码)》Django开发时,为防止频繁发送验证码,后端需用Redis限制请求频率,结合管道技术提升效率,通过生产者消费者模式解耦业务逻辑... 目录避免频繁发送 验证码1. www.chinasem.cn避免频繁发送 验证码逻辑分析2. 避免频繁

精选20个好玩又实用的的Python实战项目(有图文代码)

《精选20个好玩又实用的的Python实战项目(有图文代码)》文章介绍了20个实用Python项目,涵盖游戏开发、工具应用、图像处理、机器学习等,使用Tkinter、PIL、OpenCV、Kivy等库... 目录① 猜字游戏② 闹钟③ 骰子模拟器④ 二维码⑤ 语言检测⑥ 加密和解密⑦ URL缩短⑧ 音乐播放

Python pandas库自学超详细教程

《Pythonpandas库自学超详细教程》文章介绍了Pandas库的基本功能、安装方法及核心操作,涵盖数据导入(CSV/Excel等)、数据结构(Series、DataFrame)、数据清洗、转换... 目录一、什么是Pandas库(1)、Pandas 应用(2)、Pandas 功能(3)、数据结构二、安

Python使用Tenacity一行代码实现自动重试详解

《Python使用Tenacity一行代码实现自动重试详解》tenacity是一个专为Python设计的通用重试库,它的核心理念就是用简单、清晰的方式,为任何可能失败的操作添加重试能力,下面我们就来看... 目录一切始于一个简单的 API 调用Tenacity 入门:一行代码实现优雅重试精细控制:让重试按我