c++ WinAPI rebar控件未显示

yizd12fk  于 2023-08-09  发布在  其他
关注(0)|答案(2)|浏览(138)

我正在用C++开发一个纯WinAPI应用程序,我想在rebar控件中添加一个工具栏。我可以创建并添加工具栏,但无法显示钢筋(即使我设置了RBBS_GRIPPERALWAYS样式,也没有夹爪):
x1c 0d1x的数据
我从MSDN页面上获取了有关工具栏/钢筋控件的代码,并组装了一个最小的示例,但仍然没有成功。CreateWindow、SendMessage等返回码我看没问题。我也尝试了this question的解决方案,但无论如何我都不能让它工作。任何帮助将不胜感激。下面是完整的源代码:

#include "targetver.h"
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <CommCtrl.h>
#include <stdlib.h>
#include <malloc.h>
#include <memory.h>
#include <tchar.h>
#include "Resource.h"
#pragma comment(lib, "comctl32.lib")

// Enable visual styles
#pragma comment(linker,"\"/manifestdependency:type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"")

// Toolbar defines
#define IDM_NEW 100
#define IDM_OPEN 101
#define IDM_SAVE 102
#define NUM_TBBUTTONS 3

// Global variables
HINSTANCE g_hInst;
HIMAGELIST g_hImageList = NULL;

// Forward declarations
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
HWND CreateSimpleToolbar(HWND hwndParent);
HWND CreateSimpleRebar(HWND hwndParent, HWND hwndToolbar);

int APIENTRY wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nCmdShow) {
    // Initialize common controls.
    INITCOMMONCONTROLSEX icex;
    icex.dwSize = sizeof(INITCOMMONCONTROLSEX);
    icex.dwICC = ICC_COOL_CLASSES | ICC_BAR_CLASSES;
    InitCommonControlsEx(&icex);

    WNDCLASSEXW wcex;
    wcex.cbSize = sizeof(WNDCLASSEX);
    wcex.style = CS_HREDRAW | CS_VREDRAW;
    wcex.lpfnWndProc = WndProc;
    wcex.cbClsExtra = 0;
    wcex.cbWndExtra = 0;
    wcex.hInstance = hInstance;
    wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_REBARTEST));
    wcex.hCursor = LoadCursor(nullptr, IDC_ARROW);
    wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW);
    wcex.lpszMenuName = MAKEINTRESOURCEW(IDC_REBARTEST);
    wcex.lpszClassName = _T("RebarTest");
    wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));
    RegisterClassExW(&wcex);
    
    HWND hwndMainWindow = CreateWindowW(_T("RebarTest"), _T("AppTitle"), 
        WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, 
        nullptr, nullptr, hInstance, nullptr);
    if (!hwndMainWindow)
        return FALSE;

    ShowWindow(hwndMainWindow, nCmdShow);
    UpdateWindow(hwndMainWindow);

    MSG msg;
    while (GetMessage(&msg, nullptr, 0, 0)) {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }

    return (int)msg.wParam;
}

LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) {
    static HWND hwndToolbar, hwndRebar;
    switch (message)
    {
    case WM_CREATE:
    {
        hwndToolbar = CreateSimpleToolbar(hwnd);
        hwndRebar = CreateSimpleRebar(hwnd, hwndToolbar);
    }
    break;
    case WM_COMMAND:
    {
        int wmId = LOWORD(wParam);
        // Menüauswahl analysieren:
        switch (wmId)
        {       
        case IDM_EXIT:
            DestroyWindow(hwnd);
            break;
        default:
            return DefWindowProc(hwnd, message, wParam, lParam);
        }
    }
    break;
    case WM_DESTROY:
        PostQuitMessage(0);
        break;
    default:
        return DefWindowProc(hwnd, message, wParam, lParam);
    }
    return 0;
}

HWND CreateSimpleToolbar(HWND hwndParent) {
    // Create the toolbar.
    HWND hwndToolbar = CreateWindowEx(0, TOOLBARCLASSNAME, NULL,
        WS_CHILD | TBSTYLE_WRAPABLE, 0, 0, 0, 0, hwndParent, NULL, g_hInst, NULL);

    if (hwndToolbar == NULL)
        return NULL;

    // Create the image list.
    g_hImageList = ImageList_Create(16, 16, ILC_COLOR16 | ILC_MASK, NUM_TBBUTTONS, 0);

    // Set the image list and add buttons
    const int imageListID = 0;
    SendMessage(hwndToolbar, TB_SETIMAGELIST, (WPARAM)imageListID, (LPARAM)g_hImageList);
    SendMessage(hwndToolbar, TB_LOADIMAGES, (WPARAM)IDB_STD_SMALL_COLOR, (LPARAM)HINST_COMMCTRL);

    // Initialize button info.
    TBBUTTON tbButtons[NUM_TBBUTTONS] =
    {
        { MAKELONG(STD_FILENEW,  imageListID), IDM_NEW,  TBSTATE_ENABLED, BTNS_AUTOSIZE, {0}, 0, (INT_PTR)L"New" },
        { MAKELONG(STD_FILEOPEN, imageListID), IDM_OPEN, TBSTATE_ENABLED, BTNS_AUTOSIZE, {0}, 0, (INT_PTR)L"Open"},
        { MAKELONG(STD_FILESAVE, imageListID), IDM_SAVE, 0,               BTNS_AUTOSIZE, {0}, 0, (INT_PTR)L"Save"}
    };

    // Add buttons.
    SendMessage(hwndToolbar, TB_BUTTONSTRUCTSIZE, (WPARAM)sizeof(TBBUTTON), 0);
    SendMessage(hwndToolbar, TB_ADDBUTTONS, (WPARAM)NUM_TBBUTTONS, (LPARAM)&tbButtons);

    // Resize the toolbar, and then show it.
    SendMessage(hwndToolbar, TB_AUTOSIZE, 0, 0);
    ShowWindow(hwndToolbar, TRUE);
    return hwndToolbar;
}

