AlGaN
23rd September 2008, 11:34
Hi,
I have to intercept a generated window message (Win32 struct type MSG) sent out of a Win32/MFC DLL. So I searched for intercepting native Events and found methods
QWidget::winEvent( MSG* msg, long* result)
from QWidget and
QCoreApplication::winEventFilter( MSG* msg, long* result) from QCoreApplication.
I have to load the DLL dynamically with
LoadLibrary() and get functions with
GetProcAddress() so I do not certainly want the DLL to be loaded from QApplication derived class in my app. But the message generated is no window message either because it comes from hardware connected so the message could not fit in any QWidget derived sub-class either.
Because there seem no other possibilities I tried to load DLL from a derived QWidget class and override QWidget::winEvent(MSG* msg, long* result). So my principal parts are like this:
Engine.hpp
[...]
#ifdef BUILD_ENGINE
#define EXPORT_ENGINE Q_DECL_EXPORT
#else
#define EXPORT_ENGINE
#endif
#define WM_TAG WM_USER+11111
#include <QtCore>
#include <QWidget>
#include <windows.h>
#include <winbase.h>
class EXPORT_ENGINE MyWidget : public QWidget
{
Q_OBJECT
public:
typedef bool (*StartScan)(void*, int*, int, int, int, char*);
typedef bool (*SelectReader)(void*, int*, int*, int*, char*, int);
typedef bool (*StopScan)(void*, int);
MyWidget( QWidget* parent = 0);
bool bind();
bool open();
bool close();
virtual bool winEvent( MSG* message, long* result );
// signals:
// void tagDetected( const QString& tag );
private:
static bool StopScanDll( HWND hwParam, int id );
static bool StarScanDll( HWND hwParam, int* id, int type, int com, int baud, QString name);
static bool SelectReaderDll( HWND hwParam, int* id, int* com, int* baud, char* name);
char* mReaderName;
bool mStarted;
QHash< int, int > mBaudRateTable;
static HINSTANCE sDll;
static int sReaderID;
static int sReaderType;
static int sReaderCom;
static int sReaderBaud;
static QString sReaderName;
static bool sTagHandled;
};
#endif // ENGINE_HPP
Engine.cpp
// MyWidget.cpp
#include <QtGui>
#include "MyWidget.hpp"
HINSTANCE MyWidget::sDll = 0;
int MyWidget::sReaderID = 0;
int MyWidget::sReaderType = 0;
int MyWidget::sReaderBaud = 0;
int MyWidget::sReaderCom = 0;
QString MyWidget::sReaderName = "";
bool MyWidget::sTagHandled = false;
MyWidget::MyWidget( QWidget* parent ) : QWidget( parent )
{
sDll = LoadLibrary( L"RFID.dll" );
mReaderName = new char[255];
sTagHandled = true;
int baudRateValues[] = {0, 1200, 2400, 4800, 9600, 14400, 19200, 38400, 56000, 57600, 115200 };
for (int i = 0; i < 11; i++ )
{
mBaudRateTable[i] = baudRateValues[i];
}
}
bool MyWidget::StopScanDll( HWND hwParent, int id )
{
[...]
MyWidget::StopScan FStopScanDll;
FStopScanDll = NULL;
FStopScanDll = (MyWidget::StopScan)GetProcAddress( sDll, "StopScan" );
if ( FStopScanDll == NULL )
return false;
bool b = FStopScanDll( hwParent, id );
return b;
}
[...]
bool RfidWidget::bind()
{
bool b = SelectDll( this->winId(), &sReaderType, &sReaderCom, &sReaderBaud, mReaderName );
sReaderName = mReaderName;
return b;
}
[...]
bool MyWidget::winEvent( MSG* message, long* result )
{
UINT msg = message->message;
WPARAM wp = message->wParam;
LPARAM lp = message->lParam;
switch ( msg )
{
case WM_TAG:
qDebug() << "WM_TAG";
emit tagDetected( (char*)lp );
return true;
break;
default:
break;
}
return false;
}
Problem is, if I define my sub-class with signals (
QOBJECT macro and signal
tagDetected( const QString& ) I get linker errors from meta object compiling. I suppose this comes from interfering with native Win32 events?
Is there any other possibility to get native events like
WM_TAG message above?
Thanks for any suggestions,
AlGaN
I have to intercept a generated window message (Win32 struct type MSG) sent out of a Win32/MFC DLL. So I searched for intercepting native Events and found methods
QWidget::winEvent( MSG* msg, long* result)
from QWidget and
QCoreApplication::winEventFilter( MSG* msg, long* result) from QCoreApplication.
I have to load the DLL dynamically with
LoadLibrary() and get functions with
GetProcAddress() so I do not certainly want the DLL to be loaded from QApplication derived class in my app. But the message generated is no window message either because it comes from hardware connected so the message could not fit in any QWidget derived sub-class either.
Because there seem no other possibilities I tried to load DLL from a derived QWidget class and override QWidget::winEvent(MSG* msg, long* result). So my principal parts are like this:
Engine.hpp
[...]
#ifdef BUILD_ENGINE
#define EXPORT_ENGINE Q_DECL_EXPORT
#else
#define EXPORT_ENGINE
#endif
#define WM_TAG WM_USER+11111
#include <QtCore>
#include <QWidget>
#include <windows.h>
#include <winbase.h>
class EXPORT_ENGINE MyWidget : public QWidget
{
Q_OBJECT
public:
typedef bool (*StartScan)(void*, int*, int, int, int, char*);
typedef bool (*SelectReader)(void*, int*, int*, int*, char*, int);
typedef bool (*StopScan)(void*, int);
MyWidget( QWidget* parent = 0);
bool bind();
bool open();
bool close();
virtual bool winEvent( MSG* message, long* result );
// signals:
// void tagDetected( const QString& tag );
private:
static bool StopScanDll( HWND hwParam, int id );
static bool StarScanDll( HWND hwParam, int* id, int type, int com, int baud, QString name);
static bool SelectReaderDll( HWND hwParam, int* id, int* com, int* baud, char* name);
char* mReaderName;
bool mStarted;
QHash< int, int > mBaudRateTable;
static HINSTANCE sDll;
static int sReaderID;
static int sReaderType;
static int sReaderCom;
static int sReaderBaud;
static QString sReaderName;
static bool sTagHandled;
};
#endif // ENGINE_HPP
Engine.cpp
// MyWidget.cpp
#include <QtGui>
#include "MyWidget.hpp"
HINSTANCE MyWidget::sDll = 0;
int MyWidget::sReaderID = 0;
int MyWidget::sReaderType = 0;
int MyWidget::sReaderBaud = 0;
int MyWidget::sReaderCom = 0;
QString MyWidget::sReaderName = "";
bool MyWidget::sTagHandled = false;
MyWidget::MyWidget( QWidget* parent ) : QWidget( parent )
{
sDll = LoadLibrary( L"RFID.dll" );
mReaderName = new char[255];
sTagHandled = true;
int baudRateValues[] = {0, 1200, 2400, 4800, 9600, 14400, 19200, 38400, 56000, 57600, 115200 };
for (int i = 0; i < 11; i++ )
{
mBaudRateTable[i] = baudRateValues[i];
}
}
bool MyWidget::StopScanDll( HWND hwParent, int id )
{
[...]
MyWidget::StopScan FStopScanDll;
FStopScanDll = NULL;
FStopScanDll = (MyWidget::StopScan)GetProcAddress( sDll, "StopScan" );
if ( FStopScanDll == NULL )
return false;
bool b = FStopScanDll( hwParent, id );
return b;
}
[...]
bool RfidWidget::bind()
{
bool b = SelectDll( this->winId(), &sReaderType, &sReaderCom, &sReaderBaud, mReaderName );
sReaderName = mReaderName;
return b;
}
[...]
bool MyWidget::winEvent( MSG* message, long* result )
{
UINT msg = message->message;
WPARAM wp = message->wParam;
LPARAM lp = message->lParam;
switch ( msg )
{
case WM_TAG:
qDebug() << "WM_TAG";
emit tagDetected( (char*)lp );
return true;
break;
default:
break;
}
return false;
}
Problem is, if I define my sub-class with signals (
QOBJECT macro and signal
tagDetected( const QString& ) I get linker errors from meta object compiling. I suppose this comes from interfering with native Win32 events?
Is there any other possibility to get native events like
WM_TAG message above?
Thanks for any suggestions,
AlGaN