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()
LoadLibrary()
To copy to clipboard, switch view to plain text mode
and get functions with
GetProcAddress()
GetProcAddress()
To copy to clipboard, switch view to plain text mode
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:
[...]
#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);
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 bool sTagHandled;
};
#endif // 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
To copy to clipboard, switch view to plain text mode
// 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;
{
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;
}
// 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;
}
To copy to clipboard, switch view to plain text mode
Problem is, if I define my sub-class with signals (
QOBJECT
QOBJECT
To copy to clipboard, switch view to plain text mode
macro and signal
tagDetected( const QString& )
tagDetected( const QString& )
To copy to clipboard, switch view to plain text mode
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
WM_TAG
To copy to clipboard, switch view to plain text mode
message above?
Thanks for any suggestions,
AlGaN
Bookmarks