Как включить современный вид панели инструментов для приложения Win32?

Недавно я начал изучать программирование с графическим интерфейсом на основе Win32 API. Когда я добавляю элемент управления на панели инструментов (из comctl32.lib) в свое простое приложение, я обнаруживаю, что оно выглядит плоским, в то время как строка меню имеет более "дружественный к Windows 7" трехмерный вид (белое свечение вверху и вертикальный серый градиент сверху вниз). Разница в том, что он выглядит проводным.

Стиль панели инструментов по умолчанию

Однако я считаю, что многие другие приложения имеют одинаковый внешний вид как для строки меню, так и для панели инструментов. Например. Notepad ++ и Блокнот 2.

Блокнот ++Блокнот 2

Я прочитал некоторые официальные документы и попробовал решение, например Обзор визуальных стилей, Включение визуальных стилей, однако он включает только стиль плоских кнопок (по сравнению со старым стилем сплошных кнопок Win98). Это не имело никакого значения для стиля, который я получил на первой фотографии.

Я попытался прочитать исходный код Notepad ++. Найден и внес в мой код соответствующие изменения, но ничего не изменилось. Думаю, я потерялся в кодовой базе.

Вот мой код вызова InitCommonControlsEx и создания ToolBar.

// 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);
}

Итак, вопрос: несмотря на растровые изображения кнопок, как я могу получить трехмерный вид панели инструментов, как в примере Notepad ++ / Notepad2?

Заранее спасибо.


person Arie Xiao    schedule 16.06.2013    source источник
comment
Никогда не бывает недостатка в выборе панели инструментов. В Notepad ++ используется элемент управления Rebar, страница SDK здесь. Не похоже, что вы правильно поняли манифест визуальных стилей.   -  person Hans Passant    schedule 16.06.2013
comment
@HansPassant В примере Rebar на странице SDK показана плоская панель инструментов, встроенная в Rebar, а не в стиле Notepad ++. И пример на странице манифеста решения также показал плоский стиль. Интересно, как Nodepad ++ удалось сделать этот стиль панели инструментов из ToolBar / Rebar.   -  person Arie Xiao    schedule 16.06.2013
comment
Ну, Notepad ++ "плоский" на моей машине и на скриншоте, который вы связали. Не упустите старую версию, вкус и версии Windows быстро меняются.   -  person Hans Passant    schedule 16.06.2013
comment
Я могу подтвердить, что Ари Шоу прав, панель инструментов Win32 по умолчанию такая же, как на изображении №1. И notepad2 - ›изображение №3.   -  person dns    schedule 19.01.2014


Ответы (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);
}
person dns    schedule 19.01.2014
comment
Ах, это сработало, спасибо. Прошло много времени с тех пор, как я последний раз прикасался к WINAPI. У меня все еще проблема с тем, что панель инструментов не отображается, пока вы не наведете указатель мыши на значки. Я исследую это позже. - person Arie Xiao; 20.04.2014