2009-05-20 5 views
2

J'ai une application Windows qui utilise l'API AppBar pour l'installer en tant que barre d'application en haut de l'écran (similaire à la barre des tâches Windows elle-même). Cela fonctionne très bien et la taille du bureau est ajustée en conséquence, donc mon application est toujours visible. Toutefois, si l'utilisateur a choisi "Afficher le bureau" (Windows + D), mon application est masquée. Est-ce que quelqu'un connaît un moyen de piéger 'Show Desktop' pour que mon application reste visible (je suppose que Windows énumère toutes les fenêtres de haut niveau et les cache avec ShowWindow (SW_HIDE).)Barres d'application et «Afficher le bureau»

Répondre

1

Utilisez le code suivant et passez la poignée de la fenêtre à la fonction lors du chargement du formulaire. 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); 
} 
+0

Fonctionne un régal! Merci. – Rob

0

J'avais l'impression que la fenêtre en tant que fenêtre la plus haute (via SetWindowPos et l'indicateur HWND_TOPMOST) empêchait le bureau de la recouvrir Windows + D passe par la minimisation de toutes les fenêtres, puis dissimule celles qui ne peuvent pas être réduites en augmentant le bureau dans le z- ordre (bien, il l'a fait à one point anyway). 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 accrocher le g clavier lobal utilisant SetWindowsHookEx et un KeyboardProc. Cela aura un effet délétère sur l'expérience de l'utilisateur. Je suis allé et codé un exemple très simple de ce dont je parle. Le code suivant crée une fenêtre qui n'est pas minimisée OU couverte par un utilisateur qui appuie sur Windows + D. Notez que sur Windows 7, les gadgets sur le bureau peuvent toujours être placés 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; 
} 
+0

La définition de HWND_TOPMOST ne fonctionne pas. Je pense que je dois changer le parent de mon application sur le bureau. Je vais essayer et signaler mes conclusions. – Rob

+0

J'ai hack'd du code qui crée une fenêtre qui résiste à win + D. Espérons qu'il peut être modifié pour répondre à vos besoins. –

0

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, ignorer le message ABN_FULLSCREENAPP.

P.S. En guise d'implémentation alternative, considérez le composant commercial ShellAppBar.

+0

Cela fonctionnera mais seulement si je peux savoir si le bureau est maintenant au top, ce dont je ne suis pas sûr. Il est dommage que le ABN_FULLSCREENAPP ne vous permette pas d'interroger le HWND de la fenêtre à propos de passer en plein écran, sinon je serais en affaires. – Rob

0

En plus du answer of JKS, ici est le code de travail pour VB.NET, en supposant déjà converti votre formulaire à une barre d'accès. Vous devez appeler/appeler 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 
Questions connexes