如何清除 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,这就是问题所在
你可以这样做:
- 你可以把它放在那里,但要做到
static
- 在
WinMain
中创建 hWndEdit
,给它 ID,然后在 WM_COMMAND
中调用 hWndEdit = GetDlgItem(hWnd, ID)
- 在
WM_CREATE
中创建 hWndEdit
并执行与第二步相同的操作
- 使
hWndEdit
全局化并在 WinMain
、WM_CREATE
或任何阶段创建它
我正在用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,这就是问题所在
你可以这样做:
- 你可以把它放在那里,但要做到
static
- 在
WinMain
中创建hWndEdit
,给它 ID,然后在WM_COMMAND
中调用hWndEdit = GetDlgItem(hWnd, ID)
- 在
WM_CREATE
中创建hWndEdit
并执行与第二步相同的操作 - 使
hWndEdit
全局化并在WinMain
、WM_CREATE
或任何阶段创建它