Question

J'ai une application Windows qui utilise l'API AppBar à installer une barre d'application en haut de l'écran (similaire à la barre des tâches de Windows lui-même). Cela fonctionne très bien et la taille du bureau est ajustée en conséquence, donc ma demande est toujours visible.

Cependant, si l'utilisateur choisissez « Afficher le bureau » (Windows + D), ma demande est caché. Quelqu'un sait-il un moyen de piège « Afficher le bureau » donc je peux assurer mon application reste visible (je suppose que Windows toutes les fenêtres énumère haut niveau et les cache avec ShowWindow (SW_HIDE).

Était-ce utile?

La solution

Utiliser le code suivant et passer la poignée de fenêtre à la fonction pendant que forme la charge. Espérons que cela résout votre problème.

public void SetFormOnDesktop(IntPtr hwnd)
{
    IntPtr hwndf = hwnd;
    IntPtr hwndParent = FindWindow("ProgMan", null);
    SetParent(hwndf, hwndParent);
}

Autres conseils

I eu l'impression que le réglage de la fenêtre en tant que fenêtre supérieure (via SetWindowPos et le drapeau de HWND_TOPMOST) ont empêché le bureau de la couvrir. Windows + D passe en minimisant toutes les fenêtres, puis couvrir ceux qui ne peuvent pas être réduits au minimum en augmentant le bureau dans l'ordre z (bien, il l'a fait à un point de toute façon ). Je crois que vous pouvez faire une fenêtre unminimizable en ne passant WS_MINIMIZEBOX à CreateWindowEx, ou en utilisant WS_EX_TOOLWINDOW bien que je ne suis pas à 100% sur cette partie.

Une approche beaucoup plus lourde main serait de brancher le clavier global à l'aide SetWindowsHookEx et un KeyboardProc. Cela aura un effet délétère sur l'expérience utilisateur.


Je suis allé et codifiés un exemple très simple de ce que je parle. Le code suivant fait une fenêtre qui ne sont pas minimisés ou couvert par un utilisateur appuyant sur Windows + D. Notez que sur Windows 7, gadgets sur le bureau peuvent encore être mis au-dessus; que je ne peux pas vraiment expliquer.

#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;
}

Dans votre notification ABN_FULLSCREENAPP, vous devez déterminer si la fenêtre qui occupe la zone de travail est le bureau et si oui, ignorez le message ABN_FULLSCREENAPP.

P.S. Comme une mise en œuvre alternatif, pensez à la composante commerciale ShellAppBar .

En plus de la réponse de JKS, ici est le code de travail pour VB.NET, en supposant déjà converti votre formulaire à une barre d'accès. Vous devez p / Invoke les fonctions FindWindow et 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
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top