【问题标题】:How to enable modern look and feel of tool bar for Win32 Application?如何为 Win32 应用程序启用工具栏的现代外观?
【发布时间】:2013-06-12 15:56:27
【问题描述】:

最近开始学习基于 Win32 API 的 GUI 编程。当我将工具栏控件(来自 comctl32.lib)添加到我的简单应用程序时,我发现它看起来很平坦,而菜单栏具有更多“Windows 7 友好”的 3D 外观和感觉(顶部的白光和从上到下的垂直灰色渐变)。不同之处使它看起来很有线。

但是,我发现许多其他应用程序的菜单栏和工具栏的外观和感觉都是一致的。例如。 Notepad++Notepad 2

我看了一些官方文档并尝试了解决方案,例如Visual Styles OverviewEnabling Visual Styles,但是它只启用了平面按钮样式(与旧的Win98实体按钮样式相比)。这与我在第一张照片中得到的风格没有区别。

我试图阅读 Notepad++ 的源代码。找到 ToolBar.cpp 并相应地对我的代码进行了一些更改,但没有任何改变。我想我迷失在代码库中了。

这是我调用InitCommonControlsEx 和创建工具栏的代码。

// in WinMain
INITCOMMONCONTROLSEX icce;
icce.dwSize = sizeof(INITCOMMONCONTROLSEX);
icce.dwICC = ICC_BAR_CLASSES | ICC_COOL_CLASSES | ICC_USEREX_CLASSES;
InitCommonControlsEx(&icce);

// called in WM_CREATE handler, hwnd is the handle of the main window
VOID BuildToolBar(HWND hwnd)
{
    HWND hTool;
    TBBUTTON tbb[3];
    TBADDBITMAP tbab;

    hTool = CreateWindowEx(0, TOOLBARCLASSNAME, NULL, WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | TBSTYLE_TOOLTIPS |TBSTYLE_FLAT | CCS_TOP | BTNS_AUTOSIZE, 0, 0, 0, 0, hwnd, (HMENU)IDC_MAIN_TOOL, GetModuleHandle(NULL), NULL);
    SendMessage(hTool, TB_BUTTONSTRUCTSIZE, (WPARAM)sizeof(TBBUTTON), 0);
    SendMessage(hTool, TB_SETEXTENDEDSTYLE, 0, (LPARAM)TBSTYLE_EX_HIDECLIPPEDBUTTONS);

    tbab.hInst = HINST_COMMCTRL;
    tbab.nID = IDB_STD_SMALL_COLOR;
    SendMessage(hTool, TB_ADDBITMAP, 0, (LPARAM)&tbab);

    ZeroMemory(tbb, sizeof(tbb));
    tbb[0].iBitmap = STD_FILENEW;
    tbb[0].fsState = TBSTATE_ENABLED;
    tbb[0].fsStyle = TBSTYLE_BUTTON;
    tbb[0].idCommand = ID_FILE_NEW;

    tbb[1].iBitmap = STD_FILEOPEN;
    tbb[1].fsState = TBSTATE_ENABLED;
    tbb[1].fsStyle = TBSTYLE_BUTTON;
    tbb[1].idCommand = ID_FILE_OPEN;

    tbb[2].iBitmap = STD_FILESAVE;
    tbb[2].fsState = TBSTATE_ENABLED;
    tbb[2].fsStyle = TBSTYLE_BUTTON;
    tbb[2].idCommand = ID_FILE_SAVEAS;

    SendMessage(hTool, TB_SETBUTTONSIZE, (WPARAM)0, (LPARAM)MAKELONG(16, 16));
    SendMessage(hTool, TB_ADDBUTTONS, sizeof(tbb) / sizeof(TBBUTTON), (LPARAM)&tbb);
    SendMessage(hTool, TB_AUTOSIZE, 0, 0);
}

所以,问题是:尽管有按钮的位图,但我如何才能获得工具栏的 3D 外观,就像 Notepad++/Notepad2 示例一样?

提前致谢。

