PDA

View Full Version : Problems with recieving Windows messages using winEvent



rbrafi
30th May 2011, 18:33
Hi,
I have some problems with winEvent messages. I noticed that my program recieve Windows events only when it's active window. Furthermore for some reason it doesnt recognize some of keyboard keys. Looks like winEventFilter function is going to 'cure' this. I found in qt documentation:

To handle system wide messages, such as messages from a registered hot key, you need to install an event filter on the event dispatcher, which is returned from QAbstractEventDispatcher::instance().
I reimplemented winEvent function in my MainWindow class

mainwindow.h


...
private:
virtual bool winEvent(MSG *message, long *result);
...


mainwindow.cpp


...
bool MainWindow::winEvent(MSG *message, long *result)
{
switch(message->message)
{
case WM_KEYDOWN:
qDebug("KEYDOWN");
switch(message->wParam)
{
case Qt::Key_A :
qDebug("- A");
break;

case Qt::Key_F12 :
qDebug("- F12");
break;
default:
break;
}
break;
default:
return false;
}
return false;
}
...


After pressing A Key:


KEYDOWN
- A

After pressing F12 Key:



KEYDOWN


The problem is my stupidity. I tried many times but failed. I need some small example but there is nothing I believe... :confused:

So again: What can I do for my app to recieve winEvents while not active? And why this code can't recognize keys like: F10, F11, F12, PrtSc, Ins, Ctrl? Could you do some tiny example how to handle system wide messages, please?

wysota
30th May 2011, 21:27
You are incorrectly assuming WinAPI key identifiers and Qt key identifiers match.

rbrafi
31st May 2011, 12:05
Thank you for your reply! One of problem is solved.

But is there a way for my app to recieve windows messages when it is not active window?

wysota
31st May 2011, 12:07
I guess you'd have to install a hook using WinAPI calls. This is really out of scope of this forum.

rbrafi
31st May 2011, 20:12
Thank you again. Guess I can only hope that in future relases of Qt there will be a new function added that will allow it in easy way. :p

wysota
31st May 2011, 21:50
Why double a function that already exists?

rbrafi
1st June 2011, 01:10
If you mean hooks... well... I don't like it. I started creating in qt because I can't stand structure of WinApi...

I think about using QAbstractEventDispatcher in my program. If I get some free-time I'll look into doc and try to work with it.

wysota
1st June 2011, 01:50
I don't see how this would help. You want to intercept messages that are not meant for you, your application won't receive them unless you explicitly request that by installing a hook in Windows message loop.

rbrafi
1st June 2011, 23:34
QAbstractEventDispatcher Doc

An event dispatcher receives events from the window system and other sources. It then sends them to the QCoreApplication or QApplication instance for processing and delivery.

The event filter function set here is called for all messages taken from the system event loop before the event is dispatched to the respective target, including the messages not meant for Qt objects.

That looks fine for me. If I understand correctly it can do the work that hooks do. Still, I have a problem with implementing it into my code... Guess, I have to try again...

wysota
1st June 2011, 23:46
It doesn't say anything about events meant for other applications.

rbrafi
2nd June 2011, 00:57
Ugh... You are right... I'm assuming that "messages not meant for Qt objects" are messages for other applications and I am probably wrong. Just in case I want to give it a try...

I have problem (again :( ) with using Event Dispatcher.

My MainWindow constructor:


ui->setupUi(this);
QAbstractEventDispatcher::EventFilter MyEventFilter;
QAbstractEventDispatcher *eventDispatcher = QAbstractEventDispatcher::instance();
eventDispatcher->setEventFilter(MyEventFilter);



bool MainWindow::MyEventFilter(MSG *message)
{
switch(message->message)
{
case WM_KEYDOWN:
qDebug("KEYDOWN");
switch(message->wParam)
{
case 0x41 :
qDebug("- A");
break;

case VK_F12 :
qDebug("- F12");
break;
default:
break;
}
break;
default:
return false;
}
return false;
}

Errorlog:

In constructor 'MainWindow::MainWindow(QWidget*):
warning:'MyEventFilter' may be used uninitialized in this function
In constructor 'MainWindow::MainWindow(QWidget*):
warning:'MyEventFilter' may be used uninitialized in this function

It runs, but crashes.

How should I initialize MyEventFilter? I tried couple of times but effects were even worse than that...

wysota
2nd June 2011, 09:11
QAbstractEventDispatcher::EventFilter is supposed to be a function and you are using it as a variable.

rbrafi
6th June 2011, 16:13
I decided that it is better to use RegisterHotKey() function from winApi. It saves a lot of time in my case. Still, I feel unsatisfied for some reason :confused: Thank you for your advices. They helped a lot.