将QtWinMigrate库代码添加的MFC/Ribbon项目,可以很完美的实现MFC与QT混合编程。前述库代码可以从CSDN下载到。
下面为代码主要的地方:
1. WinApp.h
#include "Migrate/qmfcapp.h" // <---
class CMfcQtTestApp : public CWinAppEx
{
public:
CMfcQtTestApp() noexcept;
// 重写
public:
virtual BOOL InitInstance();
virtual int ExitInstance();
// 实现
UINT m_nAppLook;
BOOL m_bHiColorIcons;
virtual void PreLoadState();
virtual void LoadCustomState();
virtual void SaveCustomState();
afx_msg void OnAppAbout();
DECLARE_MESSAGE_MAP()
virtual int Run();
};
extern CMfcQtTestApp theApp;
2. WinApp.cpp
QMfcApp* _qApp = nullptr;
CMfcQtTestApp::CMfcQtTestApp() noexcept // <---
{
int argc = 0;
_qApp = new QMfcApp(argc, nullptr);
_qApp->mfc_app = this;
m_bHiColorIcons = TRUE;
m_dwRestartManagerSupportFlags = AFX_RESTART_MANAGER_SUPPORT_ALL_ASPECTS;
SetAppID(_T("MfcQtTest.AppID.NoVersion"));
//...
}
int CMfcQtTestApp::Run()
{
int ret = _qApp->exec();
delete _qApp;
ExitInstance(); //needed
return ret;
}
3. 实际我测试了在对话框里嵌入QT Widget,代码主要点如下
class CMyTestDlg : public CDialogEx
{
DECLARE_DYNAMIC(CMyTestDlg)
public:
CMyTestDlg(CWnd* pParent = nullptr); // 标准构造函数
virtual ~CMyTestDlg();
// 对话框数据
#ifdef AFX_DESIGN_TIME
enum { IDD = IDD_DIALOG1 };
#endif
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持
DECLARE_MESSAGE_MAP()
public:
virtual BOOL OnInitDialog();
afx_msg void OnDestroy();
QWinWidget* widget; // <---
};
BOOL CMyTestDlg::OnInitDialog() // <---
{
CDialogEx::OnInitDialog();
CRect rc;
GetClientRect(rc);
ClientToScreen(rc);
widget = new QWinWidget(this);
widget->setFixedSize(QSize(rc.Width(), rc.Height()));
QVBoxLayout *hbox = new QVBoxLayout(widget);
QLabel *label = new QLabel("<h2><i>Hello, </i><font color=red>I'm QT!</font><font color=blue> Enter text:</font></h2>", widget);
QLineEdit *edit = new QLineEdit(widget);
edit->setClearButtonEnabled(true);
hbox->addWidget(label);
hbox->addWidget(edit);
widget->setLayout(hbox);
CRect rcw;
GetWindowRect(rcw);
rc.OffsetRect(-rcw.TopLeft());
widget->move(rc.left, );
widget->show();
return TRUE; // return TRUE unless you set the focus to a control
// 异常: OCX 属性页应返回 FALSE
}
void CMyTestDlg::OnDestroy()
{
__super::OnDestroy();
delete widget; // <---
widget = nullptr;
}
4. 下面为实际运行结果