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

时间:2009-12-23 04:14:48

标签: c++ user-interface dll mfc

我最近问this question让我开始朝着正确的方向前进 - 至少是为了加载MFC DLL并试图显示一个dlg框。

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

我的问题:

  • 如何在MFC DLL项目中创建和显示CFormView(基于我在资源编辑器中创建的IDD_FORMVIEW)?
  • 如何让表单显示和处理输入?
  • 如何为该窗口添加事件/消息处理程序? (从.rc编辑器中执行此操作的菜单项显示为灰色)
  • 如何将菜单设置为formview? (编辑器中资源的属性不允许我将它与菜单资源相关联。(我无法弄清楚原因)

我一直在关注的链接对于如何做到这一点非常轻松和含糊不清。他们中的大多数人都认为我可以通过“向导”将主机创建为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);
}

1 个答案:

答案 0 :(得分:2)

我会调查在单独的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相关联。我不确定你为什么不能这样做。如果在树视图中选择不同的资源但主窗口显示不同的资源,资源编辑器有时可能会感到困惑。

此致