如何清除 Win32 C++ 中的文本框

how to clear a text box in Win32 C++

我正在用C++制作一个记事本,我想在点击某个按钮时清除文本框。我无法从我的文本框所在的 LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) {...} 中获取 WinMain() 函数中的文本框。这是我的文本框的代码
HWND hWndEdit = CreateWindow(TEXT("EDIT"), TEXT(""), WS_CHILD | WS_VISIBLE | WS_BORDER | WB_LEFT | ES_AUTOVSCROLL | ES_MULTILINE, 0, 0, 1366, 768, hWnd, NULL, NULL, NULL);

我试过谷歌搜索无济于事,仔细考虑了许多论坛,甚至将文本框放在 LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) {...} 内,并使用 SetWindowText(hWndEdit, _T("")),这导致我的程序冻结。我不确定该怎么做。将文本框代码放回 WinMain 函数中会阻止它冻结,但我无法再清除它了。我能做什么?

如果你需要我的所有代码,就在这里。

// compile with: /D_UNICODE /DUNICODE /DWIN32 /D_WINDOWS /c

#include <windows.h>
#include <stdlib.h>
#include <string.h>
#include <tchar.h>

// Global variables
HMENU menuStrip;

// The main window class name.
static TCHAR szWindowClass[] = _T("DesktopApp");

// The string that appears in the application's title bar.
static TCHAR szTitle[] = _T("NoteRecorder");

HINSTANCE hInst;

// Forward declarations of functions included in this code module:
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);

void AddMenuStrip(HWND hWnd);

int WINAPI WinMain(
    _In_ HINSTANCE hInstance,
    _In_opt_ HINSTANCE hPrevInstance,
    _In_ LPSTR     lpCmdLine,
    _In_ int       nCmdShow
)
{
    WNDCLASSEX 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(wcex.hInstance, L"");
    wcex.hIconSm = LoadIcon(wcex.hInstance, IDI_APPLICATION);
    wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
    wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
    wcex.lpszMenuName = NULL;
    wcex.lpszClassName = szWindowClass;
    wcex.hIconSm = LoadIcon(wcex.hInstance, IDI_APPLICATION);

    if (!RegisterClassEx(&wcex))
    {
        MessageBox(NULL,
            _T("Call to RegisterClassEx failed!"),
            _T("Windows Desktop Guided Tour"),
            NULL);

        return 1;
    }

    hInst = hInstance;

    // Height and width
    int x = 1366;
    int y = 768;

    HWND hWnd = CreateWindowEx(
        WS_EX_OVERLAPPEDWINDOW,
        szWindowClass,
        szTitle,
        WS_OVERLAPPEDWINDOW,
        CW_USEDEFAULT, CW_USEDEFAULT,
        x, y,
        NULL,
        NULL,
        hInstance,
        NULL
    );

    


    if (!hWnd)
    {
        MessageBox(NULL,
            _T("Call to CreateWindow failed!"),
            _T("NoteRecorder"),
            NULL);

        return 1;
    }

    // The parameters to ShowWindow explained:
    // hWnd: the value returned from CreateWindow
    // nCmdShow: the fourth parameter from WinMain
    ShowWindow(hWnd,
        nCmdShow);
    UpdateWindow(hWnd);

    // Main message loop:
    MSG msg;
    while (GetMessage(&msg, NULL, 0, 0))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }

    return (int)msg.wParam;
}

//  FUNCTION: WndProc(HWND, UINT, WPARAM, LPARAM)
//
//  PURPOSE:  Processes messages for the main window.
//
//  WM_PAINT    - Paint the main window
//  WM_DESTROY  - post a quit message and return
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    
    HWND hWndEdit = CreateWindow(TEXT("EDIT"), TEXT(""), WS_CHILD | WS_VISIBLE | WS_BORDER | WB_LEFT | ES_AUTOVSCROLL | ES_MULTILINE, 0, 0, 1366, 768, hWnd, NULL, NULL, NULL);

    switch (message)
    {
    case WM_COMMAND:
        switch (wParam)
        {
        case 11:
            SetWindowText(hWndEdit, _T(""));
            MessageBox(NULL,
                _T("The function has executed successfully."),
                _T("NoteRecorder"),            

                MB_ICONASTERISK);
            break;
        case 12:
            break;
        case 13:
            break;
        case 14:
            break;
        case 15:
            break;
        
        case 21:
            break;
        case 22:
            break;
        case 23:
            break;
        case 24:
            break;
        case 25:
            break;
        case 26:
            break;

        case 31:
            break;
        case 41:
            break;
        case 42:
            break;
        }


        break;
    case WM_CREATE:
        AddMenuStrip(hWnd);
        break;
    case WM_DESTROY:
        PostQuitMessage(0);
        break;
    default:
        return DefWindowProc(hWnd, message, wParam, lParam);
        break;
    }

    return 0;
}

void AddMenuStrip(HWND hWnd)
{
    menuStrip = CreateMenu();
    HMENU fileMenu = CreateMenu();
        AppendMenu(fileMenu, MF_STRING, 11, L"New");
        AppendMenu(fileMenu, MF_STRING, 12, L"Open");
        AppendMenu(fileMenu, MF_STRING, 13, L"Save");
        AppendMenu(fileMenu, MF_STRING, 14, L"Save As");
        AppendMenu(fileMenu, MF_SEPARATOR, NULL, NULL);
        AppendMenu(fileMenu, MF_STRING, 15, L"Exit");
    HMENU editMenu = CreateMenu();
        AppendMenu(editMenu, MF_STRING, 21, L"Undo");
        AppendMenu(editMenu, MF_STRING, 22, L"Redo");
        AppendMenu(editMenu, MF_SEPARATOR, NULL, NULL);
        AppendMenu(editMenu, MF_STRING, 23, L"Cut");
        AppendMenu(editMenu, MF_STRING, 24, L"Copy");
        AppendMenu(editMenu, MF_STRING, 25, L"Paste");
        AppendMenu(editMenu, MF_SEPARATOR, NULL, NULL);
        AppendMenu(editMenu, MF_STRING, 26, L"Select All");
    HMENU formatMenu = CreateMenu();
        AppendMenu(formatMenu, MF_BYCOMMAND, 31, L"Font...");
    HMENU helpMenu = CreateMenu();
        AppendMenu(helpMenu, MF_STRING, 41, L"Get Help");
        AppendMenu(helpMenu, MF_SEPARATOR, NULL, NULL);
        AppendMenu(helpMenu, MF_STRING, 42, L"About WorkPlace 247...");
    // Menu Items for the MenuStrip
    AppendMenu(menuStrip, MF_POPUP, (UINT_PTR)fileMenu, L"File");
    AppendMenu(menuStrip, MF_POPUP, (UINT_PTR)editMenu, L"Edit");
    AppendMenu(menuStrip, MF_POPUP, (UINT_PTR)formatMenu, L"Format");
    AppendMenu(menuStrip, MF_POPUP, (UINT_PTR)helpMenu, L"Help");

    SetMenu(hWnd, menuStrip);
}

我正在使用 VS2019 MSVC,Win32。

我C++也很烂,想学。提前致谢。

这是你的问题:

HWND hWndEdit = CreateWindow(TEXT("EDIT"), TEXT(""), WS_CHILD | WS_VISIBLE | WS_BORDER | WB_LEFT | ES_AUTOVSCROLL | ES_MULTILINE, 0, 0, 1366, 768, hWnd, NULL, NULL, NULL);

每次您的主要 window 收到任何消息时都会创建该编辑控件,很快 运行 资源不足。

您只需创建一次(例如,响应 WM_CREATE 消息),并将 window 句柄保存在某个静态(或全局)变量中,以便您可以使用稍后。

一种方式:将其添加到您的“全球”部分

// Global variables
HMENU menuStrip;
HWND hWndEdit = 0; // <- new line

然后将创建该控件的调用移动到 WM_CREATE 处理程序中:

case WM_CREATE:
    AddMenuStrip(hWnd);
    hWndEdit = CreateWindow(TEXT("EDIT"), TEXT(""), WS_CHILD | WS_VISIBLE | WS_BORDER | ES_AUTOVSCROLL | ES_MULTILINE, 0, 0, 1366, 768, hWnd, NULL, NULL, NULL);
    break;

每次事件发生时都会调用 WndProc,例如(鼠标移动、单击、调整大小、绘制...)
所以每条消息都会创建一个 hWndEdit,这就是问题所在
你可以这样做:

  1. 你可以把它放在那里,但要做到 static
  2. WinMain 中创建 hWndEdit,给它 ID,然后在 WM_COMMAND 中调用 hWndEdit = GetDlgItem(hWnd, ID)
  3. WM_CREATE 中创建 hWndEdit 并执行与第二步相同的操作
  4. 使 hWndEdit 全局化并在 WinMainWM_CREATE 或任何阶段创建它