I'm a little confused. Are you assuming I've sub-classed QMainWindow so that I can re-implement showEvent() and add to it's .cpp? If so, I haven't. It sounds like this is something I need to do in order to follow your suggestions. Is that correct?
Printable View
I'm a little confused. Are you assuming I've sub-classed QMainWindow so that I can re-implement showEvent() and add to it's .cpp? If so, I haven't. It sounds like this is something I need to do in order to follow your suggestions. Is that correct?
Sorry, I re-read your first post and see that you've subclassed QFrame. Put the code in that QFrame subclass instead of subclassing QMainWindow.
I tried it starting at the subclassed QFrame so that it gets it and all its children and still the only events I can get are
23 Focus about to change
9 Focus out
8 Focus in
207 InputMethodQuery
103 WindowBlocked
104 WindowUnblocked
PE obviously has it set up so that something is eating all the events. MFC accesses the events through PreTranslateMessage. Does Qt have an equivalent? I haven't been able to find one.
From what I understand of Qt, it just doesn't make sense that eventFilter isn't catching it.
Huh. About the only other thing I can suggest is to install an event filter using QCoreApplication::installNativeEventFilter(). You'll have to derive a class from QAbstractNativeEventFilter and implement the QAbstractNativeEventFilter::nativeEventFilter() method. Be sure to return "false" from the method, otherwise the messages will be eaten by your filter and never get to the rest of your app.
If this is successful at trapping messages from the PE window, then you could use this filter to create your own QEvents and post them to the event loop for handling by your QFrame.
Thanks, subclassing QAbstractNativeEventFilter and installNativeEventFilter worked. I doubt that this is what you meant, but this is what I did.
Subclassing QAbstractNativeEventFilter:
Code:
#include<QAbstractNativeEventFilter> #include <QObject> { Q_OBJECT public: ~CCustomEventFilter(); virtual bool nativeEventFilter(const QByteArray &eventType, void *message, long *result) Q_DECL_OVERRIDE; signals: void ShiftKeyDown(); void ShiftKeyUp(); }; .cpp file #include "ccustomeventfilter.h" #include "windows.h" standard default constructor that doesn't do anything bool CCustomEventFilter::nativeEventFilter(const QByteArray &eventType, void *message, long *result) { if (eventType == "windows_generic_MSG") { MSG *pMsg = (MSG*)message; if (pMsg->message == WM_KEYDOWN) { if (pMsg->wParam == VK_SHIFT) { emit ShiftKeyDown(); } } else if (pMsg->message == WM_KEYUP) { if (pMsg->wParam == VK_SHIFT) { emit ShiftKeyUp(); } } } return false; }
Then in my MainWindow program (CRat);
Code:
in CRat.h #include "ccustomeventfilter" CCustomEventFilter *m_pKeyFilter; slots: void OnKeyShiftDown(); void OnKeyShiftUp(); in CRat.cpp in constructor m_pKeyFilter = new CCustomEventFilter(); qApp->installNativeEventFilter(m_pKeyFilter); connect(m_pKeyFilter, SIGNAL(ShiftKeyDown()), this, SLOT(OnKeyShiftDown())); connect(m_pKeyFilter, SIGNAL(ShiftKeyUp()), this, SLOT(OnKeyShiftUp())); in body of code void CRat::OnKeyShiftDown() { set graph to vertical scroll } void CRat::OnKeyShiftUp() { set graph to horizontal scroll }
I tried to find examples where a subclass native event filter sent out an event or something that could act on MainWindow objects (in my case, graph windows) but couldn't find any. All the examples I could find just showed how to print out a deBug() line when it hit the event you wanted. That doesn't tell me how to get it to do anything in the program I'm working from. This was the only way I could think of to make it either throw an event or emit a signal that MainWindow could use. It works, but there has GOT to be a prettier way to do it.
Anyway, without all your help d_stranz I would have never gotten it and I thank you from the bottom of my heart.
Tony
No, that's what I did mean, but the implementation was left as an exercise for the reader... Looks like you have been successful at generating proof of concept.Quote:
Thanks, subclassing QAbstractNativeEventFilter and installNativeEventFilter worked. I doubt that this is what you meant, but this is what I did.
Shouldn't you be also checking to make sure that the window handle matches that of the PE window (or whichever child window) that is generating (some of) the messages? I would think that your native event filter would be called for -all- windows in your app (Qt and non-Qt) since it is installed at the app level and isn't restricted to any particular window. You wouldn't want the shift key to affect the PE control no matter where it is pressed in your app.
I think I mentioned in an earlier post that I haven't done any work with the windows API. Thanks for clueing me in on the windows handle. It wasn't until you mentioned it that I got to looking at the MSG struct and saw that it gave you the HWND of the window that generated the message. Now I can double check to make sure it was the PE graph that sent the message. Thanks! I had the signal/slot send/receive the HWND as a parameter and then checked it against the HWND of the PE graph in the MainWindow program (CRat) before making any changes. This thread has been a lot of help to me and I hope it helps some one else in the future that has a similar problem getting messages.Quote:
Shouldn't you be also checking to make sure that the window handle matches that of the PE window (or whichever child window) that is generating (some of) the messages?
I think it would be more efficient to check it in the native filter so you can decide not to send the signal at all instead of sending the signal for every window. Since you have derived a class from QAbstractNativeEventFilter, you can add an HWND as a member variable of that class, set it to the PE control's HWND, and check it first thing when the event comes in. If it doesn't match, then you can immediately return false instead of firing off the signal. If you have more than one of these PE controls in your app, you could make the member variable a collection of HWNDs (a QHash< HWND > maybe).Quote:
I had the signal/slot send/receive the HWND as a parameter
Glad to help. I spent years drinking the Windows Koolade before learning about Qt, so it's good to dust off the old brain cells once in a while to remember some of that stuff.Quote:
This thread has been a lot of help to me and I hope it helps some one else in the future that has a similar problem getting messages.
You can create instances of Qt event classes and use QCoreApplication::postEvent() or QCoreApplication::sendEvent() to send them to a receiver object.
However using signals as you did looks fine as well and easier in this case.
Cheers,
_