win32第六天

来源:互联网 发布:linux tts语音库 编辑:程序博客网 时间:2024/04/29 16:00
菜单和资源
菜单的分类
1.1 窗口的顶层菜单
1.2 弹出式菜单
1.3 系统菜单
HMENU类型表示菜单,菜单每一项有相应的ID。
所有的菜单项被点击后都会触发WM_COMMAND消息。
菜单项的基本风格:1.弹出菜单,分隔线,发送消息触发命令。
窗口的顶层菜单
创建菜单  
HMENU CreateMenu(VOID); //创建成功返回菜单句柄
增加菜单项
BOOL AppendMenu(
HMENU hMenu, //菜单句柄
UINT uFlags, //菜单项风格
UINT uIDNewItem, //菜单项ID
LPCTSTR lpNewItem //菜单项的名称
);
设置到窗口
BOOL SetMenu(
HWND hWnd,  //窗口句柄
HMENU hMenu //菜单句柄
);
三大基本风格:
MF_POPUP--弹出下拉菜单或子菜单uIDNewItem必须填写下拉菜单或子菜单句柄。
MF_SEPARATOR--分隔线
MF_STRING---具有这种风格的菜单项,被点击后发出消息(WM_COMMAND比较麻烦)
代码实现:为程序添加顶层菜单
void OnCreate(HWND hWnd){
HMENU hMenu=CreateMenu();
AppendMenu(hMenu,MF_POPUP,1,"文件");
AppendMenu(hMenu,MF_STRING,2,"帮助");
AppendMenu(hMenu,MF_STRING,3,"窗口");
SetMenu(hWnd,hMenu);
}




弹出式菜单 Popup
菜单的创建
HMENU CreatePopupMenu(VOID);//创建成功返回菜单句柄
加入顶层菜单
BOOL AppendMenu(
HMENU hMenu, //菜单句柄
UINT uFlags, //菜单项增加选项,MF_POPUP
UINT_PTR uIDNewItem, //弹出式菜单的句柄
LPCTSTR lpNewItem //菜单项的名称
);
void OnCreate(HWND hWnd){
HMENU hMenu=CreateMenu();
HMENU hPopMenu=CreatePopupMenu();
AppendMenu(hPopMenu,MF_STRING,5,"帮助");
AppendMenu(hPopMenu,MF_SEPARATOR,0," ");
AppendMenu(hPopMenu,MF_STRING,6,"窗口");


AppendMenu(hMenu,MF_POPUP,(UINT)hPopMenu,"文件");
AppendMenu(hMenu,MF_STRING,2,"帮助");
AppendMenu(hMenu,MF_STRING,3,"窗口");
SetMenu(hWnd,hMenu);
}
菜单命令处理:
WM_COMMAND 消息
WPARAM:
HIWORD - 对于菜单为0
LOWORD - 菜单项的ID
LPARAM - 对于菜单为NULL
命令处理过程
获取WPARAM菜单ID,根据ID处理。
void OnCommand(HWND hWnd,WPARAM wParam,LPARAM lParam){
UINT p_id=HIWORD(wParam);
UINT id=LOWORD(wParam);
if(p_id==0){
if(id==3)
PostMessage(hWnd,WM_QUIT,0,0);
}
}
菜单项的状态
在增加菜单项可以设置菜单项的状态。
可以使用菜单API 修改状态
CheckMenuItem
EnableMenuItem
函数使用时,需要通过设置MF_BYPOSITION或者MF_BYCOMMAND,确定使用菜单索引或者菜单ID。 
WM_INITMENUPOPUP
在菜单被激活但是未显示,窗口会收到这个消息
WPARAM -下拉 菜单句柄
LPARAM - LOWORD 是被点击菜单项索引
                 HIWORD 是窗口菜单标识
