[Interest] Gluing windows to the bottom [SOLVED]

Bob Hood bhood2 at comcast.net
Thu Dec 8 17:49:18 CET 2016


I went ahead and tackled it this morning.  As I suspected, it required a 
nativeEvent() handler to achieve my desired effect.  In the interests of 
posterity, here's the Windows code that works for my context. It "glues" a 
window directly onto the desktop, and keeps it from changing its Z-order when 
the user tries to click on it with the mouse:

bool Headline::nativeEvent(const QByteArray &eventType, void *message, long 
*result)
{
     *result = 0L;

     if(glue_to_desktop)
     {
if(!QString(eventType).compare("windows_generic_MSG"))
         {
             MSG* msg = (MSG*)message;

             if(msg->message == WM_WINDOWPOSCHANGING)
             {
                 RECT    r;
                 HWND    bottom = nullptr;

                 // assume the first window consuming the entire virtual
                 // desktopsize IS the desktop (e.g., "Program Manager"),
                 // andglue ourselves right on top of it
                 int desktop_width = GetSystemMetrics(SM_CXVIRTUALSCREEN);
                 int desktop_height = GetSystemMetrics(SM_CYVIRTUALSCREEN);

                 HWND w = GetTopWindow(NULL);
                 while(w)
                 {
                     GetWindowRect(w, &r);
                     if((r.right - r.left) == desktop_width && (r.bottom - 
r.top) == desktop_height)
                         break;
                     if(IsWindowVisible(w))
                         bottom = w;
                     w = GetNextWindow(w, GW_HWNDNEXT);
                 }

                 auto pwpos = (WINDOWPOS*)msg->lParam;
                 pwpos->hwndInsertAfter = bottom;
                 pwpos->flags &= (~SWP_NOZORDER);
                 // fall through to the return
             }
         }
     }

     return false;
}



On 12/5/2016 10:44 AM, Bob Hood wrote:
> Ok, here's another one for the brain trust...
>
> I'm creating windows in a tasktray application (Windows 7 64-bit).  These 
> "child" windows inherit from QWidget and are not parented, but they are 
> being created by the main application.
>
> I can "glue" them to the screen (i.e., top of Z order) using the 
> Qt::WindowStaysOnTopHint flag, and that works perfectly.  However, I want to 
> "glue" them to the desktop instead (i.e., bottom of Z order), and using 
> Qt::WindowStaysOnBottomHint doesn't appear to accomplish that with the same 
> persistence as Qt::WindowStaysOnTopHint, at least under Windows.
>
> I understand this may require a platform-specific solution, and I can accept 
> that since this tool will probably only be used under Windows.  I even tried 
> using SetWindowPos() directly after opening the window:
>
>     void Headline::showEvent(QShowEvent *event)
>     {
>         QWidget::showEvent(event);
>         SetWindowPos((HWND)winId(), HWND_BOTTOM, 0, 0, 0, 0, 
> SWP_NOACTIVATE|SWP_NOMOVE|SWP_NOSIZE);
>     }
>
> But that doesn't seem to maintain the order.  I'm also using 
> Qt::WA_ShowWithoutActivating, and that seems to work, but once I move the 
> window (using QPropertyAnimation, for example), activation and Z-order 
> shifting become an issue.  I guess my question becomes: Is there a way to 
> force a window to the background behind all other windows, and /keep/it 
> there even if it is being interacted with--programmatically or, for example, 
> by the user clicking on it?  Something tells me that intercepting and 
> ignoring events might do it, but I'm not sure if that's the right approach.
>
>
> _______________________________________________ Interest mailing list 
> Interest at qt-project.org http://lists.qt-project.org/mailman/listinfo/interest

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.qt-project.org/pipermail/interest/attachments/20161208/c07d7f60/attachment.html>


More information about the Interest mailing list