MFC調用QT編寫的DLL動態庫

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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章