对于Menu的操作,主要经验及知识点总结如下。
1.MFC中简单的菜单操作可以在开发平台上进行可视化的操作即可。即利用MFC提供的菜单属性窗口进行可视化编辑。
2.MessageBox()是CWnd类的函数。
函数原型及参数function MessageBox(hWnd: HWND; Text, Caption: PChar; Type: Word): Integer;
hWnd:对话框父窗口句柄,对话框显示在Delphi窗体内,可使用窗体的Handle属性,否则可用0,使其直接作为桌面窗口的子窗口。
Text:欲显示的信息字符串。
Caption:对话框标题字符串。
Type:对话框类型常量。
该函数的返回值为整数,用于对话框按钮的识别。
3.MFC中的命名规则。???
4.菜单的响应函数作用顺序为:视类,文档类,框架类,程序类。并且,视类和框架类可以直接使用MessageBox()函数。虽然CWnd是从CCmdTarget类派生的,但其有自己新增加的特性。故凡是从CWnd派生的类,即可以接收标准消息,也可以接收命令消息和通告消息。而对于从CCmdTarget 派生的类,则只能接收命令消息和通告消息,不能接收标准消息。
5.int AfxMessageBox( LPCTSTR lpszText, UINT nType = MB_OK, UINT nIDHelp = 0 );
int AFXAPI AfxMessageBox( UINT nIDPrompt, UINT nType = MB_OK, UINT nIDHelp = (UINT) –1 );
在第一种形式中,lpszText表示在 消息框内部显示的文本,消息框的标题为应用程序的 可执行文件名(如Hello)。在第二种形式中,nIDPrompt为要显示的文本字符串在 字符串表中的ID。 函数调用时会自动从字符串表中载入字符串并显示在消息框中。nType为消息框中显示的按钮风格和图标风格的组合,可以采用|(或)操作符组合各种风格。
与AfxMessageBox类似的函数MessageBox,它是CWnd的类成员函数:
int MessageBox( LPCTSTR lpszText,LPCTSTR lpszCaption = NULL,UINT nType = MB_OK );
两个函数的区别:AfxMessageBox比MessageBox简单一些,因为它是一个 全局函数所以不需要对应的一个窗口类,但是不能控制消息框标题,常用于 调试程序时的内部 数据输出或警告;MessageBox比较正式,常用在要提交的应用程序版本中,可以控制标题内容而不必采用含义不明的可执行文件名为标题。
6.菜单命令响应函数的系统设置点。首先,在视类的头文件中,在两个AFX_MSG注释宏之间添加了命令消息响应函数原型;然后,在视类的源文件中有两处信息,一处是在两个AFX_MSG_MAP注释宏之间添加了ON_COMMAND宏,将菜单ID号与命令响应函数关联起来。另一处是在视类源文件中的命令消息响应函数的实现代码。
7.CWnd类的函数GetMenu().
函数原型:HMENU GetMenu(HWND hWnd);
参数:hWnd:窗口句柄。(想要获得哪个菜单的句柄,就填写该菜单所在窗口的句柄)
返回值:返回值是菜单的句柄。如果给定的 窗口没有菜单,则返回NULL。如果窗口是一个子窗口,返回值无定义。
CMenu类的成员函数GetSubMenu().函数原型:HMENU GetSubMenu(HMENU hMenu,int nPos);
hMenu:菜单句柄。
nPos:激活下拉式菜单或子菜单的菜单项相对于零的位置。
返回值:如果 函数调用成功,返回值是菜单项激活的下拉式菜单或子菜单的句柄。如果菜单项没有激活一个下拉式菜单或子菜单,返回值是NULL。
8.CMenu类从CObject类派生而来。
8.1 CreateMenu()和CreatePopupMenu(),这两个函数用来创建一个菜单实例,CreateMenu()创建的是普通的菜单实例,如果想创建弹出式菜单,就要用CreatePopupMenu()函数。
8.2. AppendMenu()向菜单中添加一个子项,这个函数有两个主要的参数。第一个UINT nFlags,这个参数表明了该子项的属性特征,可以这样说,这个参数规定了菜单的样式和功能。后面会详细讲这个参数所能使用的值。第二个参数UINT_PTR nIDNewItem,根据nFlags使用不同的设置,该参数将标明菜单的资源ID或在这个菜单中的索引号。第三个参数可以省略,如果不省略,可以传入一个字符串,这个字符串将显示在菜单中(因为我准备用突破表示菜单项,所以我的工程中省略了这个参数)。
8.3. DrawItem(),这是一个虚函数,如果菜单设置成可以自绘类型,则这个函数将在生成菜单、弹出菜单、选中菜单、点击菜单等时由系统框架调用。因此,这个函数是一个很有用的函数,它可以帮你绘制出各种样式的菜单。
8.4. MeasureItem()也是一个 虚函数,当菜单被创建的时候由系统框架调用。这个函数用来设置菜单的大小。
9.CheckMenuItem是一个API函数,功能是在弹出菜单中为 菜单项增加选中标记或移除选中标记和 创建一个水平分隔线等。
函数原型:DWORD CheckMenuItem(HMENU
hmenu, UINT
uIDCheckItem, UINT
uCheck);
参数:
hmenu:含有其菜单项的标志将被提取得的菜单的句柄。
uId:其某单标志将被取得的菜单项,此参数含义由参数uFlags决定。
UFlags:用于指定参数uld的含义的值。此参数可取下列值之一:
MF_BYCOMMAND:表示参数uId给出菜单项的标识符。如果MF_BYCOMMAND和MF_BYPOSITION都没被指定,则MF_BYCOMMAND是缺省值。
MF_BYPOSITION:表示参数uId给出菜单项相对于零的位置。
返回值:如果指定的项不存在,返回值是OXFFFFFFFF;如果菜单项打开了一个子菜单,则返回值的低位含有与菜单相联系的菜单标志,高位含有子菜单的项数。否则,返回值是莱单标志的掩码(布尔OR)。
10.SetMenuDefaultltem函数.
函数功能:该函数给指定的菜单设置缺省菜单项。
函数原型:BOOL SetMenuDefaultltem(HMENU hMenu,UINT ultem,UINT fByPo );
参数:
httenu:将为其设置缺省菜单项的菜单的句柄。
Uttrne:新缺省菜单项的 标识符或位置,无缺省项时,取值为C1。此参数的含义由参数fByPoS的值决定。
ByPos:用于确定参数ultem的值的含义。如果此参数为FALSE,参数ultem表示菜单项的标识符。否则,表示菜单项的位置。
返回值:如果 函数调用成功,返回非零值;如果函数调用失败,返回值是零。若想获得更多的 错误信息,请调用GetLastError函数。
11.BOOLSetMenuItemBitmaps
(UINT
nPosition
,UINT
nFlags
,constCBitmap*
pBmpUnchecked
,constCBitmap*
pBmpChecked
).用来设置菜单图标。
第一个参数nPosition的取值由第二个参数nFlags的取值决定。如果第二个参数的取值为MF_BYPOSITION,即使用位置索引,那么第一个参数为菜单项位置索引;如果第二个参数的取值为MF_BYCOMMAND,那么第一个参数为菜单项标示,应该使用该菜单项的ID。后两个参数都是CBitmap类的指针,用来设置与菜单项关联的两个位图,其中第三个参数表示该菜单项未被选中时的位图,第四个参数表示该菜单项被选中之后的显示的位图。
12.GetSystemMetrics ()用于得到被定义的系统数据或者系统配置信息.当参数为SM_CYMENUCHECK 以像素为单位计算的菜单选中标记位图的尺寸,SM_CYMENUSIZE 以像素计算的菜单栏按钮的尺寸。
13.Format是CString类的一个成员函数,它通过格式操作使任意类型的数据转换成一个字符串。
函数声明
function Format(const Format: string; const Args: array of const): string; overload;
参数
Format里面可以写普通的字符串,比如"my name is" ,但有些格式指令字符具有特殊意义,比如"%6s"
14.SetMenu是一种计算机函数,函数功能:该函数分配一个新菜单到指定窗口。函数原型:BOOL SetMenu(HWND hWnd,HMENU hMenu)。
参数:
hWnd:菜单被分配到其中的窗口的句柄。
HMenu:新菜单的句柄。如果菜单参数为NULL,则窗口的当前菜单被删除。
返回值:如果 函数调用成功,返回非零值;如果函数调用失败,返回值是零。若想获得更多的 错误信息,请调用GetLastError函数。
备注:窗口被重画来反映菜单的修改。函数SetMenu替换原来的菜单(如果存在),但并不将其销毁。应用程序必须调用函数DestroyMenu来销毁菜单。参数为NULL呢?
15.Attach()函数和Detach()函数的作用。
基本就是把一个句柄绑定和解绑定于一个类对象上,是其可以使用MFC的函数而不是API
首先,你要明白Windows对象和MFC对象的区别。MFC对象实际上并没有把整个Windows对象都包装在其中,它只是有一个窗口句柄而已,这个窗口句柄如果指向一个实际存在的窗口对象(窗口对象,也就是WNDCLASS,是一个Windows对象),那么这个MFC对象就是有效的,否则这个MFC对象是空的。如果你还不明白,请回忆一下,当我们使用MFC创建一个窗口时,是分两步进行的,第一步,new一个CWnd对象,这一步是创建MFC对象,但是其中的HWND还是非法的,因为对应的Windows对象还没有被创建出来;第二步,调用CWnd的成员函数Create创建真正的Windows对象,同时,把先前创建的MFC的CWnd对象的HWND成员指向该窗口,这样才算创建完毕一个窗口。而如果你是用SDK方式,那么只要创建一个WNDCLASS结构,然后调用Create或者CreateEx就创建了一个窗口。
好,现在回答你的问题,你可以假设,现在你已经有了一个有效窗口句柄,那么你想把这个窗口和一个CWnd对象关联起来怎么办?很简单,用Attach,其实就是让一个CWnd对象的HWND成员指向这个窗口句柄。这就是Attach主要完成的任务。
第二个,关于Detach。如前所述,WNDCLASS其实和CWnd根本没有什么关系。它们之间只是通过CWnd的成员HWND联系起来的。如果把Attach看做“联姻”的话,那么Detach就是“离婚”了,通俗地说,就是切断一个CWnd对象和一个有效窗口的脐带。为什么要切断呢?因为CWnd是C++的对象,C++的对象有一个生存期的概念,脱离了该对象的作用域,这个对象就要被销毁,但是Windows对象没有这个特点,当销毁CWnd对象的时候,我们不一定希望WNDCLASS一起被销毁,那么在此之前,我们就先要把这个“脐带”剪断,以免“城门失火,殃及池鱼”。
16.MFC的命令更新机制.
当我们选择编辑菜单(一个下拉菜单,假设包括复制,剪切,粘贴三个菜单项)的时候,在编辑菜单被展开但是并没有显示的时候,操作系统会发出WM_INITMENUPOPUP消息,然后由程序窗口的基类如CFrameWnd接管。它会创建一个CCmdUI对象,并与程序的一第个菜单项(复制)关联,调用该对象的一个成员函数DoUpdate()。这个函数发出CN_UPDATE_COMMAND_UI消息,这条消息带有一个指向CCmdUI对象的指针。这是,系统会判断是否存在一个ON_UPDATE_COMMAND_UI宏去捕捉这个菜单项的消息。如果找到这样一个宏,就调用相应的消息响应函数进行处理,在这个函数中,可以利用传递过来的CCmdUI对象去调用响应的函数,使该菜单可以使用,或者禁用该菜单项。当更新完第一个菜单项后,同一个CCmdUI对象就设置为与第二个菜单项(剪切)想关联,依次完成所有的菜单项的处理。