《Windows API每日一练》9.25 系统菜单

/*------------------------------------------------------------------------

 060 WIN32 API 每日一练

     第60个例子POORMENU.C:使用系统菜单

     GetSystemMenu函数

     AppendMenu函数    

 (c) www.bcdaren.com 编程达人

-----------------------------------------------------------------------*/

#include <windows.h>

#define IDM_SYS_ABOUT    1

#define IDM_SYS_HELP     2

#define IDM_SYS_REMOVE   3

LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);

static TCHAR szAppName[] = TEXT("PoorMenu");

int WINAPI WinMain( _In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance,

_In_ LPSTR lpCmdLine, _In_ int nShowCmd )

{

     HMENU hMenu;

     HWND hwnd;

     MSG msg;

     WNDCLASS wndclass;

     //窗口类结构初始化

     wndclass.style           = CS_HREDRAW | CS_VREDRAW;

     wndclass.lpfnWndProc     = WndProc;

     wndclass.cbClsExtra      = 0;

     wndclass.cbWndExtra      = 0;

     wndclass.hInstance       = hInstance;

     wndclass.hCursor         = LoadCursor(NULL,IDC_ARROW);

     wndclass.hIcon           = LoadIcon(NULL,IDI_APPLICATION);

     wndclass.hbrBackground   = (HBRUSH)GetStockObject(WHITE_BRUSH);

     wndclass.lpszMenuName    = NULL;

     wndclass.lpszClassName   = szAppName;

     //注册窗口类

     if (!RegisterClass(&wndclass))

     {

          MessageBox(NULL,TEXT("This program require Windows NT!"),

                    szAppName,MB_ICONERROR);

          return 0;

     }

     //创建窗口

     hwnd = CreateWindow(szAppName,TEXT("The Poor_Person`s Menu"),

                    WS_OVERLAPPEDWINDOW,

                    CW_USEDEFAULT,CW_USEDEFAULT,

                    CW_USEDEFAULT,CW_USEDEFAULT,

                    NULL,NULL,hInstance,NULL);

     hMenu = GetSystemMenu(hwnd,FALSE);//获取系统菜单句柄副本,TRUE恢复默认值

    

     AppendMenu(hMenu,MF_SEPARATOR,0,NULL);

     AppendMenu(hMenu,MF_STRING,IDM_SYS_ABOUT,TEXT("ABOUT..."));

     AppendMenu(hMenu,MF_STRING,IDM_SYS_HELP,TEXT("HELP..."));

     AppendMenu(hMenu,MF_STRING,IDM_SYS_REMOVE,TEXT("REMOVE..."));

     ShowWindow(hwnd,nShowCmd);

     UpdateWindow(hwnd);

     while (GetMessage(&msg,NULL,0,0))

     {

          TranslateMessage(&msg);

          DispatchMessage(&msg);

     }

     return msg.wParam;

}

LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)

