如何抛出(throw)由CUserException派生的异常? 当我试图捕获(catch)一个派生类异常时,我得到以下错误"error C2039:'classCMyException': is not a member of 'CMyException' 'classCMyException': undeclared identifier 'IsKindOf': cannot convert parameter 1 from 'int*' to 'const struct CRuntimeClass*" 异常类一定要从CUserException中派生出来吗? 不,CUserException中的"User"仅仅指用户产生的异常。而把它当作你所能派生的唯一异常是种常见的误解。 如何从HDC建立一个CDC类? 有时Windows API将会给你一个DC句柄,你可以通过它建立一个CDC类。例如:下拉式列表、组合框和按钮。通过hDC你将接收到绘制消息。下面是将HDC转换成你更熟悉的CDC的程序段。你也可以将该技巧用在其他任何MFC类和Windows句柄的转换中。 void MyODList::DrawItem(LPDRAWITEMSTRUCT lpDrawItem) { CDC myDC; myDC.Attach(lpDrawItem-〉hDC); //在此插入其他需要的代码。 //如果你不将句柄分离,它将被删除,从而导致问题。 myDC.Detach(); } 另一个方法是调用CDC类的FromHandle方法: CDC * pDC = CDC:FromHandle(lpDrawItem-〉hDC);目前还不清楚哪种方法更优越―使用FromHandle()的错误也许会更少些,因为它不要求你分离(detach)句柄。 如何从磁盘上读取256色位图文件? 当前,MFC并不支持直接读取和显示DIB文件和BMP文件。然而,有很多样例应用程序能够说明如何完成该项任务。第一个例子是MFC样例程序DIBLOOK。样例MULTDOCS用DIBLOOK提供的相同源代码来读取并显示DIB文件和BMP文件。其他两个VC++中附带的例子是SDK软件包中的DIBVIEW程序和SHOWDIB程序。 如何改变一个视图的大小? 通常,你可以调用函数MoveWindow()来改变窗口的大小。在用MFC库开发的应用程序中, 视图是被框架窗口所围绕的一个子窗口。为了改变一个视图的大小,你可以通过调用函数GetParentFrame()来得到框架窗口的指针,然后调用函数MoveWindow()来改变父窗口的大小。当父框架窗口改变大小时,视图也会自动地改变大小来适应父窗口。 如何改变一个CFormView的大小? 要想详细了解的话,你可以看有关Visual C++基础知识的文章Q98598 《Using CFormView in SDI and MDI Applications》。基本上,在从CFormView类派生出来的类中,你必须覆盖函数OnInitialUpdate()。其他有关建立CFormView的细节问题,可以从该文章中获得。 在类ClikethisView中声明如下函数: virtual void OnInitialUpdate(); 在ClikethisView的代码中,函数如下: void ClikethisView::OnInitialUpdate() { //使窗口与主对话框同样大小 CFormView::OnInitialUpdate(); GetParentFrame()-〉RecalcLayout(); ResizeParentToFit( /*FALSE*/ ); } 如何使用一个文档模板的新视图? 在用AppWizard创建的应用程序中,你有两种选择:改变当前视图的派生关系或者建立一个新视图并且在你的MDI程序中同时利用新视图和原先的视图。 如何改变视图的背景色? 你可以通过处理WM_ERASEBKGND消息来改变CView、CFrameWnd或CWnd对象的背景色。请看如下的程序段: BOOL CSampleView::OnEraseBkgnd(CDC* pDC) { // 设置所要求背景色的刷子 CBrush backBrush(RGB(255, 128, 128)); // 保存旧刷子 CBrush* pOldBrush = pDC-〉SelectObject(&backBrush); CRect rect; pDC-〉GetClipBox(&rect); // 擦除所需的区域 pDC-〉PatBlt(rect.left, rect.top, rect.Width(), rect.Height(), PATCOPY); pDC-〉SelectObject(pOldBrush); return TRUE; }而我则用如下方法解决这个问题: HBRUSH dlgtest::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor) { switch (nCtlColor) { case CTLCOLOR_BTN: case CTLCOLOR_STATIC: { pDC-〉SetBkMode(TRANSPARENT); } case CTLCOLOR_DLG: { CBrush* back_brush; COLORREF color; color = (COLORREF) GetSysColor(COLOR_BTNFACE); back_brush = new CBrush(color); return (HBRUSH) (back_brush-〉m_hObject); } } return(CFormView::OnCtlColor(pDC, pWnd, nCtlColor)); } 如何得到当前视图? 最佳方法是将视图当作一个参数来传递。如果不能这样做,但你确信它是当前激活文档和当前激活视图的话,你也可以得到该视图。具体细节见Visual C++文章Q108587《Get Current CDocument or CView from Anywhere》。 简单说来,用: ((CFrameWnd*) AfxGetApp()-〉m_pMainWnd))-〉GetActiveDocument() 和: ((CFrameWnd*)(AfxGetApp()-〉m_pMainWnd))-〉GetActiveView()来得到文档和视图。一个好的方法是将它们封装在你的CMyDoc和CMyView类的静态函数中,并且核对它们是否属于正确的RUNTIME_CLASS。然而,假如这个视图不是当前激活视图或者你在运行OLE本地激活,这样将不成功。 如何在一个文档中建立多个视图? CDocTemplate::CreateNewFrame()函数创建MFC MDI应用程序中的文档的附加视图。为了调用该函数,要指定一个指向CDocument对象(指将为之建立视图的文档)的指针和一个指向可从中复制属性的框架窗口的指针。一般情形下,该函数的第二个参数为NULL。 如何在MDI程序中得到所有的视图? 你必须用一些文档中没有记载的函数: CDocument::GetFirstViewPosition(); // DOCCORE.CPP CDocument::GetNextView(); // DOCCORE.CPP CMultiDocTemplate::GetFirstDocPosition(); // DOCMULTI.CPP CMultiDocTemplate::GetNextDoc(); // DOCMULTI.CPP 你还需要与CWinApp的成员m_templateList打交道。 如何建立一个可用鼠标拉动的CScrollView类 在CIS上从MSMFC库下载AUTOSV.LZH。这个程序告诉你如何实现一个辅助消息循环来管理鼠标的活动,并提供了钩挂来对代码进行定制。这是一个免费软件。 一定要用视图/文档结构吗? MFC并不一定要求你使用文档/视图结构。查看HELLO、 MDI和HELLOAPP例子―它们就没有用那种结构。大多数MFC特性都可以在非文档/视图应用程序中得到运用。但是当你不用文档 / 视图结构时,你确实会失去一些特性,例如打印预览和许多OLE特性。 如何得到当前文档? 请详细参阅"如何得到当前视图?"章节。 文档何时被析构? 在SDI程序中,程序退出后文档就被删除。在MDI程序中,与该文档相关的最后一个视图关闭时文档就被删除。为了在SDI和MDI中同时用这个文档,你应该在虚函数DeleteContents()函数中删除该文档的数据,而不是在析构器中。 如何建立多文档? 为了加入对附加文档类型的支持,你可以在CWinApp派生类中创建和注册附加CmultiDocTemplate对象。这种方法已经在MULTDOCS样例程序中得以说明。将一个附加文档类型加入到MFC程序的一般步骤如下: 用AppWizard来创建一个新的文档类和视图类。 CMultiDocTemplate* pDocTemplate2 = new CMultiDocTemplate( IDR_DOC2TYPE, RUNTIME_CLASS(CDoc2), RUNTIME_CLASS(CMDIChildWnd),RUNTIME_CLASS(CView2)); AddDocTemplate(pDocTemplate2);最后,将定制的序列化和绘图代码加入到你的新文档和视图类中。 如何得到一个打开文档的列表? 下面的程序段指明如何得到用CDocTemplate对象建立的所有文档的指针列表。 void CMyApp::GetDocumentList(CObList * pDocList) { ASSERT(pDocList-〉IsEmpty()); POSITION pos = m_templateList.GetHeadPosition(); while (pos) { CDocTemplate* pTemplate = (CDocTemplate*)m_templateList.GetNext(pos); POSITION pos2 = pTemplate-〉GetFirstDocPosition(); while (pos2) { CDocument * pDocument; if ((pDocument=pTemplate-〉GetNextDoc(pos2)) != NULL) pDocList-〉AddHead(pDocument); } } } 在参考手册或在线帮助中,有两个CdocTemplate类的公共成员函数没有被说明。然而, 这些公共成员函数在CDocTemplate类中被定义,并且为在打开文档的列表中前后搜索提供了简单的支持。 这些函数如下: 注意,这仅对MFC3.2版本或更低版本有效,对MFC4.0版本请参考下面: void CMyApp::DoSomethingToAllDocs() { CObList pDocList; POSITION pos = GetFirstDocTemplatePosition(); while(pos) { CDocTemplate* pTemplate = GetNextDocTemplate(pos); POSITION pos2 = pTemplate-〉GetFirstDocPosition(); while(pos2) { CDocument* pDocument; if(pDocument = pTemplate-〉GetNextDoc(pos2)) pDocList.AddHead(pDocument); } } if(!pDocList.IsEmpty()){ pos = pDocList.GetHeadPosition(); while(pos) { //为每一个文档调用CDocument函数 ( (CDocument*)pDocList.GetNext(pos) ) -〉UpdateAllViews(NULL); } } 如何使我的程序在启动时不创建一个新文档? 在程序的InitInstance中的ProcessShellCommand函数之前加入: cmdInfo.m_nShellCommand = CCommandLineInfo::FileNothing |
温馨提示:喜欢本站的话,请收藏一下本站!