VC++技术内幕(第四版)笔记(第12章)

编程语言 专栏收录该内容
40 篇文章 0 订阅

/***************************************/

第十二章:菜单、键盘加速键、复文本编辑控件和属性表


1,主框架窗口包含标题栏和菜单栏,而各种各样的子窗口(包括工具栏窗口、状态栏窗口和视图窗口)覆盖着主框架窗口的客户区域。应用程序通过框架和视图之间的消息传递来控制框架和视图之间的相互作用。

2,MFC应用程序框架提供了一个非常复杂的命令消息传递系统,这些消息来自菜单的选择、键盘加速、以及工具栏和对话框按钮,另外,命令消息也可以通过调用CWnd::SendMessage或PostMessage函数来发送。
1)大多数命令消息都来自主框架窗口,但应用程序框架并没有对其一一的响应处理,需要我们自己在适当的地方添加响应函数加以响应处理。
2)当应用程序框架接收到框架窗口的命令,它将按下列次序来寻找其消息控制函数:
SDI程序(单文档):视图(VIEW类)-》文档(DOC类)-》SDI主框架窗口(FRAME类)-》应用程序(APP类)。
MDI程序(多文档):视图--》文档--》MDI子框架窗口--》MDI主框架窗口--》应用程序。
说明:
当框架接收到框架窗口命令,安上叙的次序寻找其消息控制函数的时候,一旦找到,就停止继续往下寻找,这样当路径中有多个该消息控制函数的时候,只执行先找到的那个。

3,命令传递系统反映对命令消息控制的一个方面,类的层次结构反映了对命令消息进行控制处理的另一个方面。
1)一般,派生类会继承基类所有的消息映射函数,其中包括命令消息函数。
2)如果想对基类的消息映射函数进行重载,就必须在派生类中加入相应的消息映射函数和相应的消息映射入口(及函数声明)。

4,所有的弹出式菜单都属于主框架窗口。
1)弹出式菜单上按钮(及资源编辑器中菜单项)的ID必须在0x8000-0xDFFF范围内,才可以产生可被传递的命令消息。
2)使用符号编辑器来输入ID,可以保证ID范围落在0x8000-0xDFFF范围内。
(注:书中是弹出式对话框,不过应该是弹出式菜单才对。)

5,CFrameWnd::m_bAutoMenuEnable
//Controls automatic enable and disable functionality for menu items.
//CFrameWnd类中的BOOL型数据成员,默认为TRUE。
//如果m_bAutoMenuEnable设为TRUE,则如果某菜单项在当前命令路径中无法找到相应的命令消息控制函数,则此时应用程序框架便禁用该菜单项,并将该菜单项设为灰色。
//如果m_bAutoMenuEnable设为FALSE,便可以禁止上叙自动禁用无控制函数菜单项的特性。
(试一试:自己在框架类构造函数CMainFrame::CMainFrame()中添加this->m_bAutoMenuEnable=TRUE语句,然后看看菜单里菜单项里看看有什么变化哦)


6,MFC文本编辑选择
1)CEditView类:文本大小限制在64K以内,不能设混合字体,实现了基本的编制功能。
2)CRichEditView类:使用了富文本编辑控件,支持混合字体和大数据量文本。
3)CRichEditCtrl类:封装了富文本编辑控件。
//CRichEditCtrl   A window in which the user can enter and edit text with character and paragraph formatting. The control can include embedded OLE objects.


7,示例事例说明:
事例EX12A(未优化前的)中使用CRichEditCtrl类来在基类为CView类的项目中设计编辑功能:
1)方法:构造CRichEditCtrl类对象,并为之创建控件窗口与之关联,设置控件窗口为当前视图客户区大小,使CRichEditCtrl类控件窗口覆盖当前视图客户区,CRichEditCtrl类控件窗口具有富文本编辑功能,从而完成设计。
2)实现细节:
CRichEditCtrl m_rich;//构造CRichEditCtrl对象
m_rich.Create(ES_AUTOVSCROLL | ES_MULTILINE | ES_WANTRETURN | WS_CHILD | WS_VISIBLE | WS_VSCROLL,rect,this,1);//创建控件窗口用以初始化CRichEditCtrl对象
m_rich.SetWindowPos(&wndTop,0,0,rect.right-rect.left,rect.bottom-rect.top,SWP_SHOWWINDOW);
//设置CRichEditCtrl控件窗口大小(使用GetClientRect(rect)获得视图客户区大小)和位置,即覆盖视图客户区域。
3)获取和保存控件文本技巧:
在VIEW类中获取对应DOC类对象指针:CEX12aDoc *pDoc=GetDocument();
获取控件窗口文本:m_rich.SetWindowText(pDoc->m_strText);
设置控件窗口文本:m_rich.GetWindowText(pDoc->m_strText);
技巧说明:在视图类中利用GetDocument()函数获取其对应文档类对象指针,从而可将m_rich控件窗口文本保持到文档类数据成员m_strText中。
4)CRichEditCtrl::SetModify
void SetModify( BOOL bModified = TRUE );
bModified》》A value of TRUE indicates(象征,预示) that the text has been modified, and a value of FALSE indicates it is unmodified. By default, the modified flag is set.
5)关于加速键的添加:在在资源管理器Accelerator中添加(如:ID_GETDATA   VK_F2)。

