windows 将窗口固定到桌面/将窗口粘附到桌面/“始终在底部”窗口

wtzytmuj  于 2023-01-06  发布在  Windows
关注(0)|答案(2)|浏览(419)

我正在用C ++/Win32开发一个基本的桌面应用程序。
我现在的目标是创建一个基本的"便利贴"应用程序,它可以固定/粘在桌面上,也就是说,总是在桌面前面,但总是在其他应用程序后面。这真的是一个个人项目,只是为了对抗我糟糕的记忆力,让我的任务/笔记总是在桌面上可见,这样我就不会在启动电脑时错过它们,等等。
我的目标行为将类似于Stardock Fences*("有点",因为我不打算在那里存储任何桌面图标,但你希望得到的想法)*
我从Get Started with Win32 and C++ docs开始使用sample code,以获得最基本的win32最小窗口设置。

    • 目前为止我得到的:**

1.在处理事件WM_SETFOCUS * 时,我通过在窗口过程(WindowProc)中调用SetWindowPos,设法将窗口保持在所有其他应用程序的底部和桌面的前面(我第一次尝试将事件WM_WINDOWPOSCHANGING作为suggested in this answer,但这导致拖动窗口时出现恼人的 Flink )*。

case WM_SETFOCUS:
        SetWindowPos(hwnd, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE);
        return 0;

1.* * 问题**:我的窗口一直在桌面前面除非我单击任务栏中"显示桌面"按钮上的(或点击Windows + D快捷方式)。由于我自己经常使用此快捷方式,所以我希望无论发生什么情况,我的窗口都一直在桌面上。
1.一个不够令人满意但仍然是我设法做到的事情是,在点击Windows + D * 后单击任何其他窗口时,将我的窗口带回桌面前面(这在多个显示器上通常是有意义的,例如在第一个显示器上打开一个随机应用程序,将在另一个屏幕上的桌面前面切换回我自己的应用程序)*。我可以使用事件WM_SIZE并调用ShowWindow然后SetWindowPos来完成此操作,仍在WindowProc

case WM_SIZE:
        ShowWindow(hwnd, SW_SHOWNORMAL);
        SetWindowPos(hwnd, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE);
        return 0;

虽然不理想,因为我真的希望我的应用程序总是留在桌面前面,并"生存"到显示桌面的行动。

    • 我尝试过**

我检查了这些答案,但不知道如何实现我想要的。

  1. How to make 'always-on-bottom'-window
  2. Window “on desktop”:注意,我在wWinMain中尝试了SetParent的技巧,如下所示
HWND desktop = FindWindow(L"ProgMan", L"Program Manager");
if (desktop == NULL)
{
    return 0;
}

ShowWindow(hwnd, nCmdShow);
SetParent(hwnd, desktop);

然而,我的应用程序再也看不到了,即使FindWindow没有返回NULL,而是一个实际的句柄。

  1. Make aplication always on Bottom (pinned to desktop, behind all other apps) in C++/WinAPI [duplicate]
  2. Disable Minimize, Maximize, Close buttons in Win32我尝试了这些操作来"拦截" Show Desktop事件,但似乎此事件不会随Show Desktop操作触发。
    我错过什么了吗?
2hh7jdfx

2hh7jdfx1#

正如@JonathanPotter所指出的,当点击Windows + D或Show Desktop按钮时,WM_WINDOWPOSCHANGING事件被触发,窗口被移动到-32 000, -32 000(其大小也被改变)

    • 注**:点击Windows + D时,不带WS_MINIMIZEBOX样式的窗口似乎未接收到WINDOWPOSCHANGING事件。因此,在这种情况下未检测到-32000坐标......使用ex样式WS_EX_TOOLWINDOW * 时也注意到了相同的问题(因为这个去掉了最小化框,即使你设置了样式标记WS_MINIMIZEBOX)*.没有找到解决这个问题的方法,所以我坚持使用重叠窗口。

要防止这种移动,只需在lParam中传递的WINDOWPOS结构上设置标志SWP_NOMOVESWP_NOSIZE
因此,作为最终结果,为了实现所需的行为 (即总是在每隔一个窗口之后,但总是在桌面之前),添加到doc's sample中的唯一所需代码如下,放置在窗口过程WindowProc的switch语句中:

    • 编辑**:使用HWND_BOTTOM强制Z顺序以确保窗口始终位于底部的最佳位置也是在WM_WINDOWPOSCHANGING事件中。实际上,当拖动窗口时,调用SetWindowPos以在WM_SIZE事件中强制它,就像我之前所做的那样,会在调整窗口大小时导致窗口 Flink ,而当在WM_WINDOWPOSCHANGING中直接设置WINDOWPOS结构的hwndInsertAfter属性时不发生 Flink 。
case WM_WINDOWPOSCHANGING:
{
    WINDOWPOS* pos = (WINDOWPOS*)lParam;
    // Show desktop (Windows + D) results in the window moved to -32000, -32000 and size changed
    if (pos->x == -32000) {
        // Set the flags to prevent this and "survive" to the desktop toggle
        pos->flags |= SWP_NOMOVE | SWP_NOSIZE;
    }
    // Also force the z order to ensure the window is always on bottom
    pos->hwndInsertAfter = HWND_BOTTOM;
    return 0;
}
sc4hvdpw

sc4hvdpw2#

我遇到了同样的问题,并通过使用“autohotkey”找到了解决方案。autohotkey是一个强大的免费脚本语言,用于在Windows中实现自动化,您可以从here下载。下面的脚本是一个示例,当您在.ahk文件中执行它时,它会使便笺始终位于顶部(你可以复制这些代码到一个简单的记事本,然后改变.txt到.ahk如果你已经安装了autohotkey在你的计算机上).通过右键点击.ahk文件,你也可以看到编译选项.ahk成.exe,使您能够分享它与您的其他朋友太:

#SingleInstance Force
GroupAdd, ontop, Sticky Notes ; you can replace sticky note by any application, 
                              ; if you know the name of that application window
                              ; (and its ahk_class for more specific cases). 
                              ; for example you can replace "Sticky Notes"
                              ; with "Calculator" to make calculator stay always
                              ; on top.

Loop {
 WinWait, ahk_group ontop
 WinSet, AlwaysOnTop, On
 SoundBeep, 1500
 WinWaitClose
 SoundBeep, 1000
}

(main代码为mikeyww的信用)

相关问题