Почему я не могу добавить кнопки на панель инструментов?[WINAPI] - PullRequest
2 голосов
/ 20 октября 2011

По какой-то причине, как только я пытаюсь разделить определенные блоки кода на разные функции, добавление кнопок (включая растровые изображения) на панель инструментов больше не работает.Однако, если собрать их в одном месте, это работает как обаяние.

Пока я не могу понять причину этого.Возможно, указатель работает не так, как ожидалось ...

Ожидаемый вывод: 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);
    ...
}

(Не обращайте внимания на строку состояния справа внизу, я забыл включить ее в кодв первом примере)

По очевидным причинам проблема должна лежать где-то в бите, который обрабатывает добавление растровых изображений и кнопок.Но что это, я не знаю ... что мне не хватает?

Edit1: чтобы было удобнее читать, я удалил две дополнительные кнопки (меньше кода).Он работает так же, как и раньше, то есть не работает вообще.; -)

EDIT2 : Благодаря HostileFork я обнаружил, что дескриптор окна не работает так же, как обычный необработанный указатель в 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
}

Ответы [ 2 ]

4 голосов
/ 20 октября 2011

Похоже, что вы присваиваете аргумент, который будет влиять на него только на время выполнения функции:

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 возвращаемым значением, либо передать его по ссылке или указателю, чтобы его значение можно было передать вызывающей стороне и использовать в других функциях ...

1 голос
/ 20 октября 2011

Имеет ли InitializeButtons значение по умолчанию для третьего параметра, size? Если это так, проверьте, что это такое, поскольку вы, похоже, не отправляете это значение при вызове метода. Я предполагаю, что параметр по умолчанию равен нулю, поэтому он будет передан в вызове SendMessage.

Если InitializeButtons не имеет значения по умолчанию для третьего параметра, то либо у вас есть опечатка в вашем исходном примере, у вас есть два InitializeButtons метода с различным количеством параметров (и, следовательно, вызывающий неправильный ), или ваш код не должен компилироваться:)

...