MFC-RIBBON/QT混合编程‘完美’方案

[工程建立]

  1. 在VC用向导生成一个QT GUI程序,将里面的代码文件等删除(.vcxproj等保留)
  2. 在VC用向导生成另一个MFC/Ribbon程序,将里面的代码资源文件等拷贝到前一工程
  3. 进入第一个工程,做必要小修改。
    //[app.cpp]
    QMfcApp* _qApp = nullptr;
    // CQtMFCApplication 构造
    
    CQtMFCApplication::CQtMFCApplication() noexcept
    {
    	m_bHiColorIcons = TRUE;
    
    	int argc = 0;
    	_qApp = new QMfcApp(argc, nullptr);
    	_qApp->mfc_app = this;
    	//...	
    }
    
    int CQtMFCApplication::Run()
    {
    	int ret = _qApp->exec();
    	delete _qApp;
    	ExitInstance(); //needed
    	return ret;
    
    	return CWinAppEx::Run();
    }
    
    
    //[Frame.h]
    class CMainFrame : public CMDIFrameWndEx
    {
    //...
    
    protected:
    	static QWidget* mainWidget;
    	friend QWidget* getMainWidget();
    
    private:
    	void CreateQtWidget();
    };
    
    //[Frame.cpp]
    
    QWidget* CMainFrame::mainWidget = nullptr;
    
    QWidget* getMainWidget()
    {
    	return CMainFrame::mainWidget;
    }
    
    void CMainFrame::CreateQtWidget()
    {
    	AFX_MANAGE_STATE(AfxGetStaticModuleState());
    
    	HWND hWnd = GetSafeHwnd();
    	QWidget* pQWidget = new QWinWidget(hWnd, nullptr);
    	mainWidget = pQWidget;
    }
    
    int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
    {
    	//...
    	CreateQtWidget();
    	//...
    }
    
    void CMainFrame::OnDestroy()
    {
    	CMDIFrameWndEx::OnDestroy();
    
    
    	if (mainWidget)
    	{
    		delete mainWidget;
    		mainWidget = nullptr;
    	}
    }
    
    //[view.h]
    class CQtMFCApplicationView : public CView
    {
    	//...
    private:
    	QWidget* m_qtContainer = nullptr;
    	//...
    }
    
    //[view.cpp]
    
    void CQtMFCApplicationView::OnInitialUpdate()
    {
    	CView::OnInitialUpdate();
    
    	m_qtContainer = new QWinWidget(m_hWnd, nullptr);
    	QVBoxLayout* vbox = new QVBoxLayout(m_qtContainer);
    
    	QPushButton* btn = new QPushButton(QString::fromStdWString(L"QPushButton 你好!"), m_qtContainer);
    	btn->setFixedWidth(256);
    	btn->setFixedHeight(64);
    	vbox->addWidget(btn, 0, Qt::AlignCenter);
    
    	m_qtContainer->setLayout(vbox);
    
    	QObject::connect(btn, &QPushButton::clicked, [&]()
    		{
    			QMessageBox::information(getMainWidget(), "QMessageBox Title", QString::fromStdWString(L"你点击了 QPushButton"));
    		});
    }
    
    
    void CQtMFCApplicationView::OnSize(UINT nType, int cx, int cy)
    {
    	CView::OnSize(nType, cx, cy);
    
    	if (m_qtContainer)
    	{
    		CRect clientRect;
    		GetClientRect(&clientRect);
    
    		m_qtContainer->setGeometry(clientRect.left,
    			clientRect.top,
    			clientRect.Width(), clientRect.Height());
    		m_qtContainer->show();
    	}
    }
    
    
    void CQtMFCApplicationView::OnDestroy()
    {
    	CView::OnDestroy();
    
    	if (m_qtContainer)
    	{
    		//!!!必须添加这句,否则delete后,程序崩溃退出
    		//m_qtContainer在创建时,没有PaentWidget. 如果创建时设置,则其不会显示
    		m_qtContainer->setParent(getMainWidget()); 
    		delete m_qtContainer;
    		m_qtContainer = nullptr;
    	}
    	return;
    }
    

    MFC-RIBBON/QT混合编程‘完美’方案_第1张图片

你可能感兴趣的:(c++,qt)