在 MFC DLL 中的 CDialog 派生对象中使用 CScrollView 派生对象
Using CScrollView derived object in a CDialog derived object in MFC DLL
我想有人向我解释为什么在 CDialog 派生对象中使用以下 CScrollView 派生对象有效,以及这种方法是否有隐藏的问题。
我关心的是将 CDialog 转换为 CFrameWnd,以便使用 CFrameWnd 类的CreateView()
方法为 CDialog 对象中的 CScrollView 对象创建文档/视图对。
我正在构建一个 MFC DLL,它将提供一系列 GUI 函数来显示并允许在一次显示一个页面的旧应用程序中编辑某些类型的信息。
第一个部分是提供一种在对话框中显示报表的方法,该对话框在可滚动组件中显示报表,允许用户查看整个报表。
为了在 CDialog 派生的 GUI 对象中使用 CSrollView 派生控件,我找到了这篇文章,在对话框中创建视图(一种简单的方法),因为我在使用 CScrollView 时遇到了许多 CDialog 关闭异常的问题。 我还在调试输出窗口中看到"警告:创建一个没有 CDocument 的窗格"的警告,我不再看到该警告。
使用本文中的基本概念,我有代码,它似乎在调试器中的Windows XP中的Visual Studio 2005上运行良好。
我在 CDialog 派生类中用于在OnInitDialog()
中初始化的代码如下。 我首先创建文档并将文本行放入内存区域,CDialog 派生对象的构造函数被赋予文档的地址m_pDocument
,然后在OnInitDialog()
函数中使用。
BOOL CScrollReportDialog::OnInitDialog ()
{
// Get the client area size of the dialog we are putting the
// CScrollView into and pull the right edge in sufficient to
// clear buttons on the right hand side of the dialog.
RECT rectSize;
GetClientRect (&rectSize);
rectSize.right -= 120;
// allocate and set up the view document context linking the view
// to a particular document, in our case a CScrollDocument.
CCreateContext pContext;
pContext.m_pCurrentDoc = m_pDocument;
pContext.m_pNewViewClass = RUNTIME_CLASS(CScrollReport);
// Cast the pointer to this dialog into a CFrameWnd pointer allowing
// us to access the CFrameWnd methods. Both CDialog and CFrameWnd are
// derived from CWnd so we can get away with this.
CFrameWnd* pFrameWnd = (CFrameWnd *) ((CWnd *)this);
CScrollReport *pView = (CScrollReport *)pFrameWnd->CreateView(&pContext);
ASSERT(pView);
// Set an initial scroll size for the CScrollView which will be
// modified in the OnDraw () later when presenting the actual view
// and we have the complete document and can calculate the document's
// scrollable size properly.
CSize sizeTotal;
sizeTotal.cx = rectSize.right;
sizeTotal.cy = 1 * rectSize.bottom;
pView->SetScrollSizes(MM_TEXT, sizeTotal);
pView->ShowWindow(SW_NORMAL);
/**
* After a view is created, resize window area of the view to fit into the
* dialog. Since this is a CScrollView, set an initial size for the
* size of the object being scrolled.
*/
pView->MoveWindow(&rectSize);
return TRUE;
}
查看 MFC 源以了解CFrameWnd::CreateView()
不存在对任何 CFrameWnd 数据的依赖。 但是,该方法的实现可能会在以后更改。
CFrameWnd::CreateView()
的 MFC 源版本使用 MFC 动态对象创建来创建视图的实例。 然后,它将视图的实际窗口创建为具有特定 MFC 文档/视图窗口标识符的子窗口。
与其依靠CFrameWnd::CreateView()
来保持相同的实现,我们可以实现自己的版本。
该函数的修改部分是将 CDialog 对象转换为 CFrameWnd 对象,以便使用CreateView()
实现的特定代码访问CreateView()
方法,如下所示。
#if 0
// Cast the pointer to this dialog into a CFrameWnd pointer allowing
// us to access the CFrameWnd methods. Both CDialog and CFrameWnd are
// derived from CWnd so we can get away with this.
CFrameWnd* pFrameWnd = (CFrameWnd *) ((CWnd *)this);
CScrollReport *pView = (CScrollReport *)pFrameWnd->CreateView(&pContext);
ASSERT(pView);
#else
// Use the approach from CFrameWnd::CreateView() to create a view and
// link the view with the document. We use the dynamic CreateObject()
// functionality to create a CScrollReport view object. We use the
// standard child window id for the first view of an instance of the
// MFC document/view architecture. We are basing this on a copy of
// the CFrameWnd::CreateView () method from the MFC source.
int nID = AFX_IDW_PANE_FIRST;
CScrollReport *pView = (CScrollReport *)pContext.m_pNewViewClass->CreateObject();
ASSERT(pView);
ASSERT_KINDOF(CWnd, pView);
if (pView) {
if (!pView->Create(NULL, NULL, AFX_WS_DEFAULT_VIEW, CRect(0,0,0,0), this, nID, &pContext)) {
TRACE0("Warning: could not create view for dialog.n");
return FALSE;
}
} else {
TRACE0("Warning: dynamic create of CScrollView for dialog failed.n");
return FALSE;
}
#endif
编辑1月28
日遇到的一个问题是,有时对话框将显示在全屏应用程序下方。 结果是与 CScrollView 的对话框不可见。
有关使用SetWindowPos()
函数的示例,请参阅堆栈溢出始终在前面对话框。 我在返回之前以OnInitDialog()
方法使用它。
- 如何使用单独文件中的派生类访问友元函数对象
- 使用基类指针创建对象时,缺少派生类析构函数
- 为什么此派生对象无法访问基类的后递减方法?
- 将带有派生模板的对象传递给接受具有基本模板的对象的功能
- 放置派生C++的新基子对象
- 在 C++ 中将对象转换为派生类型
- 链表包含 c++ 中不同的派生类对象
- 如何在不使用指针的情况下将派生类的对象作为参数传递给基类中的函数?
- 如何在新的派生对象中获取基本对象的数据?
- 如何将成员函数作为参数传递并在派生对象上执行方法列表
- 获取我的基类以递增派生类对象整数
- 派生类中的对象
- 在没有默认构造函数的情况下创建的派生对象
- OOP 标识派生对象
- 如何创建派生对象的向量?
- 按基类对象访问派生类资源时出错
- 将基类分配给派生对象,反之亦然,以C++以及静态和动态对象之间的差异
- static_cast将此对象派生到C++中的基类
- 如何在构造函数完成后立即销毁从 QWindow 对象派生的内容
- 我可以判断std::type_info对象是否等于另一个对象或从另一个对象派生的类吗?