8,学用属性表
这里提供一种利用资源管理器创建属性表的方法:
第一步:利用资源管理器添加几个对话框作为属性页(这样可方便往属性页上添加控件并处理了)。
第二步:分别为作为属性页的对话框创建类,基类采用CPropertyPage。
第三步:利用类向导创建用户属性表类,基类采用CPropertySheet。
第四步:在刚创建的用户属性表类中添加需要属性页类数据成员,并在属性表类构造函数中调用CPropertySheet::AddPage函数将所需要的属性页一一添加到属性表中去。目前为止属性表类创建结束。
第五步: 在需要创建和显示属性表的地方构造用户属性表对象,并调用CPropertySheet::DoModal显示。
说明:
1)CPropertySheet
Objects of class CPropertySheet represent property sheets, otherwise known as tab dialog boxes. A property sheet consists of a CPropertySheet object and one or more CPropertyPage objects. A property sheet is displayed by the framework as a window with a set of tab indices, with which the user selects the current page, and an area for the currently selected page.

Even though CPropertySheet is not derived from CDialog, managing a CPropertySheet object is similar to managing a CDialog object.

Exchanging data between a CPropertySheet object and some external object is similar to exchanging data with a CDialog object.

2)CPropertyPage
Objects of class CPropertyPage represent individual pages of a property sheet, otherwise known as a tab dialog box. As with standard dialog boxes, you derive a class from CPropertyPage for each page in your property sheet. To use CPropertyPage-derived objects, first create a CPropertySheet object, and then create an object for each page that goes in the property sheet. Call CPropertySheet::AddPage for each page in the sheet, and then display the property sheet by calling CPropertySheet::DoModal for a modal property sheet, or CPropertySheet::Create for a modeless property sheet.

3)Apply按钮的处理:
在所有的属性表类中,只要控件给属性页发送一个消息(如:点击或选择属性页上的控件,框架便调用该属性页OnCommand函数来响应这些控件所发出的通告消息,OnCommand函数是虚函数),在每个属性页中重载OnCommand函数设置SetModified(TRUE)可使Apply按钮有效。
当用户点击Apply按钮,框架自动调用OnApply函数,可以在重载它来完成一些重要的任务。
CWnd::OnCommand 
virtual BOOL OnCommand( WPARAM wParam, LPARAM lParam );
//The framework calls this member function when the user selects an item from a menu, when a child control sends a notification message, or when an accelerator keystroke is translated.

CPropertyPage::OnApply
virtual BOOL OnApply( );
//This member function is called by the framework when the user chooses the OK or the Apply Now button. When the framework calls this function, changes made on all property pages in the property sheet are accepted, the property sheet retains focus, and OnApply returns TRUE (the value 1). Before OnApply can be called by the framework, you must have called SetModified and set its parameter to TRUE. This will activate the Apply Now button as soon as the user makes a change on the property page.

Override this member function to specify what action your program takes when the user clicks the Apply Now button. When overriding, the function should return TRUE to accept changes and FALSE to prevent changes from taking effect.

The default implementation of OnApply calls OnOK.


9,CMenu类
CMenu类对象可以用来表示各种Windows菜单,包括顶层菜单项及相应的弹出式菜单。
添加菜单方法:
程序添加法:1)定义菜单资源;2)构造菜单对象;3)调用CMenu::LoadMenu函数将菜单将菜单资源载入;4)调用CWnd::SetMenu函数将菜单连接到框架窗口中;5)调用CMenu::Detach函数把对象HMENU句柄独立出来(这样当CMenu对象销毁时候,菜单不随之销毁)
/
/

另一中简便的添加菜单方法:如果想为某对话框添加菜单,可从话框属性中Menu项中选择资源管理器中的需要的菜单完成添加工作。

10,创建浮动式弹出菜单
步骤:
1)用资源编辑器添加菜单资源
2)在视图类或其他接收鼠标右键单击的窗口类中添加WM_CONTEXTMENU消息控制函数,编辑代码如下:
void CAboutDlg::OnContextMenu(CWnd* pWnd, CPoint point)
{
 CMenu menu;
 menu.LoadMenu(IDR_MENU1);
 menu.GetSubMenu(0)->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON,point.x,point.y,this);
 
}
说明:
GetSubMenu函数得到指向弹出式菜单的CMenu指针。
TrackPopupMenu在指定位置显示浮动菜单,并跟踪弹出菜单的选择项。

11,关于扩展命令的处理:
扩展命令无法使用向导添加,需要自己添加,添加的方法如普通的命令处理类似。具体参看书P256-257页。


/
后续章节笔记待续

 
  • 0
    点赞
  • 0
    评论
  • 0
    收藏
  • 扫一扫,分享海报

参与评论 您还未登录,请先 登录 后发表或查看评论
©️2022 CSDN 皮肤主题:大白 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值