带有System.Windows.Forms的MFC ActiveX控件
MFC ActiveX control with System.Windows.Forms
我正在尝试创建一个ActiveX控件,该控件包含一个System.Windows.Forms.Integration.ElementHost控件以承载控件中的WPF内容。
我可以使用MFC创建ActiveX控件,也可以在其中加载MFC CDialog。但是,一旦我尝试创建托管控件,它就会在上崩溃,并出现AccessViolationException
return CreateControl(info,dwStyle,&pt,&size,pParentWnd,nID);
这在afxwinforms.inl:122中。
我的MainDialog.cpp文件如下:
// MainDialog.cpp : implementation file
//
#include "stdafx.h"
#include "MFCAX.h"
#include "MainDialog.h"
#include "afxdialogex.h"
// CMainDialog dialog
IMPLEMENT_DYNAMIC(CMainDialog, CDialog)
CMainDialog::CMainDialog(CWnd* pParent /*=NULL*/)
: CDialog(CMainDialog::IDD, pParent)
{
}
CMainDialog::~CMainDialog()
{
}
void CMainDialog::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//DDX_ManagedControl(pDX, IDC_BUTTON1, m_elementHost);
}
BOOL CMainDialog::OnInitDialog()
{
CDialog::OnInitDialog();
AFX_MANAGE_STATE(AfxGetStaticModuleState());
System::Windows::Forms::MessageBox::Show(gcnew System::String("init"));
return m_elementHost.CreateManagedControl(WS_CHILD | WS_VISIBLE, IDC_BUTTON1, this);
}
BEGIN_MESSAGE_MAP(CMainDialog, CDialog)
END_MESSAGE_MAP()
// CMainDialog message handlers
此时会显示消息框,但随后会出现上述崩溃。
我觉得只少了一小块,但我真的不知道该去哪里找。感谢您的帮助。
我终于弄明白了,所以我会在这里快速概述一下有类似问题的人该怎么做:
首先:不要走WinForms ElementHost中的WPF路线,它比这容易得多!
要加载WPF控件并将其显示在ActiveX控件上,请使用以下方法:
HWND CMFCAXCtrl::GetUserControl1Hwnd(HWND parent, int x, int y, int width, int height)
{
System::Windows::Interop::HwndSourceParameters^ sourceParams = gcnew System::Windows::Interop::HwndSourceParameters("MFCWPFApp");
sourceParams->PositionX = x;
sourceParams->PositionY = y;
sourceParams->Height = height;
sourceParams->Width = width;
sourceParams->ParentWindow = System::IntPtr(parent);
sourceParams->WindowStyle = WS_VISIBLE | WS_CHILD;
m_hwndSource = gcnew System::Windows::Interop::HwndSource(*sourceParams);
EventReceiver^ recv = gcnew EventReceiver(this);
m_wpfUC = gcnew WpfExample::TestControl();
m_wpfUC->Clicked += gcnew System::EventHandler(recv, &EventReceiver::Handler);
m_hwndSource->RootVisual = m_wpfUC;
return (HWND) m_hwndSource->Handle.ToPointer();
}
您必须设置一个HwndSource来在中绘制WPF控件。您还可以连接事件处理程序等来处理C++中的WPF事件(请参阅Clicked事件处理程序)。
相应的成员定义如下:
gcroot<System::Windows::Interop::HwndSource^> m_hwndSource;
gcroot<WpfExample::TestControl^> m_wpfUC;
HWND m_hwndWPF;
现在是棘手的部分:加载这样的程序集时似乎出现了问题,找不到任何未安装在GAC中的程序集。因此,您必须连接自己的汇编解析器。在那里,你必须确保一个程序集只加载一次,否则你会得到奇怪的错误和异常。一个快速而肮脏的实现可能是这样的:
ref class Resolved {
public:
// just needed to store the assembly that was loaded.
static System::Reflection::Assembly^ assembly;
};
System::Reflection::Assembly^ ResolveHandler(System::Object^ Sender, System::ResolveEventArgs^ args)
{
return Resolved::assembly;
}
以及在控件的OnCreate方法中:
Resolved::assembly = System::Reflection::Assembly::LoadFile(gcnew System::String("Path:\To\My\assembly\WpfExample.dll"));
System::AppDomain::CurrentDomain->AssemblyResolve += gcnew System::ResolveEventHandler(ResolveHandler);
// To create the main dialog
m_hwndWPF = GetUserControl1Hwnd(this->GetSafeHwnd(), 0, 0, 500, 500);
现在您已经准备好了,应该能够在任何支持ActiveX的遗留项目中使用WPF。
相关文章:
- C++ MFC Libraries in Travis CI
- 从 bmp 文件数据创建 MFC CBitmap
- 如何在 MFC 中显示文件的所有行
- 目录删除 MFC 的问题
- MFC:如何设置CEdit框的焦点?
- 断言"id < 0"在Qt ActiveX中失败
- 在MFC应用程序中缩放RDP ActiveX较大
- MFC vs ATL for ActiveX
- 如何在 com 的界面或非 mfc 应用程序中使用 ActiveX 控件?
- Windows 7:MFC ActiveX 控件不会在任何文件夹中创建文件
- 无法向 MFC ActiveX 添加函数
- 如何防止 MFC 应用程序即时关闭与 ActiveX 冲击波闪光控件
- 如何替换/更新 MFC 对话框中的 ActiveX 控件
- MFC应用程序中Delphi 7和Delphi XE4之间的ActiveX差异
- MFC 设计器中的"Cannot access ActiveX Control type library"错误
- 没有ActiveX或MFC的Windows Media Player自动化是可能的吗?
- 无法在 MFC Windowless Activex 中获取 Cwnd 类的句柄?
- 带有System.Windows.Forms的MFC ActiveX控件
- C++/MFC - 防止挂起的子控件 (ActiveX) 控件冻结整个 UI
- MFC为OPOS添加Typelib或ActiveX