Win32 API从磁盘文件图片创建工具栏图标

发布时间 2023-04-28 22:47:06作者: 老铁来了啊

关键字:Win32 API从磁盘,文件,图片创建工具栏图标,包含提示文字。

编译命令:g++ demo01.cpp -mwindows -lcomctl32 -ldwmapi -o demo01 -static -Wall -std=c++11

#define UNICODE

#include <Windows.h>
#include <strsafe.h>
#include <commctrl.h>

/*****
 * CALLBACK代表__stdcall 参数的传递顺序 从右到左 依次入栈 并且在函数返回前 依次出栈
 * HWND UINT WPARAM LPARAM
 * 消息所属的窗口句柄
 * 消息名称 WM_XXX消息名
 * 键盘附加消息
 * 鼠标附加消息
 */
HINSTANCE g_hInstance;
LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    switch (uMsg)
    {
    case WM_CREATE:
    {
        HIMAGELIST hImageList = ImageList_Create(48, 48, ILC_COLOR32 | ILC_MASK, 3, 1);

        // HICON hIcon = LoadIcon(GetModuleHandle(NULL),
        //                        MAKEINTRESOURCE(IDI_ICON1 + i));
        for (int i = 11; i < 14; i++)
        {
            HICON hIcon = (HICON)::LoadImage(NULL, TEXT("D:\\code\\AUtils\\cpp\\winframe\\icon\\000.ico"), IMAGE_ICON, 48, 48, LR_LOADFROMFILE);
            ImageList_AddIcon(hImageList, hIcon);
            DestroyIcon(hIcon);
        }

        //创建工具条控件
        HWND hToolBar = CreateWindow(TOOLBARCLASSNAME, NULL,
                                     WS_CHILD | WS_VISIBLE | TBSTYLE_WRAPABLE, 0, 0, 0, 0, hWnd, (HMENU)1,
                                     g_hInstance, NULL);

        //设置工具条的图片列表
        ::SendMessage(hToolBar, TB_SETIMAGELIST, 0, (LPARAM)hImageList);

        //添加一些按钮到工具条上去
        TBBUTTON tbButtons[3] = {
            {0, NULL, TBSTATE_ENABLED, TBSTYLE_BUTTON | BTNS_AUTOSIZE, {0}, 0, (INT_PTR)TEXT("按钮1")},
            {1, NULL, TBSTATE_ENABLED, TBSTYLE_BUTTON | BTNS_AUTOSIZE, {0}, 0, (INT_PTR)TEXT("按钮2")},
            {2, NULL, TBSTATE_ENABLED, TBSTYLE_BUTTON | BTNS_AUTOSIZE, {0}, 0, (INT_PTR)TEXT("按钮3")}};

        ::SendMessage(hToolBar, TB_BUTTONSTRUCTSIZE, (WPARAM)sizeof(TBBUTTON), 0);
        ::SendMessage(hToolBar, TB_ADDBUTTONS, (WPARAM)3, (LPARAM)&tbButtons);

        //自动调整工具条的大小并显示
        ::SendMessage(hToolBar, TB_AUTOSIZE, 0, 0);
        ::ShowWindow(hToolBar, true);
    }
    break;
    case WM_PAINT:
    {
    }
    break;
    case WM_SIZE:
    {
    }
    break;
    case WM_COMMAND:
    {
    }
    break;
    case WM_LBUTTONDOWN:
    {
        int xPos = LOWORD(lParam);
        int yPos = HIWORD(lParam);
        TCHAR buffer[256];
        StringCchPrintf(buffer, 256, TEXT("xPos: %d, yPos: %d"), xPos, yPos);
        MessageBox(hWnd, buffer, TEXT("WM_LBUTTONDOWN"), MB_OK);
    }
    break;
    case WM_KEYDOWN:
    {
    }
    break;
    case WM_CLOSE:
    {
        DestroyWindow(hWnd);
    }
    break;
    case WM_DESTROY:
    {
        PostQuitMessage(0);
    }
    break;
    default:
    {
    }
    }
    return DefWindowProc(hWnd, uMsg, wParam, lParam);
}

// WINAPI代表__stdcall 参数的传递顺序 从右到左 依次入栈 并且在函数返回前 依次出栈
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
    WNDCLASS wc;
    wc.cbClsExtra = 0;                                      // 类的额外内存
    wc.cbWndExtra = 0;                                      // 窗口额外内存
    wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); // 背景
    wc.hCursor = LoadCursor(NULL, IDC_ARROW);               // 光标 第一个为NULL代表使用系统提供的光标
    wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);             // 图标 第一个为NULL代表使用系统提供的图标
    wc.hInstance = hInstance;                               // 应用程序实例句柄
    wc.lpfnWndProc = WindowProc;                            // 回调函数
    wc.lpszClassName = TEXT("main");                        // 窗口类名称
    wc.lpszMenuName = NULL;                                 // 菜单名称
    wc.style = CS_HREDRAW | CS_VREDRAW;                     // 显示风格
    g_hInstance = hInstance;
    RegisterClass(&wc);

    /*****
     * CreateWindow()
     * lpClassName,lpWindowName,dwStyle,x,y,nWidth,nHeight,hWndParent,hMenu,hInstance,lpParam
     * 类名
     * 标题名
     * WS_OVERLAPPEDWINDOW 混合风格
     * x坐标 CW_USEDEFAULT
     * y坐标
     * 宽
     * 高
     * 父窗口 NULL
     * 菜单 NULL
     * 实例句柄 hInstance
     * 附加值
     */
    HWND hWnd = CreateWindow(wc.lpszClassName, TEXT("Windows"), WS_OVERLAPPEDWINDOW,
                             CW_USEDEFAULT,
                             CW_USEDEFAULT,
                             CW_USEDEFAULT,
                             CW_USEDEFAULT,
                             NULL, NULL, hInstance, NULL);
    if (hWnd == NULL)
    {
        return 0;
    }
    ShowWindow(hWnd, SW_SHOWNORMAL);
    UpdateWindow(hWnd);

    /*****
     * HWND hwnd; 主窗口句柄
     * UINT message; 具体消息名称
     * WPARAM wParam; 附加消息 键盘消息
     * LPARAM lParam; 附加消息 鼠标消息
     * DWORD time; 消息产生时间
     * POINT pt; 附加消息 鼠标消息 x y
     */
    MSG msg;

    /*****
     * LPMSG lpMsg,HWND hWnd,UINT wMsgFilterMin,UINT wMsgFilterMax
     * 消息
     * 捕获窗口 NULL代表捕获所有窗口
     * 最小的过滤消息 0代表捕获所有消息
     * 最大的过滤消息 0代表捕获所有消息
     */
    while (GetMessage(&msg, NULL, 0, 0))
    {
        // 如果按的是组合键 需要翻译
        TranslateMessage(&msg);
        // 单按一个键盘就直接分发消息
        DispatchMessage(&msg);
    }
    return 0;
}

运行结果: