Need Inspiration for my Transparent Tooltip Widget
-
Hey guys,
I am developing a transparent full-screen always-on-top overlay. Let us say its name is TRA. It should pass through all mouse clicks to the next window (outside of Qt) but it should be able to display tooltips in a specific region of the display (here I do not need clicks to be passed). I am developing with C++ and Qt6.I am new to Windows and its windows system/manager, so I tried a lot, but now I guess I need a hint from someone more experienced... I work on two scenarios and maybe someone has an idea how to solve one of them:
-
Non full-screen overlay: I finished my work making TRA just for the specific region without implementing to pass clicks which would be fine. The problem is that TRA is always on top, which is good, but when I click outside the specific region and thus TRA, TRA is not focused anymore and do not show any tooltips. Is it possible to have TRA always reacting to show tooltip independent from any actions outside of TRA?
-
Full-screen overlay: To overcome the window-focus problem, I decided to try a full-screen variant of it. Tooltips are working finde because with every click the window stays in focus. Now I need to pass the clicks to the stuff of Windows outside of TRA. I found setting the exstyles from the
Windows.h, so I build something like that:
void TransparentWindow::mousePressEvent(QMouseEvent *event){ QPoint pos = event->globalPos(); if(event->button() == Qt::LeftButton){ sendClick(pos, Mouse::LEFT_DOWN); } else if(event->button() == Qt::RightButton){ sendClick(pos, Mouse::RIGHT_DOWN); } } void TransparentWindow::mouseReleaseEvent(QMouseEvent *event){ QPoint pos = event->globalPos(); if(event->button() == Qt::LeftButton){ sendClick(pos, Mouse::LEFT_UP); } else if(event->button() == Qt::RightButton){ sendClick(pos, Mouse::RIGHT_UP); } } void TransparentWindow::sendClick(const QPoint &pos, Mouse mouse){ setWindowTransparent(); POINT point; point.x = static_cast<LONG>(pos.x()); point.y = static_cast<LONG>(pos.y()); HWND hwnd = WindowFromPoint(point); if (hwnd != nullptr) { INPUT input; input.type = INPUT_MOUSE; input.mi.dx = 0; input.mi.dy = 0; input.mi.mouseData = 0; input.mi.time = 0; input.mi.dwExtraInfo = 0; switch (mouse) { case Mouse::LEFT_DOWN: input.mi.dwFlags = MOUSEEVENTF_LEFTDOWN; m_mouseProcessing = true; break; case Mouse::LEFT_UP: input.mi.dwFlags = MOUSEEVENTF_LEFTUP; m_mouseProcessing = false; break; case Mouse::RIGHT_DOWN: input.mi.dwFlags = MOUSEEVENTF_RIGHTDOWN; m_mouseProcessing = true; break; case Mouse::RIGHT_UP: input.mi.dwFlags = MOUSEEVENTF_RIGHTUP; m_mouseProcessing = false; break; } // SetCursorPos(point.x, point.y); SendInput(1, &input, sizeof(INPUT)); } else { qDebug() << "No Window found."; } unsetWindowTransparent(); } void TransparentWindow::setWindowTransparent(){ m_exStyle |= WS_EX_LAYERED | WS_EX_TRANSPARENT; SetWindowLong(m_hwnd, GWL_EXSTYLE, m_exStyle); SetLayeredWindowAttributes(m_hwnd, RGB(0, 0, 0), 255, LWA_ALPHA); Sleep(100); } void TransparentWindow::unsetWindowTransparent(){ m_exStyle &= ~WS_EX_LAYERED & ~WS_EX_TRANSPARENT; SetWindowLong(m_hwnd, GWL_EXSTYLE, m_exStyle); SetLayeredWindowAttributes(m_hwnd, RGB(0, 0, 0), 255, LWA_ALPHA); }Technically it works, but it is not pretty and needs some work. but the recreation(?) of the exstyles makes the transparent window
-