编辑控件无法正常运行

时间:2018-05-06 15:31:03

标签: c++ winapi

我今天开始学习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个点,我的文字出现了。我转到菜单选择文件 - &gt;子 - &gt;更改,我的窗口名称更改为3点...。 但!如果我删除这些:| ES_MULTILINE | ES_AUTOVSCROLL然后文本框正常工作但菜单没有显示在我的窗口中。

我发现我必须使用EN_CHANGE做一些事情,但是我知道什么。我尝试将WM_COMMAND更改为EN_CHANGE,我的文本框工作正常,但其他菜单按钮根本不起作用...

1 个答案:

答案 0 :(得分:1)

您的失败是由同样处理所有编辑控件通知引起的。您需要测试通知代码(在HIWORD(wParam)中找到)以查看它是否为EN_CHANGE,并让您处理的通知传递到DefWindowProc

您还有一个更大的错误,即您使用非void返回类型到达函数的右括号。你需要总是回报一些东西;当你没有调用DefWindowProc时,系统仍然需要一个返回值。当您将WM_COMMAND更改为EN_CHANGE时,事情开始起作用的原因不是因为您正在处理EN_CHANGE,而是因为您不再对WM_COMMAND进行错误处理,而是让DefWindowProc接受他们。

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