⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 06.5.1 动态添加子菜单的实现.txt

📁 网上第一本以TXT格式的VC++深入详解孙鑫的书.全文全以TXT格式,并每一章节都分了目录,清晰易读
💻 TXT
字号:
6.5.1 动态添加子菜单的实现
为了在窗口中显示键盘输入的文字内容,视类需要捕获 WM CHAR消息,这可以利用 ClassWizard来完成消息响应函数的添加。
另外,程序在运行时,只是在第一次输入一行文字后按下回车键时,需要在菜单栏上添加一个动态子菜单,以后只是向这个子菜单添加菜单项。这就需要为视类添加一个成员变量,用来指示当前是第几次按下回车键。
因此,我们为视类添加一个 int类型的私有成员变量: m_nIndex.并在视类构造函数中将其初始化为-1.
另外,还需要为视类增加一个 CMenu类型的成员变量 m_menu.用于创建新的子菜单使用。然后在 WM_CHAR消息响应函数中需要进行判断,只有是第一次按下回车键时,才为程序添加一个新的子菜单,具体实现代码如例 6-32所示。
例 6-32 

void CMenu2View: :OnChar(UINT nChar, UINT nRepCnt , U工 NT nFlags) { 
202 I ~~~ 


// TODO: Add your message handler code here and/or call default 
if(OxOd nChar) 
if(0++m_nIndex ) 
m_menu.CreatePopupMenu();
 GetParent()->GetMenu()->AppendMenu(MF_POPUP, (UI NT)m_menu.m_ hMenu, PhoneBook"); 
} 
} 
CView::OnChar(nChar, nRepC口t, nFlags); 

上述例6-32所示代码中,当第一次按下回车键时,首先创建一个弹出菜单,然后把这个菜单项目添加到程序的菜单栏上。这段代码中有一个问题需要注意:之前,我们都是在 CMainFrame类中调用GetMenu函数来获取程序的菜单栏指针,而视类窗口是没有菜单的,因此在视类中直接调用GetMenu函数是无法获得程序的菜单栏对象的。如果要在视类中获得属于框架类的菜单栏对象的话,首先需要利用 GetParent函数获得视类的父窗口,即框架类窗口对象,然后再调用框架类窗口对象的GetMenu函数就可以获得程序的菜单栏对象
的指针了。 
Build并运行Menu2程序,读者可以随便敲几个字符(因为这时我们还没有为Menu2程序添加显示输入字符的代码,因此,程序窗口中不会显示输入的字符),然后按下回车键,这时将会发现Menu2程序的菜单栏上并没有添加【PhoneBook】子菜单,但当我们把鼠标移动到应该显示这个子菜单的位置时,或者程序窗口的尺寸发生变化之后,这个子菜单就出现了。
为什么会出现这样的现象?为什么先前在CMainFrame类的OnCreate函数中进行的菜单操作会立即显示结果?这是因为CMainFrame类的OnCreate函数的作用是实现窗口的创建,也就是说,在调用这个函数时,程序的窗口还未创建和显示,所以在这个函数中对窗口上菜单所作的修改会立即在程序界面上呈现出来。但在窗口创建并显示完成之后,再去修改程序菜单的内容时,需要对菜单栏进行一次重绘操作才能显现修改的结果。 CWnd类提供了一个DrawMenuBar成员函数用来完成菜单栏的重绘操作。我们可以在上述例 6-32所示代码中,在添加菜单项目之后,使菜单栏进行一次重绘操作,修改后的代码如例6-33所示。
例6-33 

void CMenu2View::OnChar(UINT nChar, UINT nRepCnt , U工NT nFlags) 
// TODO: Add your message handler code here and/or call default 
if(OxOd nChar) 
if(O ++m_nIndex) 
m_menu.CreatePopupMenu(); 
GetParent()->GetMenu()->AppendMenu(MF_POPUP, (U工NT)m_menu.m_hMenu, "PhoneBook"); 
DrawMenuBar(); 
CView : :OnChar(nChar, nRepCnt , nFlags); 
Build井运行 Menu2程序,读者可以随便输入几个字符并按下回车键,将会发现程序的状态和刚才是一样的:程序的菜单栏上还是没有出现 PhoneBook于菜单,当我们把鼠标移动到应该显示这个子菜单的位置时,或者程序窗口的尺寸发生变化之后,这个子菜单就出现了。
这又是什么原因呢?阅读上述例 6-33所示代码,可以发现当前我们是在视类中调用 DrawMenuBar这个函数,前面的内容已经讲过,菜单是属于框架类窗口的,因此,应该让框架类窗口去重绘菜单栏。这样的话,在 CMenu2View类的 OnChar函数中,就应该先利用 GetParent函数获得视类的父窗口:框架类窗口,然后再利用该窗口对象去调用 DrawMenuBar函数。修改后的代码如例 6-34所示。
例 6-34 

void CMenu2View : :OnChar(UINT nChar , UINT nRepCnt , UINT nFlags) 

11  TOOO:  Add your message  handler  code here and/or  call default  
if(OxOd  nChar)  
{  
if(O  ++m_nlndex)  

m_menu.CreatePopupMenu(); 

GetParent()->GetMenu()->AppendMenu(MF_POPUP, (UINT)m_menu.m_hMenu , 
"PhoneBook" ) ; 
GetParent()->OrawMenuBar() ; } 
} 

CView: :OnChar(nChar, nRepCnt , nFlags); 
读者可以测试一下这时的 Menu2程序,当按下回车键后,将会发现程序的菜单栏上立即多了一个子菜单: PhoneBook。 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -