主要思路:
在MFC中如果要创建wxwidgets 的窗口为MFC窗口的子窗口就要把MFC的窗口封装成wxwindow,即做一个虚拟窗口。同理如果要在wxwidgets上使用MFC窗口并把wxwidgets窗口作为MFC窗口的父窗口也要把wxwidgets 窗口封装成MFC窗口做一个虚拟化。因为wxwidgets的窗口在windows系统中最终是调用windows系统函数进行窗口的创建。MFC的窗口也是最终调用windowsAPI进行创建。这使得两个框架在底层窗口的创建时相同的。
具体的创建步骤如下:
通过MFC向导自动创建一个ActiveX控件工程。在自动生成的控件ActiveXCtrl类构造函数中添加如下代码:
int argc = 0;
char ** argv = NULL;
m_pApp = new FreeChartApp();
wxApp::SetInstance(m_pApp);
wxEntryStart(argc,argv);
m_pApp->OnInit();
构造这个wxwidgets的App主要是为了进行消息循环。
2.在MFC的ActiveXCtrl窗口中创建系统OnCreate消息,OnCreate消息中的具体代码如下:
int CFreeChartActiveXCtrl::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (COleControl::OnCreate(lpCreateStruct) == -1)
return -1;
// TODO: Add your specialized creation code here
RECT rectActiveX;
this->GetWindowRect(&rectActiveX);
m_pActiveXWindow = new wxWindow(); // We create a dummy window
m_pActiveXWindow->SetHWND((WXHWND)this->m_hWnd); // We set the ActiveX HWND
m_pActiveXWindow->AdoptAttributesFromHWND();
wxGetApp().SetTopWindow(m_pActiveXWindow);
m_chartPanel = new wxChartPanel(m_pActiveXWindow,wxID_ANY,NULL,wxPoint(0,0),wxSize(rectActiveX.right - rectActiveX.left, rectActiveX.bottom - rectActiveX.top));
wxBoxSizer* boxSizer = new wxBoxSizer( wxVERTICAL );
m_pActiveXWindow->SetSizer(boxSizer);
boxSizer->Add(m_chartPanel, 1, wxALL|wxGROW);
//m_chartPanel->SetChart(CreateBarChart());
return 0;
}
在OnCreate消息中获取MFC ActiveXCtrl窗口的句柄,根据获取的ActiveXCtrl窗口的句柄进行wxwidgets窗口的构建及把ActiveXCtrl窗口虚拟成wxwidgts窗口。然后以这个虚拟窗口为我们要创建的窗口的父亲,这样就能创建我们自己需要的窗口了。具体的代码已经分享。
3.最后在MFC创建的窗口类ActiveXCtrl的析构函数中完成对wxwidgets窗口的关闭处理。
CFreeChartActiveXCtrl::~CFreeChartActiveXCtrl()
{
// TODO: 在此清理控件的实例数据。
m_pApp->OnExit();
m_pApp->CleanUp();
wxApp::SetInstance(NULL);
delete m_pApp;
wxModule::CleanUpModules();
}
至此一个wxwidgets窗口移植到ActiveX中的工作就完成了。希望对同样需要进行wxwidgets窗口封装成ActiveX控件的朋友有所帮助。