题
我有一个Windows的应用程序,使用的应用栏API安装应用程序的屏幕(类似于Windows的任务条本身)。这个伟大的工程和桌面大小是相应的调整,所以我应用程序总是可见的。
但是,如果用户选择显示桌面'(Windows+D),我的申请被隐藏。任何人都不会知道的一种方法的陷阱'显示桌面'所以我可以保证,我的申请停留可见(我认为Windows列举了所有的顶级窗户和隐藏他们与ShowWindow(SW_HIDE).
解决方案
使用下面的代码和窗口句柄传递给而形式负载的功能。 希望这样可以解决你的问题。
public void SetFormOnDesktop(IntPtr hwnd)
{
IntPtr hwndf = hwnd;
IntPtr hwndParent = FindWindow("ProgMan", null);
SetParent(hwndf, hwndParent);
}
其他提示
我的印象是,设置窗口作为一个最上面的窗口(通过 SetWindowPos 和HWND_TOPMOST标志)防止桌面从复盖它。Windows+D通过减少所有的窗户,然后掩盖了那些不能降到最低程度提高台式在z-order(嗯,它有没有在 一点无论如何).我相信你可以做一个窗口unminimizable通过不通过WS_MINIMIZEBOX要如下,或者使用WS_EX_TOOLWINDOW尽管我不是100%在的那一部分。
一个多重的手的办法将是要挂钩的全球键盘的使用SetWindowsHookEx和KeyboardProc.这将产生有害的影响的用户经验。
我去和编码了一个非常简单的例子是什么我说的。以下代码使一个窗口,是不能最小化或复盖的用户打Windows+D。请注意,在Windows7,小玩意在桌面上仍然可以带上;我真的不能解释。
#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;
}
在您的ABN_FULLSCREENAPP通知,您需要确定占用工作区的窗口是否为桌面,如果是,忽略ABN_FULLSCREENAPP消息。
P.S。作为一种替代实施方式中,考虑商业 ShellAppBar 组件。
除了JKS 的答案,这里是工作代码VB.NET,假设你已经转换的形式一个appbar。你需要的P / Invoke功能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
不隶属于 StackOverflow