c - 为什么我似乎无法向工具栏添加按钮? [WINAPI]

标签 c winapi button toolbar

出于某种原因,一旦我尝试将某些代码块分成不同的函数,向工具栏添加按钮(包括位图)就不再起作用。然而,将它们放在一个地方就像一种魅力。

但我无法找出其中的原因。也许指针没有按预期工作...

预期输出是这样的: Working version with buttons in the toolbar

相关代码:

LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    switch(msg)
    {
        case WM_CREATE:
            CreateUserInterface(hwnd);
            break;
        ...
    }
    return 0;
}

void CreateUserInterface(HWND hwnd)
{
    HFONT hfDefault;
    HWND hEdit;

    HWND hTool;
    TBADDBITMAP tbab;
    TBBUTTON tbb[TBBSIZE];

    HWND hStatus;
    int statWidths[] = {100, -1};

    // create edit control
    hEdit = CreateWindowEx(WS_EX_CLIENTEDGE,
                         "EDIT",
                         "",
                         WS_CHILD | WS_VISIBLE | WS_VSCROLL | WS_HSCROLL |
                         ES_MULTILINE | ES_AUTOVSCROLL | ES_AUTOHSCROLL,
                         0, 0, 100, 100,
                         hwnd, (HMENU) IDC_MAIN_EDIT,
                         GetModuleHandle(NULL), NULL);

     if(hEdit == NULL)
     {
         MessageBox(hwnd, "Could not create edit box!", "Error!",
                 MB_OK | MB_ICONERROR);
     }

     hfDefault = GetStockObject(DEFAULT_GUI_FONT);
     SendMessage(hEdit, WM_SETFONT, (WPARAM) hfDefault, MAKELPARAM(FALSE, 0));

     // create toolbar
     hTool = CreateWindowEx(0, TOOLBARCLASSNAME, NULL,
                         WS_CHILD | WS_VISIBLE,
                         0, 0, 0, 0,
                         hwnd, (HMENU) IDC_MAIN_TOOL,
                         GetModuleHandle(NULL), NULL);

     if(hTool == NULL)
     {
         MessageBox(hwnd, "Could not create tool bar!", "Error!",
                 MB_OK | MB_ICONERROR);
     }    

     SendMessage(hTool, TB_BUTTONSTRUCTSIZE, (WPARAM) sizeof(TBBUTTON), 0);

     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_SAVE_AS;

     SendMessage(hTool, TB_ADDBUTTONS, sizeof(tbb)/sizeof(TBBUTTON), (LPARAM) &tbb);
}

我得到的是:

Here the buttons are missing

相关代码:

#define TBBSIZE 1
void CreateUserInterface(HWND hwnd)
{
    ...
    HWND hTool;
    TBADDBITMAP tbab;
    TBBUTTON tbb[TBBSIZE];
    ...

    CreateToolbar(hwnd, hTool);
    InitializeBitmap(hTool, &tbab);
    InitializeButtons(htool, tbb, TBBSIZE);
    ...
}

void CreateToolbar(HWND hwnd, HWND hTool)
{
    hTool = CreateWindowEx(0, TOOLBARCLASSNAME, NULL,
                        WS_CHILD | WS_VISIBLE,
                        0, 0, 0, 0,
                        hwnd, (HMENU) IDC_MAIN_TOOL,
                        GetModuleHandle(NULL), NULL);

    if(hTool == NULL)
    {
        MessageBox(hwnd, "Could not create tool bar!", "Error!",
                MB_OK | MB_ICONERROR);
    }

    SendMessage(hTool, TB_BUTTONSTRUCTSIZE, (WPARAM) sizeof(TBBUTTON), 0);
}

void InitializeBitmap(HWND hTool, TBADDBITMAP *tbab)
{
    (*tbab).hInst = HINST_COMMCTRL;
    (*tbab).nID = IDB_STD_SMALL_COLOR;

    SendMessage(hTool, TB_ADDBITMAP, 0, (LPARAM) tbab);
}

void InitializeButtons(HWND hTool, TBBUTTON *tbb, int size)
{
    ZeroMemory(tbb, sizeof(*tbb) * size);
    tbb[size-size].iBitmap = STD_FILENEW;
    tbb[size-size].fsState = TBSTATE_ENABLED;
    tbb[size-size].fsStyle = TBSTYLE_BUTTON;
    tbb[size-size].idCommand = ID_FILE_NEW;

    SendMessage(hTool, TB_ADDBUTTONS, size, (LPARAM) tbb);
    ...
}

(不要介意右下角的状态栏,我忘了将其包含在第一个示例的代码中)

出于显而易见的原因,问题肯定出在处理添加位图和按钮的位中的某个位置。但我不知道它是什么......我错过了什么?

编辑1:为了使其更容易阅读,我删除了两个附加按钮(更少的代码)。它的工作方式仍然相同,即根本不工作。 ;-)

EDIT2:感谢 HostileFork,我发现 Windows 句柄的工作方式与 C 中普通原始指针的工作方式不太一样。解决方案是传递 hTool 的地址CreateToolbar 函数:

#define TBBSIZE 1
void CreateUserInterface(HWND hwnd)
{
    ...
    HWND hTool;
    ...

    CreateToolbar(hwnd, &hTool);
    ...
}

void CreateToolbar(HWND hwnd, HWND *hTool)
{
    *hTool = CreateWindowEx(0, TOOLBARCLASSNAME, NULL,
                    WS_CHILD | WS_VISIBLE,
                    0, 0, 0, 0,
                    hwnd, (HMENU) IDC_MAIN_TOOL,
                    GetModuleHandle(NULL), NULL);

    ... // and so on
}

最佳答案

看起来您正在分配一个参数,这只会在函数的持续时间内影响它:

void CreateToolbar(HWND hwnd, HWND hTool)
{
    hTool = CreateWindowEx(0, TOOLBARCLASSNAME, NULL,
                    WS_CHILD | WS_VISIBLE,
                    0, 0, 0, 0,
                    hwnd, (HMENU) IDC_MAIN_TOOL,
                    GetModuleHandle(NULL), NULL);
    ...
}

您需要使 hTool 成为返回值,或者通过引用或指针传递它,以便它的值可以向上冒泡到调用者并在其他函数中使用...

关于c - 为什么我似乎无法向工具栏添加按钮? [WINAPI],我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7834873/

相关文章:

c - 如何使用 libxml2 库在 c 中解析 XML 字符串而不是 XML 文档

连接字符串并将它们存储在 ANSI C 的缓冲区中

c++ - 了解 C++ 中的自删除程序

visual-studio-2010 - 尝试加载 dll 时出错 - 尝试加载格式不正确的程序。 (HRESULT : 0x8007000B) 的异常

c - 如何将 char 数组的值传递给 C 中另一个文件中的函数?

c - strcpy 无法正确处理动态分配的 char 数组

c++ - 无法将项目添加到 Win32 列表框控件

android - 如何在一行中对齐 3 个按钮,android?

html - 我怎样才能让一个图像作为一个按钮,并让它在点击时执行一个 Action (启动一个关键帧事件,运行一个脚本)?

html - Firefox 在带有边框的按钮中的图像周围添加了额外的空间