无法将缩略图按钮添加到窗口?

时间:2016-06-25 12:39:03

标签: c++ windows winapi

我正在尝试将缩略图按钮添加到窗口,但没有错误,也没有显示缩略图按钮。我阅读了以下页面以供参考:

  1. Your First Windows Program;

  2. ITaskbarList3::ThumbBarAddButtons method;

  3. some code on github

  4. 环境:win10 64bit,vs2015

    // function WindowProc and wWinMain are copied from msdn directly.
    
    #include "stdafx.h"
    #include <windows.h>
    #include "shobjidl.h" 
    #include <exception>
    
    
    LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
    
    HRESULT addThumbnailButtons(HWND hwnd) {
        HRESULT hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE);
        if (SUCCEEDED(hr)) {
            ITaskbarList4* ptbl = nullptr;
            HRESULT hr = CoCreateInstance(CLSID_TaskbarList, NULL, CLSCTX_INPROC_SERVER,
                IID_PPV_ARGS(&ptbl));
    
            if (SUCCEEDED(hr)) {
                // create 2 buttons
                THUMBBUTTON thmb[2] = {};
    
                thmb[0].dwMask = THB_TOOLTIP;
                thmb[0].iId = 0;
                wcscpy_s(thmb[0].szTip, L"Button 1");
    
                thmb[1].dwMask = THB_TOOLTIP;
                thmb[1].iId = 1;
                wcscpy_s(thmb[1].szTip, L"Button 2");
    
                //ptbl->HrInit();
                hr = ptbl->ThumbBarAddButtons(hwnd, ARRAYSIZE(thmb), thmb);
    
                ptbl->Release();
    
                return hr;
            }
            else {
                throw std::exception("createInstance failed");
            }
        }else{
            throw std::exception("coinitialize failed");
        }
    }
    
    int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE, PWSTR pCmdLine, int nCmdShow)
    {
        // Register the window class.
        const wchar_t CLASS_NAME[] = L"Sample Window Class";
    
        WNDCLASS wc = {};
    
        wc.lpfnWndProc = WindowProc;
        wc.hInstance = hInstance;
        wc.lpszClassName = CLASS_NAME;
    
        RegisterClass(&wc);
    
        // Create the window.
    
        HWND hwnd = CreateWindowEx(
            0,                              // Optional window styles.
            CLASS_NAME,                     // Window class
            L"Learn to Program Windows",    // Window text
            WS_OVERLAPPEDWINDOW,            // Window style
    
                                            // Size and position
            CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
    
            NULL,       // Parent window    
            NULL,       // Menu
            hInstance,  // Instance handle
            NULL        // Additional application data
        );
    
        if (hwnd == NULL)
        {
            return 0;
        }
    
        HRESULT hr = addThumbnailButtons(hwnd);
        if (FAILED(hr)) {
            throw std::exception("addbuttons failed");
        }
    
        ShowWindow(hwnd, nCmdShow);
    
        // Run the message loop.
    
        MSG msg = {};
        while (GetMessage(&msg, NULL, 0, 0))
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
    
        return 0;
    }
    
    LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
    {
        switch (uMsg)
        {
        case WM_DESTROY:
            PostQuitMessage(0);
            return 0;
    
        case WM_PAINT:
        {
            PAINTSTRUCT ps;
            HDC hdc = BeginPaint(hwnd, &ps);
    
            FillRect(hdc, &ps.rcPaint, (HBRUSH)(COLOR_WINDOW + 1));
    
            EndPaint(hwnd, &ps);
        }
        return 0;
    
        }
        return DefWindowProc(hwnd, uMsg, wParam, lParam);
    }
    

1 个答案:

答案 0 :(得分:5)

根据ITaskBarList3文档:

  

当应用程序显示窗口时,其任务栏按钮由系统创建。当按钮就位后,任务栏会向窗口发送TaskbarButtonCreated消息。您的应用程序应调用RegisterWindowMessage(L"TaskbarButtonCreated")并在其wndproc中处理该消息。 在调用任何ITaskbarList3方法之前,您的应用程序必须接收该消息

您必须在致电addThumbnailButtons()之前等待该消息,例如:

UINT uMsgTaskbarCreated;

int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE, PWSTR pCmdLine, int nCmdShow)
{
    uMsgTaskbarCreated = RegisterWindowMessage(L"TaskbarButtonCreated");

    // Register the window class.
    const wchar_t CLASS_NAME[] = L"Sample Window Class";

    WNDCLASS wc = {};

    wc.lpfnWndProc = WindowProc;
    wc.hInstance = hInstance;
    wc.lpszClassName = CLASS_NAME;

    RegisterClass(&wc);

    // Create the window.

    HWND hwnd = CreateWindowEx(
        0,                              // Optional window styles.
        CLASS_NAME,                     // Window class
        L"Learn to Program Windows",    // Window text
        WS_OVERLAPPEDWINDOW,            // Window style

                                        // Size and position
        CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,

        NULL,       // Parent window    
        NULL,       // Menu
        hInstance,  // Instance handle
        NULL        // Additional application data
    );

    if (hwnd == NULL)
    {
        return 0;
    }

    ShowWindow(hwnd, nCmdShow);

    // Run the message loop.

    MSG msg = {};
    while (GetMessage(&msg, NULL, 0, 0))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }

    return 0;
}

LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    switch (uMsg)
    {
        case WM_DESTROY:
            PostQuitMessage(0);
            return 0;

        case WM_PAINT:
        {
            PAINTSTRUCT ps;
            HDC hdc = BeginPaint(hwnd, &ps);

            FillRect(hdc, &ps.rcPaint, (HBRUSH)(COLOR_WINDOW + 1));

            EndPaint(hwnd, &ps);
            return 0;
        }

        default:
            if ((uMsg == uMsgTaskbarCreated) && (uMsgTaskbarCreated != 0))
            {
                HRESULT hr = addThumbnailButtons(hwnd);
                if (FAILED(hr)) {
                    ...;
                }
            }
            break;
        }

    return DefWindowProc(hwnd, uMsg, wParam, lParam);
}