代码之家  ›  专栏  ›  技术社区  ›  Rob

应用程序栏和“显示桌面”

  •  2
  • Rob  · 技术社区  · 16 年前

    我有一个Windows应用程序,它使用AppBarAPI作为应用程序条安装在屏幕顶部(类似于Windows任务栏本身)。这很好,桌面大小也相应地调整,所以我的应用程序总是可见的。

    但是,如果用户选择“显示桌面”(Windows+D),则会隐藏我的应用程序。是否有人知道陷阱“显示桌面”的方法,以便我可以确保我的应用程序保持可见(我假设Windows枚举所有顶级窗口并用ShowWindow(sw_hide)隐藏它们)。

    4 回复  |  直到 11 年前
        1
  •  1
  •   Marvin Dickhaus Dillie-O    11 年前

    使用以下代码并在窗体加载时将窗口句柄传递给函数。 希望这能解决你的问题。

    public void SetFormOnDesktop(IntPtr hwnd)
    {
        IntPtr hwndf = hwnd;
        IntPtr hwndParent = FindWindow("ProgMan", null);
        SetParent(hwndf, hwndParent);
    }
    
        2
  •  0
  •   Kevin Montrose    16 年前

    我的印象是将窗口设置为最上面的窗口(通过 SetWindowPos 和hwnd_的最上面的标志)阻止桌面覆盖它。Windows+D通过最小化所有窗口,然后用z顺序提升桌面来覆盖那些无法最小化的窗口(它在 one point anyway )。我相信你可以通过不将ws_minimizebox传递给createWindowEx,或者使用ws_ex_toolWindow来使窗口不可最小化,尽管我在这方面不是100%。

    一个更重的方法是使用setwindowshookex和keyboardproc钩住全局键盘。这将对用户体验产生有害影响。


    我去编了一个非常简单的例子来说明我在说什么。下面的代码生成了一个窗口,用户点击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;
    }
    
        3
  •  0
  •   logicnp    15 年前

    在您的abn_fullscreenapp通知中,您需要确定占用工作区的窗口是否是桌面,如果是,请忽略abn_fullscreenapp消息。

    P.S.作为替代实施方案,考虑商业 ShellAppBar 组件。

        4
  •  0
  •   Community CDub    8 年前

    除了 answer of 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