您的位置:首页 > 其它

MFC学习笔记——ASSERT、GetSystemMenu、IDM_ABOUTBOX

2016-07-19 20:07 302 查看
介绍一段代码:

在系统菜单中添加字符串资源IDS_ABOUTBOX和菜单资源IDM_ABOUTBOX。

// IDM_ABOUTBOX 必须在系统命令范围内。
// 低4位是系统内部使用的
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
// 如果一个应用程序增加命令到窗口菜单,应该使用小于0xF000的标识符数
ASSERT(IDM_ABOUTBOX < 0xF000);

// 获得窗口菜单的拷贝
CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL)
{
BOOL bNameValid;
CString strAboutMenu;
bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);
ASSERT(bNameValid);
if (!strAboutMenu.IsEmpty())
{
// 添加一条水平线
pSysMenu->AppendMenu(MF_SEPARATOR);
// IDM_ABOUTBOX表示要执行的动作,因为在点击这个菜单项时,将会发送消息,消息中nID就是这个ID,通过比 对ID产生相应的动作
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
}


只有在主窗口是对话框的MFC应用程序中才会出现这个消息IDM_ABOUTBOX。

IDM_ABOUTBOX是MFC框架在“InitDialog”函数中加入的“系统菜单”消息,用来弹出“IDD_ABOUTBOX”指定的对话框。

关于((nID & 0xFFF0) == IDM_ABOUTBOX):

在MSDN中SysCommand的帮助中,有这样一段:

In WM_SYSCOMMAND messages, the four low-order bits of the nID parameter are used internally by Windows. When an application tests the value of nID, it must combine the value 0xFFF0 with the nID value by using the bitwise-AND operator to obtain the correct result.

即nID的低四位是Windows内部用的,应用程序在检测这个ID时,必须用 0xFFF0与nID相与,屏蔽低四位,根据相与的结果来产生相应的动作。

ASSERT

ASSERT(布尔表达式)

在VC中检查变量合法性一般利用ASSERT(x)宏,ASSERT的作用在于检查表达式是否为假或为NULL,如果为假则会引发异常。在MFC中ASSERT宏被大量使用,它的优点是即使出现了WM_QUIT消息也能显示断言失效消息框。

当ASSERT失败并引发异常时会有对话框弹出并报告发生该ASSERT失败位置。并允许选择继续运行(Ignore)或是终止(Abort)程序。(当然选择继续运行是很危险的)选择Retry将会启动调试软件对程序进行调试。

此外还有一点,ASSERT宏只在调试版本中才会有作用,在调试版本中ASSERT(f)宏被展开为

do
{
if (!(f) && AfxAssertFailedLine(THIS_FILE, __LINE__))
AfxDebugBreak();
} while (0)


而在发行版本中会被展开为:

((void)0)

所以对程序内部状态改变的代码不能够放置在ASSERT宏中否则在发行版中会出现不正常的现象。

可将断言(ASSERT)用于:

(1)可以使用断言语句捕捉逻辑错误。可以在程序逻辑必须为真的条件上设置断言。除非发生逻辑错误,否则断言对程序无任何影响。

(2)可以使用断言语句检查操作的结果。断言对于快速直观地检查不明显的操作结果最有价值。

(3)可以使用断言在代码中已处理了错误的点处测试错误类型。

GetSystemMenu

GetSystemMenu

函数功能:该函数允许应用程序为复制或修改而访问窗口菜单(系统菜单或控制菜单)。

**函数原型:**HMENU GetSystemMenu(HWND hWnd,BOOL bRevert);

参数:

hWnd:拥有窗口菜单拷贝的窗口的句柄。

bRevert:指定将执行的操作。如果此参数为FALSE,GetSystemMenu返回当前使用窗口菜单的拷贝的句柄。该拷贝初始时与窗口菜单相同,但可以被修改。

如果此参数为TRUE,GetSystemMenu重置窗口菜单到缺省状态。如果存在先前的窗口菜单,将被销毁。

返回值:如果参数bRevert为FALSE,返回值是窗口菜单的拷贝的句柄:如果参数bRevert为TRUE,返回值是NULL。

备注:任何没有用GetSystemMenu函数来生成自己的窗口菜单拷贝的窗口将接受标准窗口菜单。

窗口菜单最初包含的菜单项有多种标识符值,如SC_CLOSE,SC_MOVE和SC_SIZE。

窗口菜单上的菜单项发送WM_SYSCOMMAND消息。

所有预定义的窗口菜单项的标识符数大于0xF000。如果一个应用程序增加命令到窗口菜单,应该使用小于0xF000的标识符数

系统根据状态自动变灰标准窗口菜单上的菜单项。应用程序通过响应在任何某单显示之前发送的WM_INITMENU消息来实现选取和变灰。

Windows CE环境下,不支持系统菜单,但GetSyemMenu以宏的方式实现,以保持和已存在代码的兼容性。可以使用该宏的返回菜单句柄使关闭框无效,与在Windows桌面平台上一样。Windows CE下的返回值没有其他用处。参数bRevert无用。

用下面的代码使关闭按钮无效:

EnableMenultem(GetSystemMenu(hwnd,FALSE),SC_CLOSE,MF_BYCOMMAND I MF_GRAYED);

速查:Windows NT:3.1及以上版本;Windows:95及以上版本;Windows CE:1.0及以上版本;头文件:winuser.h;输入库:user32.lib。

注意:以上介绍的是API函数,在MFC中作为class CWnd的成员函数声明为 CMenu* GetSystemMenu(BOOL bRevert) const; 只有一个参数。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: