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

《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"菜单资源所占有的内存。

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • Ubuntu18.04安装ROS
  • 【解密】记一次辽宁省某综合实践教学管理平台加解密算法分析
  • Proteus元器件库与仪器仪表
  • excel、word、ppt 下载安装步骤整理
  • 网络编程笔记
  • 电影购票小程序论文(设计)开题报告
  • 原创音乐小程序的设计
  • JVM:SpringBoot TomcatEmbeddedWebappClassLoader
  • 深度学习-4-PyTorch中的数据加载器Dataset和DataLoader
  • Paddle 打包部署
  • Vue 3中使用 Lottie 动画
  • python自动化之validator验证数据【代码示例】
  • STM32智能停车场管理系统教程
  • 如何在SpringCloud中使用Kafka Streams实现实时数据处理
  • Vue3单文件jsx输出多组件示例遇到的坑
  • [数据结构]链表的实现在PHP中
  • AHK 中 = 和 == 等比较运算符的用法
  • android百种动画侧滑库、步骤视图、TextView效果、社交、搜房、K线图等源码
  • classpath对获取配置文件的影响
  • Java 网络编程(2):UDP 的使用
  • Puppeteer:浏览器控制器
  • Three.js 再探 - 写一个跳一跳极简版游戏
  • Travix是如何部署应用程序到Kubernetes上的
  • Vue组件定义
  • 对象引论
  • 回流、重绘及其优化
  • 看域名解析域名安全对SEO的影响
  • 算法-图和图算法
  • 通过获取异步加载JS文件进度实现一个canvas环形loading图
  • 通过来模仿稀土掘金个人页面的布局来学习使用CoordinatorLayout
  • 小程序测试方案初探
  • 小李飞刀:SQL题目刷起来!
  • 验证码识别技术——15分钟带你突破各种复杂不定长验证码
  • 曜石科技宣布获得千万级天使轮投资,全方面布局电竞产业链 ...
  • ​Benvista PhotoZoom Pro 9.0.4新功能介绍
  • #职场发展#其他
  • $.ajax,axios,fetch三种ajax请求的区别
  • (day18) leetcode 204.计数质数
  • (el-Transfer)操作(不使用 ts):Element-plus 中 Select 组件动态设置 options 值需求的解决过程
  • (vue)el-cascader级联选择器按勾选的顺序传值,摆脱层级约束
  • (带教程)商业版SEO关键词按天计费系统:关键词排名优化、代理服务、手机自适应及搭建教程
  • (非本人原创)我们工作到底是为了什么?​——HP大中华区总裁孙振耀退休感言(r4笔记第60天)...
  • (机器学习-深度学习快速入门)第三章机器学习-第二节:机器学习模型之线性回归
  • (一)u-boot-nand.bin的下载
  • (转)EXC_BREAKPOINT僵尸错误
  • (转)shell中括号的特殊用法 linux if多条件判断
  • (转载)Linux 多线程条件变量同步
  • (最全解法)输入一个整数,输出该数二进制表示中1的个数。
  • .htaccess配置重写url引擎
  • .NET delegate 委托 、 Event 事件,接口回调
  • .net framework4与其client profile版本的区别
  • .NET周刊【7月第4期 2024-07-28】
  • /usr/bin/python: can't decompress data; zlib not available 的异常处理
  • @四年级家长,这条香港优才计划+华侨生联考捷径,一定要看!
  • [100天算法】-实现 strStr()(day 52)