MFC呼叫QT編寫的DLL動態庫
阿新 • • 發佈:2019-01-31
MFC呼叫QT編寫的動態庫,如果QT dll裡面用到了一些訊息迴圈相關的介面,比如QTimer,QEventLoop等,會由於沒有QAppAplication而導致這些調用出現異常,如果DLL裡面沒有介面顯示的話,解決方法還是相對比較簡單的。主要思想是使用windows API hook函式,將MFC的訊息丟入QT去繞一圈,然後再交由MFC去處理,這樣QT便有啟用處理自己的訊息,如果本生已經是QT應用,則不做任何處理。
static bool g_bOwnApplication = false;
static HINSTANCE g_hInstance;
BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpvReserved*/ )
{
if (dwReason == DLL_PROCESS_ATTACH)
g_hInstance = hInstance;
if (dwReason == DLL_PROCESS_DETACH && g_bOwnApplication)
delete qApp;
return TRUE;
}
bool InitSdk()
{
if ( !g_bOwnApplication )
g_bOwnApplication = CMfcApp::pluginInstance(g_hInstance);
}
這裡放在InitSdk裡面去呼叫CMfcApp::pluginInstance而不在dllmain裡面去掉用,主要是防止靜態載入導致的QApplication衝突問題。
下面是CMfcApp的實現:
//.h
#pragma once
//for MFC use qt dll
//this solution from qt-solutions git-hub
#include <QCoreApplication>
#include <qnamespace.h>
#include <windef.h>
class CMfcApp
{
public:
CMfcApp();
~CMfcApp();
static LRESULT CALLBACK QtFilterProc(int nCode, WPARAM wParam, LPARAM lParam);
static bool pluginInstance(Qt::HANDLE plugin);
private:
static HHOOK s_hHook;
};
//.cpp
#include "MfcApp.h"
#include <WinBase.h>
#include <WinUser.h>
#include <processthreadsapi.h>
HHOOK CMfcApp::s_hHook = NULL;
LRESULT CALLBACK CMfcApp::QtFilterProc(int nCode, WPARAM wParam, LPARAM lParam)
{
if (qApp) {
// don't process deferred-deletes while in a modal loop
qApp->sendPostedEvents(0, -1);
}
return CallNextHookEx(s_hHook, nCode, wParam, lParam);
}
CMfcApp::CMfcApp()
{
}
CMfcApp::~CMfcApp()
{
}
bool CMfcApp::pluginInstance(Qt::HANDLE plugin)
{
if (qApp)
return false;
s_hHook = SetWindowsHookEx(WH_GETMESSAGE, QtFilterProc, 0, GetCurrentThreadId());
int argc = 0;
(void)new QCoreApplication(argc, 0);
if (plugin) {
char filename[MAX_PATH] = { 0 };
if (GetModuleFileNameA((HINSTANCE)plugin, filename, MAX_PATH))
LoadLibrary(filename);
}
return true;
}