c++ - 如何在工具栏控件中创建不同大小的按钮(Win32 API)
问题描述
我想在工具栏中插入不同大小的按钮。让我们说例如2个按钮。一个的大小为 32x16,另一个为 16x16。我使用了两个图像列表。每个图像列表都有自己的图像尺寸(第一个 32x16 - 第二个 16x16)。但问题是,当我编译代码时,我得到了正确加载的图像,但按钮的宽度相同(32)。
代码:
//(1) Create the Toolbar ImageList
HIMAGELIST hImageListLarge = ImageList_Create(32, 16, ILC_COLOR8 | ILC_MASK, 1, 0);
if (!hImageListLarge)
return false;
HIMAGELIST hImageListSmall = ImageList_Create(16, 16, ILC_COLOR8 | ILC_MASK, 1, 0);
if (!hImageListSmall)
return false;
//(2) Fill the Image List
if (ImageList_Add(hImageListLarge,
LoadBitmap(m_hInstance, MAKEINTRESOURCE(IDB_TB_CONNECT_TO)),
LoadBitmap(m_hInstance, MAKEINTRESOURCE(IDB_TB_CONNECT_TO_MASK))) == -1)
return false;
if (ImageList_Add(hImageListSmall,
LoadBitmap(m_hInstance, MAKEINTRESOURCE(IDB_TB_HELP)),
LoadBitmap(m_hInstance, MAKEINTRESOURCE(IDB_TB_HELP_MASK))) == -1)
return false;
//(3) Create the Toolbar window
m_hToolbar = CreateWindowEx(0, TOOLBARCLASSNAME, nullptr,
WS_CHILD | TBSTYLE_WRAPABLE | TBSTYLE_AUTOSIZE | TBSTYLE_LIST | TBSTYLE_TOOLTIPS ,
0, 0, 0, 0, m_hWnd, nullptr, m_hInstance, nullptr);
if (m_hToolbar == nullptr)
return false;
//(4) Sets the Image list for the Toolbar
SendMessage(m_hToolbar, CCM_SETVERSION, 5, 0);
SendMessage(m_hToolbar, TB_SETIMAGELIST, 0, (LPARAM)hImageListLarge);
SendMessage(m_hToolbar, TB_SETIMAGELIST, 1, (LPARAM)hImageListSmall);
//(5) Initialize the TBBUTTON structures for each button
m_tbButtons[0].fsStyle = BTNS_SEP;
m_tbButtons[1].iBitmap = MAKELONG(0, 0);
m_tbButtons[1].idCommand = ID_CONNECTIONS_CONNECT_TO;
m_tbButtons[1].fsState = TBSTATE_ENABLED;
m_tbButtons[1].fsStyle = BTNS_BUTTON | BTNS_AUTOSIZE;
m_tbButtons[1].iString = (INT_PTR)TEXT("Connect to");
m_tbButtons[2].iBitmap = MAKELONG(0, 1);
m_tbButtons[2].idCommand = ID_HELP_ABOUT;
m_tbButtons[2].fsState = TBSTATE_ENABLED;
m_tbButtons[2].fsStyle = BTNS_BUTTON | BTNS_AUTOSIZE ;
m_tbButtons[2].iString = (INT_PTR)TEXT("Help");
//(6) Add buttons to the toolbar
SendMessage(m_hToolbar, TB_BUTTONSTRUCTSIZE, (WPARAM)sizeof(TBBUTTON), 0);
SendMessage(m_hToolbar, TB_ADDBUTTONS, 3, (LPARAM)m_tbButtons);
//(7) auto Resize the toolbar
SendMessage(m_hToolbar, TB_AUTOSIZE, 0, 0);
SendMessage(m_hToolbar, TB_SETEXTENDEDSTYLE, 0, (LPARAM)TBSTYLE_EX_MIXEDBUTTONS);
ShowWindow(m_hToolbar, SW_SHOW);
//(8) Modify the size of the separator that will hold the combobox
TBBUTTONINFO tbbi;
tbbi.cbSize = sizeof(tbbi);
tbbi.dwMask = TBIF_SIZE | TBIF_BYINDEX;
tbbi.cx = 500;
SendMessage(m_hToolbar, TB_SETBUTTONINFO, (WPARAM)0, (LPARAM)& tbbi);
tbbi.cx = 32;
SendMessage(m_hToolbar, TB_SETBUTTONINFO, (WPARAM)1, (LPARAM)& tbbi);
tbbi.cx = 16;
SendMessage(m_hToolbar, TB_SETBUTTONINFO, (WPARAM)2, (LPARAM)& tbbi);
//(9) Get the Rectangle occupied by the separator
RECT rcSep;
SendMessage(m_hToolbar, TB_GETITEMRECT, (WPARAM)0, (LPARAM)& rcSep);
//(10) Create the hosts comboBox
m_hComboHosts = CreateWindow(WC_COMBOBOXW, nullptr, WS_CHILD | CBS_DROPDOWN | WS_VISIBLE,
rcSep.left, rcSep.top, rcSep.right - rcSep.left, rcSep.bottom - rcSep.top, m_hToolbar,
(HMENU)IDC_COMBO_HOSTS, m_hInstance, nullptr);
if (!m_hComboHosts)
return false;
return true;
解决方案
我使用第一个 TB_SETBUTTONINFO 消息来修改按钮(分隔符)的大小。要使其足够大以容纳组合框控件:
//(8) Modify the size of the separator that will hold the combobox
TBBUTTONINFO tbbi;
tbbi.cbSize = sizeof(tbbi);
tbbi.dwMask = TBIF_SIZE | TBIF_BYINDEX;
tbbi.cx = 500;
SendMessage(m_hToolbar, TB_SETBUTTONINFO, (WPARAM)0, (LPARAM)& tbbi);
这是创建组合框的代码:
//(9) Get the Rectangle occupied by the separator
RECT rcSep;
SendMessage(m_hToolbar, TB_GETITEMRECT, (WPARAM)0, (LPARAM)& rcSep);
//(10) Create the hosts comboBox
m_hComboHosts = CreateWindow(WC_COMBOBOXW, nullptr, WS_CHILD | CBS_DROPDOWN | WS_VISIBLE,
rcSep.left, rcSep.top, rcSep.right - rcSep.left, rcSep.bottom - rcSep.top, m_hToolbar,
(HMENU)IDC_COMBO_HOSTS, m_hInstance, nullptr);
这按预期工作。
但是当我尝试添加另外两个按钮 (32x16 - 16x16) 时,我总是得到与第一个 Imagelist (32) 相同的宽度。
但是当我交换图像列表索引时,我得到(两者都为 16)。
我正在使用新的视觉样式 ComCtl32.lib
推荐阅读
- sql - 在复制设置中禁用分发时出错
- unix - 如何在 linux docker 容器中使用文件名模式获取多个文件的基本名称
- php - Laravel $request->validated() 用于请求正文中具有对象数据类型的数据
- c# - 我该如何解决这个错误 StackExchange.Redis.RedisConnectionException: UnableToConnect on redisaec.redis.cache.windows.net:6380/Interactive
- c# - 1000后递增值,不自动递增SQL
- r - 如何在 R 中不使用 GGally 的情况下绘制矩阵列数据的所有组合?
- angular - Angular:当字符串插值在 html 中显示数据但错误 ctx 在控制台中未定义时,访问 *ngFor 循环中的对象数组时出现问题
- scala - 以我的名字(Spark、Scala)将数据帧输出到一个 csv 文件
- php - 在 laravel 中运行测试时无法找到 [App\Models\User] 的工厂
- c++ - 如何在clang中为一行禁用-Wvexing-parse?