窗口菜单:窗口顶层菜单,系统菜单。
弹出式菜单,这个值只能是0或1.
case WM_INITMENUPOPUP:
OnInitMenuPopup(hWnd,wParam,lParam);
void OnInitMenuPopup(HWND hWnd,WPARAM wParam,LPARAM lParam){
char szText[256];
sprintf(szText,"菜单句柄:%d,菜单项的位置:%d,是否为窗口菜单:%d\n",wParam,LoWoRD(lParam),HIWORD(lParam);
WriteConsole(g_output,szText,strlen(szText),NULL,NULL);
}


1 系统菜单的获取
HMENU GetSystemMenu(
HWND hWnd,//窗口句柄
BOOL bRevert //重置选项
); 返回获取到的系统菜单句柄
bRevert:TRUE - 删除旧菜单,恢复到默认的系统菜单
FALSE - 返回当前的系统菜单句柄。
2 系统菜单的修改
AppendMenu
DeleteMenu
3 系统菜单命令响应
通过WM_SYSCOMMAND响应菜单命令。
WPARAM的LOWORD是命令ID
HMENU hSys=GetSystemMenu(hWnd,FALSE);
for(int i=0;i<6;i++){
DeleteMenu(hSys,0,MF_BYPOSITION);
}
AppendMenu(hSys,MF_SEPARATOR,0,"");
Appendmenu(hSys,MF_STRING,1001,"我的菜单项");
右键菜单Context Menu的使用
右键菜单是在右键弹起时设置菜单。
1 创建菜单
右键菜单是一个弹出式菜单,使用CreatePopupMenu创建。
2 显示菜单
BOOL TrackPopupMenu(
HMENU hMenu, //菜单句柄
UINT uFlags, //显示方式
int x,//水平位置,屏幕坐标系
int y,//垂直位置,屏幕坐标系
int nReserved, //保留,必须0
HWND hWnd, //处理菜单消息的窗口句柄
CONST RECT *prcRect //NULL,忽略
); TrackPopupMenu是阻塞函数
WM_NOTIFY 是最麻烦的消息,其次排第二的是 WM_COMMAND
这里需要两个函数:
ClientToScreen窗口位置转换到屏幕坐标。
BOOL ClientToScreen(
HWND hWnd,
LPPOINT point;//既要输入,也要输出
};
ScreenToClient屏幕坐标转换到客户区坐标


void OnRButtonUp(HWND hWnd,LPARAM lParam){
HMENU hPMenu=CreatePopupMenu();
RECT rc;
GetClientRect(hWnd,&rc);
AppendMenu(hPMenu,MF_STRING,1000,"新建");
AppendMenu(hPMenu,MF_STRING,1001,"取消");
AppendMenu(hPMenu,MF_STRING,1002,"退出");
POINT pt;
pt.x=LOWORD(lParam);
pt.y=HIWORD(lParam);
ClientToScreen(hWnd,&pt);
TrackPopupMenu(hPMenu,TPM_LEFTALIGN|TPM_VCENTERALIGN,pt.x ,pt.y,0,hWnd,NULL);


}


3 命令处理
WM_COMMAND,与窗口菜单一致
如果Track设置了TPM_RETURNCMD选项,那么点击的菜单项ID通过函数的返回值获取.如果没有这个风格则不返回点击菜单项的ID.


菜单项的状态
WM_INITMENUPOPUP,按照弹出菜单处理
1 鼠标右键抬起
WM_RBUTTONUP 鼠标右键消息窗口坐标系坐标,要使用需要转换成屏幕坐标系
ClientToScreen
ScreenToClient
2 WM_CONTEXTMENU<专业消息>
WParam - 右键点击的窗口句柄
LPARAM - LOWORD X坐标,屏幕坐标系
HIWORD Y坐标,屏幕坐标系
WM_CONTEXTMENU消息是在WM_RBUTTONUP消息之后产生。
千万不要迷恋可视化界面。否则没饭吃哇。
资源相关
资源脚本文件:*.rc
编译器:RC.exe
菜单资源的使用
1.添加菜单资源(VC中添加可视化)
2.加载菜单资源
2.1在注册时设置菜单资源
2.2加载菜单资源,设置到窗口
HMENU LoadMenu(
HINSTANCE hInstance,//handle to module
LPCTSTR lpMenuName,//menu name or resource identifier
);返回菜单句柄
CreateWindowEx
SetMenu
上述两个函数都是通过菜单句柄添加。
窗口注册类中也有:LPCTSTR lpszMenuName; 
MAKEINTRESOURCE--将数字形式的资源ID,转换成字符串形式的资源ID。
MAKEINTRESOURCE(IDR_MENU1);
wce.lpszMenuName=MAKEINTRESOURCE(IDR_MENU1);
赋值后编译会报错。#include "resource.h"
HMENU hMenu=LoadMenu(g_hInstance,MAKeINTRESOURCE(IDR_MENU1));
0 0