Results 1 to 18 of 18

Thread: Click-through window

  1. #1
    Join Date
    Oct 2008
    Posts
    306
    Thanks
    6
    Thanked 9 Times in 8 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Exclamation Click-through window

    In a past thread there didn't seem to be a simple solution to have a click-through window. I was wondering if there was a way by disabling all mouse events, or passing them back to the OS.
    I tried hiding and showing the window really fast but if the mouse button continues being pressed the window continues to grab the moue event.
    Someone said that I could make a 1 pixel "hole" on the window. If anyone has already done a click-through window please share the know...

  2. #2
    Join Date
    Jan 2006
    Location
    Munich, Germany
    Posts
    4,709
    Thanks
    21
    Thanked 418 Times in 411 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows

    Default Re: Click-through window

    I haven't seen your other thread so I am not sure what it is you need.
    But making a hole in a widget is really easy - just use setMask().
    http://doc.trolltech.com/4.6/qwidget.html#setMask
    ==========================signature=============== ==================
    S.O.L.I.D principles (use them!):
    https://en.wikipedia.org/wiki/SOLID_...iented_design)

    Do you write clean code? - if you are TDD'ing then maybe, if not, your not writing clean code.

  3. #3
    Join Date
    Oct 2008
    Posts
    306
    Thanks
    6
    Thanked 9 Times in 8 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: Click-through window

    I basically need a window to stay always on top (till now ok) and be click-through window. Imagine a image always on your screen, but you can't click on it. Using setMask() is a option, but using:
    Qt Code:
    1. void mouseMoveEvent(QMouseEvent *event)
    2. {
    3. setMask(region);
    4. }
    To copy to clipboard, switch view to plain text mode 
    goes too slow, and if the mouse moves to quickly the user would still be able to click on the window. (slow as in not updating the mask fast enought because of mouseMoveEvent gets called "too slow" )

  4. #4
    Join Date
    Jan 2006
    Location
    Munich, Germany
    Posts
    4,709
    Thanks
    21
    Thanked 418 Times in 411 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows

    Default Re: Click-through window

    If you click through widget is not a top level window, then you can use mapToGlobal() and handle the click on the parent widget.
    ==========================signature=============== ==================
    S.O.L.I.D principles (use them!):
    https://en.wikipedia.org/wiki/SOLID_...iented_design)

    Do you write clean code? - if you are TDD'ing then maybe, if not, your not writing clean code.

  5. #5
    Join Date
    Oct 2008
    Posts
    306
    Thanks
    6
    Thanked 9 Times in 8 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: Click-through window

    What do you mean with top-level? This is how my program call the widget:

    main.cpp:
    Qt Code:
    1. #include "app.h"
    2.  
    3. App w;
    4. w.show();
    To copy to clipboard, switch view to plain text mode 

    app.h:

    Qt Code:
    1. #include "widget.h"
    2.  
    3. Widget cantClick;
    To copy to clipboard, switch view to plain text mode 

    app.cpp:
    Qt Code:
    1. cantClick..setWindowFlags(Qt::FramelessWindowHint | Qt::SubWindow);
    2. cantClick.show();
    To copy to clipboard, switch view to plain text mode 

  6. #6
    Join Date
    Nov 2006
    Location
    Poland
    Posts
    35
    Thanks
    2
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11

    Default Re: Click-through window

    I think what you are trying to do will require platform dependency.

    Under X11 you can try reimplementing QWidget::x11Event ( XEvent * event ) and, for every pointer event i.e. ButtonPress, ButtonRelease, MotionNotify (http://tronche.com/gui/x/xlib/events/types.html), search the X11 window stack for the next window laying under the mouse and send the message to it.
    Returning false in the above function will allow you to handle the event within your window in a standard Qt's way.
    X11 window stack is ordered by widnows' z-order, so you just need to find the first window which contains the mouse pointer position and is not your own window (QWidget::winId()).

    I don't know how to achieve this on other platforms.

    Hope this helps.

  7. #7
    Join Date
    Oct 2008
    Posts
    306
    Thanks
    6
    Thanked 9 Times in 8 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: Click-through window

    Well, my target platform is Windows. I know that this is doable when programming using the WinAPI(don't know how but I know it can be...). Is there a way to "wrap" my program with the WinAPI? Or even code just this specific "window" with WinAPI and still be able to comunicate with it in a signal/slot manner?

  8. #8
    Join Date
    Oct 2008
    Posts
    306
    Thanks
    6
    Thanked 9 Times in 8 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: Click-through window

    http://www.codeproject.com/KB/wtl/transparent.aspx
    The class Igor made (in the above link) seems to do just that, but it's made for the WinAPI. How can I use his class to modify the window QT is creating?
    While doing research I came across this explanation as to how a app implemented "Click-through":
    http://bytes.com/topic/visual-basic-...-click-through
    The reason you can click through with ClocX is because it's drawn directly
    to the main screen (if you set it to click through).
    How could that be done, then?

    Drawing directly onto the desktop's hDC wouldn't show on screen, if
    there's a window on top of it, would it?
    Try this out. This will get you started.

    Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tic
    Dim dc As IntPtr = Me.GetDC(IntPtr.Zero
    Dim grfx As Graphics = Graphics.FromHdc(dc
    Dim ft As New Font(Me.Font.Name, 25, GraphicsUnit.Point
    grfx.DrawString("Writing on the desktop! Isn't this cool?", ft, Brushes.Black,125, 150
    ft.Dispose(
    grfx.Dispose(
    End Su
    Well, when it comes to Windows programming I know absolutly nothing to be able to understand exactly what's going on and how to achieve something similar in QT. Anyone?

  9. #9
    Join Date
    Jan 2006
    Location
    Munich, Germany
    Posts
    4,709
    Thanks
    21
    Thanked 418 Times in 411 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows

    Default Re: Click-through window

    I think that your problem is that you want "conflicting" things.
    One one hand, you want to draw directly on the desktop.
    On the other, you want what ever it is you want to draw, behave as a window.
    So that is a conceptual paradox.

    On top of that, you want to do that with Qt, which is meant to be crossplatform, and this is very much native.

    Still this is possible, but I am not sure that doing it with Qt would be the way to go, since you will have to go as low level as Qt lets you to get close to the native API.

    Here is an article that explains how to draw dirrectlz on the the desktop.
    http://www.codeguru.com/cpp/g-m/mult...cle.php/c4719/
    That on its own is not difficult.
    You could even (probably) use Qt do draw a dialog (by drawing it on a QPixmap, and giving its data as a CBitmap to the code in the article).
    Then you will have to "listen" for the clicks on the desktop, and see if they fall in your painted dialog region, and handle them accordingly.
    ==========================signature=============== ==================
    S.O.L.I.D principles (use them!):
    https://en.wikipedia.org/wiki/SOLID_...iented_design)

    Do you write clean code? - if you are TDD'ing then maybe, if not, your not writing clean code.

  10. #10
    Join Date
    Oct 2008
    Posts
    306
    Thanks
    6
    Thanked 9 Times in 8 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: Click-through window

    One one hand, you want to draw directly on the desktop.
    On the other, you want what ever it is you want to draw, behave as a window.
    So that is a conceptual paradox.
    `

    I want both, but not at the same time. Or the user will choose Click-through window or normal movable window.
    So if Click-through is choosen, the window(QGraphicsView) gets hidden and passes it's data(?) to somewhere that will draw it to screen.
    Can QT draw directly to screen?

    Then you will have to "listen" for the clicks on the desktop, and see if they fall in your painted dialog region, and handle them accordingly.
    Well, when it's set to click-trough I don't need to know when the mouse clicks the painted area.

    And the link you posted is a Visual Basic project, is this only doable in VB? Or can WinAPI/C++ handle that too?
    Last edited by been_1990; 21st February 2010 at 23:50. Reason: updating...

  11. #11
    Join Date
    Jan 2006
    Location
    Munich, Germany
    Posts
    4,709
    Thanks
    21
    Thanked 418 Times in 411 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows

    Default Re: Click-through window

    Well, when it's set to click-trough I don't need to know when the mouse clicks the painted area.
    Then the link I gave you will solve your problem - if you don't need to catch the mouse clicks, all you have to do is draw on the desktop, and that article shows how to do it.


    And the link you posted is a Visual Basic project, is this only doable in VB? Or can WinAPI/C++ handle that too?
    I have no idea what you are talking about.
    The code there is C++ with windows API which is C.
    Even if it was VB, the WINAPI is always C, even in VB, and you would use it the same in VB or C++.
    ==========================signature=============== ==================
    S.O.L.I.D principles (use them!):
    https://en.wikipedia.org/wiki/SOLID_...iented_design)

    Do you write clean code? - if you are TDD'ing then maybe, if not, your not writing clean code.

  12. #12
    Join Date
    Oct 2008
    Posts
    306
    Thanks
    6
    Thanked 9 Times in 8 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: Click-through window

    Sorry, I confused a VS project file with it being in VB. The example shows how to draw to the screen, but will they be click-through? My goal is not only drawing to the screen directly. The goal here is to make a app click-through, no matter how.
    Last edited by been_1990; 22nd February 2010 at 16:10.

  13. #13
    Join Date
    Oct 2008
    Posts
    306
    Thanks
    6
    Thanked 9 Times in 8 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: Click-through window

    Is there a way to send Windows (trough WinAPI) a mouse down event? If that is possible:
    user clicks on window -> make a hole on window with setMask() -> send a mouse-down event trough WinAPI - -> remove mask -> be happy!

  14. #14
    Join Date
    Oct 2008
    Posts
    306
    Thanks
    6
    Thanked 9 Times in 8 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: Click-through window

    Bump!... So? Anyone?

  15. #15
    Join Date
    Jan 2006
    Location
    Munich, Germany
    Posts
    4,709
    Thanks
    21
    Thanked 418 Times in 411 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows

    Default Re: Click-through window

    look, you described well what you want.
    You know how to catch a mouse event in Qt, you know how to set a mask.
    Now use google and MSDN to figure out how you can send events using WinAPI.
    You are not the first person to want to synthesize mouse event win WinAPI, so google should be pretty helpful.
    CodeGuru is a good place to ask C++ and windows programming questions.
    You can't expect us to feed you with everything, or do the searching for you, specially if its off topic. (not Qt)
    If you have specific questions post them.
    ==========================signature=============== ==================
    S.O.L.I.D principles (use them!):
    https://en.wikipedia.org/wiki/SOLID_...iented_design)

    Do you write clean code? - if you are TDD'ing then maybe, if not, your not writing clean code.

  16. #16
    Join Date
    Oct 2008
    Posts
    306
    Thanks
    6
    Thanked 9 Times in 8 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: Click-through window

    You're rigth high_flyer, I made opened a thread on dreamincode.net, and they helped me find out how to call mouse clicks trough the WinAPI. And after some time messing with mouse events I finnaly created what I needed.
    I'm rigth now writing and clicking away with this big, grey, 1400x900 px, semi-transparent app on top of the web browser. Here is what I came up with:

    stdafx.h:
    Qt Code:
    1. #ifndef STDAFX_H
    2. #define STDAFX_H
    3. #pragma once
    4. #define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
    5. #define _WIN32_WINNT 0x0500 // so the code would compile
    6. #include <windows.h>
    7. #endif // STDAFX_H
    To copy to clipboard, switch view to plain text mode 
    Link: http://www.daniweb.com/forums/thread6727.html
    main.cpp:
    Qt Code:
    1. #include <QtGui/QApplication>
    2. #include "widget.h"
    3.  
    4.  
    5. int main(int argc, char *argv[])
    6. {
    7. QApplication a(argc, argv);
    8. Widget w;
    9. w.show();
    10. return a.exec();
    11. }
    To copy to clipboard, switch view to plain text mode 

    widget.h:
    Qt Code:
    1. #ifndef WIDGET_H
    2. #define WIDGET_H
    3.  
    4. #include <QWidget>
    5.  
    6. namespace Ui {
    7. class Widget;
    8. }
    9.  
    10. class Widget : public QWidget {
    11. Q_OBJECT
    12. public:
    13. Widget(QWidget *parent = 0);
    14. ~Widget();
    15.  
    16. protected:
    17. void changeEvent(QEvent *e);
    18. void mouseMoveEvent(QMouseEvent *event);
    19. void mousePressEvent(QMouseEvent *event);
    20. void dragEnterEvent ( QDragEnterEvent * event );
    21. void dragMoveEvent ( QDragMoveEvent * event );
    22. void dropEvent ( QDropEvent * event ) ;
    23. bool eventFilter(QObject *obj, QEvent *event);
    24.  
    25. private:
    26. Ui::Widget *ui;
    27. int mouseX;
    28. int mouseY;
    29. };
    30.  
    31. #endif // WIDGET_H
    To copy to clipboard, switch view to plain text mode 

    widget.cpp:
    Qt Code:
    1. #include "widget.h"
    2. #include "ui_widget.h"
    3. #include "stdafx.h"
    4. #include <QtGui>
    5. #include <QDebug>
    6.  
    7. Widget::Widget(QWidget *parent) :
    8. QWidget(parent),
    9. ui(new Ui::Widget)
    10. {
    11. ui->setupUi(this);
    12. this->setWindowFlags(Qt::WindowStaysOnTopHint);
    13. setWindowOpacity(0.4);
    14. installEventFilter(this);
    15. setMouseTracking(true);
    16. setAttribute(Qt::WA_MouseNoMask);
    17. setAcceptDrops(true);
    18.  
    19. }
    20.  
    21. Widget::~Widget()
    22. {
    23. delete ui;
    24. }
    25.  
    26. void Widget::mouseMoveEvent(QMouseEvent *event)
    27. {
    28. mouseX = event->x(); // ____ Always update mouse position
    29. mouseY = event->y(); //
    30. QRegion maskedRegion(0, 0,width(), height(), QRegion::Rectangle); // mask the entire app
    31. QRegion maskedRegion3(mouseX-1, mouseY-1,2,2, QRegion::Rectangle);// mask a 2 px square around the mouse
    32. setMask(maskedRegion.subtract(maskedRegion3)); // ...
    33. }
    34.  
    35. void Widget::mousePressEvent(QMouseEvent *event)
    36. {
    37. mouseX = event->x(); // ...
    38. mouseY = event->y(); // ...
    39. QRegion maskedRegion(0, 0,width(), height(), QRegion::Rectangle);// ...
    40. QRegion maskedRegion3(mouseX-1, mouseY-1,2,2, QRegion::Rectangle);// ...
    41. setMask(maskedRegion.subtract(maskedRegion3));// ...
    42.  
    43. // INPUT windows class from stdafx.h
    44. INPUT *buffer = new INPUT[1]; //allocate a buffer
    45.  
    46. buffer->type = INPUT_MOUSE;
    47. buffer->mi.dx = 100;
    48. buffer->mi.dy = 100;
    49. buffer->mi.mouseData = 0;
    50. buffer->mi.dwFlags = MOUSEEVENTF_LEFTDOWN;
    51. buffer->mi.time = 0;
    52. buffer->mi.dwExtraInfo = 0;
    53.  
    54. SendInput(1,buffer,sizeof(INPUT));
    55. delete (buffer); //clean up our messes.
    56. }
    57.  
    58.  
    59. bool Widget::eventFilter(QObject *obj, QEvent *event)
    60. {
    61. if (event->type() == QEvent::MouseButtonPress)
    62. {
    63. QRegion maskedRegion(0, 0,width(), height(), QRegion::Rectangle);
    64. QRegion maskedRegion3(mouseX-1, mouseY-1,2,2, QRegion::Rectangle);
    65. setMask(maskedRegion.subtract(maskedRegion3));
    66.  
    67. INPUT *buffer = new INPUT[1]; //allocate a buffer
    68.  
    69. buffer->type = INPUT_MOUSE;
    70. buffer->mi.dx = 100;
    71. buffer->mi.dy = 100;
    72. buffer->mi.mouseData = 0;
    73. buffer->mi.dwFlags = MOUSEEVENTF_LEFTDOWN;
    74. buffer->mi.time = 0;
    75. buffer->mi.dwExtraInfo = 0;
    76. SendInput(1,buffer,sizeof(INPUT));
    77. delete (buffer); //clean up our messes.*/
    78. }else
    79. return false;//QWidget::eventFilter(obj, event);
    80. }
    81. //
    82. //
    83. // masking the app at the mouse's pos when dragging |
    84. // V
    85. //
    86. void Widget::dragEnterEvent ( QDragEnterEvent * event )
    87. {
    88. mouseX = event->pos().x(); // ...
    89. mouseY = event->pos().y(); // ...
    90. QRegion maskedRegion(0, 0,width(), height(), QRegion::Rectangle); // ...
    91. QRegion maskedRegion3(mouseX-1, mouseY-1,2,2, QRegion::Rectangle);// ...
    92. setMask(maskedRegion.subtract(maskedRegion3));// ...
    93. event->accept(); // accept event so that dragMoveEvent and dropEvent get called also
    94. }
    95.  
    96. void Widget::dragMoveEvent ( QDragMoveEvent * event )
    97. {
    98.  
    99. mouseX = event->pos().x();
    100. mouseY = event->pos().y();
    101. QRegion maskedRegion(0, 0,width(), height(), QRegion::Rectangle);
    102. QRegion maskedRegion3(mouseX-1, mouseY-1,2,2, QRegion::Rectangle);
    103. setMask(maskedRegion.subtract(maskedRegion3));
    104. event->accept();
    105. }
    106.  
    107. void Widget::dropEvent ( QDropEvent * event )
    108. {
    109. mouseX = event->pos().x();
    110. mouseY = event->pos().y();
    111. QRegion maskedRegion(0, 0,width(), height(), QRegion::Rectangle);
    112. QRegion maskedRegion3(mouseX-1, mouseY-1,2,2, QRegion::Rectangle);
    113. setMask(maskedRegion.subtract(maskedRegion3));
    114. event->accept();
    115. }
    116.  
    117.  
    118. // generated by QtCreator
    119. void Widget::changeEvent(QEvent *e)
    120. {
    121. QWidget::changeEvent(e);
    122. switch (e->type()) {
    123. case QEvent::LanguageChange:
    124. ui->retranslateUi(this);
    125. break;
    126. default:
    127. break;
    128. }
    129. }
    To copy to clipboard, switch view to plain text mode 

    I'm so happy, I would be jumping up and down if I wasn't so tired.
    Maybe one of you super coders wants to tweak this and make a proper tutorial for newbies like myself? I would like to know if the code used can be better, if I did some mistakes please point them out!

  17. #17
    Join Date
    Nov 2006
    Location
    Poland
    Posts
    35
    Thanks
    2
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11

    Lightbulb Re: Click-through window

    If anyone needs the same effect on X11, here is the code:

    Qt Code:
    1. #include <QX11Info>
    2. #include <X11/Xlib.h>
    3. #include <X11/extensions/shape.h>
    4.  
    5. MyWidget::MyWidget() : QWidget()
    6. {
    7. QRegion region;
    8. XShapeCombineRegion( QX11Info::display(), winId(), ShapeInput, 0, 0, region.handle(), ShapeSet );
    9. }
    To copy to clipboard, switch view to plain text mode 
    You need link X11 extensions library. You may add this to your .pro file:
    LIBS += -lXext

    Note that window's decoration will still be clickable, so you will probably have to get rid of it.

  18. #18
    Join Date
    Mar 2006
    Location
    belgium
    Posts
    14
    Thanks
    1
    Thanked 1 Time in 1 Post
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Click-through window

    window masks are different from the OP's question, see http://doc.qt.io/qt-5/qwidget.html#setMask-1
    when you click within the region, the event is not passed on to the underlying window

Similar Threads

  1. How to get mouse click events outside the Qt window?
    By montylee in forum Qt Programming
    Replies: 11
    Last Post: 13th July 2015, 22:55
  2. Replies: 0
    Last Post: 2nd January 2010, 09:58
  3. QWT right click window.. (Context Menu)
    By maveric in forum Qt Programming
    Replies: 4
    Last Post: 25th May 2008, 09:07
  4. close window when click on a label
    By sabeesh in forum Qt Programming
    Replies: 3
    Last Post: 29th October 2007, 08:35
  5. QTextBrowser - click on link - closes window
    By bruccutler in forum Newbie
    Replies: 2
    Last Post: 19th June 2007, 21:39

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.