문제

AppBar API를 사용하여 화면 상단에 응용 프로그램 표시 줄 (Windows Task Bar 자체와 유사)을 설치하는 Windows 앱이 있습니다. 이것은 훌륭하게 작동하고 데스크탑 크기가 그에 따라 조정되므로 내 응용 프로그램은 항상 보입니다.

그러나 사용자가 'Show Desktop'(Windows+D)을 선택하면 응용 프로그램이 숨겨져 있습니다. 누구든지 'Show Desktop'을 함정하는 방법을 알고 있으므로 응용 프로그램이 표시되는지 확인할 수 있습니다 (Windows가 모든 최상위 창을 열거하고 Showwindow (SW_HIDE)로 숨겨져 있다고 가정합니다.

도움이 되었습니까?

해결책

다음 코드를 사용하고 양식로드 중에 창 핸들을 함수로 전달하십시오. 바라건대 이것은 당신의 문제를 해결합니다.

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

다른 팁

나는 창을 가장 맨 위 창으로 설정한다는 인상을 받았습니다 ( setwindowpos 그리고 HWND_TOP MESTER FLAG)는 데스크탑이 그것을 덮지 못했습니다. Windows+D는 모든 창문을 최소화 한 다음 Z- 주문에서 데스크탑을 올려 최소화 할 수없는 창을 덮습니다 (음, 그것은 어쨌든 한 점). 나는 당신이 ws_minimizebox를 CreateWindowEx에 전달하지 않거나 WS_EX_TOOLWINDOW를 사용하여 창을 미확인 할 수 없다고 생각합니다.

훨씬 더 무거운 접근 방식은 Setwindowshookex와 키보드 프로크를 사용하여 글로벌 키보드를 연결하는 것입니다. 이것은 사용자 경험에 해로운 영향을 미칩니다.


나는 내가 말하는 것의 정말로 간단한 예를 가서 코딩했다. 다음 코드는 Windows+D를 치는 사용자가 최소화하거나 덮지 않는 창을 만듭니다. Windows 7에서는 데스크탑의 가제트를 여전히 그 위에 가져올 수 있습니다. 나는 실제로 설명 할 수 없습니다.

#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 메시지를 무시해야합니다.

추신 대안 구현으로서 광고를 고려하십시오 ShellAppbar 요소.

여기에 덧붙여 JKS의 답변, 여기에 vb.net 용 작업 코드가 이미 있습니다. 이미 양식을 AppBar로 변환했다고 가정합니다. 함수를 p/호출해야합니다 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
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top