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

news2024/11/15 11:16:43

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

 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.coloradmin.cn/o/1925014.html

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

相关文章

Java02--基础概念

一、注释 注释是在程序指定位置添加的说明性信息 简单理解&#xff0c;就是对代码的一种解释 1.单行注释 格式: //注释信息 2.多行注释 格式: /*注释信息*/ 3.文档注释 格式: /**注释信息*/ 注释使用的细节: 注释内容不会参与编译和运…

九盾安防丨如何判断叉车是否超速?

在现代物流和生产流程中&#xff0c;叉车是提高效率和降低成本的关键工具。然而&#xff0c;叉车的高速行驶也带来了安全隐患&#xff0c;这就要求我们对其进行严格的安全管理。九盾安防&#xff0c;作为业界领先的安防专家&#xff0c;今天就为大家揭晓如何判断叉车是否超速&a…

OpenCV距离变换函数distanceTransform的使用

操作系统&#xff1a;ubuntu22.04OpenCV版本&#xff1a;OpenCV4.9IDE:Visual Studio Code编程语言&#xff1a;C11 功能描述 distanceTransform是OpenCV库中的一个非常有用的函数&#xff0c;主要用于计算图像中每个像素到最近的背景&#xff08;通常是非零像素到零像素&…

VMware_centos8安装

目录 VMware Workstation Pro的安装 安装centos VMware Workstation Pro的安装 正版VMware 17百度网盘下载链接 (含秘钥) 链接&#xff1a;https://pan.baidu.com/s/16zB-7IAACM_1hwR1nsk12g?pwd1111 提取码&#xff1a;1111 第一次运行会要求输入秘钥 秘钥在上边的百度网盘…

【Leetcode】最小数字游戏

你有一个下标从 0 开始、长度为 偶数 的整数数组 nums &#xff0c;同时还有一个空数组 arr 。Alice 和 Bob 决定玩一个游戏&#xff0c;游戏中每一轮 Alice 和 Bob 都会各自执行一次操作。游戏规则如下&#xff1a; 每一轮&#xff0c;Alice 先从 nums 中移除一个 最小 元素&…

docker安装nginx并配置https

参考 docker安装nginx并配置https-腾讯云开发者社区-腾讯云 (tencent.com) 证书的生成 参见&#xff1a;SpringBoot项目配置HTTPS接口的安全访问&#xff08;openssl配置&#xff09;_配置接口访问-CSDN博客 步骤 1: 拉取Nginx镜像 docker pull nginx 好使的镜像如下&#x…

DockerCompose拉取DockerHub镜像,并部署OpenMetaData

参考博主&#xff1a;http://t.csdnimg.cn/i49ET 一、DockerCompose拉取DockerHub镜像 方法一&#xff08;不太行&#xff09;&#xff1a; 在daemon.json文件中添加一些国内还在服务的镜像站&#xff08;可能某些镜像会没有&#xff09; ([ -f /etc/docker/daemon.json ] ||…

RK3568笔记三十五:LED驱动开发测试

若该文为原创文章&#xff0c;转载请注明原文出处。 字符设备驱动程序的基本框架&#xff0c;主要是如何申请及释放设备号、添加以及注销设备&#xff0c;初始化、添加与删除 cdev 结构体&#xff0c;并通过 cdev_init 函数建立 cdev 和 file_operations 之间的关联&#xff0c…

每日一练:奇怪的TTL字段(python实现图片操作实战)

打开图片&#xff0c;只有四种数字&#xff1a;127&#xff0c;191&#xff0c;63&#xff0c;255 最大数字为255&#xff0c;想到进制转换 将其均转换为二进制&#xff1a; 发现只有前2位不一样 想着把每个数的前俩位提取出来&#xff0c;组成新的二进制&#xff0c;然后每…

Python中的数据容器及其在大数据开发中的应用

在Python编程中&#xff0c;数据容器是存储和组织数据的基本工具。作为大数据开发者&#xff0c;了解并灵活运用各种容器类型对于高效处理大规模数据至关重要。今天&#xff0c;我们将从Set出发&#xff0c;探讨Python中的各种数据容器&#xff0c;以及它们在大数据处理中的应用…

