Barre di applicazione e 'Mostra Desktop'
Domanda
Ho un'applicazione Windows che utilizza l'API AppBar per installare come barra delle applicazioni nella parte superiore dello schermo (simile alla barra delle applicazioni di Windows stesso). Questa grande opera e la dimensione del desktop è adeguato di conseguenza, in modo dalla mia domanda è sempre visibile.
Tuttavia, se l'utente sceglie 'Mostra Desktop' (Windows + D), la mia domanda è nascosto. Qualcuno sa di un modo per intrappolare 'Mostra Desktop' così posso garantire resta visibile la mia domanda (suppongo che Windows enumera tutte le finestre di primo livello e li nasconde con ShowWindow (SW_HIDE).
Soluzione
Utilizzare il seguente codice e passare l'handle di finestra alla funzione, mentre il carico forma. Speriamo che questo risolve il problema.
public void SetFormOnDesktop(IntPtr hwnd)
{
IntPtr hwndf = hwnd;
IntPtr hwndParent = FindWindow("ProgMan", null);
SetParent(hwndf, hwndParent);
}
Altri suggerimenti
Ho avuto l'impressione che l'impostazione della finestra come una finestra in primo piano (tramite SetWindowPos e la bandiera HWND_TOPMOST) hanno impedito il desktop da coprirlo. Windows + D passa attraverso minimizzare tutte le finestre, e poi coprire quelli che non può essere minimizzato aumentando desktop in ordine z (bene, ha fatto al un certo punto comunque ). I belive è possibile effettuare una finestra unminimizable da non passare WS_MINIMIZEBOX a CreateWindowEx, o utilizzando WS_EX_TOOLWINDOW anche se non sono al 100% su quella parte.
Un approccio molto più pesante di mano potrebbe essere quella di collegare la tastiera globale utilizzando SetWindowsHookEx e KeyboardProc. Ciò avrà un effetto deleterio sulla user experience.
Sono andato e codificato un esempio molto semplice di quello che sto parlando. Il codice seguente effettua una finestra che non è minimizzata o coperto da un utente premendo Windows + D. Si noti che su Windows 7, gadget sul desktop possono ancora essere portati sopra di esso; che non posso davvero spiegare.
#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;
}
La tua segnalazione ABN_FULLSCREENAPP, è necessario stabilire se la finestra che occupa l'area di lavoro è il desktop e in caso affermativo, ignora il messaggio ABN_FULLSCREENAPP.
P.S. In un'implementazione alternativa, prendere in considerazione il commerciale ShellAppBar componente.
In aggiunta alla risposta di JKS , qui è il codice di lavoro per VB.NET, supponendo che già convertito il modulo a un appbar. È necessario p / richiamare il FindWindow
funzioni e 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