{

     switch (message)

     {

     case WM_SYSCOMMAND:

          switch (LOWORD(wparam))

          {

          case IDM_SYS_ABOUT:

               MessageBox(hwnd,TEXT("A Poor-Person`s Menu Program\n")

                         TEXT("(C)www.bcdaren.com 编程达人

"),szAppName,MB_ICONINFORMATION);

              return 0;

    

          case IDM_SYS_HELP:

               MessageBox(hwnd,TEXT("Help not yet implemented!"),

                         szAppName,MB_ICONEXCLAMATION);

               return 0;

          case IDM_SYS_REMOVE:

               GetSystemMenu(hwnd,TRUE);//使上一个窗口菜单失效

               return 0;

          }

          break;

     case WM_DESTROY:

          PostQuitMessage(0);

          return 0;

     }

     return DefWindowProc(hwnd,message,wparam,lparam);

}

/******************************************************************************

_in 输入参数

_out 输出参数

_opt 参数是可选的,就是可以为NULL

_ecount 所指向的缓存的元素个素也就是括号里的数字

这些宏都被定义为空,只是让程序更容易理解!

*******************************************************************************

GetSystemMenu函数:使应用程序能够访问窗口菜单(也称为系统菜单或控制菜单)以进行复制和修改

如果此参数为FALSE,则GetSystemMenu返回当前使用的窗口菜单副本的句柄。该副本最初与窗口菜单相同,但可以修改。

如果此参数为TRUE,则GetSystemMenu会将窗口菜单重置为默认状态。上一个窗口菜单(如果有)被破坏。

HMENU GetSystemMenu(

  HWND hWnd,   //拥有窗口菜单副本的窗口句柄

  BOOL bRevert

);

*******************************************************************************

AppendMenu函数:将新项目追加到指定菜单栏,下拉菜单,子菜单或快捷菜单的末尾。您可以使用此功能来指定菜单项的内容,外观和行为

BOOL AppendMenuA(

  HMENU    hMenu,   //菜单句柄

  UINT     uFlags,  //控制新菜单项的外观和行为。

  UINT_PTR uIDNewItem,   //新菜单项的标识符,或者,如果uFlags参数设置为MF_POPUP,则为下拉菜单或子菜单的句柄

  LPCSTR   lpNewItem     //新菜单项的内容

);

*/

       运行结果:

图9-14 使用系统菜单

 

总结

实例POORMENU.C并没有添加菜单资源,而是直接将菜单添加到了系统菜单中。

首先定义了3个菜单项ID:

#define IDM_SYS_ABOUT    1

#define IDM_SYS_HELP     2

#define IDM_SYS_REMOVE   3

然后在主程序中调用GetSystemMenu函数,获取系统菜单句柄的副本。

hMenu = GetSystemMenu(hwnd,FALSE);//获取系统菜单句柄副本,TRUE恢复默认值

接着4次调用AppendMenu函数,在系统菜单内添加包括分隔符在内的4个菜单。

实例的窗口过程拦截系统菜单消息WM_SYSCOMMAND,分别根据菜单ID处理"ABOUT..."、"HELP..."和"REMOVE..."菜单。其中"REMOVE..."菜单调用GetSystemMenu函数去除新添加的系统菜单项。

GetSystemMenu(hwnd,TRUE);//使上一个窗口菜单失效

9.2.6 第61练:没有弹出菜单的多层顶级菜单

/*------------------------------------------------------------------------

 061 WIN32 API 每日一练

     第61个例子NOPOPUPS.C:没有弹出菜单的多层顶级菜单

     LoadMenu函数

     SetMenu函数

     DestroyMenu函数    

 (c) www.bcdaren.com 编程达人

-----------------------------------------------------------------------*/

#include <windows.h>

#include "resource.h"

LRESULT CALLBACK Wndproc(HWND, UINT, WPARAM, LPARAM);

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd )

{

     HWND hwnd;

     static TCHAR szAppName[] = TEXT("NoPopUps");

    (略)

     return msg.wParam;

}

LRESULT CALLBACK Wndproc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)

{

     static HMENU hMenuMain,hMenuEdit,hMenuFile;//三个顶级菜单

     HINSTANCE hInstance;

     switch (message)

     {

     case WM_CREATE:

          hInstance = (HINSTANCE)GetWindowLong(hwnd,GWL_HINSTANCE);

          //加载三个独立的顶级菜单

          hMenuMain = LoadMenu(hInstance,TEXT("MenuMain"));

          hMenuEdit = LoadMenu(hInstance,TEXT("MenuEdit"));

          hMenuFile = LoadMenu(hInstance,TEXT("MenuFile"));

          //将hMenuMain设置为窗口顶级菜单

          SetMenu(hwnd,hMenuMain);

          return 0;

     case WM_COMMAND:

          switch(LOWORD(wparam))

          {

          case ID_MAIN:

               SetMenu (hwnd,hMenuMain);//将新菜单分配给指定的窗口

               return 0;

          case ID_EDIT:

               SetMenu(hwnd,hMenuEdit);

               return 0;

          case ID_FILE:

               SetMenu(hwnd,hMenuFile);

               return 0;

          case ID_FILE_NEW:

          case ID_FILE_OPEN:

          case ID_FILE_SAVE:

          case ID_FILE_SAVE_AS:    

          case ID_EDIT_UNDO:    

          case ID_EDIT_CUT:

          case ID_EDIT_COPY:

          case ID_EDIT_PASTE:

          case ID_EDIT_CLEAR:

               MessageBeep(0);

               return 0;

          }

          break;

     case WM_DESTROY:

          SetMenu(hwnd,hMenuMain);//将新菜单分配给指定的窗口

          DestroyMenu(hMenuFile);//销毁指定的菜单并释放该菜单占用的所有内存

          DestroyMenu(hMenuEdit);

          PostQuitMessage(0);

          return 0;

     }

     return DefWindowProc(hwnd,message,wparam,lparam);

}

