如何在 MFC 常规 DLL 中创建和使用 CFormView? (视觉工作室 2008)

Posted

技术标签:

【中文标题】如何在 MFC 常规 DLL 中创建和使用 CFormView? (视觉工作室 2008)【英文标题】:How do I create and use a CFormView in an MFC regular DLL? (visual studio 2008) 【发布时间】:2009-12-23 04:14:47 【问题描述】:

我最近问过this question,这让我朝着正确的方向开始——至少是为了加载 MFC DLL 并尝试显示一个 dlg 框。

问题是,典型的对话框作为 APP 的主窗口是可怕的。创建一个新的 exe 项目来做我想做的事对我来说非常简单,但问题是我有一个 DLL,而这些工具似乎不允许我将类连接到资源中的 windows 窗体编辑。因此,我似乎无法处理我需要的事件。

我的问题:

如何在 MFC DLL 项目中创建和显示 CFormView(基于我在资源编辑器中创建的 IDD_FORMVIEW)? 如何让表单显示并处理输入? 如何为该窗口添加事件/消息处理程序? (从 .rc 编辑器执行此操作的菜单项显示为灰色) 如何为表单视图设置菜单? (编辑器中资源的属性不允许我将其与菜单资源相关联。(我不知道为什么)

我一直在查看的链接非常简单且关于如何执行此操作的模棱两可。他们中的大多数人认为我可以通过“向导”将大型​​机创建为 MFC 单文档应用程序 - 但事实并非如此。

现在我在我创建的窗口类上调用 Create() 并将桌面的 CWnd 作为父级传递。

我不确定我是否正确地对 CFormView 进行了子类化。事实上,我很确定我几乎没有做我需要做的事情,尽管我尝试按照我看到的说明进行操作。

然后我调用 ShowWindow(SW_SHOW),但我仍然什么也没看到。

我认为这应该很简单。我要做的就是显示我在表单编辑器中创建的表单。

我该怎么做?最简单的方法是什么?

这是一些代码 - 调用它的 cpp 代码

MainForm *mf = new MainForm();

mf->Create(CWnd::GetDesktopWindow());

mf->ShowWindow(SW_SHOW);

这是 MainForm 类的 .h 文件

#include "afxcmn.h"



// MainForm form view

class MainForm : public CFormView

    DECLARE_DYNCREATE(MainForm)

public:
    MainForm();
    virtual ~MainForm();


public: 
    virtual BOOL Create(CWnd* pParent);

public:
    enum  IDD = IDD_FORMVIEW_MAIN ;
#ifdef _DEBUG
    virtual void AssertValid() const;
#ifndef _WIN32_WCE
    virtual void Dump(CDumpContext& dc) const;
#endif
#endif

protected:
    virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support

    DECLARE_MESSAGE_MAP()
public:
    CListCtrl m_SymbolSetList;
;

这是 MainForm 的 cpp

#include "stdafx.h"
#include "MainForm.h"


// MainForm

IMPLEMENT_DYNCREATE(MainForm, CFormView)

MainForm::MainForm()
    : CFormView(MainForm::IDD)




MainForm::~MainForm()



void MainForm::DoDataExchange(CDataExchange* pDX)

    CFormView::DoDataExchange(pDX);
    DDX_Control(pDX, IDC_LIST_SYMBOLSETS, m_SymbolSetList);


BEGIN_MESSAGE_MAP(MainForm, CFormView)
END_MESSAGE_MAP()


// MainForm diagnostics

#ifdef _DEBUG
void MainForm::AssertValid() const

    CFormView::AssertValid();


#ifndef _WIN32_WCE
void MainForm::Dump(CDumpContext& dc) const

    CFormView::Dump(dc);

#endif
#endif //_DEBUG

BOOL MainForm::Create(CWnd* pParent)

    CRect rect; 
    //pParent->GetClientRect(rect);
    return CFormView::Create(NULL, NULL, WS_CHILD | WS_VISIBLE, rect, pParent, 0, NULL);

【问题讨论】:

是的,我知道 Qt 非常出色,我已经下载了它,并且正在努力学习它。但是现在我们没有时间学习如何构建、使用和部署它。它将在我们软件的下一个版本中使用。 【参考方案1】:

我将研究在单独的 MFC UI 线程中创建和显示您的窗口。 MFC 有自己的机制将 Windows 消息传递给 CWnd 派生对象,称为消息泵,它需要初始化其内部结构才能工作。我认为你需要使用框架函数调用来做到这一点。试试这个版本的 AfxBeginThread:

CWinThread* AfxBeginThread(

CRuntimeClass* pThreadClass,
int nPriority=HREAD_PRIORITY_NORMAL,
UINT nStackSize = 0,
DWORD dwCreateFlags = 0,
LPSECURITY_ATTRIBUTES lpSecurityAttrs = NULL 

);

并将您的表单作为 pThreadClass 传递;有 RUNTIME_CLASS 宏可以为你做这件事。然后,您从框架代码中结束线程。

至于消息处理,请尝试在资源编辑器中打开表单的属性,然后单击顶部的消息按钮。然后,您可以将处理程序添加到您需要处理的消息中。

我能够将 Menu 属性与菜单的资源 ID 相关联。我不知道你为什么不能这样做。如果您在树视图中选择了不同的资源,但您的主窗口显示了不同的资源,资源编辑器有时可能会感到困惑。

问候

【讨论】:

以上是关于如何在 MFC 常规 DLL 中创建和使用 CFormView? (视觉工作室 2008)的主要内容,如果未能解决你的问题,请参考以下文章

在 CPP 中创建和使用 DLL

在 VC++ 中创建 DLL (Visual Studio 2008)

如何初始化堆,以便常规 MFC dll 中的静态构造函数可以使用它?

使用带有共享 mfc dll 的常规 dll

MFC dll

MFC dll