MFC文档视图结构中缺省的命令处理
孙鑫MFC视频 笔记
/*CDC *pDC=GetDC();
pDC->MoveTo(m_ptOrigin);
pDC->LineTo(point);
ReleaseDC(pDC);必须成对使用。*/
//CClientDC dc(this);
/*CClientDC dc(GetParent());
3)用CClientDC
4)用CWindowDC,用它甚至可以整个屏幕区域画线。
下面是上面4种方法的代码
/*HDC hdc;
hdc=::GetDC(m_hWnd);
MoveToEx(hdc,m_ptOrigin.x,m_ptOrigin.y,NULL);
LineTo(hdc,point.x,point.y);
12.GetDC()与ReleaseDC()要成对使用,否则会内存泄漏。同样,BeginPaint()与EndPaint()。
13.GetStockObject()得到画笔、画刷、字体、调色板的句柄,使用时必须用类型转换。
14.什么时候用NULL,什么时候用0.答,对指针赋值时用NULL,对变量赋值时用0.
}
而在BOOL CTestApp::InitInstance()中的代码
CSingleDocTemplate* pDocTemplate;
pDocTemplate = new CSingleDocTemplate(
IDR_MAINFRAME,
RUNTIME_CLASS(CTestDoc),
dc.MoveTo(m_ptOrigin);
dc.LineTo(point);此处不需要ReleaseDC,因为CClientDC会自动释放DC*/
mfc面试题
mfc面试题MFC(Microsoft Foundation Classes)是微软公司开发的一套C++类库,用于进行Windows应用程序的开发。
MFC面试题主要涉及MFC框架的基本概念、使用方法和相关编程技巧。
以下将以问题和答案的形式介绍几个常见的MFC面试题。
问题1:MFC是什么?它的作用是什么?答:MFC全称为Microsoft Foundation Classes,是微软在VisualC++中提供的一组类库。
它的作用是封装了Windows操作系统的API,简化了Windows应用程序的开发过程。
通过使用MFC,开发人员可以更加方便地创建图形界面、响应用户操作和调用系统功能。
问题2:MFC的架构是怎样的?答:MFC的架构可以分为三层:应用程序层、框架层和操作系统层。
应用程序层是开发人员编写的具体应用程序代码,包括窗口类、对话框类、消息处理函数等。
框架层是MFC提供的类库,包括CWinApp、CFrameWnd、CView等类,用于管理应用程序的生命周期、创建主窗口、处理消息等。
操作系统层是Windows操作系统提供的API,MFC通过封装这些API,以提供更高层次的抽象和易用性。
问题3:如何创建一个MFC应用程序?答:创建MFC应用程序的步骤如下:1. 打开Visual Studio,选择创建新项目。
2. 选择Visual C++ -> MFC -> MFC应用程序。
3. 输入项目名称,选择保存位置,点击确定。
4. 在向导中选择应用程序类型(单文档、多文档、对话框等)、界面风格和其他选项。
5. 点击完成,Visual Studio将自动生成一个基本的MFC应用程序框架。
问题4:如何处理MFC中的消息?答:MFC中的消息处理通过消息映射表和消息处理函数完成。
首先,需要在类声明中使用`DECLARE_MESSAGE_MAP()`宏来声明消息映射表。
然后,在类实现中使用`BEGIN_MESSAGE_MAP`和`END_MESSAGE_MAP`宏来定义消息映射表的起止位置。
MFC中CEdit类使用方法小结
CEdit类提供了Windows编辑控件中的功能。
编辑控件是一个子窗口矩形,用户可以向其中输入文本。
可以通过对话模板或直接从代码中创建一个编辑控件。
在两种情形下,首先调用CEdit构造程序构造CEdit对象,再调用Create成员函数创建Windows编辑控件并将其与CEdit对象连接。
构造在CEdit的派生类中可以单步实现。
为派生类编写构造程序并从构造程序中调用Create。
CEdit从CWnd继承了重要的功能,要在CEdit对象中设置或获取文本,使用CWnd成员函数SetWindowText和GetWindowText,可以设置和得到编辑控件的全部内容,即使它是一个多行控件。
如果编辑控件是多行的,使用CEdit成员函数GetLine,GetSel,GetSel和ReplaceSel 来获取和写入控件的部分文本。
如果要处理编辑控件发往其父类(通常是一个CDialog派生类)的通知消息,则向父类中为每一消息添加一个消息映射入口和消息处理成员函数。
各消息映射入口可采用如下形式:ON_Notification(id,memberFxn)其中id指定了发送通知的编辑控件的子窗口ID,memberFxn为你写好的处理通知的父成员函数的名字。
父函数形式如下:afx_msgvoidmemberFxn();下面是一组可能的消息映射入口,以及在何种情况下向父类发送的描述:ON_EN_CHANGE?????用户采取的行动可能会改变编辑控件的文本。
与EN_UPDATE通知消息不同,该通知是在?????????????????Windows更新显示之后发送的。
ON_EN_ERRSPACE???编辑控件不能为特定请求分配足够的空间。
ON_EN_HSCROLL????用户单击了编辑控件中的水平滚动条,父窗口在屏幕更新之前被通知。
ON_EN_KILLFOCUS??编辑控件失去输入焦点。
ON_EN_MAXTEXT????当前输入超过了为编辑控件指定的数目,并作截尾处理。
关于MFC的有些知识
关于MFC的有些知识实验⼀1、在VC++中,⼯程与各种源⽂件之间是什么关系?解答:⼯程的实质是⼀些相互关联的源⽂件的集合,可以把项⽬理解成⼀个⼯作任务, 开发环境中,⼯程包含在⼯作区间中,⼀个⼯作区可以管理多个⼯程2、⼀个VC++⼯程下会有3个⽂件夹,这3个⽂件夹分别是什么?以.cpp为后缀的⽂件会添加到哪个⽂件夹中?以.h为后缀⽂件会添加到哪个⽂件夹中?解答:分别是head Files ,Sourse Files, Resourse Files ,.cpp放在Sourse ⽂件⾥⾯,.h放在Head Files⽂件⾥3,以win32 console application⼯程为例,简述⼯程的建⽴,⽂件的添加,⼯程的编译和链接及⼯程的执⾏过程。
解答:这个就是win32 console application⼯程的实例验证过程。
实验⼆1.简述Windows应⽤程序的特点。
解答:⼀.事件驱动的程序设计它是⼀种“被动”式程序设计⽅法,程序开始运⾏时,处于等待⽤户输⼊事件状态,然后取得事件并作出相应反应,处理完毕⼜返回并处于等待事件状态。
⼆. 消息循环与输⼊消息是⼀种报告有关事件发⽣的通知。
· 事件驱动是靠消息循环机制来实现的。
· Windows应⽤程序的消息来源有以下四种:(1)输⼊消息(2)控制消息(3)系统消息(4)⽤户消息三. 图形输出Windows程序的所有输出都是图形,字符也被作为图形来处理。
· GDI提供两种基本服务:创建图形输出和存储图象。
· 绘图函数分为三类:⼀是⽂字输出;⼆是⽮量图形函数,⽤于画线、圆等⼏何图形;三是光栅(位图)图形函数,⽤于绘制位图。
四. ⽤户界⾯对象⽤户界⾯对象:窗⼝边框系统菜单框标题栏菜单栏⼯具条客户区垂直滚动条和⽔平滚动条状态栏图标光标插⼊符对话框控件消息框五.资源共享· 常见的资源包括:设备上下⽂,画刷,画笔,字体,对话框控制,对话框,图标,定时器,插⼊符号,通信端⼝,电话线等。
MFC多文档多视图编程
深入了解MFC中的文挡/视结构李泽宇金刚熊联欢姜军(华中理工大学图象识别与人工智能研究所)Visual C++ 5.0 以其功能强大、用户界面友好而倍受程序员们的青睐。
但是,在当前的Microsoft 基本类库4.2 版本中,大约有将近200 个类,数千个函数,加之Microsoft 公司隐藏了一些技术细节,使得人们深入学习MFC变得十分困难。
MFC的AppWizard可以生成三种类型的应用程序:基于对话框的应用、单文档应用(SDI)和多文档应用(MDI)。
前两者的结构较简单,本文不再赘叙。
笔者拟从MFC中的文档/视结构入手,分析一些函数的流程,并解决编制MDI 应用程序过程中的一些常见问题。
(一)、了解文档/视结构MFC应用程序模型历经多年以有了相当大的发展。
有一个时期,它只是个使用应用程序对象和主窗口对象的简单模型。
在这个模型中,应用程序的数据作为成员变量保持在框架窗口类中,在框架窗口的客户区中,该数据被提交显示器。
随着MFC2。
0的问世,一种应用程序结构的新方式----MFC文档/视结构出现了。
在这种结构中,CFrameWnd繁重的任务被委派给几个不同类,实现了数据存储和显示的分离。
一般情况下,采用文档/视结构的应用程序至少应由以下对象组成:。
应用程序是一个CwinApp派生对象,它充当全部应用程序的容器。
应用程序沿消息映射网络分配消息给它的所有子程序。
框架窗口是一CfrmeWnd派生对象。
文档是一个CDocument派生对象,它存储应用程序的数据,并把这些信息提供给应用程序的其余部分。
视窗是Cview派生对象,它与其父框架窗口用户区对齐。
视窗接受用户对应用程序的输入并显示相关联的文档数据。
通常,应用程序数据存在于简单模型中的框架窗口中。
在文档/视方式中,该数据移入称为document 的独立数据对象。
当然,文档不一定是文字,文档是可以表现应用程序使用的数据集的抽象术语。
而用户输入处理及图形输出功能从框架窗口转向视图。
MFC使用教程范文
MFC使用教程范文MFC(Microsoft Foundation Classes)是微软公司为Windows操作系统开发的一套面向对象的应用程序框架,用于简化Windows应用程序的开发过程。
MFC提供了一系列的类和函数,开发者可以利用这些类和函数来创建、管理和控制Windows应用程序。
本文将为您介绍MFC的基本使用方法和步骤。
一、MFC的基本概念和组成MFC是建立在Windows API之上的一层封装,它提供了一系列的类和函数,开发者可以利用这些封装好的类和函数来开发Windows应用程序。
MFC的组成包括:应用程序类、窗口类、对话框类和视图类。
1.应用程序类:MFC的应用程序类是整个应用程序的入口点,它包含了应用程序的初始化和销毁过程,以及主消息循环。
2.窗口类:窗口类用于创建和管理应用程序中的窗口,包括主窗口、子窗口和对话框等。
3.对话框类:对话框类用于创建和管理应用程序中的对话框,对话框是一种特殊的窗口,用于和用户进行交互。
4.视图类:视图类用于创建和管理应用程序中的视图,视图是应用程序中显示数据的区域。
二、MFC应用程序的创建步骤下面将介绍MFC应用程序的创建步骤。
1. 打开Visual Studio IDE,并选择"创建新项目"。
2.在"创建新项目"对话框中,选择"C++"->"MFC",点击"下一步"。
3.在"应用程序信息"对话框中,填写应用程序的名称和位置等信息,点击"完成"。
4. Visual Studio将自动创建一个MFC应用程序模板,并打开主窗口的代码和界面文件。
5.在主窗口的代码文件中,可以编写处理消息和事件的代码。
6.在主窗口的界面文件中,可以通过拖拽控件来设计应用程序的界面。
7.编译并运行应用程序,查看效果。
三、MFC应用程序的消息处理MFC应用程序中的消息处理是通过重载消息处理函数来实现的。
MFC文档视图结构中缺省的命令处理
MFC文档视图结构中缺省的命令处理文档视图结构中,缺省的命令处理在文档视图结构所构建的框架中,很多命令ID都有缺省的命令处理。
很多功能都由他们完成,但这些功能在程序中不“可见”,不便于对程序的理解。
以下归纳了常见的缺省处理及其流程在需要时候,可以重载这些函数以实现特定功能1.ID_FILE_NEW2.ID_FILE_OPEN3.ID_FILE_SAVE4.ID_FILE_SAVE_AS5.ID_FILE_SAVE_COPY_AS6.ID_FILE_CLOSE7.ID_FILE_UPDATE8.ID_FILE_PRINT_SETUP9.ID_FILE_PRINT10.ID_FILE_PRINT_PREVIEW11.缺省编辑控制ID12.ID_WINDOW_NEW13.ID_WINDOW_ARRANGE14.ID_WINDOW_CASCADE15.ID_WINDOW_TILE_HORZ16.ID_WINDOW_TILE_VERT17.ID_WINDOW_SPLIT18.ID_APP_ABOUT19.ID_APP_EXIT20.ID_HELP_INDEX21.ID_HELP_USING22.ID_CONTEXT_HELP23.ID_HELP24.ID_DEFAULT_HELP25.ID_NEXT_PANE26.ID_PREV_PANE27.ID_OLE_INSERT_NEW28.ID_OLE_EDIT_LINKS29.ID_VIEW_TOOLBAR30.ID_VIEW_STATUS_BAR1.ID_FILE_NEWCWinApp::OnFileNew调用m_pDocManager->OnFileNew()void CDocManager::OnFileNew(){if (m_templateList.IsEmpty()){TRACE0("Error: no document templates registered with CWinApp.\n");AfxMessageBox(AFX_IDP_FAILED_TO_CREATE_DOC);return;}CDocTemplate* pTemplate = (CDocTemplate*)m_templateList.GetHead();//如果含有多个文档模板,显示一个新建文档类型对话框if (m_templateList.GetCount() > 1){// more than one document template to choose from // bring up dialog prompting userCNewTypeDlg dlg(&m_templateList);int nID = dlg.DoModal();if (nID == IDOK)pTemplate = dlg.m_pSelectedTemplate;elsereturn; // none - cancel operation}ASSERT(pTemplate != NULL);ASSERT_KINDOF(CDocT emplate, pTemplate);//建立空文件pTemplate->OpenDocumentFile(NULL);// if returns NULL, the user has already been alerted }2.ID_FILE_OPENCWinApp::OnFileOpen调用m_pDocManager->OnFileOpen()void CDocManager::OnFileOpen(){//出现打开文件对话框文件取得文件名CString newName;if (!DoPromptFileName(newName, AFX_IDS_OPENFILE,OFN_HIDEREADONLY | OFN_FILEMUSTEXIST, TRUE, NULL)) return;//使用OpenDocumentFileAfxGetApp()->OpenDocumentFile(newName);// if returns NULL, the user has already been alerted}3.ID_FILE_SAVECDocument::OnFileSave()调用DoFileSave()void CDocument::OnFileSave(){DoFileSave();}DoFileSave()又将调用DoSave()BOOL CDocument::DoFileSave(){DWORD dwAttrib = GetFileAttributes(m_strPathName);//如果文件是只读,或已经不存在了if (dwAttrib & FILE_ATTRIBUTE_READONLY){//使用带NULL参数的DoSaveif (!DoSave(NULL)){TRACE0("Warning: File save with new name failed.\n"); return FALSE;}}else{//使用DoSave(....)if (!DoSave(m_strPathName)){TRACE0("Warning: Filesave failed.\n");return FALSE;}}return TRUE;}DoSave()的实现BOOL CDocument::DoSave(LPCTSTR lpszPathName, BOOL bReplace)//如果文件名参数为空,则让用户取名// note: lpszPathName can be different than 'm_strPathName'{CString newName = lpszPathName;if (newName.IsEmpty()){CDocTemplate* pT emplate = GetDocTemplate();ASSERT(pTemplate != NULL);newName = m_strPathName;if (bReplace && newName.IsEmpty()){newName = m_strTitle;// check for dubious filenameint iBad = newName.FindOneOf(_T(" #%;/\\"));if (iBad != -1)newName.ReleaseBuffer(iBad);// append the default suffix if there is oneCString strExt;if (pTemplate->GetDocString(strExt, CDocTemplate::filterExt) &&!strExt.IsEmpty()){ASSERT(strExt[0] == '.');newName += strExt;}}//"保存为"对话框if (!AfxGetApp()->DoPromptFileName(newName,bReplace ? AFX_IDS_SAVEFILE : AFX_IDS_SAVEFILECOPY,OFN_HIDEREADONLY | OFN_PATHMUSTEXIST, FALSE, pTemplate))return FALSE; // don't even attempt to save}CWaitCursor wait;//保存,由OnSaveDocument完成if (!OnSaveDocument(newName)){if (lpszPathName == NULL){// be sure to delete the fileTRY{CFile::Remove(newName);}CATCH_ALL(e){TRACE0("Warning: failed to delete file \n");DELETE_EXCEPTION(e);}END_CATCH_ALL}return FALSE;}// reset the title and change the document nameif (bReplace)SetPathName(newName);return TRUE; // success}使用了文档类的OnSaveDocument完成保存动作BOOL CDocument::OnSaveDocument(LPCTSTR lpszPathName){CFileException fe;CFile* pFile = NULL;pFile = GetFile(lpszPathName, CFile::modeCreate |CFile::modeReadWrite | CFile::shareExclusive, &fe);if (pFile == NULL){ReportSaveLoadException(lpszPathName, &fe,TRUE, AFX_IDP_INVALID_FILENAME);return FALSE;}//建立保存用的CArchiveCArchive saveArchive(pFile, CArchive::store | CArchive::bNoFlushOnDelete);saveArchive.m_pDocument = this;saveArchive.m_bForceFlat = FALSE;TRY{CWaitCursor wait;//使用文档类的序列化操作完成实际存档行为Serialize(saveArchive); // save mesaveArchive.Close();ReleaseFile(pFile, FALSE);}CATCH_ALL(e){ReleaseFile(pFile, TRUE);TRY{ReportSaveLoadException(lpszPathName, e,TRUE, AFX_IDP_FAILED_TO_SAVE_DOC);}END_TRYDELETE_EXCEPTION(e);return FALSE;}END_CATCH_ALLSetModifiedFlag(FALSE); // back to unmodifiedreturn TRUE; // success}4.ID_FILE_SAVE_ASCDocument::OnFileSaveAs()具体实现:调用NULL参数的DoSave(..)void CDocument::OnFileSaveAs(){if (!DoSave(NULL))TRACE0("Warning: File save-as failed.\n"); }5.ID_FILE_SAVE_COPY_ASThe COleServerDoc::OnFileSaveCopyAs 6.ID_FILE_CLOSECDocument::OnFileClosevoid CDocument::OnFileClose(){//保存内容if (!SaveModified())return;//关闭文档OnCloseDocument();}如果需要保存,调用DoFileSave(..)BOOL CDocument::SaveModified(){//没有改动if (!IsModified())return TRUE;//得到文件名CString name;if (m_strPathName.IsEmpty()){// get name based on captionname = m_strTitle;if (name.IsEmpty())VERIFY(name.LoadString(AFX_IDS_UNTITLED));}else{// get name based on file title of path namename = m_strPathName;if (afxData.bMarked4){AfxGetFileTitle(m_strPathName,name.GetBuffer(_MAX_PATH), _MAX_PATH);name.ReleaseBuffer();}}CString prompt;AfxFormatString1(prompt, AFX_IDP_ASK_TO_SAVE, name); //对话框:文件已被改动,是否保存switch (AfxMessageBox(prompt, MB_YESNOCANCEL, AFX_IDP_ASK_TO_SAVE)){case IDCANCEL:return FALSE; // don't continuecase IDYES://保存文件if (!DoFileSave())return FALSE; // don't continuebreak;case IDNO:// If not saving changes, revert the documentbreak;default:ASSERT(FALSE);break;}return TRUE;}7.ID_FILE_UPDATECOleServerDoc::OnUpdateDocument8.ID_FILE_PRINT_SETUPCWinApp::OnFilePrintSetup9.ID_FILE_PRINTCView::OnFilePrint10.ID_FILE_PRINT_PREVIEW CView::OnFilePrintPreview 11.缺省编辑控制IDID_EDIT_CLEARID_EDIT_CLEAR_ALLID_EDIT_COPYID_EDIT_CUTID_EDIT_FINDID_EDIT_PASTEID_EDIT_PASTE_LINKID_EDIT_PASTE_SPECIAL ID_EDIT_REPEATID_EDIT_REPLACEID_EDIT_SELECT_ALLID_EDIT_UNDOID_EDIT_REDO这些ID在对应的编辑视中有相应处理函数12.ID_WINDOW_NEWCMDIFrameWnd::OnWindowNewvoid CMDIFrameWnd::OnWindowNew(){//找到当前窗口,得到对应文档模板,使用文档模板的成员CreateNewFrame建立新窗口CMDIChildWnd* pActiveChild = MDIGetActive();CDocument* pDocument;if (pActiveChild == NULL ||(pDocument = pActiveChild->GetActiveDocument()) == NULL){TRACE0("Warning: No active document for WindowNew command.\n");AfxMessageBox(AFX_IDP_COMMAND_FAILURE);return; // command failed}// otherwise we have a new frame !CDocTemplate* pTemplate = pDocument->GetDocT emplate();ASSERT_VALID(pTemplate);CFrameWnd* pFrame = pTemplate->CreateNewFrame(pDocument, pActiveChild);if (pFrame == NULL){TRACE0("Warning: failed to create new frame.\n");return; // command failed}pTemplate->InitialUpdateFrame(pFrame, pDocument);}13.ID_WINDOW_ARRANGEID_WINDOW_ARRANGE,以及ID_WINDOW_CASCADE、ID_WINDOW_TILE_HORZ、ID_WINDOW_TILE_VERT都由OnMDIWindowCmd()处理OnMDIWindowCmd将相应消息发送给m_hWndMDIClientBOOL CMDIFrameWnd::OnMDIWindowCmd(UINT nID){ASSERT(m_hWndMDIClient != NULL);UINT msg;UINT wParam = 0;switch (nID){default:return FALSE; // not for uscase ID_WINDOW_ARRANGE:msg = WM_MDIICONARRANGE;break;case ID_WINDOW_CASCADE:msg = WM_MDICASCADE;break;case ID_WINDOW_TILE_HORZ:wParam = MDITILE_HORIZONTAL;// fall throughcase ID_WINDOW_TILE_VERT:ASSERT(MDITILE_VERTICAL == 0);msg = WM_MDITILE;break;}::SendMessage(m_hWndMDIClient, msg, wParam, 0); return TRUE;}14.ID_WINDOW_CASCADE参见ID_WINDOW_ARRANGE15.ID_WINDOW_TILE_HORZ参见ID_WINDOW_ARRANGE16.ID_WINDOW_TILE_VERT参见ID_WINDOW_ARRANGE17.ID_WINDOW_SPLITCSplitterWnd::DoKeyboardSplit用键盘控制分割窗口BOOL CSplitterWnd::DoKeyboardSplit(){ASSERT_VALID(this);int ht;if (m_nRows > 1 && m_nCols > 1)ht = splitterIntersection1; // split existing row+colelse if (m_nRows > 1)ht = vSplitterBar1; // split existing rowelse if (m_nCols > 1)ht = hSplitterBar1; // split existing colelse if (m_nMaxRows > 1 && m_nMaxCols > 1)ht = bothSplitterBox; // we can split bothelse if (m_nMaxRows > 1)ht = vSplitterBox; // we can split rowselse if (m_nMaxCols > 1)ht = hSplitterBox; // we can split columnselsereturn FALSE; // can't split// start trackingStartTracking(ht);CRect rect;rect.left = m_rectTracker.Width() / 2;rect.top = m_rectTracker.Height() / 2;if (m_ptTrackOffset.y != 0)rect.top = m_rectTracker.top;if (m_ptTrackOffset.x != 0)rect.left = m_bTracking2 ? m_rectTracker2.left :m_rectTracker.left;rect.OffsetRect(-m_ptTrackOffset.x, -m_ptTrackOffset.y);ClientToScreen(&rect);SetCursorPos(rect.left, rect.top);return TRUE;}18.ID_APP_ABOUT建立CWinApp::OnAppAbout();19.ID_APP_EXITCWinApp::OnAppExit直接向主窗口发送WM_CLOSE消息void CWinApp::OnAppExit(){// same as double-clicking on main window close box ASSERT(m_pMainWnd != NULL);m_pMainWnd->SendMessage(WM_CLOSE);}20.ID_HELP_INDEXCWinApp::OnHelpIndex21.ID_HELP_USINGCWinApp::OnHelpUsing22.ID_CONTEXT_HELPCWinApp::OnContextHelp23.ID_HELPCWinApp::OnHelp24.ID_DEFAULT_HELPCWinApp::OnHelpIndex25.ID_NEXT_PANECSplitterWnd::OnNextPaneCmd26.ID_PREV_PANECSplitterWnd::OnNextPaneCmd27.ID_OLE_INSERT_NEW28.ID_OLE_EDIT_LINKS29.ID_VIEW_TOOLBAR切换AFX_IDW_TOOLBAR工具条消息映射ON_UPDATE_COMMAND_UI(ID_VIEW_TOOLBAR, OnUpdateControlBarMenu)ON_COMMAND_EX(ID_VIEW_TOOLBAR, OnBarCheck)BOOL CFrameWnd::OnBarCheck(UINT nID){ASSERT(ID_VIEW_STATUS_BAR == AFX_IDW_STATUS_BAR);ASSERT(ID_VIEW_TOOLBAR == AFX_IDW_TOOLBAR);ASSERT(ID_VIEW_REBAR == AFX_IDW_REBAR);CControlBar* pBar = GetControlBar(nID);if (pBar != NULL){//设置该工具条状态ShowControlBar(pBar, (pBar->GetStyle() & WS_VISIBLE) == 0, FALSE);return TRUE;}return FALSE;}void CFrameWnd::OnUpdateControlBarMenu(CCmdUI* pCmdUI){ASSERT(ID_VIEW_STATUS_BAR == AFX_IDW_STATUS_BAR);ASSERT(ID_VIEW_TOOLBAR == AFX_IDW_TOOLBAR);ASSERT(ID_VIEW_REBAR == AFX_IDW_REBAR);CControlBar* pBar = GetControlBar(pCmdUI->m_nID);if (pBar != NULL){pCmdUI->SetCheck((pBar->GetStyle() & WS_VISIBLE) != 0);return;}pCmdUI->ContinueRouting();}30.ID_VIEW_STATUS_BAR实现方法与ID_VIEW_TOOLBAR相同上一页下一页。
MFC中文件菜单命令缺省处理流程剖析
MFC中文件菜单命令缺省处理流程剖析
徐志波
【期刊名称】《电脑编程技巧与维护》
【年(卷),期】2000(000)011
【摘要】MFC引入的文档-视结构,极大地便利了我们的编程。
不过很多时候,它并不能完全满足我们的需要,此时就要我们自己去对它作一些改造。
然而微软的文档对许多细节并没有涉及。
作者对MFC源代码作了一番钻研,将获得的一些经验与大家共享。
本文的内容主要是对“文件”菜单中的各菜单命令
ID_FILE_NEW,ID_FILE_OPEN,ID_FILE_SAVE,ID_FILE_SAVEAS,ID_FILE_CLOSE 的缺省处理作一番剖析,并在此基础上给出一个改进。
ID_FILE_NEW和
ID_FILE_OPEN的缺省处理由CWinApp进行。
【总页数】3页(P7-9)
【作者】徐志波
【作者单位】无
【正文语种】中文
【中图分类】TP311.1
【相关文献】
1.在MFC应用程序中浏览PDF、Word文档文件 [J], 郎锐
2.MFC中通用文件对话框的定制 [J], 陈静;郑浩斌
3.MFC中的文件操作 [J], 盖素丽;辛凤艳
4.翻译中的文化缺省剖析 [J], 张耘
5.在MFC应用程序中浏览PDF、Word文档文件 [J], 郎锐
因版权原因,仅展示原文概要,查看原文内容请购买。
mfc课后习题答案
mfc课后习题答案MFC课后习题答案在学习过程中,课后习题是一种非常重要的辅助学习方法。
通过完成课后习题,我们可以巩固所学知识,加深对概念和原理的理解,并且提高解决问题的能力。
然而,有时候我们可能会遇到一些难题,无法得到正确的答案。
在这篇文章中,我将分享一些关于MFC课后习题的答案,希望对大家的学习有所帮助。
首先,我们先来回顾一下MFC的基本概念和原理。
MFC,即Microsoft Foundation Class,是微软公司开发的一套用于Windows操作系统的应用程序框架。
它提供了一系列的类和函数,用于简化Windows程序的开发过程。
MFC的核心是C++类库,它通过封装Windows API,使得开发者可以更加方便地创建图形用户界面(GUI)应用程序。
接下来,我们来看一些常见的MFC课后习题。
1. 什么是MFC的文档视图模型?答案:MFC的文档视图模型是一种软件设计模式,用于将数据和用户界面分离。
在MFC中,文档表示应用程序的数据,视图表示数据的可视化呈现方式。
模型则是文档和视图之间的桥梁,用于协调数据的读取、修改和显示。
2. 如何创建一个MFC应用程序?答案:要创建一个MFC应用程序,首先需要打开Visual Studio开发环境。
然后,选择“新建项目”,在模板中选择“MFC应用程序”。
接下来,按照向导的指引,设置应用程序的名称、保存位置和其他选项。
最后,点击“完成”按钮,Visual Studio将自动生成一个基本的MFC应用程序框架。
3. 如何在MFC应用程序中添加一个按钮?答案:要在MFC应用程序中添加一个按钮,首先需要在资源视图中找到对应的对话框资源。
然后,双击打开对话框资源编辑器。
在编辑器中,选择“按钮”工具,然后在对话框上拖动鼠标,绘制一个按钮的形状。
接下来,可以通过属性窗口设置按钮的文本、大小和其他属性。
最后,保存并关闭对话框资源编辑器,即可在应用程序中看到添加的按钮。
4. 如何处理MFC应用程序中的按钮点击事件?答案:要处理MFC应用程序中的按钮点击事件,首先需要在对话框资源编辑器中选择按钮,然后右键点击按钮,选择“添加事件处理程序”。
MFC使菜单项变灰
}
mfc中缺省的习惯是当没有updatecmdui句柄时程序是使能enable菜单菜单自动变成使能只要关掉缺省值就可以了把下面的代码加入你的程序
MFC使菜单项变灰
一、没有UpdateCmdUI句柄时
MFC中缺省的习惯是当没有UpdateCmdUI句柄时程序是使能(Enable)菜单,菜单自动变成使能,只要关掉缺省值就可以了,把下面的代码加入你的Байду номын сангаас序
CMainFrm::CMainFrm
{
// Other stuff
this->m_bAutoMenuEnable = false;
}
然后在消息响应函数中添加如下代码:
CMenu* m_menu = GetMenu();
CMenu* submenu = m_menu->GetSubMenu(0);
submenu->EnableMenuItem(ID_FILE_NEW, MF_BYCOMMAND | MF_GRAYED);
一、有UpdateCmdUI句柄时
在框架中添加菜单ID的ON_UPDATE_COMMAND_UI消息,在相应函数参数中会有“CCmdUI* pCmdUI”这个参数,添加如下代码:
pCmdUI->Enable(false);
就可是这个菜单变灰显
GetDlgItem(ID_PASTE)->EnableWindow(FALSE);
CMenu menu;
if(menu.LoadMenu(IDR_XXX_MENU))
{
CPoint m_point;
::GetCursorPos(&m_point);
mfc ctreeview用法
mfc ctreeview用法MFC CTreeView 是Microsoft Foundation Classes(MFC)中的一个类,用于创建和管理树形视图控件。
树形视图控件是一种常用的界面控件,它通常用于展示层级结构的数据,如文件系统,项目组织或数据库表等。
在本文中,我们将一步一步介绍如何使用MFC CTreeView 创建和管理树形视图控件,包括创建视图类,初始化树形视图,添加节点,展开和折叠节点以及响应节点的选择事件等。
第一步:创建视图类首先,在MFC 应用程序中创建一个新的视图类,以用于展示树形视图控件。
可以使用Visual Studio IDE 中的“添加类”功能来创建视图类。
确保选择“CFormView”为基类,并为视图类命名,例如“CTreeViewDemoView”。
第二步:添加树形视图控件到视图中在视图类的头文件中声明一个CTreeView 对象,以用于管理树形视图控件。
可以使用类向导或手动添加以下代码:cppclass CTreeViewDemoView : public CFormView{...CTreeView m_treeView;...};然后,在视图类的初始化过程中,创建树形视图控件并将其添加到视图中。
可以在OnInitialUpdate 方法中添加以下代码:cppvoid CTreeViewDemoView::OnInitialUpdate(){CFormView::OnInitialUpdate();初始化树形视图控件CRect rect;GetClientRect(&rect);m_treeView.Create(WS_VISIBLE WS_CHILD TVS_HASLINES TVS_LINESATROOT TVS_HASBUTTONS, rect, this, 0);...}第三步:初始化树形视图在树形视图控件创建并添加到视图中后,我们需要初始化树形视图的数据。
MFC教程
01章用向导创建文档窗口MFC教程是小雅最怕写的内容,除了水平问题之外,还有一点就是,MFC将许多程序封装起来,使众多程序员在编程时,即使编出了程序,也不知究竟为什么这样就可以了。
这一现象使小雅想到当今的Java程序员,许多人在开发外包项目时,因为整个FrameWork已经建成,自己只是担当其中一部分功能,出了BUG之后,找原因非常困难。
在SDK教程中,小雅将各种功能进行详细解说,而MFC教程中,只是用例子来讲解MFC的原理,学会原理之后,就会感到MFC比SDK编程省了许多事。
小雅在SDK教程中,为了讲明API功能,用的方法都是C语言的方法,而MFC用的全是C++的内容,因此,学习MFC必须对C++有较深的了解,不会C语言、C++语言而能够学会MFC的人只能是吹牛。
小雅的“C语言教程”和“C++语言教程”都是按照标准C/C++来写的,在Unix、Linux、Windows都适用,这是很重要的基础。
SDK教程主要是让初学者明白WindowsAPI的功能,以及程序的实现方法,基本上是“C语言+ API”,而MFC基本上是“C++ + API”。
SDK编程和MFC是可以相互转化,相互调用的,因为MFC 封装了绝大部分API,但不是所有的API函数。
注意:SDK并不是只能用C语言来写,用C++一样编程,小雅在作教程时为了把内容说清楚,同时兼顾不会C++的人员才使用C语言。
对于初学者,小雅建议在C/C++的基础上用MFC来编程,一是省去了很多编程,二是用上了C++的面向对象编程的思想。
当今要找一个C++的项目来一边做一边学是很困难的。
小雅自己也一直想找一个C++的工作而未能如愿。
通过学习MFC 再反过来加强一下学的不是很深的C++,不是很好的一个方法吗?不过,MFC和SDK与C/C++不同点在消息事件处理方面,初学者要学会这一内容。
关于“”有“托管”和“非托管”二种编程方式,小雅的SDK教程和MFC教程全部是“非托管”编程,也就是传统编程。
mfc中字体设置详解
mfc中字体设置详解展开全文为了能选用不同的字体和大小来输出文本串,须使用作为GDI对象的 CFont类。
Windows和常用的字处理软件(如Word)、绘图软件(如CorelDraw)等应用软件会提供多种与设备无关的字体,主要是TrueType轮廓字体。
CFont类是CGDIObject的派生类:CObject→ CGDIObject→ CFont。
只有一个缺省构造函数CFont( );在CFont类中,必须用字体创建成员函数CreateFont[Indirect]或CreatePointFont [Indirect]来初始化。
其中的CreatePointFont提供了创建字体的一种简单方法:BOOL CreatePointFont( int nPointSize, LPCTSTR lpszFaceName, CDC* pDC = NULL );参数nPointSize为字体的大小,以0.1点(像素/墨点/磅数)为单位,如汉字的字号与nPointSize值及磅数的对应关系见下表:参数lpszFaceName为字体名称字符串的指针。
若pDC非空,则系统会将设备单位点自动转换为pDC中的映射模式所指定的逻辑单位,如CFont font;font.CreatePointFont(160, '宋体');注意:CFont类的这些逻辑字体创建函数,并不是从无到有创建一个新的GDI字体,而只是从GDI的物理字体库中选择与所设置参数最匹配的字体。
为了方便用户选择各种字体参数,可使用字体公用对话框:汉字的字号与磅数字体公用对话框使用字体公用对话框需要用到CFontDialog类。
CFontDialog类的构造函数为CFontDialog( LPLOGFONT lplfInitial = NULL, DWORD dwFlags = CF_EFFECTS | CF_SCREENFONTS, CDC* pdcPrinter = NULL, CWnd* pParentWnd = NULL );其中,lplfInitial为逻辑字体结构的指针(可用CFont的成员函数GetLogFont来获得,参见《Windows程序设计》),dwFlags为对话框的可选参数,CF_EFFECTS表示对话框中有删除线和下划线复选框与选择颜色的下拉式组合框,CF_SCREENFONTS则使得对话框中只列出系统支持的显示字体。
MFC常用控件
MFC常用控件
2021/7/1
1
对话框的组成
在VC++中,对话框主要是由对话框资源和对话框类组 成:
1. 对话框资源
对话框资源中描述的是对话框的大小、风格等特性, 以及对话框中控件的类型和它们的位置。定义对话框 资源最简单、最有效的方法就是使用Visual C++中的 资源编辑器。
2. 对话框类
10数据交换mfc类库使用数据交换ddx机制在对话框的控件和对话框类的数据成员之间交换数据updatedatatrue将数据从对话框的控制传递到对话框对象的数据成员缺省的调用在对话框的onokupdatedatafalse将数据传送到对话框中缺省的调用发生在对话框的oninitdialog创建一个有模式对用户可以在任何时候调用updatedata进行数据交换该函数参数缺省值为true
静态文本控件(Static Text Control); 静态图片(Picture Control);属性有:Center,image,Real
size,Type,Image和Color
2021/7/1
11
按钮
常见的按钮有如下几种类型:命令按钮、单选按钮和复选 按钮。
➢ 命令按钮(button):命令按钮适用于消息的发送,通常用于执行某个命 令。
2021/7/1
21
mfc的replacebutton用法
MFC(Microsoft Foundation Class)中的ReplaceButton是一个常用的控件,用于MFC(Microsoft Foundation Class)中的ReplaceButton是一个常用的控件,用于在文本编辑器中实现“查找和替换”功能。
它通常与Edit控件一起使用,以提供用户友好的界面。
以下是使用ReplaceButton的基本步骤:1. 在对话框设计器中添加一个Edit控件和一个ReplaceButton控件。
2. 为ReplaceButton控件分配一个ID,例如IDC_REPLACE_BUTTON。
3. 在对话框类中定义一个CFindReplaceDialog对象,并在OnInitDialog()函数中初始化该对象。
4. 为ReplaceButton控件添加一个单击事件处理程序,在该处理程序中调用CFindReplaceDialog对象的DoModal()函数,以显示查找和替换对话框。
5. 在CFindReplaceDialog对象的DoModal()函数中,根据用户的输入执行查找和替换操作。
以下是一个简单的示例代码:```cpp// MyDialog.hclass CMyDialog : public CDialogEx{public:CMyDialog(CWnd* pParent = NULL);enum { IDD = IDD_MYDIALOG_DIALOG };protected:virtual void DoDataExchange(CDataExchange* pDX);virtual BOOL OnInitDialog();DECLARE_MESSAGE_MAP()public:CString m_strText; // 存储编辑框中的文本};// MyDialog.cpp#include "MyDialog.h"#include "FindReplaceDlg.h" // 包含CFindReplaceDialog类的定义CMyDialog::CMyDialog(CWnd* pParent /*=NULL*/): CDialogEx(CMyDialog::IDD, pParent){}void CMyDialog::DoDataExchange(CDataExchange* pDX){CDialogEx::DoDataExchange(pDX);DDX_Text(pDX, IDC_EDIT1, m_strText); // 将编辑框中的文本与m_strText变量关联}BEGIN_MESSAGE_MAP(CMyDialog, CDialogEx)ON_BN_CLICKED(IDC_REPLACE_BUTTON, &CMyDialog::OnBnClickedReplaceButton) // 为ReplaceButton添加单击事件处理程序END_MESSAGE_MAP()BOOL CMyDialog::OnInitDialog(){CDialogEx::OnInitDialog();SetWindowText(_T("查找和替换示例")); // 设置对话框标题return TRUE;}void CMyDialog::OnBnClickedReplaceButton() // ReplaceButton的单击事件处理程序{CFindReplaceDlg dlg; // 创建CFindReplaceDialog对象dlg.m_strSearch = _T("要查找的字符串"); // 设置要查找的字符串dlg.m_strReplace = _T("替换后的字符串"); // 设置替换后的字符串dlg.m_bWholeWord = true; // 设置为全字匹配模式(可选)int result = dlg.DoModal(); // 显示查找和替换对话框,并获取结果代码if (result == IDOK) // 如果用户点击了“确定”按钮,则执行查找和替换操作{m_strText.Replace(dlg.m_strSearch, dlg.m_strReplace); // 使用Replace()函数执行查找和替换操作UpdateData(FALSE); // 更新编辑框中的文本显示}}```。
MFC中文件操作、查找与选择总结
MFC总结(一):MFC中文件操作、查找与选择总结(1)本文主要涉及以下几个方面,均为在MFC编程中较为常用的:CFile操作、CArchive操作、如何选择文件和文件夹、如何查找文件、获取当前目录、_access函数等。
(一)使用CFile类操作文件CFile类在MFC的文件操作中应该是最常用的了。
主要的成员函数有Open、Close、Write、Read、Seek、SeekToEnd、GetLength、GetPosition,具体用法见MSDN。
(1)文件打开操作:文件打开有两种方式,一种是先定义类对象,在用Open函数打开;一种是在定义类对象时传入文件名和打开方式。
分别如下CFile file;if(!file.Open(lpszFileName, nOpenFlags ))return;或CFile file(lpszFileName, nOpenFlags);(2)文件打开方式:文件打开方式,即上述nOpenFlags的值主要由一些宏定义的值组合而成,具体见MSDN,常用的有如下几种:A. CFile::modeCreate | CFile::modeNoTruncate |CFile::modeWrite,以写文件的方式打开,如果文件不存在,则新建文件,否则打开已有文件进行写入操作,此时不会清空原有文件;B. 将上述CFile::modeWrite更换为CFile::modeRead或者CFile::modeReadWrite可实现读操作或者同时读写。
(3)判断文件结束判断文件是否结束,没有结束则继续读取,否则关闭退出。
这点在编程时常用。
对于CFile常用的判断文件结束的方法是:while(file.GetPosition() < file.GetLength()){ //文件未结束//Add code ....}(4)值得注意的几点:A. 当文件名中包含路径时,要注意使用\\,如C:\\MyFile.DAT,在Unicode下时,需要使用_T("C:\\MyFile.DAT");B. 采用(2)中A方式写文件时,注意使用file.SeekToEnd()将文件指针移至文件尾,再写入,否则会覆盖已有的数据,这点经常被很多初学者忽视;C. 在打开文件后就要紧接着写下Close,养成这样的习惯,避免忘记关闭文件。
MFC期末复习简答题及答案
MFC 期末复习及答案1 简述MFC 应用程序的执行过程。
2 简述文档/视图与其他类对象的关系。
3 简述MFC 消息映射机制。
4 消息WM_LBUTTONDOWN 的消息映射宏和消息处理函数是什么?5 如何自定义消息?如何发送自定义消息?6 GDI 创建哪几种类型的图形输出?7 什么是设备环境?它的主要功能有哪些?8 什么是GDI,它有什么功能?MFC 将GDI 函数封装在哪个类中?9 请叙述设备无关性的含义,实现设备无关性需要哪几个环节?10 MFC 提供了哪几种设备环境类?它们各自有什么用途?11 简述传统的SDK 获取设备环境的方法。
12 简述创建和使用自定义画笔的步骤。
13 简述采用MFC 方法编程时,显示一个DDB 位图的步骤。
14 简述菜单设计的主要步骤。
15 为应用程序创建快捷菜单主要有哪些方法?16 如何动态创建菜单?17 创建工具栏的基本步骤有哪些?18 简述MFC 创建状态栏所做的工作。
19 简述创建和使用模态对话框的主要步骤。
20 如何向对话框模板资源添加控件?如何添加与控件关联的成员变量?21 什么是DDX 和DDV?编程时如何使用MFC 提供的DDX 功能?22 简述创建属性页对话框的主要步骤。
23 在应用程序中访问控件的方法有哪些?24 单选按钮控件如何成组?25 组合框与列表框相比有什么不同?如何给组合框添加初始的列表项?26 通过哪几个主要成员函数完成文档与视图之间的相互作用?并简述这些成员函数的功能。
27 简述文档序列化与一般文件处理的区别。
28.如何让用户定义的类支持序列化?1 简述MFC 应用程序的执行过程。
MFC 应用程序启动时,首先创建应用程序对象theApp。
这时将自动调用应用程序类的构造函数初始化对象theApp,然后由应用程序框架调用MFC 提供的WinMain( )主函数。
在WinMain( )主函数中,首先通过调用全局函数GetApp( )来获取theApp 的指针pApp,然后通过该指针调用theApp 的成员函数InitInstance( )来初始化应用程序。
mfc 路径去除文件名 -回复
mfc 路径去除文件名-回复mfc路径去除文件名,是指在MFC(Microsoft Foundation Classes)框架中,如何从一个完整的文件路径中提取出路径部分,去除文件名部分。
在开发过程中,经常需要对文件进行操作,而路径和文件名往往是分开处理的。
在MFC中,可以通过使用CFile类中的GetFilePath()方法来获取文件的完整路径,并且可以使用合适的方法来去除文件名部分,得到只包含路径的字符串。
以下是一步一步的解析如何使用MFC来去除文件名部分:步骤1:导入MFC头文件在MFC的代码文件中,首先需要导入afx.h头文件,该文件包含了使用MFC框架所需的基本类和函数。
cpp#include "stdafx.h"步骤2:声明文件路径变量在函数体开始的地方,声明一个CFile类的实例,并将其命名为file。
cppCFile file;步骤3:打开文件使用CFile类的Open()方法来打开需要操作的文件。
这里假设文件已经存在,并且路径也是有效的。
cppfile.Open(_T("C:\\Test\\example.txt"), CFile::modeRead);步骤4:获取文件路径使用CFile类的GetFilePath()方法来获取完整的文件路径,并将其存储到一个CString类型的变量中。
在这个例子中,我们将路径保存到path变量中。
cppCString path;path = file.GetFilePath();步骤5:去除文件名部分针对获取到的完整路径字符串,可以使用MFC字符串处理函数来截取除文件名部分的路径。
一种常见的方法是使用ReverseFind()方法来查找路径中最后一个反斜杠字符的位置,并使用Left()方法来截取字符串中从第一个字符到反斜杠字符的子字符串。
cppint pos = path.ReverseFind(_T('\\'));CString filePath = path.Left(pos);步骤6:打印结果完成路径处理之后,可以使用MFC的CString类中的GetBuffer()方法来获取C风格的字符串,并将其输出。
mfc用法 -回复
mfc用法-回复问题:MFC是什么?它的用法是什么?MFC(Microsoft Foundation Class)是微软公司开发的一套C++类库,用于Windows操作系统下的图形用户界面(GUI)应用程序的开发。
MFC 为开发者提供了一系列的类和函数,用于创建窗口、处理消息、绘制界面元素等操作,大大简化了Windows应用程序的开发过程。
下面将以步骤的方式来回答MFC的用法问题:第一步:创建MFC应用程序在开始使用MFC之前,需要安装Visual Studio开发环境。
打开Visual Studio后,选择“新建项目”,在弹出的对话框中选择“Visual C++”->“MFC应用程序”。
在下一步中,可以选择创建一个对话框应用程序或者基于文档的应用程序。
根据自己的需求进行选择,并为应用程序命名和指定保存位置。
完成这一步后,会自动生成一个基本的MFC应用程序的框架。
第二步:设计用户界面接下来,需要设计用户界面。
MFC提供了许多控件,如按钮、文本框、列表框等,可以通过拖拽的方式将这些控件添加到窗口中。
通过属性窗口可以对控件进行属性设置,如大小、位置、文本内容等。
使用这些控件和属性设置,可以设计出符合自己需求的用户界面。
第三步:处理消息在MFC中,用户操作会触发消息的产生,如点击按钮、改变文本框内容等。
MFC提供了一套消息映射机制,可以将用户操作映射到相应的处理函数上。
打开应用程序的主窗口类(通常是CMainFrame类)的头文件,可以看到一系列的消息映射函数声明。
在这些函数中,可以编写相应的代码来处理用户操作产生的消息。
第四步:编写功能代码除了处理消息外,还需要编写其他功能代码来实现应用程序的具体功能。
比如,可以在按钮的点击处理函数中编写代码,实现某个文件的读写操作;或者在文本框的改变处理函数中编写代码,实现数据的验证和保存等。
根据应用程序的需求,编写相应的功能代码。
第五步:调试和测试在程序编写完毕后,需要进行调试和测试,确保应用程序的正确性和稳定性。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
OFN_HIDEREADONLY | OFN_PATHMUSTEXIST, FALSE, pTemplate))
return FALSE; // don't even attempt to save
if (bReplace && newName.IsEmpty())
{
newName = m_strTitle;
// check for dubious filename
int iBad = newName.FindOneOf(_T(" #%;/\\"));
if (iBad != -1)
if (pFile == NULL)
{
ReportSaveLoadException(lpszPathName, &fe,
TRUE, AFX_IDP_INVALID_FILENAME);
return FALSE;
}
//建立保存用的CArchive
CArchive saveArchive(pFile, CArchive::store | CArchive::bNoFlushOnDelete);
newName.ReleaseBuffer(iBad);
// append the default suffix if there is one
CString strExt;
if (pTemplate->GetDocString(strExt, CDocTemplate::filterExt) &&
BOOL CDocument::OnSaveDocument(LPCTSTR lpszPathName)
{
CFileException fe;
CFile* pFile = NULL;
pFile = GetFile(lpszPathName, CFile::modeCreate |
CFile::modeReadWrite | CFile::shareExclusive, &fe);
{
//出现打开文件对话框文件取得文件名
CString newName;
if (!DoPromptFileName(newName, AFX_IDS_OPENFILE,
OFN_HIDEREADONLY | OFN_FILEMUSTEXIST, TRUE, NULL))
return;
18.ID_APP_ABOUT
19.ID_APP_EXIT
20.ID_HELP_INDEX
21.ID_HELP_USING
22.ID_CONTEXT_HELP
23.ID_HELP
24.ID_DEFAULT_HELP
25.ID_NEXT_PANE
26.ID_PREV_PANE
11.缺省编辑控制ID
12.ID_WINDOW_NEW
13.ID_WINDOW_ARRANGE
14.ID_WINDOW_CASCADE
15.ID_WINDOW_TILE_HORZ
16.ID_WINDOW_TILE_VERT
17.ID_WINDOW_SPLIT
3.ID_FILE_SAVE
4.ID_FILE_SAVE_AS
5.ID_FILE_SAVE_COPY_AS
6.ID_FILE_CLOSE
7.ID_FILE_UPDATE
8.ID_FILE_PRINT_SETUP
9.ID_FILE_PRINT
10.ID_FILE_PRINT_PREVIEW
saveArchive.m_pDocument = this;
saveArchive.m_bForceFlat = FALSE;
TRY
{
CWaitCursor wait;
//使用文档类的序列化操作完成实际存档行为
Serialize(saveArchive); // save me
void CDocManager::OnFileNew()
{
if (m_templateList.IsEmpty())
{
TRACE0("Error: no document templates registered with CWinApp.\n");
AfxMessageBox(AFX_IDP_FAILED_TO_CREATE_DOC);
// if returns NULL, the user has already been alerted
}
2.ID_FILE_OPEN
CWinApp::OnFileOpen
调用m_pDocManager->OnFileOpen()
void CDocManager::OnFileOpen()
// bring up dialog prompting user
CNewTypeDlg dlg(&m_templateList);
int nID = dlg.DoModal();
if (nID == IDOK)
pTemplate = dlg.m_pSelectedTemplate;
{
CString newName = lpszPathName;
if (newName.IsEmpty())
{
CDocTemplate* pTemplate = GetDocTemplate();
ASSERT(pTemplate != NULL);
newName = m_strPathName;
}
return TRUE;
}
DoSave()的实现
BOOL CDocument::DoSave(LPCTSTR lpszPathName, BOOL bReplace)
//如果文件名参数为空,则让用户取名
// note: lpszPathName can be different than 'm_strPathName'
27.ID_OLE_INSERT_NEW
28.ID_OLE_EDIT_LINKS
29.ID_VIEW_TOOLBAR
30.ID_VIEW_STATUS_BAR
1.ID_FILE_NEW
CWinApp::OnFileNew
调用m_pDocManager->OnFileNew()
else
return; // none - cancel operation
}
ASSERT(pTemplate != NULL);
ASSERT_KINDOF(CDocTemplate, pTemplate);
//建立空文件
pTemplate->OpenDocumentFile(NULL);
//如果文件是只读,或已经不存在了
if (dwAttrib & FILE_ATTRIBUTE_READONLY)
{
//使用带NULL参数的DoSave
if (!DoSave(NULL))
{
TRACE0("Warning: File save with new name failed.\n");
}
CWaitCursor wait;
//保存,由OnSaveDocument完成
if (!OnSaveDocument(newName))
{
if (lpszPathName == NULL)
{
// be sure to delete the file
TRY
文档视图结构中,缺省的命令处理
在文档视图结构所构建的框架中,很多命令ID都有缺省的命令处理。很多功能都由他们完成,但这些功能在程序中不“可见”,不便于对程序的理解。
以下归纳了常见的缺省处理及其流程
在需要时候,可以重载这些函数以实现特定功能
1.ID_FILE_NEW
2.ID_FILE_OPEN
return TRUE; // success
}
4.ID_FILE_SAVE_AS
CDocument::OnFileSaveAs()
具体实现:调用NULL参数的DoSave(..)
void CDocument::OnFileSaveAs()
{
if (!DoSave(NULL))
return;
}
CDocTemplate* pTemplate = (CDocTemplate*)m_templateList.GetHead();
//如果含有多个文档模板,显示一个新建文档类型对话框
if (m_templateList.GetCount() > 1)
{
// more than one document template to choose from
return FALSE;
}
}
else
{
//使用DoSave(....)
if (!DoSave(m_strPathName))
{
TRACE0("Warning: File save failed.\n");
return FALSE;
}
TRUE, AFX_IDP_FAILED_TO_SAVE_DOC);
}
END_TRY
DELETE_EXCEPTION(e);