Редактирование управления не работает правильно - PullRequest
0 голосов
/ 06 мая 2018

Я начал изучать winapi c ++ сегодня.И я написал эту простую программу, которая должна изменить имя окна на имя, которое я пишу в текстовом поле:

#include <Windows.h>

LRESULT CALLBACK WindowProcedure(HWND, UINT, WPARAM, LPARAM);

void AddMenu(HWND);
void AddControl(HWND);


HWND hEdit;

int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrewInst, LPSTR args, int ncmdshow)
{
    WNDCLASSW wc = { 0 };
    wc.hbrBackground = (HBRUSH)COLOR_WINDOW;
    wc.hCursor = LoadCursor(NULL, IDC_ARROW);
    wc.hInstance = hInst;
    wc.lpszClassName = L"class";
    wc.lpfnWndProc = WindowProcedure;

    if (!RegisterClassW(&wc))
        return -1;

    CreateWindowW(L"class", L"Window", WS_OVERLAPPEDWINDOW | WS_VISIBLE, 100, 100, 500, 500, NULL, NULL, NULL, NULL);
    MSG msg = { 0 };
    while (GetMessage(&msg, NULL, NULL, NULL))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    return 0;
}

LRESULT CALLBACK WindowProcedure(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp)
{
    switch (msg)
    {
    case WM_COMMAND:
        switch (wp)
        {
        case 1:
            MessageBeep(MB_SERVICE_NOTIFICATION); break;
        case 2:
            DestroyWindow(hWnd); break;
        case 3:
            wchar_t text[100];
            GetWindowTextW(hEdit, text, 100);
            SetWindowTextW(hWnd, text);
            break;
        }
    case WM_CREATE:
        AddMenu(hWnd);
        AddControl(hWnd);
        break;
    case WM_DESTROY:
        PostQuitMessage(0);
        break;
    default:
        return DefWindowProcW(hWnd, msg, wp, lp);
    }
}

void AddMenu(HWND hWnd)
{
    HMENU hMenu;
    hMenu = CreateMenu();
    HMENU file;
    file = CreateMenu();
    HMENU Sub;
    Sub = CreateMenu();

    AppendMenu(hMenu, MF_POPUP, (UINT_PTR)file, "File");

    AppendMenu(file, MF_STRING, 1, "Open");
    AppendMenu(file, MF_POPUP, (UINT_PTR)Sub, "Sub");

    AppendMenu(file, MF_STRING, 2, "Exit");

    AppendMenu(Sub, MF_STRING, 3, "Change");

    SetMenu(hWnd, hMenu);

}

void AddControl(HWND hWnd)
{
    CreateWindowW(L"Static", L"Enter text: ", WS_VISIBLE | WS_CHILD | WS_BORDER | SS_CENTER, 200, 100, 100, 20, hWnd, NULL, NULL, NULL);
    hEdit = CreateWindowW(L"Edit", L"...", WS_VISIBLE | WS_CHILD | WS_BORDER | ES_MULTILINE | ES_AUTOVSCROLL, 200, 152, 100, 50, hWnd, NULL, NULL, NULL);

}

По умолчанию в текстовом поле у ​​меня есть ....Поэтому я запускаю свою программу, начиная набирать hello world для примера, но ничего не меняется.Я выделил свои 3 точки, которые должны были измениться, и бум, мой текст появился.Я иду в меню выберите Файл -> Под - - Изменить, и мое имя окна меняется на 3 точки ....НО!Если я удаляю это: | ES_MULTILINE | ES_AUTOVSCROLL, тогда текстовое поле работает правильно, но меню не отображается в моем окне.

Я обнаружил, что должен сделать что-то с EN_CHANGE, но не знаю, что.Я попытался изменить WM_COMMAND на EN_CHANGE, и мое текстовое поле работало правильно, но другие кнопки меню не работали вообще ...

1 Ответ

0 голосов
/ 06 мая 2018

Ваш сбой вызван одинаковой обработкой всех уведомлений управления редактированием. Вам нужно проверить код уведомления (найденный в HIWORD(wParam)), чтобы увидеть, является ли он EN_CHANGE, и позволить не обрабатываемым уведомлениям проходить к DefWindowProc.

У вас также есть еще большая ошибка в том, что вы достигаете закрывающей скобки функции с типом возврата, отличным от void. Вы должны всегда что-то возвращать; когда вы не вызываете DefWindowProc, система все еще ожидает возвращаемое значение. Причина, по которой все начинает работать, когда вы меняете WM_COMMAND на EN_CHANGE, не в том, что вы обрабатываете EN_CHANGE, а в том, что у вас больше нет неправильной обработки WM_COMMAND, и вместо этого позвольте DefWindowProc принять их.

Падение с WM_COMMAND на WM_CREATE тоже не помогает.

LRESULT CALLBACK WindowProcedure(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    switch (msg)
    {
    case WM_COMMAND:
        switch (HIWORD(wParam)) /* command kind */
        {
        case 0: // menus
            switch (LOWORD(wParam)) /* child ID */
            {
            case 1:
                MessageBeep(MB_SERVICE_NOTIFICATION);
                return 0;
            case 2:
                DestroyWindow(hWnd);
                return 0;
            case 3:
                wchar_t text[100];
                GetWindowTextW(hEdit, text, 100);
                SetWindowTextW(hWnd, text);
                return 0;
            }
            break;
        }
        break;
    case WM_CREATE:
        AddMenu(hWnd);
        AddControl(hWnd);
        return 0;
    case WM_DESTROY:
        PostQuitMessage(0);
        return 0;
    }
    // break actions also reach here
    return DefWindowProcW(hWnd, msg, wParam, lParam);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...