HWND CreateSimpleRebar(HWND hwndParent, HWND hwndToolbar) {
    // Check parameters.
    if (!hwndParent || !hwndToolbar)
        return NULL;

    // Create the rebar.
    HWND hwndRebar = CreateWindowEx(WS_EX_TOOLWINDOW,
        REBARCLASSNAME, NULL,
        WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN | 
        RBS_VARHEIGHT | CCS_NODIVIDER | RBS_BANDBORDERS,
        0, 0, 0, 0,
        hwndParent, NULL, g_hInst, NULL);

    if (!hwndRebar)
        return NULL;

    // Get the height of the toolbar.
    DWORD dwBtnSize = (DWORD)SendMessage(hwndToolbar, TB_GETBUTTONSIZE, 0, 0);
    
    REBARBANDINFO rbBand;
    rbBand.cbSize = sizeof(REBARBANDINFO);
    rbBand.fMask =
        RBBIM_STYLE       // fStyle is valid.
        | RBBIM_TEXT        // lpText is valid.
        | RBBIM_CHILD       // hwndChild is valid.
        | RBBIM_CHILDSIZE   // child size members are valid.
        | RBBIM_SIZE;       // cx is valid
    rbBand.fStyle = RBBS_CHILDEDGE | RBBS_GRIPPERALWAYS;
    rbBand.lpText = (LPWSTR)_T("");
    rbBand.hwndChild = hwndToolbar;
    rbBand.cyChild = LOWORD(dwBtnSize);
    rbBand.cxMinChild = NUM_TBBUTTONS * HIWORD(dwBtnSize);
    rbBand.cyMinChild = LOWORD(dwBtnSize);
    rbBand.cx = 0;  // The default width is the width of the buttons.

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

字符串

3yhwsihp

3yhwsihp1#

正如在这个问题的注解中所描述的,你需要定义一个_WIN32_WINNT,我假设你可能在你的“targetver.h”头中有它。由于您正在声明公共控件版本6,因此我认为您至少需要针对WS-2003/Vista。我第一次用你的代码尝试#define WINVER 0x0601#define _WIN32_WINNT_WIN7 0x0601,它在我的机器上工作。
我认为你链接的问题有点过时了,这个表说通用控件版本6的结构大小应该是REBARBANDINFO_V6_SIZE。然而,我遇到了4像素的高度问题,从您的链接问题时,使用该结构的大小。保持代码大小不变对我来说很有用。
我认为真实的的问题是你的工具栏是处理自己的大小和定位。如“关于工具栏控件”页所述,您需要更改

HWND hwndToolbar = CreateWindowEx(0, TOOLBARCLASSNAME, NULL, WS_CHILD | TBSTYLE_WRAPABLE, 0, 0, 0, 0, hwndParent, NULL, g_hInst, NULL);

字符串
到这个

HWND hwndToolbar = CreateWindowEx(0, TOOLBARCLASSNAME, NULL, WS_CHILD | TBSTYLE_WRAPABLE | CCS_NORESIZE | CCS_NOPARENTALIGN, 0, 0, 0, 0, hwndParent, NULL, g_hInst, NULL);


在CreateSimpleToolbar函数中,以便主体钢筋可以控制工具栏的大小和位置。

vsmadaxz

vsmadaxz2#

我花了一天的大部分时间试图解决类似的问题。我正在使用CommCtrl verson 6,因此需要使用REBARBANDINFO_V6_SIZE。我已经使用了RBBS_VARIABLEHEIGHT,所以需要包括cxMaxChildcyIntegral,它们没有包括在MS示例中。据我所知,通过不设置cxMaxChild属性,它被设置为0,因此钢筋的高度永远不会超过子元素的最大高度。注意,REBARBANDINFO_V3_SIZE应该是可以的,因为RBBS_VARIABLEHEIGHTcxMaxChildcyIntegral包含在verson 4.7中。

相关问题