更改快捷键后不生效的问题
问题原因: 创建项目时选择 “使用菜单栏和工具栏”
使用这种方式创建的应用程序,会将其应用信息,如菜单等资源记录在注册表中,每次启动时从注册表加载,会忽略代码中的修改,导致出现在程序中修改了菜单却无效的问题。
如何区分项目是使用哪种菜单? “经典菜单"还是"菜单和工具栏”?
看APP继承类,“经典菜单”继承CWinApp
“菜单和工具栏”继承“”CWinAppEx
解决办法:
在App类中添加: ExitInstance 实现,如1
int CMFCApplication1App::ExitInstance() {
AfxOleTerm(FALSE);
this->CleanState(); //清空注册表信息
return CWinAppEx::ExitInstance();
}
上下文菜单
(经典菜单)
上下文菜单,或者称之为"右键菜单",这种菜单一般是在单击鼠标右键时弹出。制作弹出菜单步骤:
新建菜单资源
在应用初始化时加载菜单资源
BOOL Cdraw3View::PreCreateWindow(CREATESTRUCT& cs)
{
// TODO: 在此处通过修改
// CREATESTRUCT cs 来修改窗口类或样式
m_DrawMenu.LoadMenu(IDR_MENU1);
return CView::PreCreateWindow(cs);
}
在点击右键时显示菜单
void Cdraw3View::OnRButtonDown(UINT nFlags, CPoint point)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
CMenu* pPopup = m_DrawMenu.GetSubMenu(0);
//转换成屏幕坐标(反方向也可以转换)
ClientToScreen(&point);
pPopup->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTALIGN, point.x, point.y, this);
CView::OnRButtonDown(nFlags, point);
}
知识点:
1.屏幕坐标和客户区坐标
(菜单和工具栏)
新建项目时“菜单和工具栏”
app类中的初始化
BOOL CcontentMenuApp::InitInstance(){
...
InitContextMenuManager();
...
}
app类的PreLoadState,加载菜单资源
void CcontentMenuApp::PreLoadState()
{
BOOL bNameValid;
CString strName;
bNameValid = strName.LoadString(IDS_EDIT_MENU);
ASSERT(bNameValid);
GetContextMenuManager()->AddMenu(strName, IDR_POPUP_EDIT);
}
显示弹出菜单
void CcontentMenuView::OnContextMenu(CWnd* /* pWnd */, CPoint point)
{
#ifndef SHARED_HANDLERS
theApp.GetContextMenuManager()->ShowPopupMenu(IDR_POPUP_EDIT, point.x, point.y, this, TRUE);
#endif
}
通过代码修改菜单栏
"经典菜单"类型项目,使用代码修改菜单栏(增加,插入,删除)
int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct){
...
CMenu menu;
menu.CreateMenu();
menu.AppendMenu(MF_STRING, 111, _T("Hello"));
menu.AppendMenu(MF_STRING, 112, _T("World"));
menu.AppendMenu(MF_STRING, 113, _T("Other"));
GetMenu()->AppendMenu(MF_POPUP, (UINT)menu.m_hMenu, _T("Test"));
menu.Detach();
...
}
"使用菜单和工具栏"类型项目,修改使用代码修改菜单栏
int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct){
...
CMenu menu;
menu.CreatePopupMenu();
menu.AppendMenu(MF_STRING, ID_MSG_LINE, _T("画线"));
menu.AppendMenu(MF_STRING, ID_MSG_RECT, _T("画矩形"));
menu.AppendMenu(MF_STRING, ID_MSG_ELLIPSE, _T("画椭圆"));
menu.AppendMenu(MF_STRING, ID_MSG_PEN, _T("画笔"));
CMenu* mu = CMenu::FromHandle(GetMenuBar()->GetDefaultMenu());
mu->AppendMenu(MF_POPUP, (UINT)menu.m_hMenu, _T("Test"));
menu.Detach();
...
}
知识点: 窗口类,窗口对象,窗口
窗口类: C++类,如CWnd, CView
窗口对象: 由窗口类生成的C++对象,如CWnd对象,CView对象等
窗口: Win32底层结构:WNDCLASS, 大多用HWND(窗口句柄)表示
关系:
1.每个窗口对象都包含一个窗口
2.窗口对象使用Create方法创建窗口,在Create方法中将窗口对象与窗口进行绑定
3.窗口对象与窗口的生命周期不同,并不同生共死
MFC框架理论
关键类
CWinApp: MFC应用程序抽象,管理Document Template
CFrameWnd: 框架窗口,负责创建应用主窗口,含标题栏,菜单栏,工具栏,状态栏等
CView: 负责展示应用数据,View其实是一个没有边框的窗口, 客户区
CDocument: 负责存储应用数据
CDocTemplate:Document Template: 隐藏Boss, 负责管理MainFrame,View和Document
BOOL Cdraw3App::InitInstance(){
...
// 注册应用程序的文档模板。 文档模板
// 将用作文档、框架窗口和视图之间的连接
CSingleDocTemplate* pDocTemplate;
pDocTemplate = new CSingleDocTemplate(
IDR_MAINFRAME,
RUNTIME_CLASS(Cdraw3Doc),
RUNTIME_CLASS(CMainFrame), // 主 SDI 框架窗口
RUNTIME_CLASS(Cdraw3View));
if (!pDocTemplate)
return FALSE;
AddDocTemplate(pDocTemplate);
...
}