我有一个Windows应用程序,它使用AppBar API作为应用程序栏安装在屏幕顶部(类似于Windows任务栏本身)。这很好用,桌面大小也相应调整,因此我的应用程序始终可见。
但是,如果用户选择“显示桌面”(Windows + D),我的应用程序将被隐藏。有没有人知道陷阱'显示桌面'的方法所以我可以确保我的应用程序保持可见(我假设Windows枚举所有顶级窗口并用ShowWindow(SW_HIDE)隐藏它们。
答案 0 :(得分:1)
使用以下代码并在窗体加载时将窗口句柄传递给函数。 希望这可以解决您的问题。
public void SetFormOnDesktop(IntPtr hwnd)
{
IntPtr hwndf = hwnd;
IntPtr hwndParent = FindWindow("ProgMan", null);
SetParent(hwndf, hwndParent);
}
答案 1 :(得分:0)
我的印象是将窗口设置为最顶层窗口(通过SetWindowPos和HWND_TOPMOST标志)会阻止桌面覆盖它。 Windows + D通过最小化所有窗口,然后通过在z顺序中提升桌面来掩盖那些无法最小化的窗口(好吧,它在one point anyway处完成)。我相信你可以通过不将WS_MINIMIZEBOX传递给CreateWindowEx或者使用WS_EX_TOOLWINDOW来创建一个无法实现的窗口,尽管我不是100%的那部分。
更重要的方法是使用SetWindowsHookEx和KeyboardProc挂钩全局键盘。这将对用户体验产生有害影响。
<小时/> 我去编写了一个我正在谈论的一个非常简单的例子。以下代码使窗口未被最小化或由用户点击Windows + D覆盖。请注意,在Windows 7上,桌面上的小工具仍然可以高于它;我无法解释。
#include <windows.h>
#include <tchar.h>
#define WIN_TITLE _T("Resists Win+D Window")
#define WIN_CLASS _T("Resists Win+D Class")
LRESULT CALLBACK CustomWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
//Special behavior goes here
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
HWND CreateMainWindow(HINSTANCE hInstance)
{
WNDCLASSEX wcex;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = CustomWndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_APPLICATION));
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wcex.lpszMenuName = NULL;
wcex.lpszClassName = WIN_CLASS;
wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_APPLICATION));
if (!RegisterClassEx(&wcex))
{
exit(1);
}
HWND hWnd = CreateWindowEx(
WS_EX_TOOLWINDOW,
WIN_CLASS,
WIN_TITLE,
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
500,
100,
NULL,
NULL,
hInstance,
NULL
);
if (!hWnd)
{
exit(1);
}
return hWnd;
}
/*
Main entry point
*/
int WINAPI WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
HWND hwnd = CreateMainWindow(hInstance);
ShowWindow(hwnd, nCmdShow);
SetWindowPos(hwnd, HWND_TOPMOST, -1, -1, -1, -1, SWP_NOMOVE | SWP_NOSIZE);
UpdateWindow(hwnd);
MSG msg;
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return (int) msg.wParam;
}
答案 2 :(得分:0)
在ABN_FULLSCREENAPP通知中,您需要确定占用工作区的窗口是否为桌面,如果是,请忽略ABN_FULLSCREENAPP消息。
P.S。作为替代实现,请考虑商业ShellAppBar组件。
答案 3 :(得分:0)
除answer of JKS之外,这里是VB.NET的工作代码,假设您已将表单转换为appbar。您需要p /调用函数FindWindow
和SetFormOnDesktop
。
'In your form
Public Sub New()
'Stuff
SetFormOnDesktop(Me.Handle)
'More stuff
End Sub
'In your form or somewhere else.
<DllImport("user32.dll", SetLastError:=True, CharSet:=CharSet.Auto)> _
Private Shared Function FindWindow( _
ByVal lpClassName As String, _
ByVal lpWindowName As String) As IntPtr
End Function
<DllImport("user32.dll", SetLastError:=True, CharSet:=CharSet.Auto)> _
Public Shared Function SetParent(_
ByVal hWndChild As IntPtr, ByVal hWndNewParent As IntPtr) As IntPtr
End Function
Public Sub SetFormOnDesktop(hwnd As IntPtr)
Dim hwndf As IntPtr = hwnd
Dim hwndParent As IntPtr = FindWindow("ProgMan", Nothing)
SetParent(hwndf, hwndParent)
End Sub