/********************************************************************

LoadMenu函数:加载指定的菜单资源

HMENU LoadMenuA(

  HINSTANCE hInstance,//包含要加载的菜单资源的模块的句柄

  LPCSTR    lpMenuName//菜单资源名称

);

********************************************************************

SetMenu函数:将新菜单分配给指定的窗口

BOOL SetMenu(

  HWND  hWnd,//窗口句柄

  HMENU hMenu//新的菜单句柄

);

********************************************************************

DestroyMenu函数:销毁指定的菜单并释放该菜单占用的所有内存

BOOL DestroyMenu(

  HMENU hMenu//要销毁的菜单句柄

);

*/

    061_NOPOPUPS.C.rc资源脚本文件中包含3个菜单资源:

/

//

// Menu

//

MENUMAIN MENU

BEGIN

    POPUP "MAIN"

    BEGIN

        MENUITEM "FILE",                        ID_FILE

        MENUITEM "EDIT",                        ID_EDIT

    END

END

MENUFILE MENU

BEGIN

    POPUP "FILE"

    BEGIN

        MENUITEM "NEW",                         ID_FILE_NEW

        MENUITEM "OPEN",                        ID_FILE_OPEN

        MENUITEM "SAVE",                        ID_FILE_SAVE

        MENUITEM "SAVE_AS",                     ID_FILE_SAVE

        MENUITEM "MAIN",                        ID_MAIN

    END

END

MENUEDIT MENU

BEGIN

    POPUP "EDIT"

    BEGIN

        MENUITEM "UNDO",                        ID_EDIT_UNDO

        MENUITEM "CUT",                         ID_EDIT_CUT

        MENUITEM "COPY",                        ID_EDIT_COPY

        MENUITEM "PASTE",                       ID_EDIT_PASTE

        MENUITEM "CLEAR",                       ID_EDIT_CLEAR

        MENUITEM "MAIN",                        ID_MAIN

    END

END

运行结果:

图9-15 没有弹出菜单的多层顶级菜单

 

总结

实例NOPOPUPS.C给出了一个没有弹出菜单的多层顶级菜单的例子。实例在窗口过程处理WM_CREATE消息时,调用LoadMenu函数,分别加载"MenuMain"、"MenuEdit"和"MenuFile"三个菜单资源,并返回三个菜单资源的句柄。

处理WM_COMMAND消息:

点击ID_MAIN菜单时,调用SetMenu函数将"MenuMain"菜单分配给窗口。

点击ID_EDIT菜单时,调用SetMenu函数将"MenuEdit"菜单分配给窗口。

点击ID_FILE菜单时,调用SetMenu函数将"MenuFile"菜单分配给窗口。

处理WM_DESTROY消息时,调用SetMenu函数将"MenuMain"菜单分配给窗口。并调用DestroyMenu函数销毁"MenuEdit"和"MenuFile"菜单资源所占有的内存。

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

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

相关文章

亿康源用科技引领发展,开启大健康产业新篇章