【问题讨论】:

  • 工具栏选择永远不缺。 Notepad++ 使用 Rebar 控件,SDK 页面is here。看起来您的视觉样式清单不正确。
  • @HansPassant SDK 页面上的 Rebar 示例显示了嵌入在 Rebar 中的平面工具栏,而不是 Notepad++ 样式。 “清单”解决方案页面上的示例也显示了平面样式。我想知道 Nodepad++ 是如何从 ToolBar/Rebar 中制作出工具栏样式的。
  • 好吧,Notepad++ 在我的机器上和你链接的屏幕截图上是“平的”。注意旧版本,口味和 Windows 版本变化很快。
  • 我可以确认 Arie Shaw 是对的,默认的 Win32 工具栏与图像 #1 相同。和记事本2->图像#3。

标签: c windows winapi user-interface comctl32


【解决方案1】:

先创建工具栏,再创建钢筋。

rbBand.hbmBack 必须设置为 NULL 以获得现代外观工具栏, 或从下面的代码中删除 RBBIM_BACKGROUND 标志。

创建钢筋的方法如下:

HWND WINAPI CreateRebar (HWND hwndOwner)
{
    REBARINFO     rbi;
    REBARBANDINFO rbBand;
    RECT          rc;
    HWND   hwndCB, hwndRB;
    DWORD  dwBtnSize;

    hwndRB = CreateWindowExW(WS_EX_TOOLWINDOW,
        REBARCLASSNAME,
        NULL,
        WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS |
        WS_CLIPCHILDREN | RBS_VARHEIGHT |
        CCS_NODIVIDER,
        0, 0, 0, 0,
        hwndOwner,
        NULL,
        GetModuleHandleW(NULL),
        NULL);
    if (!hwndRB)
        return NULL;
    // Initialize and send the REBARINFO structure.
    rbi.cbSize = sizeof(REBARINFO);  // Required when using this
    // structure.
    rbi.fMask = 0;
    rbi.himl = (HIMAGELIST)NULL;
    if (!SendMessage(hwndRB, RB_SETBARINFO, 0, (LPARAM)&rbi))
        return NULL;
    // Initialize structure members that both bands will share.
    rbBand.cbSize = sizeof(REBARBANDINFO);  // Required
    rbBand.fMask = RBBIM_COLORS | RBBIM_TEXT | RBBIM_BACKGROUND |
        RBBIM_STYLE | RBBIM_CHILD | RBBIM_CHILDSIZE |
        RBBIM_SIZE;
    rbBand.fStyle = RBBS_CHILDEDGE | RBBS_FIXEDBMP;
    rbBand.hbmBack = NULL;  //
    // Create the combo box control to be added.
    hwndCB = CreateWindowW(TEXT("COMBOBOX"), NULL,
        WS_CHILD | WS_VISIBLE | CBS_HASSTRINGS | CBS_DROPDOWNLIST,
        410, 20, 120, 110, (HWND) NULL, NULL, NULL, NULL);;
    // Set values unique to the band with the combo box.
    GetWindowRect(hwndCB, &rc);
    rbBand.lpText = "Combo Box";
    rbBand.hwndChild = hwndCB;
    rbBand.cxMinChild = 0;
    rbBand.cyMinChild = rc.bottom - rc.top;
    rbBand.cx = 200;

    // Add the band that has the combo box.
    SendMessage(hwndRB, RB_INSERTBAND, (WPARAM)-1, (LPARAM)&rbBand);


    // Get the height of the toolbar.
    dwBtnSize = SendMessage(toolbar1, TB_GETBUTTONSIZE, 0, 0);

    // Set values unique to the band with the toolbar.
    rbBand.lpText = "Tool Bar";
    rbBand.hwndChild = toolbar1;
    rbBand.cxMinChild = 0;
    rbBand.cyMinChild = HIWORD(dwBtnSize);
    rbBand.cx = 250;

    // Add the band that has the toolbar.
    SendMessage(hwndRB, RB_INSERTBAND, (WPARAM)-1, (LPARAM)&rbBand);
    return (hwndRB);
}

【讨论】:

  • 啊,成功了,谢谢。自从我上次接触 WINAPI 以来已经有很长时间了。在您将鼠标放在图标上之前,我仍然遇到工具栏不显示的问题。我稍后会调查。
猜你喜欢
  • 2012-08-20
  • 2021-07-18
  • 2012-04-25
  • 1970-01-01
  • 2018-06-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多