C++windows内核编程笔记day06 代码创建菜单
来源:互联网 发布:淘宝销量排行榜2015 编辑:程序博客网 时间:2024/06/05 18:43
创建菜单:
HMENU CreateMenu(VOID);
添加菜单项:
BOOL AppendMenu( HMENU hMenu, // handle to menu
UINT uFlags, // menu-item options
UINT_PTR uIDNewItem, // identifier, menu, or submenu
LPCTSTR lpNewItem // menu-item content
);
uFlags:
MF_POPUP -有子菜单的菜单项目,uIDNewItem要设置为子菜单的句柄(转换为uint)
MF_SEPARATOR -分隔线
MF_STRING -一般菜单项,被点击后会发送消息 WM_COMMAND
MF_MENUBREAK -换一列
把菜单加到窗口:
BOOL SetMenu( HWND hWnd, // handle to window HMENU hMenu // handle to menu
);
//修改菜单的勾选状态
DWORD CheckMenuItem( HMENU hmenu, // handle to menu
UINT uIDCheckItem, // menu item to check or uncheck
UINT uCheck // menu item options
);
uCheck:
MF_BYCOMMAND -填写菜单id
MF_BYPOSITION -填写菜单索引
MF_CHECKED/MF_UNCHECKED //1/0 --是否选中
//触发菜单点击事件
case WM_COMMAND:
On_Command(hwnd,wparam);
break;
//点击事件处理
void On_Command(HWND hwnd,WPARAM wparam)
{
bool IsFromMenu=(HIWORD(wparam)==0?true:false);//点击菜单:0,加速键:1
unsigned int id=LOWORD(wparam);//被点的控件id
switch(id)
{
case 10011:
//MessageBox(NULL,"打开","info",MB_OK);
if(isChecked)
{
CheckMenuItem(menu1,id,MF_BYCOMMAND|MF_UNCHECKED);isChecked=false;
}
else{ CheckMenuItem(menu1,id,MF_BYCOMMAND|MF_CHECKED);isChecked=true;
//MessageBox(NULL,"1","info",MB_OK);
}
break;
}
}
//设置可用或不可用,与CheckMenuItem用法一样
BOOL EnableMenuItem(HMENU hMenu,// handle to menu
UINT uIDEnableItem, // menu item to update
UINT uEnable // options
);
WM_INITMENUPOPUP //弹出菜单在被点击还未弹出来之前触发的消息
LRESULT CALLBACK WindowProc(
HWND hwnd, // handle to window
UINT uMsg, // WM_INITMENUPOPUP
WPARAM wParam, // handle to menu (HMENU)
LPARAM lParam // item position and indicator
);
lParam:
LOWORD 被点击菜单的索引
HIWORD 将要显示的菜单是否为窗口菜单(弹出式菜单不属于窗口菜单)
系统菜单的操作,消息:WM_SYSCOMMAND,不太重要,一般不用。
HMENU GetSystemMenu( HWND hWnd, // handle to window
BOOL bRevert // 是否返回默认菜单
);
AppendMenu //前面用过
//删除菜单,根据位置删除时,删除前一个,后面一个会改变位置。
BOOL DeleteMenu( HMENU hMenu, // handle to menu
UINT uPosition, // menu item identifier or position
UINT uFlags // option(MF_BYPOSITION/MF_BYCOMMAND)
);
右键菜单:弹出式菜单,前面用过,这里主要在右键时显示菜单。
BOOL TrackPopupMenu(
HMENU hMenu, // handle to shortcut menu
UINT uFlags, // options
int x, // horizontal position
int y, // vertical position
int nReserved, // reserved, must be zero
HWND hWnd, // handle to owner window
CONST RECT *prcRect // ignored
);
uFlags:
TPM_RETURNCMD -点击菜单项,不发出WM_COMMAND消息,但有返回值(被点击菜单的ID)
//右键消息处理函数,也可以在WM_CONTEXTMENU消息中处理(专门处理)
//WM_CONTEXTMENU 在 WM_RBUTTONUP之后触发的
//WM_CONTEXTMENU 中的坐标不需要转换
void OnRButtonUp(HWND hwnd,LPARAM lparam)
{
HMENU menucontext=CreatePopupMenu();
AppendMenu(menucontext,MF_STRING,103,"查看");
AppendMenu(menucontext,MF_STRING,104,"放大");
AppendMenu(menucontext,MF_STRING,105,"缩小");
POINT pt={0};
pt.y=HIWORD(lparam);
pt.x=LOWORD(lparam);
ClientToScreen(hwnd,&pt);//将客户区坐标转换为相对于屏幕的坐标
int cmdid= TrackPopupMenu(menucontext,TPM_LEFTALIGN|TPM_LEFTBUTTON|TPM_RETURNCMD,pt.x,pt.y,0,
hwnd,NULL);//在鼠标位置显示菜单
char txt[30]={0};
sprintf(txt,"被点的菜单ID:%d\n",cmdid);
MessageBox(hwnd,txt,"info",MB_OK);
}
ScreenToClient();//坐标转换函数
代码示例:
同样创建win32 application
主要cpp代码修改为:
// win32app.cpp : Defines the entry point for the application.//#include "stdafx.h"#include <stdio.h>HINSTANCE g_hinstance=0;//全局句柄HMENU menu1=0,menu2=0;HANDLE g_houtput=0;void OnCreate(HWND hwnd,LPARAM lparam){HMENU menu=CreateMenu();menu1=CreatePopupMenu();AppendMenu(menu1,MF_STRING|MF_CHECKED,10011,"打开");AppendMenu(menu1,MF_STRING,10012,"保存");AppendMenu(menu1,MF_SEPARATOR,0,NULL);AppendMenu(menu1,MF_STRING|MF_MENUBREAK,10013,"退出");menu2=CreatePopupMenu();AppendMenu(menu2,MF_STRING,10021,"复制");AppendMenu(menu2,MF_STRING|MF_GRAYED,10022,"粘贴");AppendMenu(menu,MF_POPUP,(UINT)menu1,"文件");AppendMenu(menu,MF_SEPARATOR,0,NULL);AppendMenu(menu,MF_POPUP,(UINT)menu2,"编辑");SetMenu(hwnd,menu); HMENU menusys=GetSystemMenu(hwnd,FALSE); for(int i=0;i<6;i++) { // DeleteMenu(menusys,0,MF_BYPOSITION);//删除系统菜单项 } AppendMenu(menusys,MF_STRING,101,"我的菜单");}LRESULT CALLBACK OnInitMunuPopUp(HWND hwnd, // handle to windowUINT uMsg, // WM_INITMENUPOPUPWPARAM wParam, // handle to menu (HMENU)LPARAM lParam // item position and indicator){unsigned int index=LOWORD(lParam);int IsWindowMenu=HIWORD(lParam);char txt[200]={0};sprintf(txt,"OnInitMenuPopUp:menu:%d,Index:%d,IsWindow:%d\n",wParam,index,IsWindowMenu);WriteConsole(g_houtput,txt,strlen(txt),NULL,NULL);return 0;}bool isChecked=true;void On_Command(HWND hwnd,WPARAM wparam){bool IsFromMenu=(HIWORD(wparam)==0?true:false);unsigned int id=LOWORD(wparam);switch(id){case 10011://MessageBox(NULL,"打开","info",MB_OK);if(isChecked){CheckMenuItem(menu1,id,MF_BYCOMMAND|MF_UNCHECKED);isChecked=false;}else{ CheckMenuItem(menu1,id,MF_BYCOMMAND|MF_CHECKED);isChecked=true;//MessageBox(NULL,"1","info",MB_OK);}break;}}void OnSysCommand(HWND hwnd,WPARAM wparam){bool IsFromMenu=(HIWORD(wparam)==0?true:false);unsigned int id=LOWORD(wparam);switch(id){case 101:MessageBox(hwnd,"我的菜单","info",MB_OK);break;default://MessageBox(hwnd,"我的菜单1","info",MB_OK);break;}}void OnRButtonUp(HWND hwnd,LPARAM lparam){// HMENU menucontext=CreatePopupMenu();// AppendMenu(menucontext,MF_STRING,103,"查看");// AppendMenu(menucontext,MF_STRING,104,"放大");// AppendMenu(menucontext,MF_STRING,105,"缩小");// POINT pt={0};// pt.y=HIWORD(lparam);// pt.x=LOWORD(lparam);// ClientToScreen(hwnd,&pt);//将客户区坐标转换为相对于屏幕的坐标// int cmdid= TrackPopupMenu(menucontext,TPM_LEFTALIGN|TPM_LEFTBUTTON|TPM_RETURNCMD,pt.x,pt.y,0,// hwnd,NULL);//在鼠标位置显示菜单// char txt[30]={0};// sprintf(txt,"被点的菜单ID:%d\n",cmdid);// MessageBox(hwnd,txt,"info",MB_OK);}void OnContextMenu(HWND hwnd,LPARAM lparam){ HMENU menucontext=CreatePopupMenu(); AppendMenu(menucontext,MF_STRING,103,"查看"); AppendMenu(menucontext,MF_STRING,104,"放大"); AppendMenu(menucontext,MF_STRING,105,"缩小"); POINT pt={0}; pt.y=HIWORD(lparam); pt.x=LOWORD(lparam); //ClientToScreen(hwnd,&pt);//将客户区坐标转换为相对于屏幕的坐标 int cmdid= TrackPopupMenu(menucontext,TPM_LEFTALIGN|TPM_LEFTBUTTON|TPM_RETURNCMD,pt.x,pt.y,0, hwnd,NULL);//在鼠标位置显示菜单if(cmdid!=0){ char txt[30]={0}; sprintf(txt,"被点的菜单ID:%d\n",cmdid); MessageBox(hwnd,txt,"info",MB_OK);}}//回调函数LRESULT CALLBACK WinProc(HWND hwnd,UINT msg,WPARAM wparam,LPARAM lparam){switch(msg){case WM_SYSCOMMAND:if(wparam==SC_CLOSE){int ret=MessageBox(NULL,"是否退出","info",MB_YESNO);if(ret==IDYES){//下面代码会自动关闭和销毁//PostQuitMessage(0);}else return 0;//不执行下面代码}OnSysCommand(hwnd,wparam);break;//在创建窗口之后还未显示的时候case WM_CREATE:OnCreate(hwnd,lparam);break;case WM_DESTROY:PostQuitMessage(0);break;case WM_COMMAND:On_Command(hwnd,wparam);break;case WM_INITMENUPOPUP:OnInitMunuPopUp(hwnd,msg,wparam,lparam);break;case WM_RBUTTONUP:OnRButtonUp(hwnd,lparam);break;case WM_CONTEXTMENU:OnContextMenu(hwnd,lparam);break;}return DefWindowProc(hwnd,msg,wparam,lparam);}//注册窗口类BOOL Register(LPSTR lpClassName,WNDPROC wndproc){WNDCLASSEX wce={0};wce.cbSize=sizeof(wce);wce.cbClsExtra=200;wce.cbWndExtra=200;wce.hbrBackground=(HBRUSH)(COLOR_WINDOW+1);wce.hCursor=NULL;wce.hIcon=NULL;wce.hIconSm=NULL;wce.hInstance=g_hinstance;wce.lpfnWndProc=wndproc;wce.lpszClassName=lpClassName;wce.lpszMenuName=NULL;wce.style=CS_HREDRAW|CS_VREDRAW;ATOM atom= RegisterClassEx(&wce);if(atom==0){MessageBox(NULL,"注册失败","info",MB_OK);return FALSE;}return TRUE;}//创建窗口HWND CreateMain(LPSTR lpClassName,LPSTR lpWndName){HWND hwnd=CreateWindowEx(0,lpClassName,lpWndName,WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,NULL,NULL,g_hinstance,"hello create");return hwnd;}//创建子窗口HWND CreateChild(HWND phwnd,LPSTR lpClassName,LPSTR lpWndName){if(Register(lpClassName,DefWindowProc)==0){MessageBox(phwnd,"创建子窗口失败","info",MB_OK);return NULL;}//子窗口风格,都要 WS_CHILD|WS_VISIBLEHWND hwnd=CreateWindowEx(0,lpClassName,lpWndName,WS_CHILD|WS_VISIBLE|WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,CW_USEDEFAULT,200,200,phwnd,NULL,g_hinstance,NULL);return hwnd;}//显示窗口void Display(HWND hwnd){ShowWindow(hwnd,SW_SHOW);UpdateWindow(hwnd);}//处理消息void MSGdeal(){MSG msg={0};while(GetMessage(&msg,NULL,0,0)){TranslateMessage(&msg);//翻译消息 DispatchMessage(&msg);//派发给 WinProc 处理消息 }}int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow){AllocConsole();//调试程序方法g_houtput=GetStdHandle(STD_OUTPUT_HANDLE);g_hinstance=hInstance; // TODO: Place code here.if(Register("main",WinProc)==0){MessageBox(NULL,"注册失败","提示",MB_OK);return 0;}HWND hwnd= CreateMain("main","pro1");Display(hwnd);MSGdeal();return 0;}
0 0
- C++windows内核编程笔记day06 代码创建菜单
- C++windows内核编程笔记day07_day08,可视化建菜单、加速键使用、绘图等
- C++windows内核编程笔记day01_day02
- C++windows内核编程笔记day03_day04_day05
- 寒江独钓-Windows内核安全编程笔记-第4章代码
- C++windows内核编程笔记day13 进程、线程与信号量
- C++windows内核编程笔记day14 其他线程同步技术
- windows内核安全编程笔记
- Windows内核编程学习笔记
- 标C编程笔记day06 动态分配内存、函数指针、可变长度参数
- C++MFC编程笔记day06 MFC向导、MFC绘图类使用
- C++MFC编程笔记day06 MFC向导、MFC绘图类使用
- IOS之c语言笔记 day06
- 寒江独钓-Windows内核安全编程笔记-第3章代码和笔记
- day06笔记
- day06笔记
- 《windows核心编程》学习笔记 内核对象
- 《从汇编语言到windows内核编程》笔记
- UVA532
- HDU 2074 叠筐
- Quoit Design - HDU 1007 分治
- HDU 2075 A|B?
- js的Prototype属性 解释及常用方法
- C++windows内核编程笔记day06 代码创建菜单
- 端口号的理解
- HDU 2076 夹角有多大(题目已修改,注意读题)
- 找工作笔试面试那些事儿(16)---linux相关知识点(1)
- Hibernate调试——定位查询源头
- 0cfnQUEyqHS
- 线性规划与网络流24题:《汽车加油行驶问题》
- 细说UI线程和Windows消息队列
- HDU 2077 汉诺塔IV