&#xff08;本台记者报&#xff09;近日&#xff0c;杭州有一家公司凭借深厚的科技研发实力与卓越的创新能力在大健康领域屡受好评&#xff0c;其研发的新品一经推出便成为行业热议。为了探寻该公司的经营秘诀&#xff0c;我们找到了这家公司——亿康源&#xff0c;并有幸与亿…

C/C++ Windows 与 Unix 平台上面使用 access 访问文件函数

在 Windows 与 Unix 平台上面得 C/C 之中&#xff0c;都标准提供了 access 函数得实现&#xff0c;只不过参数会有一些不同。 为了确保跨平台编译、兼容得通用、及一致性&#xff0c;所以人们需要显示定义&#xff1a; #if defined(_WIN32) #include <io.h> #else #incl…

防火墙组网与安全策略实验

实验要求&#xff1a; 实现&#xff1a; 防火墙接口配置&#xff1a; 所有接口均配置为三层接口 由于G1/0/3口下为vlan环境&#xff0c;所以防火墙需要配置子接口 &#xff1a; 交换机划分vlan分开生产区和办公区、配置trunk干道 &#xff1a; 安全策略&#xff1a; 生产区访…

深度学习概览

引言 深度学习的定义与背景 深度学习是机器学习的一个子领域&#xff0c;涉及使用多层神经网络分析和学习复杂的数据模式。深度学习的基础可以追溯到20世纪80年代&#xff0c;但真正的发展和广泛应用是在21世纪初。计算能力的提升和大数据的可用性使得深度学习在许多领域取得…

[C++] 由浅入深理解面向对象思想的组成模块

文章目录 (一) 类的默认成员函数(二) 构造函数构造函数的特征构造函数示例无参构造带参构造 冲突:全缺省参数的构造函数与无参构造函数 &#xff08;三&#xff09;析构函数特性析构函数的析构过程解析 &#xff08;四&#xff09;拷贝构造函数什么是拷贝构造&#xff1f;特性为…

Angular页面项目以HTTPS方式启动调试

在 Angular 项目中&#xff0c;可以使用 HTTPS 启动开发服务器进行调试。以下是具体步骤&#xff1a; 1、生成 SSL 证书 首先&#xff0c;需要生成 SSL 证书。可以使用 OpenSSL 来生成自签名证书。 在 Windows 上&#xff0c;可以通过 Git Bash 或其他终端执行以下命令&#x…

初始c语言(2)运算符与表达式

一 c语言提供的运算符类型 以上会后续介绍 二 现阶段我们掌握如下的基本操作符 注意&#xff01;计算机的除法只会保留整数部分&#xff08;若被除数未负则不同的软件取整的结果不唯一&#xff09; 三 自加&#xff08;&#xff09;自减&#xff08;--&#xff09;符号 若为…

Vue3 defineProps的使用

1.什么是defineProps defineProps是Vue3中的一种新的组件数据传递方式&#xff0c;可以用于在子组件中定义接收哪些父组件的props。当父组件的props发生变化时&#xff0c;子组件也会随之响应。 2.如何使用defineProps&#xff1f; 在子组件中可以使用defineProps声明该组件…

流媒体服务器(21)—— mediasoup 之媒体流score评分计算(二)

目录 前言 正文 1、期望收包数 2、实际收包数 3、丢包数 4、修复包数 5、重传包数 6、综合计算 结尾 《流媒体服务器》专栏总览丨蓄力计划_开源流媒体服务器对比-CSDN博客 前言 上一篇文章介绍了 mediasoup 有一套评估媒体传输通道优劣的机制,主要是通过 score 评分…

Jmeter-单用户单表查询千条以上数据,前端页面分页怎么做

这里写自定义目录标题 单用户单表查询千条以上数据 单用户单表查询千条以上数据 对于单用户查询千条以上数据&#xff0c;但是前端页面做了分页的情况下 可以直接把查询接口下的分页限制去掉&#xff0c;便可查询出当前页面查询条件下的全部数据 例如去掉如下内容&#xff1…

GESP CCF C++ 四级认证真题 2024年6月

