C++ (Qt)HRESULT __stdcall DllGetClassObject( _In_ REFCLSID rclsid, _In_ REFIID riid, _Out_ LPVOID *ppv);
C++ (Qt)qApp->processEvents()
C++ (Qt)// DLLWrapper.hclass DLLWrapper{public: static bool init(HINSTANCE inst = NULL); static void uninit(); private: DLLWrapper();}; // DLLWrapper.cppHHOOK hook = 0; LRESULT CALLBACK hook_callback(int code, WPARAM wParam, LPARAM lParam){ if (qApp) qApp->sendPostedEvents(); return CallNextHookEx(hook, code, wParam, lParam);}//------------------------------------------------------------------------------//------------------------------------------------------------------------------ bool DLLWrapper::init(HINSTANCE inst){ if (qApp) return false; QT_WA({ hook = SetWindowsHookExW(WH_GETMESSAGE, hook_callback, 0, GetCurrentThreadId()); }, { hook = SetWindowsHookExA(WH_GETMESSAGE, hook_callback, 0, GetCurrentThreadId()); }); if (!hook) return false; int argc = 0; new QApplication(argc, 0); return true;}//------------------------------------------------------------------------------ void DLLWrapper::uninit(){ if (hook) { UnhookWindowsHookEx(hook); hook = 0; }}//------------------------------------------------------------------------------
C++ (Qt)void init_dll(){ ... DLLWrapper::init(); ...} void uninit_dll(){ qApp->quit(); DLLWrapper::uninit(); delete qApp;}
C++ (Qt)DWORD MyThreadFunction( LPVOID lpParam ){ QCoreApplication * app = NULL; int argc = 0; app = new QCoreApplication(argc, NULL); QLibrary * dllClass = new QLibrary(); app->exec(); return DWORD();}
C++ (Qt)QLibrary * dllClass = new QLibrary();
C++ (Qt) class TimerHandler : public QObject{ Q_OBJECTpublic: explicit TimerHandler(QObject *parent = 0) {}public slots: void handleTimeout() { static int counter = 0; ++counter ; }} void foo() // или DllGetClassObject или любая другая ф-я{ QTimer *timer = new QTimer(); QObject *obj = new TimerHandler(); QObject::connect(timer, SIGNAL(timeout()), obj, SLOT(handleTimeout))); timer->start(1000);}
C++ (Qt)bool showDialog( HWND parent )
C++ (Qt)void foo(){ DLLWrapper::init(); QTimer *timer = new QTimer(); QObject *obj = new TimerHandler(); QObject::connect(timer, SIGNAL(timeout()), obj, SLOT(handleTimeout))); timer->start(1000);}
C++ (Qt)#ifndef DLL_H#define DLL_H #include <windows.h> class Dll{public: static BOOL Main(HINSTANCE dllInstance, DWORD reason, LPVOID reserved); static HRESULT GetClassObject(REFCLSID classId, REFIID interfaceId, PVOID *object); // это, наверное, можно заменить на foo() и прочее.public: static HINSTANCE instance; private: static bool attachQtApplication(); static bool detachQtApplication(); static VOID CALLBACK qtEventsTimerProc(HWND hwnd, UINT msg, UINT_PTR eventId, DWORD time); static UINT_PTR m_timerIdentifier; static UINT m_timerInterval;}; #endif // DLL_H
C++ (Qt)#include "dll.h" #include <QCoreApplication> HINSTANCE Dll::instance = NULL; UINT_PTR Dll::m_timerIdentifier = 0;UINT Dll::m_timerInterval = 1; // every 1 msec BOOL Dll::Main(HINSTANCE dllInstance, DWORD reason, LPVOID reserved){ UNREFERENCED_PARAMETER(reserved); Dll::instance = dllInstance; switch (reason) { case DLL_PROCESS_DETACH: Dll::detachQtApplication(); break; case DLL_PROCESS_ATTACH: ::DisableThreadLibraryCalls(dllInstance); Dll::attachQtApplication(); break; case DLL_THREAD_ATTACH: break; case DLL_THREAD_DETACH: break; default: break; } return TRUE;} HRESULT Dll::GetClassObject(REFCLSID classId, REFIID interfaceId, PVOID *object){ // Здесь, собственно (внутри MyFactory и прочих кишках), я могу уже создавать QObject-ы, коннектиться к сигналам/слотам и прочее.. // тут ваш код должен быть.. return MyFactory::Create(classId, interfaceId, object);} bool Dll::attachQtApplication(){ if (!qApp) { int argc = 1; QCoreApplication*app = new QCoreApplication(argc, NULL); Q_UNUSED(app); if (!Dll::m_timerIdentifier) { Dll::m_timerIdentifier = ::SetTimer(NULL, 0, Dll::m_timerInterval, Dll::qtEventsTimerProc); if (!Dll::m_timerIdentifier) return false; } } return true;} bool Dll::detachQtApplication(){ if (Dll::m_timerIdentifier) { ::KillTimer(NULL, Dll::m_timerIdentifier); Dll::m_timerIdentifier = 0; } if (qApp) delete qApp; return true;} VOID Dll::qtEventsTimerProc(HWND hwnd, UINT msg, UINT_PTR eventId, DWORD time){ Q_UNUSED(hwnd); Q_UNUSED(msg); Q_UNUSED(eventId); Q_UNUSED(time); if (qApp) qApp->processEvents();} //// Native calls// STDAPI DllGetClassObject(REFCLSID classId, REFIID interfaceId, PVOID *object){ return Dll::GetClassObject(classId, interfaceId, object);} STDAPI_(BOOL) DllMain(HINSTANCE dllInstance, DWORD reason, LPVOID reserved){ return Dll::Main(dllInstance, reason, reserved);}