Page 1 of 2 12 LastLast
Results 1 to 20 of 29

Thread: native event of child window

  1. #1
    Join Date
    Mar 2014
    Location
    USA
    Posts
    85
    Thanks
    17
    Thanked 2 Times in 2 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default native event of child window

    I have a sub-classed QFrame and have a third party windows type window as a child. Is there a virtual function, something like virtual bool nativeEvent(...) or some other way to get the native events of that child window?

  2. #2
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    5,230
    Thanks
    302
    Thanked 864 Times in 851 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: native event of child window

    If you can get a window handle for your native window, you can embed it in a QWindow using QWindow::fromWinId(), and can further map it to a QWidget using QWidget::createWindowContainer(). This should give you access to the events using the normal Qt event loop and event handlers.
    <=== The Great Pumpkin says ===>
    Please use CODE tags when posting source code so it is more readable. Click "Go Advanced" and then the "#" icon to insert the tags. Paste your code between them.

  3. #3
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,416
    Thanks
    37
    Thanked 1,544 Times in 1,494 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: native event of child window

    That is likely very platform specific, e.g. if the system sends events not just to the program but also to the host.

    Even if that is possible, it could be automatic or require some form of registration.

    If we assume for a moment that this is the case for the platform you are working on, then native events would be available to a native event filter, see QCoreApplication::setNativeEventFilter().

    Cheers,
    _

  4. #4
    Join Date
    Mar 2014
    Location
    USA
    Posts
    85
    Thanks
    17
    Thanked 2 Times in 2 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: native event of child window

    I don't have a WId to use QWindow::fromWinId() with, all I have is the windows handle data type HWND and don't know how to convert it to a WId. It's not a Qt window, so I can't use ->winId() to get it and the way it gets generated all I get returned is the HWND so that's all I have to work with as an identifier. What I'm working with is not a QObject or a Qanything. It's embedded in (a child of) a customized QFrame.
    Last edited by TonyInSoMD; 21st December 2016 at 10:26.

  5. #5
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,416
    Thanks
    37
    Thanked 1,544 Times in 1,494 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: native event of child window

    I think a WId on Windows is a HWND handle.

    Anyway, you've got the embedding part already done, no?

    Cheers,
    _

  6. #6
    Join Date
    Mar 2014
    Location
    USA
    Posts
    85
    Thanks
    17
    Thanked 2 Times in 2 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: native event of child window

    my HWND is m_hRectPe. Its parent is ui.m_frame_RectGraph which is a sub-class of QFrame. I'm trying to get events from m_hRectPe. The data type of m_hRectPe is proprietary a ProEssentials graph. It does operate off of windows events. I subclassed QWindow into CPeWindow and re-implemented the keyPressEvent and put a break in there just to see if it gets called. So I've got this

    Qt Code:
    1. Rat.h
    2. CPeWindow *m_pRectWindow;
    3.  
    4. Rat.cpp
    5. m_pRectWindow = (CPeWindow*)QWindow::fromWinId((WId)m_hRectPe);
    To copy to clipboard, switch view to plain text mode 
    I would think this would give me a QWindow pointer to m_hRectPe that I could then use to get Qt events from.

    in CPeWindow I have

    Qt Code:
    1. CPeWindow.cpp
    2. void CPeWindow::keyPressEvent(QKeyEvent *ev)
    3. {
    4. if(ev->key() == Qt::Key_Alt) // Break right here so that if a key press event occurs, it stops the program here
    5. {
    6. int x = 1;
    7. }
    8. }
    To copy to clipboard, switch view to plain text mode 

    when m_hRectPe has focus and I press a key, nothing happens. From previous suggestions, this route seemed to make the most sense, or am I out in left field.

    I'm sorry if I sound ignorant, its just been hard trying to create a hybrid of Qt and ProEssentials

    P.S.
    The ProEssentials guys only know how to work in mfc.

    Tony

  7. #7
    Join Date
    Mar 2014
    Location
    USA
    Posts
    85
    Thanks
    17
    Thanked 2 Times in 2 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: native event of child window

    I did some more checking, I'm 99.999% sure the WinID of m_pRectWindow is the same as m_hRectPe, that they're both pointing to the same window

  8. #8
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    5,230
    Thanks
    302
    Thanked 864 Times in 851 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: native event of child window

    If you reimplement CPeWindow:: event() do you see any events at all from the MFC window?
    <=== The Great Pumpkin says ===>
    Please use CODE tags when posting source code so it is more readable. Click "Go Advanced" and then the "#" icon to insert the tags. Paste your code between them.

  9. #9
    Join Date
    Mar 2014
    Location
    USA
    Posts
    85
    Thanks
    17
    Thanked 2 Times in 2 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: native event of child window

    I put in the code
    Qt Code:
    1. bool CPeWindow::event(QEvent *ev)
    2. {
    3. int x = 1; // set break here to see if it enters the function, should catch ANY event
    4. return true;
    5. }
    To copy to clipboard, switch view to plain text mode 
    But it never enters the function no matter what I do
    Last edited by TonyInSoMD; 21st December 2016 at 19:28.

  10. #10
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    5,230
    Thanks
    302
    Thanked 864 Times in 851 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: native event of child window

    I see this in the ProEssentials MFC DLL documentation:

    PEcreate is similar to the Windows CreateWindow function. However, it always creates a child window and places this child into the provided parent. The PEcreate function returns the Windows handle for the newly created control and this handle must be used to set properties and eventually destroy the control. As with most child windows, the ProEssentials controls will communicate with its parent through WM_COMMAND notification messages.
    So it might be that the HWND you are getting is actually the parent window and not that of the control itself. The parent window could be eating all of the events.

    If I had the time I'd download the demo and see what I could do, but time is not something I have a lot of at the moment. One thing you may find when mixing MFC and Qt is lots of apparent memory leaks upon program exit when you watch your program in the debugger. These aren't real and apparently result from MFC and Qt DLLs and static objects being unloaded / freed in a different order from how they were loaded / created. It's a nuisance that makes it hard to find real memory leaks.

    And the "are you sure it's plugged in" question: You've correctly derived CPEWindow from QWindow, added the Q_OBJECT macro, etc., etc., right?
    <=== The Great Pumpkin says ===>
    Please use CODE tags when posting source code so it is more readable. Click "Go Advanced" and then the "#" icon to insert the tags. Paste your code between them.

  11. #11
    Join Date
    Mar 2014
    Location
    USA
    Posts
    85
    Thanks
    17
    Thanked 2 Times in 2 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: native event of child window

    Before I forget to say it, thanks for everyone's time and help. The Q_OBJECT macro is in there, I'm not sure what else would need to be added other than the standard c++ stuff when sub-classing. In this particular case, the "provided parent" is the sub-classed QFrame I mentioned in the first post. The QFrame receives the WM_COMMAND messages which I get using nativeEvent. When the message->message is WM_COMMAND in the QFrame, the HIWORD(message->wParam) tells me what the communication is. They have one for keypress but not keyrelease. I'm trying to find a way to capture the keyrelease event so I can switch between vertical and horizontal scroll depending on whether the Alt key is depressed. When I asked the folks at ProEssentials if there was a way to do it, they said to add this to their sample code:

    Qt Code:
    1. DLL, C++,
    2.  
    3. In our VC demo, PEViews file
    4.  
    5. Header file
    6.  
    7. protected:
    8. //{{AFX_MSG(CPEView)
    9. afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
    10. afx_msg void OnSize(UINT nType, int cx, int cy);
    11. afx_msg BOOL OnEraseBkgnd(CDC* pDC);
    12.  
    13. // new func
    14. virtual BOOL PreTranslateMessage(MSG* pMsg);
    15.  
    16. CPP file
    17.  
    18. // new implementation
    19. BOOL CPEView::PreTranslateMessage(MSG* pMsg) {
    20. if ( pMsg->message == WM_KEYDOWN )
    21. {
    22. if (pMsg->wParam = VK_MENU)
    23. {
    24. PEnset(m_hPE, PEP_nMOUSEWHEELFUNCTION, PEMWF_VERT_SCROLL);
    25. }
    26. return TRUE;
    27. }
    28. else if (pMsg->message == WM_KEYUP )
    29. {
    30. if (pMsg->wParam = VK_MENU)
    31. {
    32. PEnset(m_hPE, PEP_nMOUSEWHEELFUNCTION, PEMWF_HORZ_SCROLL);
    33. }
    34. return TRUE;
    35. }
    36. else
    37. return CView::PreTranslateMessage(pMsg);
    To copy to clipboard, switch view to plain text mode 

    I have no idea how to translate this from MFC to Qt. I don't know jack about MFC. Maybe I should have said all this up front, if so my sincerest apologies. When I said I wasn't working in MFC, it was Qt, ProEssentials offered to customize the code for a measly $1000 USD. $1000 to add a keyrelease wparam to WM_COMMAND which in my opinion I can't believe doesn't already exist considering they have one for keypress. I'll get off my soap box now.

    edit after post
    I'm starting to think that the ProEssentials window is not a "Windows" window in that it doesn't generate events with MSG's. The only MSG's it generates are the self-made self-emitted WM_COMMAND MSG's. There aren't any Windows (or Qt) events to catch because they're not generated, only the ProEssentials events which ProEssentials generates. If so, I've been spinning my and your wheels all this time and you have my apologies. What do you think, does it sound like I might be right?
    Last edited by TonyInSoMD; 22nd December 2016 at 12:19.

  12. #12
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,416
    Thanks
    37
    Thanked 1,544 Times in 1,494 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: native event of child window

    Quote Originally Posted by TonyInSoMD View Post
    Qt Code:
    1. Rat.h
    2. CPeWindow *m_pRectWindow;
    3.  
    4. Rat.cpp
    5. m_pRectWindow = (CPeWindow*)QWindow::fromWinId((WId)m_hRectPe);
    To copy to clipboard, switch view to plain text mode 
    I would think this would give me a QWindow pointer to m_hRectPe that I could then use to get Qt events from.
    No, this wouldn't give you an object of your class, just make the standard QWindow object be interpreted as your class.

    I.e. fromWind() wraps the native window in QWindow of a subclass thereof, your cast just tells the compiler to reinterpret the object as being of your type.
    It doesn't become your type.

    What you could try is to install an event filter, (as in QObject::eventFilter(), on the returned window, but I doubt it will see any of the events sent to the wrapped window from outside Qt.

    Quote Originally Posted by TonyInSoMD View Post
    The ProEssentials guys only know how to work in mfc.
    I haven't used this myself but I was made aware that it is possible to run MFC and Qt in the same process.
    It looks like the library to do that is https://github.com/qtproject/qt-solu...r/qtwinmigrate
    existing custom controls developed with MFC or Win32 can be integrated into Qt widgets
    Cheers,
    _

  13. The following user says thank you to anda_skoa for this useful post:

    d_stranz (22nd December 2016)

  14. #13
    Join Date
    Mar 2014
    Location
    USA
    Posts
    85
    Thanks
    17
    Thanked 2 Times in 2 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: native event of child window

    Yeah, I tried eventFilter, event, nativeEvent, keyPressEvent keyReleaseEvent but none of them do anything. I haven't written any of my code in MFC so there's nothing to translate.
    The code they told me to add gets added during creation of the parent window. It intercepts the events/messages before they get sent to the ProEssentials child window. At least, that's the way I understand it, I could be wrong. In order to add something similar to my code, I would think it would have to happen in the constructor of CPeFrame (the QFrame that's the parent window). Qt doesn't have anything like that that I know of. Is there something in qApp maybe that sees all events regardless of who the child is? Maybe? I'm grasping at straws, but I'm starting to think I need to give up the ghost and accept that there's no way to do it using Qt. Which would suck.

  15. #14
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,416
    Thanks
    37
    Thanked 1,544 Times in 1,494 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: native event of child window

    Quote Originally Posted by TonyInSoMD View Post
    I haven't written any of my code in MFC so there's nothing to translate.
    While the framework is intended to serve for migrations from MFC to Qt, its main feature for doing that is to allow a "mixed mode" applications.
    I.e. Qt's widgets can be used in a predominantly MFC based applications or vice versa, basically allowing a step by step migration.

    My line of thinking is that if you have code that would work in an MFC application, then maybe it would also work if the target control was part of the Qt application via this hybrid mechanism.

    How do you currently embed the target component?
    Is it running in a separate process and you are emedding that process' window using fromWinId(), is it a COM component and you are using QAxWidget or something else?

    Cheers,
    _

  16. #15
    Join Date
    Mar 2014
    Location
    USA
    Posts
    85
    Thanks
    17
    Thanked 2 Times in 2 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: native event of child window

    Just in case it makes a difference, I'm working in VisualStudio 2013
    The following is the code to create a graph window
    Qt Code:
    1. m_hRectWnd = (HWND)ui.m_frame_RectGraph->windId(); // ui.m_frame_RectGraph is a sub-classed QFrame so that I can access nativeEvents, etc. is to be parent window of graph window
    2. RECT rect;
    3. GetClientRect(m_hRectWnd, &rect);
    4. m_hRectPE = PECreate(PECONTROL_SGRAPH, WS_VISIBLE, &rect, m_hRectWnd, 1001)
    5. // m_hRectPE is HWND of the ProEssentials graph window
    6. // PECONTROL_SGRAPH determines what type of graph is being created, in this case a rectangular scientific graph
    7. // WS_VISIBLE is the window style
    8. // &rect is location and size of object passed to the Windows CreateWindow function
    9. // m_hRectWnd is the parent window to place control passed to the Windows CreateWindow function
    10. // 1001 is random, it can be any number
    To copy to clipboard, switch view to plain text mode 
    It's not a COM, QAxWidget or any other special library other than the ProEssentials library. As far as Qt libraries go, it's just the basics.
    It's all running in a single process.

  17. #16
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    5,230
    Thanks
    302
    Thanked 864 Times in 851 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: native event of child window

    So now if you do something like this:

    Qt Code:
    1. QWindow * pWindow = QWindow::fromWinId( WinId( m_hRectPE ) );
    2. pWindow->installEventFilter( this );
    To copy to clipboard, switch view to plain text mode 

    and implement MainWindow:: eventFilter(), do you see events coming from the chart?
    <=== The Great Pumpkin says ===>
    Please use CODE tags when posting source code so it is more readable. Click "Go Advanced" and then the "#" icon to insert the tags. Paste your code between them.

  18. #17
    Join Date
    Mar 2014
    Location
    USA
    Posts
    85
    Thanks
    17
    Thanked 2 Times in 2 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: native event of child window

    in event filter I put:
    Qt Code:
    1. bool CRat::eventFilter(QObject *pObject, QEvent *pEvent)
    2. {
    3. int x;
    4. int y = (WId)m_hRectPE; // used to verify object throwing the event is the graph window
    5. if(pObject->isWindowType)
    6. {
    7. x = ((QWindow*)pObject)->winId(); // used to verify the object throwing the event is the graph window
    8. }
    9. qDebug() << "Object = " << x << "Graph = " << y << "Event Type = " << pEvent->type();
    10. return false;
    11. }
    To copy to clipboard, switch view to plain text mode 

    The only events I can get to trigger are:
    resize, but only during construction
    Focus In
    Focus About to Change
    Focus Out
    On left mouse click: Input Method Query
    When using a menu option to open a user input window:
    Window Blocked
    Window Unblocked

    I've tried everything I can think of to trigger another event, but nothing happens. The graph has built-in keyboard shortcuts, for example the "x" key brings up an export window. Pressing these do not trigger an event even though events (keyPress keyRelease) are obviously occurring.

  19. #18
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    5,230
    Thanks
    302
    Thanked 864 Times in 851 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: native event of child window

    I am guessing that your plot window is probably a composite and that the handle you are getting is just the top-most parent. In that case, it is likely that whatever events the lower level windows are handling are either eaten by them or passed up to the top-most parent, which eats them instead.

    You might have to drop into Windows code to determine 1) if there is actually a window hierarchy inside the top-level control, and 2) if you can create a QWindow around one of these and see the events you want.

    There is an EnumChildWindows() method in the Windows API that you can use for this purpose. It takes a handle to the top-most window along with a pointer to a callback function that will be called for every child window found. You could use it like this:

    Qt Code:
    1. // In MainWindow.cpp
    2.  
    3. #include <windows.h> // probably needed
    4. BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lParam)
    5. {
    6. MainWindow * pMain = (MainWindow *)lParam;
    7. QWindow * pWind = QWindow::fromWinId( hwnd );
    8. pWind->installEventFilter( pMain );
    9. return TRUE;
    10. }
    11.  
    12. void MainWindow::EnumeratePEChildren( HWND hPERect )
    13. {
    14. EnumChildWindows( hPERect, EnumWindowsProc, LPARAM( this ) );
    15. }
    To copy to clipboard, switch view to plain text mode 

    This will result in the event filter you have already written being installed on every child window of the PERect window (if any). You'll be able to see (by way of the QObject argument to the event filter) which child window is sending which event. Hopefully you'll see some of what you are trying to intercept.

    Note that the enumeration is recursive - you will get -all- children, all the way down the hierarchy if the hierarchy exists. You could try retrieving other information about the window (eg. GetWindowText(), etc.) to see if the name of the window makes sense or to narrow it down by what you do inside it. At that point, you should be able to determine exactly which child is the one to watch.
    <=== The Great Pumpkin says ===>
    Please use CODE tags when posting source code so it is more readable. Click "Go Advanced" and then the "#" icon to insert the tags. Paste your code between them.

  20. #19
    Join Date
    Mar 2014
    Location
    USA
    Posts
    85
    Thanks
    17
    Thanked 2 Times in 2 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: native event of child window

    Sorry about the long delay in my response, I was out for the Christmas holiday. I'm going to show my ignorance here. All my programming has been in Qt and I've never really had to resort to the Windows API. Don't assume there's I step I'm just going to "know" because any idiot would. I'm dumber than an idiot in this case. The main class for the program is CRat (RCS Analysis Tool). I added d_stranz's code exactly to the .cpp . The only difference is I also added
    Qt Code:
    1. void EnumeratePEChildren( HWND hPERect );
    To copy to clipboard, switch view to plain text mode 
    to the .h file
    Is there something I need to add to the .h file for the CALLBACK function? Where the callback function is called in EnumeratePEChildren it doesn't have any parameters or even parenthesis with it. Is this correct? When I try to compile I get an
    error C2065: 'EnumWindowsProc' : undeclared identifier
    error, which doesn't surprise me looking at the code. What step am I missing?
    While I'm at it, I'm guessing I would run EnumeratePEChildren at the end of the constructor after all the other windows have been created. Is this correct? Can I use it in the constructor if the PE windows have been previously created in the constructor?
    Again, thanks for all the help. You guys have really gone out of your way to help.

    Tony

  21. #20
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    5,230
    Thanks
    302
    Thanked 864 Times in 851 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: native event of child window

    error C2065: 'EnumWindowsProc' : undeclared identifier
    Did you add the function I wrote (EnumWindowsProc) to the MainWindow.cpp file? Did you add it before or after your implementation of MainWindow:: EnumeratePEChildren()? The compiler is complaining because it can't resolve your reference to that function when you use it in EnumeratePEChildren. So if you did add it, you probably need to move it ahead of your use of it in EnumPEChildren() (or add a forward declaration).

    The #include <windows.h> is there because it is probably necessary for the declaration of the Windows API function EnumChildWindows() and the declarations of the BOOL and CALLBACK macros / typedefs.

    I would not call the EnumeratePEChildren method in the constructor. It might be OK to do so, but it is probably a better idea to call it in the MainWindow showEvent(). At that point, all of the windows have been fully instantiated and are ready to be made visible. In the constructor, the widgets / windows have been created, but they might not be fully instantiated (eg. with zero size, etc.)

    If you are using Visual C++, I think the linker will automatically link in the required Windows run-time libraries to resolve the reference to the EnuChildWIndows() function.
    <=== The Great Pumpkin says ===>
    Please use CODE tags when posting source code so it is more readable. Click "Go Advanced" and then the "#" icon to insert the tags. Paste your code between them.

Similar Threads

  1. Replies: 0
    Last Post: 9th August 2016, 16:37
  2. Native parent window for QWidget (IPreviewHandler)
    By Kevsoft in forum Qt Programming
    Replies: 3
    Last Post: 19th July 2015, 13:24
  3. Replies: 5
    Last Post: 17th September 2013, 06:45
  4. Replies: 11
    Last Post: 4th June 2008, 07:22

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.