第 1 题 下列代码中&#xff0c;输出结果是&#xff08; &#xff09; A. 12 24 24 12 B. 24 12 12 24 C. 12 12 24 24 D. 24 24 12 12 第 2 题 下面函数不能正常执行的是&#xff08;&#xff09; A. B. C. D. 第 3 题 下面程序…

AI Native时代:重塑人机交互与创作流程

随着2024年上海世界人工智能大会的圆满落幕&#xff0c;业界领袖们纷纷就AI应用的新机遇展开深入讨论。结合a16z播客中的观点&#xff0c;本文将探讨AI原生&#xff08;AI Native&#xff09;应用的几个关键特征&#xff0c;这些特征正在重新定义我们的工作方式和创作过程。 一…

0708,LINUX目录相关操作 + LINUX全导图

主要是冷气太足感冒了&#xff0c;加上少吃药抗药性差&#xff0c;全天昏迷&#xff0c;学傻了学傻了 01&#xff1a;简介 02&#xff1a; VIM编辑器 04&#xff1a;目录 05&#xff1a;文件 03&#xff1a;常用命令 06&#xff1a;进程 07&#xff1a;进程间的通信 cat t_c…

LeetCode 每日一题 2024/7/8-2024/7/14

记录了初步解题思路 以及本地实现代码&#xff1b;并不一定为最优 也希望大家能一起探讨 一起进步 目录 7/8 724. 寻找数组的中心下标7/9 3102. 最小化曼哈顿距离7/10 2970. 统计移除递增子数组的数目 I7/11 2972. 统计移除递增子数组的数目 II7/12 2974. 最小数字游戏7/13 301…

微信小程序毕业设计-青少年科普教学系统项目开发实战(附源码+论文)

大家好&#xff01;我是程序猿老A&#xff0c;感谢您阅读本文&#xff0c;欢迎一键三连哦。 &#x1f49e;当前专栏&#xff1a;微信小程序毕业设计 精彩专栏推荐&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb; &#x1f380; Python毕业设计…

ftp pool 功能分析及 golang 实现

本文探究一种轻量级的 pool 实现 ftp 连接。 一、背景 简要介绍&#xff1a;业务中一般使用较多的是各种开源组件&#xff0c;设计有点重&#xff0c;因此本文探究一种轻量级的 pool 池的思想实现。 期望&#xff1a;设置连接池最大连接数为 N 时&#xff0c;批量执行 M 个 F…

vs2017/2019串口Qt Serial Port/modbus使用报错

vs2017/2019 Qt Serial Port/modbus配置 /* * 严重性 代码 说明 项目 文件 行 禁止显示状态 错误 LNK2019 无法解析的外部符号 "__declspec(dllimport) public: __cdecl QModbusTcpClient::QModbusTcpClient(class QObject *)" (__imp_??…

基于javaScript的冒泡排序

目录 一.前言 二.设计思路和原理 三.源代码展示 四. 案例运行结果 一.前言 冒泡排序简而言之&#xff0c;就是一种算法&#xff0c;能够把一系列的数据按照一定的顺序进行排列显示&#xff08;从小到大或从大到小&#xff09;。例如能够将数组[5,4,3,2,1]中的元素按照从小到…

读书笔记 《软技能:代码之外的生存指南(第2版)》

关于时间 每天记录并追踪自己的时间&#xff0c;以便我能了解自己的时间都去哪儿了 每天高效工作的时间有多少 这点皮皮哥深有同感,我发现我其实真正效率高的是早上,我一般周末周日的早晨回起的很早,泡一杯挂耳☕️,就在我的mac本上开始了本周的创作,我喜欢这种感觉 关于营…

ES6 Class 的继承(十一)

Class 可以通过extends关键字实现继承&#xff0c;这比 ES5 的通过修改原型链实现继承&#xff0c;要清晰和方便很多。 class Point { } class ColorPoint extends Point { }继承的特性&#xff1a; extends 关键字&#xff1a;使用 extends 来表示一个类继承自另一个类。supe…