Win32 API - 如何使可调整大小的文本框类似于 MS-Paint 中的文本
Win32 API - How to make resizable textbox similar to text in MS-Paint
我尝试使用 Visual Studio 为我自己的简单 Paint win32 项目复制 MS-Paint 中的文本按钮。 用户点击按钮,select一个矩形区域作为文本框,然后在中输入文本:
我做了一些研究,但不知道如何将其应用到我的项目中。我试图首先在屏幕上的特定位置创建一个文本框(单击按钮后)并允许用户输入文本(稍后我将尝试弄清楚如何允许用户进入 select 文本区域)。这是代码片段:
HWND textbox; //global variable
//LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
case WM_COMMAND:
{
int wmId = LOWORD(wParam);
// Parse the menu selections:
switch (wmId)
{
case IDM_ABOUT:
DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
break;
case IDM_EXIT:
DestroyWindow(hWnd);
break;
case IDC_TEXTBOX:
CreateWindowEx(
NULL, L"textbox", L"",
WS_CHILD | WS_VISIBLE | WS_BORDER,
100, 100, 100, 100, hWnd, (HMENU)0, NULL, NULL
);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
}
break;
case WM_CREATE:
CreateWindowEx(NULL, L"BUTTON", L"CreateTextBox",
WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON, 10, 10, 150, 40, hWnd,
(HMENU)IDC_TEXTBOX, NULL, NULL);
break;
结果如下:
很简单,但是我写的代码不起作用。单击按钮后不会出现文本框。因此,取得了零进展,我不知道现在该做什么。所以问题是:为什么我的解决方案失败了?以及 如何在我的项目中正确实现 MS-Paint 中的文本按钮?
感谢大家的评论,我找到了解决方案,它们是:
为什么我的问题的解决方案失败了:“文本框”不是正确的windowclass。在这种情况下,我将它们更改为编辑(更多关于 EDIT control)并且我需要的 window 出现了。
如何在我的项目中实现 MS-Paint 中的文本按钮:当用户按住鼠标左键时按钮并拖动鼠标到 select 文本区域,我们绘制一个矩形。当鼠标左键弹起时(用户已完成 selecting 文本区域),我们在矩形区域中创建一个 window。这是相关代码:
int fromX, fromY;
int toX, toY;
bool isPreview;
bool isDrawingTextbox = false;
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
HANDLE_MSG(hWnd, WM_CREATE, OnCreate);
HANDLE_MSG(hWnd, WM_COMMAND, OnCommand);
HANDLE_MSG(hWnd, WM_DESTROY, OnDestroy);
HANDLE_MSG(hWnd, WM_PAINT, OnPaint);
HANDLE_MSG(hWnd, WM_LBUTTONDOWN, OnLButtonDown);
HANDLE_MSG(hWnd, WM_LBUTTONUP, OnLButtonUp);
HANDLE_MSG(hWnd, WM_MOUSEMOVE, OnMouseMove);
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
BOOL OnCreate(HWND hwnd, LPCREATESTRUCT lpCreateStruct)
{
CreateWindowEx(NULL, L"BUTTON", L"CreateTextBox",
WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON, 10, 10, 150, 40, hwnd,
(HMENU)IDC_TEXTBOX, NULL, NULL);
return TRUE;
}
void OnCommand(HWND hwnd, int id, HWND hwndCtl, UINT codeNotify)
{
switch (id)
{
case IDC_TEXTBOX:
isDrawingTextbox = true;
break;
default:
break;
}
}
void OnDestroy(HWND hwnd)
{
PostQuitMessage(0);
}
void OnPaint(HWND hwnd)
{
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hwnd, &ps);
if (isDrawingTextbox) {
HPEN hPen = CreatePen(PS_DASHDOT, 3, RGB(0, 0, 0));
Rectangle(hdc, fromX, fromY, toX, toY);
}
EndPaint(hwnd, &ps);
}
void OnLButtonDown(HWND hwnd, BOOL fDoubleClick, int x, int y, UINT keyFlags)
{
isPreview = true;
fromX = x;
fromY = y;
HDC hdc = GetDC(hwnd);
MoveToEx(hdc, x, y, NULL);
}
void OnLButtonUp(HWND hwnd, int x, int y, UINT keyFlags)
{
isPreview = false;
if (isDrawingTextbox) {
if (toY < fromY) {
int temp = fromY;
fromY = toY;
toY = temp;
}
if (toX < fromX) {
int temp = fromX;
fromX = toX;
toX = temp;
}
int width = abs(fromX - toX);
int height = abs(fromY - toY);
CreateWindowEx(
NULL, L"EDIT", L"",
WS_CHILD | WS_BORDER | WS_VISIBLE | ES_MULTILINE,
fromX, fromY, width, height, hwnd, (HMENU)0, NULL, NULL
);
}
}
void OnMouseMove(HWND hwnd, int x, int y, UINT keyFlags)
{
if (isPreview) {
toX = x;
toY = y;
InvalidateRect(hwnd, NULL, TRUE);
}
}
这是我自己解决问题的方法。请随时回答您更好的解决方案。
我尝试使用 Visual Studio 为我自己的简单 Paint win32 项目复制 MS-Paint 中的文本按钮。 用户点击按钮,select一个矩形区域作为文本框,然后在中输入文本:
我做了一些研究,但不知道如何将其应用到我的项目中。我试图首先在屏幕上的特定位置创建一个文本框(单击按钮后)并允许用户输入文本(稍后我将尝试弄清楚如何允许用户进入 select 文本区域)。这是代码片段:
HWND textbox; //global variable
//LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
case WM_COMMAND:
{
int wmId = LOWORD(wParam);
// Parse the menu selections:
switch (wmId)
{
case IDM_ABOUT:
DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
break;
case IDM_EXIT:
DestroyWindow(hWnd);
break;
case IDC_TEXTBOX:
CreateWindowEx(
NULL, L"textbox", L"",
WS_CHILD | WS_VISIBLE | WS_BORDER,
100, 100, 100, 100, hWnd, (HMENU)0, NULL, NULL
);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
}
break;
case WM_CREATE:
CreateWindowEx(NULL, L"BUTTON", L"CreateTextBox",
WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON, 10, 10, 150, 40, hWnd,
(HMENU)IDC_TEXTBOX, NULL, NULL);
break;
结果如下:
很简单,但是我写的代码不起作用。单击按钮后不会出现文本框。因此,取得了零进展,我不知道现在该做什么。所以问题是:为什么我的解决方案失败了?以及 如何在我的项目中正确实现 MS-Paint 中的文本按钮?
感谢大家的评论,我找到了解决方案,它们是:
为什么我的问题的解决方案失败了:“文本框”不是正确的windowclass。在这种情况下,我将它们更改为编辑(更多关于 EDIT control)并且我需要的 window 出现了。
如何在我的项目中实现 MS-Paint 中的文本按钮:当用户按住鼠标左键时按钮并拖动鼠标到 select 文本区域,我们绘制一个矩形。当鼠标左键弹起时(用户已完成 selecting 文本区域),我们在矩形区域中创建一个 window。这是相关代码:
int fromX, fromY;
int toX, toY;
bool isPreview;
bool isDrawingTextbox = false;
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
HANDLE_MSG(hWnd, WM_CREATE, OnCreate);
HANDLE_MSG(hWnd, WM_COMMAND, OnCommand);
HANDLE_MSG(hWnd, WM_DESTROY, OnDestroy);
HANDLE_MSG(hWnd, WM_PAINT, OnPaint);
HANDLE_MSG(hWnd, WM_LBUTTONDOWN, OnLButtonDown);
HANDLE_MSG(hWnd, WM_LBUTTONUP, OnLButtonUp);
HANDLE_MSG(hWnd, WM_MOUSEMOVE, OnMouseMove);
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
BOOL OnCreate(HWND hwnd, LPCREATESTRUCT lpCreateStruct)
{
CreateWindowEx(NULL, L"BUTTON", L"CreateTextBox",
WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON, 10, 10, 150, 40, hwnd,
(HMENU)IDC_TEXTBOX, NULL, NULL);
return TRUE;
}
void OnCommand(HWND hwnd, int id, HWND hwndCtl, UINT codeNotify)
{
switch (id)
{
case IDC_TEXTBOX:
isDrawingTextbox = true;
break;
default:
break;
}
}
void OnDestroy(HWND hwnd)
{
PostQuitMessage(0);
}
void OnPaint(HWND hwnd)
{
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hwnd, &ps);
if (isDrawingTextbox) {
HPEN hPen = CreatePen(PS_DASHDOT, 3, RGB(0, 0, 0));
Rectangle(hdc, fromX, fromY, toX, toY);
}
EndPaint(hwnd, &ps);
}
void OnLButtonDown(HWND hwnd, BOOL fDoubleClick, int x, int y, UINT keyFlags)
{
isPreview = true;
fromX = x;
fromY = y;
HDC hdc = GetDC(hwnd);
MoveToEx(hdc, x, y, NULL);
}
void OnLButtonUp(HWND hwnd, int x, int y, UINT keyFlags)
{
isPreview = false;
if (isDrawingTextbox) {
if (toY < fromY) {
int temp = fromY;
fromY = toY;
toY = temp;
}
if (toX < fromX) {
int temp = fromX;
fromX = toX;
toX = temp;
}
int width = abs(fromX - toX);
int height = abs(fromY - toY);
CreateWindowEx(
NULL, L"EDIT", L"",
WS_CHILD | WS_BORDER | WS_VISIBLE | ES_MULTILINE,
fromX, fromY, width, height, hwnd, (HMENU)0, NULL, NULL
);
}
}
void OnMouseMove(HWND hwnd, int x, int y, UINT keyFlags)
{
if (isPreview) {
toX = x;
toY = y;
InvalidateRect(hwnd, NULL, TRUE);
}
}
这是我自己解决问题的方法。请随时回答您更好的解决方案。