社交App iOS审核中的4.3问题:深入分析与解决策略

社交App审核中的4.3问题&#xff1a;深入分析与解决策略 在iOS应用开发和审核过程中&#xff0c;开发者经常会遇到苹果审核4.3问题。这一问题往往涉及应用的设计和内容重复性&#xff0c;导致应用被拒绝上架。为了帮助开发者更好地理解和解决这一问题&#xff0c;本文将对4.3问…

基于复旦微JFMQL100TAI的全国产化FPGA+AI人工智能异构计算平台,兼容XC7Z045-2FFG900I

基于上海复旦微电子FMQL45T900的全国产化ARM核心板。该核心板将复旦微的FMQL45T900&#xff08;与XILINX的XC7Z045-2FFG900I兼容&#xff09;的最小系统集成在了一个87*117mm的核心板上&#xff0c;可以作为一个核心模块&#xff0c;进行功能性扩展&#xff0c;能够快速的搭建起…

C语言操作符优先级

1 C语言操作符优先级 熟悉操作符的优先级&#xff0c;避免意外的求值顺序。 2. 运算符优先级记忆方法 利用优先级表或常见记忆口诀来记忆运算符的优先级。

嵌入式人工智能应用-篇外-烧写说明

1 外部接线 1.1 前期准备 需要准备的工具 ⚫ 一根 Mini USB 线 ⚫ 嵌入式人工智能教学科研平台 ⚫ 12V DC 电源 ⚫ 一台电脑 1.2 接线 12V DC 电源接入 12V IN&#xff1b;Mini USB 线连接 USB OTG&#xff1b;如果有两条 Mini USB 线&#xff0c;可以接入 UART2 to USB 口…

python2

一、条件语句 具体有如下&#xff1a;if、if......elif、if......elif......else 注意格式&#xff1a; if后面的条件表达式没有&#xff08;&#xff09;&#xff0c;以&#xff1a;作为结尾对于多分支的条件&#xff0c;不是写成else if 而是elif注意条件下一行要有缩进 …

Stable Diffusion 使用

目录 背景 最简单用法 进阶用法 高手用法 safetensor 一、概述 二、主要特点 背景 Stable Diffusion 开源后&#xff0c;确实比较火&#xff0c;上次介绍了下 Stable Diffusion 最简单的concept。今天继续介绍下&#xff0c;以Liblib 为例&#xff0c;介绍下如何使用参…

排序——交换排序

在上篇文章我们详细介绍了排序的概念与插入排序&#xff0c;大家可以通过下面这个链接去看&#xff1a; 排序的概念及插入排序 这篇文章就介绍一下一种排序方式&#xff1a;交换排序。 一&#xff0c;交换排序 基本思想&#xff1a;两两比较&#xff0c;如果发生逆序则交换…

Java | Leetcode Java题解之第234题回文链表

题目&#xff1a; 题解&#xff1a; class Solution {public boolean isPalindrome(ListNode head) {if (head null) {return true;}// 找到前半部分链表的尾节点并反转后半部分链表ListNode firstHalfEnd endOfFirstHalf(head);ListNode secondHalfStart reverseList(firs…

《BASeg: Boundary aware semantic segmentation for autonomous driving》论文解读

期刊&#xff1a;Neural Networks | Journal | ScienceDirect.com by Elsevier 年份&#xff1a;2023 代码&#xff1a;https://github.com/Lature-Yang/BASeg 摘要 语义分割是自动驾驶领域街道理解任务的重要组成部分。现有的各种方法要么专注于通过聚合全局或多尺度上下文…

读人工智能全传12人工智能导致的问题1

1. 人工智能会导致什么问题 1.1. 人工智能是一门通用技术&#xff1a;它的应用仅仅受限于我们的想象 1.1.1. 所有的技术都可能产生意想不到的效果&#xff0c;未来几十年甚至几百年内都存在可能性 1.2. 所有的技术都可能被滥用 1.2.1. 我们的无名氏祖先率先用上了火&#x…