在 C++ 中使用 Winform 作为视图
Posted
技术标签:
【中文标题】在 C++ 中使用 Winform 作为视图【英文标题】:Using a Winform as a View in C++ 【发布时间】:2012-08-28 07:06:11 【问题描述】:我试图在我的 MFC 应用程序中使用 Winform 作为视图,但我似乎无法让它工作。它编译并运行,但是在启动视图时它崩溃,表明无法创建控件: afxwinforms.inl
return CreateControl(info,dwStyle,&pt,&size,pParentWnd,nID);
有人可以在这里帮助我吗,将不胜感激 我目前有以下代码:
MyWinFormsView .h:
#pragma once
#include <vcclr.h>
#include <afxwinforms.h>
#include "MyViewUserControl.h"
#include "MyDoc.h"
// CMyWinFormsView view
class CMyWinFormsView : public CWinFormsView
DECLARE_DYNCREATE(CMyWinFormsView)
protected:
CMyWinFormsView(); // protected constructor used by dynamic creation
virtual ~CMyWinFormsView();
public:
CMyDoc* GetDocument();
DspAnalog::MyViewUserControl^ GetControl();
public:
virtual void OnDraw(CDC* pDC); // overridden to draw this view
#ifdef _DEBUG
virtual void AssertValid() const;
#ifndef _WIN32_WCE
virtual void Dump(CDumpContext& dc) const;
#endif
#endif
protected:
DECLARE_MESSAGE_MAP()
virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
public:
virtual void OnInitialUpdate();
protected:
virtual void PostNcDestroy();
public:
BEGIN_DELEGATE_MAP( CMyWinFormsView )
END_DELEGATE_MAP()
//afx_msg void OnTextChanged(System::Object ^ o, System::EventArgs ^ e);
//afx_msg void OnSaveChangesClick(System::Object ^ o, System::EventArgs ^ e);
;
#ifndef _DEBUG // debug version in View.cpp
inline CMyDoc* CMyWinFormsView::GetDocument()
return (CMyDoc*)m_pDocument;
#endif
MyWinFormsView.cpp:
#include "stdafx.h"
#include "MyWinFormsView.h"
#include "MyViewUserControl.h"
// CMyWinFormsView
IMPLEMENT_DYNCREATE(CMyWinFormsView, CWinFormsView)
CMyWinFormsView::CMyWinFormsView() : CWinFormsView(DspAnalog::MyViewUserControl::typeid)
CMyWinFormsView::~CMyWinFormsView()
BEGIN_MESSAGE_MAP(CMyWinFormsView, CWinFormsView)
END_MESSAGE_MAP()
// CMyWinFormsView drawing
void CMyWinFormsView::OnDraw(CDC* pDC)
CMyDoc* pDoc = GetDocument();
// CMyWinFormsView diagnostics
#ifdef _DEBUG
void CMyWinFormsView::AssertValid() const
CWinFormsView::AssertValid();
#ifndef _WIN32_WCE
void CMyWinFormsView::Dump(CDumpContext& dc) const
CWinFormsView::Dump(dc);
#endif
CMyDoc* CMyWinFormsView::GetDocument() // non-debug version is inline
ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CMyDoc)));
return (CMyDoc*)m_pDocument;
#endif //_DEBUG
DspAnalog::MyViewUserControl^ CMyWinFormsView::GetControl()
System::Windows::Forms::Control^ control = CWinFormsView::GetControl();
return safe_cast<DspAnalog::MyViewUserControl^>(control);
BOOL CMyWinFormsView::PreCreateWindow(CREATESTRUCT& cs)
return CWinFormsView::PreCreateWindow(cs);
void CMyWinFormsView::OnInitialUpdate()
CWinFormsView::OnInitialUpdate();
// *** Workaround bottom dock initial sizing issue
/* System::Windows::Forms::ScrollableControl ^scrlCtrl = dynamic_cast<System::Windows::Forms::ScrollableControl^>(GetControl());
if (scrlCtrl != nullptr)
CRect rcView;
GetClientRect(&rcView);
System::Drawing::Size size(0,0);
scrlCtrl->AutoScrollMinSize = size;
*/
// *** End workaround
CMyDoc* pDoc = GetDocument();
DspAnalog::MyViewUserControl^ viewControl = GetControl();
void CMyWinFormsView::PostNcDestroy()
CWinFormsView::PostNcDestroy();
MyViewUserControl.h:
#pragma once
#using <mfcmifc80.dll>
using namespace System;
using namespace System::ComponentModel;
using namespace System::Collections;
using namespace System::Windows::Forms;
using namespace System::Data;
using namespace System::Drawing;
//using namespace System::Runtime::InteropServices;
namespace MyDsp
/// <summary>
/// Summary for MyViewUserControl
/// </summary>
public ref class MyViewUserControl : public System::Windows::Forms::UserControl,
public Microsoft::VisualC::MFC::IView,
public Microsoft::VisualC::MFC::ICommandTarget
public:
MyViewUserControl(void)
InitializeComponent();
//
//TODO: Add the constructor code here
//
protected:
/// <summary>
/// Clean up any resources being used.
/// </summary>
~MyViewUserControl()
if (components)
delete components;
private: DevExpress::XtraEditors::SimpleButton^ simpleButton1;
protected:
private:
/// <summary>
/// Required designer variable.
/// </summary>
System::ComponentModel::Container ^components;
#pragma region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
void InitializeComponent(void)
this->simpleButton1 = (gcnew DevExpress::XtraEditors::SimpleButton());
this->SuspendLayout();
//
// simpleButton1
//
this->simpleButton1->Location = System::Drawing::Point(44, 101);
this->simpleButton1->Name = L"simpleButton1";
this->simpleButton1->Size = System::Drawing::Size(75, 23);
this->simpleButton1->TabIndex = 0;
this->simpleButton1->Text = L"simpleButton1";
//
// MyViewUserControl
//
this->AutoScaleDimensions = System::Drawing::SizeF(6, 13);
this->AutoScaleMode = System::Windows::Forms::AutoScaleMode::Font;
this->Controls->Add(this->simpleButton1);
this->Name = L"MyViewUserControl";
this->ResumeLayout(false);
#pragma endregion
public:
// Implementing IView and ICommandTarget interfaces
virtual void OnInitialUpdate();
virtual void OnUpdate();
virtual void OnActivateView(bool bActivate);
virtual void Initialize(Microsoft::VisualC::MFC::ICommandSource^ cmdSrc);
System::Void Command1Handler(System::UInt32 cmdUI);
int iActivateCount;
;
MyViewUserControl.cpp
#include "MyViewUserControl.h"
namespace MyDsp
#define ID_CVIEWCMDS_COMMAND1 32771
void MyViewUserControl::OnInitialUpdate()
this->iActivateCount = 0;
void MyViewUserControl::OnUpdate()
void MyViewUserControl::OnActivateView(bool activate)
this->iActivateCount++;
void MyViewUserControl::Initialize(Microsoft::VisualC::MFC::ICommandSource^ cmdSrc)
//Microsoft::VisualC::MFC::CommandHandler^ command;
//command = gcnew Microsoft::VisualC::MFC::CommandHandler( this, &MyViewUserControl::Command1Handler );
// Use the same control ID as in the resource.h of the MFC project
//cmdSrc->AddCommandHandler( ID_CVIEWCMDS_COMMAND1, command );
// Handler for the MFC menu command
void MyViewUserControl::Command1Handler(System::UInt32 cmdUI)
//this->toolStripStatusLabel1->Text = "Selected Command1";
【问题讨论】:
当您的任何应用程序崩溃时,您的第一反应应该是在调试器中运行程序。它将帮助您定位程序崩溃的位置,让您查看函数的调用方式和位置,并让您检查变量和参数以帮助您了解是什么可能导致崩溃。 就像我说的,但是我忘了提到行号 (122) afxwinforms.inl return CreateControl(info,dwStyle,&pt,&size,pParentWnd,nID); 是的,但它是一个系统文件。如果您将调用堆栈向上转到您的代码,那在哪里? wfrmview.cpp 第 108 行 fSucceeded=fSucceeded && m_control.CreateManagedControl(m_pManagedViewType,WS_VISIBLE, rect, this,nID); 【参考方案1】:你知道the microsoft mfc-winform integration example吗?
开始的一些提示: 不要在 System... 命名空间上使用 using,导致 c++/cli 有时不匹配
看例子中每个c++文件的编译器选项,有很多东西要设置(/clr等)
【讨论】:
其实我是以此为出发点的。好的,所以现在我决定在我的项目中使用示例中的代码,并尝试首先让它工作。现在我遇到以下问题:使用命名空间 System::Runtime::InteropServices;原因:错误 C2872:'FILETIME':模棱两可的符号,所以现在我坚持使用 FILETIME 的多个定义:S 删除使用命名空间 System::Runtime::InteropServices;解决了这个问题,但我仍然有我原来的问题,解决方案现在构建并运行,但是当创建视图时,它在 wfrmview.cpp 第 108 行崩溃 fSucceeded=fSucceeded && m_control.CreateManagedControl(m_pManagedViewType,WS_VISIBLE, rect, this,nID); 为什么需要winform作为mfc视图,就不能使用带有winform控件的原生mfc视图吗?以上是关于在 C++ 中使用 Winform 作为视图的主要内容,如果未能解决你的问题,请参考以下文章
winform程序访问Microsoft.Win32空间的问题