在我的 Win32 应用程序中,我有一个工具栏,它需要有一个主组合框下拉菜单,从左侧开始跨越工具栏的 70%,然后是任何附加按钮(例如在本例中为剪切/复制/粘贴) - 可能在一个小的分隔符之后。
[--------------------Dropdown-------------------V] | [Cut][Copy][Paste]
在此代码中,我首先为工具栏创建子 ComboBox 控件,并使其具有 Toolbar Rect 宽度的 70% setWindowPos
,然后继续使用常规按钮。但是,没有 ComboBox,只显示了 3 个按钮。
我想我必须SetWindowPos
对每个按钮都这样做,但我希望它们自然流动而不需要明确地定位它们,就像没有组合框一样。
void CreateToolbar1(HWND hWndParent)
{
// Declare and initialize local constants.
const int ImageListID = 0;
const int numButtons = 3;
const int bitmapSize = 16;
const DWORD buttonStyles = BTNS_AUTOSIZE;
// Create the toolbar.
hWndToolbar1 = CreateWindowEx(0, TOOLBARCLASSNAME, NULL,
WS_CHILD | TBSTYLE_WRAPABLE | TBSTYLE_FLAT, 0, 0, 0, 0,
hWndParent, NULL, GetModuleHandle(NULL), NULL);
// Obtain toolbar's rectangle coordinates
RECT rectToolbar1;
SendMessage(hWndToolbar1, TB_GETITEMRECT, (WPARAM)0, (LPARAM)&rectToolbar1);
// Add ComboBox control to toolbar, should take up 70% of the width
HWND hWndDropdown = CreateWindowEx(WS_EX_CLIENTEDGE, WC_COMBOBOXEX, NULL, WS_CHILD | WS_VISIBLE | CBS_DROPDOWNLIST, 0, 0, 100, 35, hWndToolbar1, NULL, GetModuleHandle(NULL), NULL);
SetWindowPos(hWndDropdown, NULL, rectToolbar1.left, rectToolbar1.top, 0.7 * (rectToolbar1.right - rectToolbar1.left), rectToolbar1.bottom - rectToolbar1.top, SWP_SHOWWINDOW);
// Add 3 regular buttons afterwards (Cut/Copy/Paste)
// ---
// Create the image list.
g_hImageList = ImageList_Create(bitmapSize, bitmapSize, // Dimensions of individual bitmaps.
ILC_COLOR16 | ILC_MASK, // Ensures transparent background.
numButtons, 0);
// Set the image list.
SendMessage(hWndToolbar1, TB_SETIMAGELIST,
(WPARAM)ImageListID,
(LPARAM)g_hImageList);
// Load the button images.
SendMessage(hWndToolbar1, TB_LOADIMAGES,
(WPARAM)IDB_STD_SMALL_COLOR,
(LPARAM)HINST_COMMCTRL);
// Initialize buttons Cut/Copy/Paste
TBBUTTON tbButtons[numButtons] =
{
{ MAKELONG(STD_CUT, ImageListID), IDM_CUT, TBSTATE_ENABLED, buttonStyles, {0}, 0, (INT_PTR)L"Cut" },
{ MAKELONG(STD_COPY, ImageListID), IDM_COPY, TBSTATE_ENABLED, buttonStyles, {0}, 0, (INT_PTR)L"Copy"},
{ MAKELONG(STD_PASTE, ImageListID), IDM_PASTE, 0, buttonStyles, {0}, 0, (INT_PTR)L"Paste"}
};
// Add buttons.
SendMessage(hWndToolbar1, TB_BUTTONSTRUCTSIZE, (WPARAM)sizeof(TBBUTTON), 0);
SendMessage(hWndToolbar1, TB_ADDBUTTONS, (WPARAM)numButtons, (LPARAM)&tbButtons);
// Resize the toolbar, and then show it.
SendMessage(hWndToolbar1, TB_AUTOSIZE, 0, 0);
ShowWindow(hWndToolbar1, TRUE);
}
这是两个独立问题合作的结果:
第一个问题意味着,即使组合框在那里,你也看不到它。它完全隐藏在第一个工具栏按钮后面。除了更改代码以计算所需的宽度外,无需执行任何其他操作。
第二个问题需要更多关注。为了理解核心原理,这里是工具栏控件的定义:
值得注意的是,工具栏控件不提供对托管任意控件的专门支持。文档主题如何在工具栏中嵌入非按钮控件更加明确:
由此得出的推论是,整个布局信息都存储在
TBBUTTON
通过消息分配的数组中TB_ADDBUTTONS
。每个元素要么描述一个按钮,要么描述一个分隔符。向工具栏添加任意控件的解决方法是向数组添加一个分隔符(所需宽度的像素)TBBUTTON
以保留控件的空间,例如:第一个条目为组合框控件保留了空间。它实际上是一个不接收用户输入的占位符。虽然这可行,但感觉很笨重。
更好的解决方案是使用Rebar控件。除其他功能外,它还提供对托管任意控件的专用支持。