Frage

Ich habe eine Windows-Anwendung, die die AppBar API verwendet als Anwendungsleiste am oberen Rand des Bildschirms (ähnlich dem Windows-Taskleiste selbst) zu installieren. Dies funktioniert gut und die Desktop-Größe wird entsprechend angepasst, so dass meine Anwendung ist immer sichtbar.

Wenn jedoch der Benutzer-Desktop anzeigen "(Windows + D) wählen, meine Anwendung ist versteckt. Kennt jemand eine Möglichkeit zu stoppen ‚Desktop anzeigen‘, so kann ich sicher, meine Anwendung sichtbar bleibt (Ich gehe davon aus, dass Windows listet alle Fenster der obersten Ebene und versteckt sie mit Showwindow (SW_HIDE).

War es hilfreich?

Lösung

Verwenden Sie den folgenden Code und das Fenster-Handle auf die Funktion, während Form Last passieren. Hoffentlich löst Ihr Problem.

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

Andere Tipps

Ich hatte den Eindruck, dass das Fenster als oberstes Fenster Einstellung (über SetWindowPos und die HWND_TOPMOST flag) verhindert den Desktop davon abdeckt. Windows + D geht durch alle Fenster minimiert wird, und dann diese Abdeckung, die nicht durch eine Erhöhung der Desktop in der z-Reihenfolge minimiert werden kann (na ja, es hat unter ein Punkt sowieso ). Ich glaube man kann ein Fenster macht unminimizable von nicht WS_MINIMIZEBOX zu CreateWindowEx vorbei, oder mit WS_EX_TOOLWINDOW obwohl ich nicht zu 100% auf dem Teil bin.

Ein viel schwerer handed Ansatz wäre, die globale Tastatur SetWindowsHookEx und KeyboardProc einzuhaken. Dies wird eine schädliche Wirkung auf die User Experience haben.


Ich ging hin und codiert ein wirklich einfaches Beispiel, was ich spreche. Der folgende Code macht ein Fenster, das von einem Benutzer schlägt Windows-+ D nicht minimiert oder abgedeckt ist. Beachten Sie, dass auf Windows 7, Gadgets auf dem Desktop noch darüber gebracht werden können; was ich kann nicht wirklich erklären.

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

In Ihrer ABN_FULLSCREENAPP Benachrichtigung, müssen Sie bestimmen, ob das Fenster den Arbeitsbereich besetzt die Desktop ist und wenn ja, ignorieren die ABN_FULLSCREENAPP Nachricht.

P. S. Als alternative Implementierung, betrachten die kommerzielle ShellAppBar Komponente.

Neben der Antwort von JKS , hier arbeitet Code für VB.NET, vorausgesetzt, bereits Sie Ihre Form umgewandelt zu einem appbar. Sie müssen p / aufrufen, um die Funktionen FindWindow und 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
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top