VS2010下对话框添加菜单栏和工具栏及其启用,禁用同步
来源:互联网 发布:javascript视频网站 编辑:程序博客网 时间:2024/06/08 18:59
VS2010下对话框添加菜单栏和工具栏及其启用,禁用同步
在对话框模式下,菜单栏和工具栏都需要我们自己手动添加。
<一>添加菜单栏
1、菜单栏的添加比较简单,只需我们创建好“菜单”资源后(即:资源视图->右键单击”XXXDlg.rc”->”添加资源”->资源类型”Menu”->”新建”)创建我们想要的菜单。
2、双击资源视图下的对话框ID->”属性”->找到”MENU”->单击下箭头找到创建好的MENU的ID->选中保存。
运行对话框,就会看到菜单栏已在对话框的顶部了。
<二>添加工具栏
1、首先我们创建工具栏(资源类型”Toolbar”)或加载事先已经准备好的工具栏来源(资源类型”Toolbar”->导入)
2、有了工具栏,那么在XXXDlg.h中,添加CToolBar类型或其派生类型的一个变量如:
(CdlgToolBar m_ToolBar),在XXXDlg.cpp中添加OnInitDialog函数中添加如下代码(最简单但不完全):
2
3
4
5
6
7
8
CBRS_TOOLTIPS/*, CRect(0,0,0,0)*/) || !m_ToolBar.LoadToolBar(IDR_TOOLBAR2) )
{
TRACE0("failed to create toolbar\n");
return FALSE;
}
RepositionBars(AFX_IDW_CONTROLBAR_FIRST, AFX_IDW_CONTROLBAR_LAST, 0); // 显示工具栏
或如下代码(完整完全自己控制):
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
// Create toolbar at the top of the dialog window
if (m_ToolBar.Create(this))
{
m_ToolBar.LoadBitmap(m_nIDBitmap);
m_ToolBar.SetButtons(m_lpaIDToolBar, m_cIDToolBar);
}
m_ToolBar.SetBarStyle(m_ToolBar.GetBarStyle() |
CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC);
// We need to resize the dialog to make room for control bars.
// First, figure out how big the control bars are.
CRect rcClientStart;
CRect rcClientNow;
GetClientRect(rcClientStart);
RepositionBars(AFX_IDW_CONTROLBAR_FIRST, AFX_IDW_CONTROLBAR_LAST,
0, reposQuery, rcClientNow);
// Now move all the controls so they are in the same relative
// position within the remaining client area as they would be
// with no control bars.
CPoint ptOffset(rcClientNow.left - rcClientStart.left,
rcClientNow.top - rcClientStart.top);
CRect rcChild;
CWnd* pwndChild = GetWindow(GW_CHILD);
while (pwndChild)
{
pwndChild->GetWindowRect(rcChild);
ScreenToClient(rcChild);
rcChild.OffsetRect(ptOffset);
pwndChild->MoveWindow(rcChild, FALSE);
pwndChild = pwndChild->GetNextWindow();
}
// Adjust the dialog window dimensions
CRect rcWindow;
GetWindowRect(rcWindow);
rcWindow.right += rcClientStart.Width() - rcClientNow.Width();
rcWindow.bottom += rcClientStart.Height() - rcClientNow.Height();
MoveWindow(rcWindow, FALSE);
// And position the control bars
RepositionBars(AFX_IDW_CONTROLBAR_FIRST, AFX_IDW_CONTROLBAR_LAST, 0);
// Set the icon for this dialog. The framework does this automatically
// when the application's main window is not a dialog
SetIcon(m_hIcon, TRUE); // Set big icon
SetIcon(m_hIcon, FALSE); // Set small icon
// Finally, center the dialog on the screen
CenterWindow();
那么,现在运行程序,就可以看到效果。
<三>菜单栏的状态(选中、打钩、禁用)改变
基于对话框的菜单栏的状态的改变需要我们自己实现,这里就可以借助单文档,多文档等的实现来给对话框设置对话框的状态改变。网上有这么这么一种方法,是可用的,:
问题描述:
在基于对话框的MFC应用应用程序中,自己给对话框建立一个菜单,想让菜单选中后,对应的菜单项前显示“对勾”或“点”,
但无法用ON_UPDATE_COMMAND_UI更新菜单。
从命令用户界面处理函数(Command UI handler)改变菜单状态(启用/禁用,选择/取消选择,更改文字)在由对话框处理时没有正常工作。
void CTestDlg::OnUpdateFileExit(CCmdUI*pCmdUI)
{
pCmdUI->SetCheck(TRUE); // 没有文字前显示选定标记.
pCmdUI->SetRadio(TRUE); // 没有在文字前显示点.
pCmdUI->SetText("Close"); //没有更改菜单文字.
}
解决如下:
原因
在下拉菜单显示的时候, WM_INITMENUPOPUP消息被先发送以显示菜单项。MFC CFrameWnd::OnInitMenuPopup函数遍历菜单项并为每个菜单项调用
更新命令处理函数(如果有的话).菜单的外观被更新以反映它的状态(启用/禁用,选择/取消选择)
更新用户界面机制在基于对话框的应用程序中不能工作,因为CDialog没有OnInitMenuPopup处理函数,而使用CWnd's默认处理函数,该函数没有为菜单项调用更新命令处理函数。
添加该处理函数,可以使用类向导来添加(即:项目->类向导->类名选”CXXXDlg”->消息里搜” WM_INITMENUPOPUP”->添加)如果消息里没有该消息,可以使用类向导类的”添加自定义消息”进行添加或进行手动添加。如:
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
Public:
//......
afx_msg void OnInitMenuPopup(CMenu* pPopupMenu, UINT nIndex, BOOL bSysMenu); // 添加
//......
DECLARE_MESSAGE_MAP()
//在CXXXDlg.cpp中
BEGIN_MESSAGE_MAP(CXXXDlg, CDialog)
//......
ON_WM_INITMENUPOPUP() // 添加
//......
END_MESSAGE_MAP()
void CXXXDlg::OnInitMenuPopup(CMenu* pPopupMenu, UINT nIndex, BOOL bSysMenu)
{
CDialog::OnInitMenuPopup(pPopupMenu, nIndex, bSysMenu);
if(!bSysMenu && pPopupMenu)
{
CCmdUI cmdUI;
cmdUI.m_pOther = NULL;
cmdUI.m_pMenu = pPopupMenu;
cmdUI.m_pSubMenu = NULL;
UINT count = pPopupMenu->GetMenuItemCount();
cmdUI.m_nIndexMax = count;
for(UINT i=0; i<count; i++)
{
UINT nID = pPopupMenu->GetMenuItemID(i);
if(-1 == nID || 0 == nID)
{
continue;
}
cmdUI.m_nID = nID;
cmdUI.m_nIndex = i;
cmdUI.DoUpdate(this, FALSE);
}
}
}
设置完上述步骤之之后,再为各个菜单项的ID分别添加ON_UPDATE_COMMAND_UI菜单命令更新机制。其中一个如:
(项目->类向导->类名选”CXXXDlg”->命令”菜单项ID”->”UPDATE_COMMAND_UI”->编辑代码)
2
3
4
5
{
// TODO: 在此添加命令更新用户界面处理程序代码
pCmdUI->Enable(TRUE);
}
在VS2010下,我开始依照MSDN的DLGcbr32例子(后面有这个例子的链接地址)来修改, 从CTooBar类中派生出一个控制条来CDlgToolBar类中,在此类中添加响应WM_IDLEUPDATECMDUI消息(参照DLGcbr32代码里的Dlgbars.h和Dlgbars.cpp)设置完上述之后,在菜单栏里就可以看到设置效果。但这时,工具栏和菜单栏并不能够做到同步,工具栏的设置还需要要一些努力。
但我的Dlg类始终不能够响应WM_IDLEUPDATECMDUI这个消息,可以在类向导中重载WindowProc函数,看能否捕捉到WM_IDLEUPDATECMDUI,如:
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
{
// TODO: 在此添加专用代码和/或调用基类
if(message == WM_IDLEUPDATECMDUI)
{
AfxMessageBox(_T("响应了WM_IDLEUPDATECMDUI消息"));
return 0;
}
// if (message == WM_KICKIDLE)
// {
// //AfxMessageBox(_T("响应了WM_KICKIDLE消息"));
// //SendMessage(WM_IDLEUPDATECMDUI, wParam, lParam);
// UpdateDialogControls(this, true);
// return 0;
// }
return CDialog::WindowProc(message, wParam, lParam);
}
通过测试,我的对话框是捕捉不到WM_IDLEUPDATECMDUI消息的,这就导致了不能在CdlgToolBar类响应WM_IDLEUPDATECMDUI自然对话框中的工具栏各选项得不到应答。所以,还好,
<四>菜单栏,工具栏(禁用,启用)同步
下面方法就不需要响应WM_IDLEUPDATECMDUI、WM_INITMENUPOPUP消息了,就可以实现菜单栏,工具栏同步。
(1)虚函数Cdialog::ContinueModal函数可以实现类似功能,重载此函数代码如下:
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
{
// TODO: 在此添加专用代码和/或调用基类
if(m_ToolBar.IsWindowVisible()) // 如果对话框有工具栏,m_ToolBar为工具栏
{
CFrameWnd* pParent = (CFrameWnd*) m_ToolBar.GetParent();
if(pParent)
m_ToolBar.OnUpdateCmdUI(pParent, (WPARAM)TRUE);
}
CMenu* pMainMenu = GetMenu(); // 如果对话框存在菜单,更新菜单
CCmdUI cmdUI;
for (UINT n = 0; n < pMainMenu->GetMenuItemCount(); ++n)
{
CMenu* pSubMenu = pMainMenu->GetSubMenu(n);
cmdUI.m_nIndexMax = pSubMenu->GetMenuItemCount();
for (UINT i = 0; i < cmdUI.m_nIndexMax;++i)
{
cmdUI.m_nIndex = i;
cmdUI.m_nID = pSubMenu->GetMenuItemID(i);
cmdUI.m_pMenu = pSubMenu;
cmdUI.DoUpdate(this, FALSE);
}
}
return CDialog::ContinueModal();
}
好了,重载了此函数之后,终于实现了工具栏与菜单栏的同步问题。
(2)还有一种实现方法就是实现WM_KICKIDLE消息消息,在WM_KICKIDLE消息的映射函数中我们可以这样写(同ContinueModal函数的实现),同样可以ContinueModal函数的功能
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
{
// 如果对话框有工具栏,m_ToolBar为工具栏
if(m_ToolBar.IsWindowVisible())
{
CFrameWnd* pParent = (CFrameWnd*) m_ToolBar.GetParent();
if(pParent)
m_ToolBar.OnUpdateCmdUI(pParent, (WPARAM)TRUE);
}
// 如果对话框存在菜单,更新菜单
CMenu* pMainMenu = GetMenu();
CCmdUI cmdUI;
for (UINT n = 0; n < pMainMenu->GetMenuItemCount(); ++n)
{
CMenu* pSubMenu = pMainMenu->GetSubMenu(n);
cmdUI.m_nIndexMax = pSubMenu->GetMenuItemCount();
for (UINT i = 0; i < cmdUI.m_nIndexMax;++i)
{
cmdUI.m_nIndex = i;
cmdUI.m_nID = pSubMenu->GetMenuItemID(i);
cmdUI.m_pMenu = pSubMenu;
cmdUI.DoUpdate(this, FALSE);
}
}
//UpdateDialogControls(this, true);
return 0;
}
更多细节详见MSDN的DLGcbr32例子:
示例介绍:http://msdn.microsoft.com/zh-cn/library/ccstww6w(v=vs.90).aspx
DlgCbr32代码:http://download.csdn.net/detail/johnnyhu90/5835135
我的测试代码:http://download.csdn.net/detail/johnnyhu90/5837561
- VS2010下对话框添加菜单栏和工具栏及其启用,禁用同步
- VS2010下对话框添加菜单栏和工具栏及其启用,禁用同步
- VS2010下对话框添加菜单栏和工具栏及其启用,禁用同步
- vs2010添加菜单栏和工具栏
- 启用和禁用工具栏按钮!
- 启用和禁用工具栏按钮!
- BGP-启用和禁用同步
- MFC基于对话框的菜单栏,工具栏和状态栏的创建
- MFC的对话框工具栏、状态栏、和菜单栏的编辑
- 添加菜单栏、工具栏按钮、状态栏,并将菜单栏和工具栏关联
- VS2010的MFC对话框程序中添加菜单栏的过程
- VS2010的MFC对话框程序中添加菜单栏的过程
- QT工具栏和菜单栏
- 菜单栏、工具栏和状态栏
- 菜单栏和工具栏-1
- 菜单栏和工具栏-2
- 使用Qt designer 向菜单栏和工具栏添加action
- VC 实现菜单项及工具栏按钮同步禁用与启用
- WCF身份验证之用户名密码认证
- Spring学习(五)OpenSessionInView
- 摩拜单车
- hive: command not found错误解决
- selenium学习笔记(一)
- VS2010下对话框添加菜单栏和工具栏及其启用,禁用同步
- selenium+jenkins网页自动化测试的构建
- Ajax GET请求
- jface databinding:使用CheckboxTableViewer实现表中(Set)对象与CheckTable中选中条目数据绑定
- 计算机网络(谢希仁第六版)3-24和3-25整理
- request.getSession(false)和request.getSession(true)用法区别
- linux下串口编程简单实例
- adb server version (31) doesn’t match this client (36); killing… * daemon started successfully *
- 友盟分享简单集成和常见问题解决