如何抛出(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*"
你必需通过使用DECLARE_DYNAMIC()和IMPLEMENT_DYNAMIC()宏来使你的CMyException类可以动态地创建。CATCH宏希望能够得到关于被抛出类的运行时刻信息。
异常类一定要从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++(www.cppentry.com)中附带的例子是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程序中同时利用新视图和原先的视图。
为了创建一个新视图,你可以用ClassWizard由CView派生一个新的类。当新类创建以后,利用新视图或修改由AppWizard提供的视图,两者的步骤是相同的。
修改视类的头文件,从而将所有对CView类的引用改名为你所想要的名称。本例中的类由CScrollView派生而来。通常,这个步骤包括对类的改变,视类将由如下方式派生而来:
class CMyView : public CScrollView
修改视类的实现文件,从而将所有对CView的引用改名为你所想要的名称。这包括将IMPLEMENT_DYNCREATE那一行的语句改为:
IMPLEMENT_DYNCREATE(CMyView, CScrollView)
将BEGIN_MESSAGE_MAP那一行的语句改为:
BEGIN_MESSAGE_MAP(CMyView, CScrollView)
并且将其他所有的CView改成CScrollView.
假如你修改的视图是由AppWizard生成的,那么就不需要作更多的修改了。而如果你在创建一个新视图,先在CWinApp::InitInstance()函数中找到对AddDocTemplate()函数的调用。AddDocTemplate()函数的第三个参数是RUNTIME_CLASS(CSomeView),用CMyView来代替CSomeView,就可以将当前视图改为新视图。在MDI应用程序中,你可以增加第二个AddDocTemplate()函数调用来使用多视图类型,将RUNTIME_CLASS(CSomeView)改为RUNTIME_CLASS (CMyView)。
如何改变视图的背景色?
你可以通过处理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));
}