文本框输入操作

0

这是我做的两个简易输入框,希望实现文本基本的输入操作,现在的代码有以下问题:

  1. 第二个输入框输入不了数字
  2. 第一个输入框在输入完毕后不能取消输入或点击到第二个输入框进行输入

请问应该如何修改?

	bool isinputbox_1click = false;		// 输入框1是否被点击
	bool isinputbox_2click = false;		// 输入框2是否被点击
	string inputbox_1,inputbox_2;		// 存储输入内容的字符串
	int times_A = 0;					// 存储输入次数
	int times_B = 0;					// 存储输入次数
	while (1)
	{
		MOUSEMSG m;
		m = GetMouseMsg();
		//输入框1
		if (isin(m.x, m.y, 152, 35, 380, 69) && m.uMsg == WM_LBUTTONUP)		// 判断是否鼠标在按钮区域且被按下
		{
			isinputbox_1click = true;										// 输入框被按下为真
			if (isinputbox_2click == true)									// 判断第二个输入框是否为真
			{
				isinputbox_2click = false;									// 如果为真,使其为假 (为避免两个输入框同时被按下)
				setlinecolor(WHITE);										// 将第二个点击后的提示覆盖
				roundrect(153, 96, 379, 129, 8, 8);
			}
			//鼠标样式修改
			HCURSOR hcur = LoadCursor(NULL, IDC_IBEAM);						// 加载系统预置的鼠标样式-输入
			HWND hwnd = GetHWnd();											// 获取绘图窗口句柄
			SetClassLong(hwnd, GCL_HCURSOR, (long)hcur);					// 设置窗口类的鼠标样式
			setlinecolor(RGB(247, 241, 142));								
			roundrect(153, 34, 379, 68, 8, 8);
			char c;															// 保存键盘消息
			FlushConsoleInputBuffer(GetStdHandle(STD_INPUT_HANDLE));		// 清楚输入消息
			FlushMouseMsgBuffer();											// 清楚鼠标消息
			do
			{
				if(_kbhit())												// 监听键盘信息;当有键盘按下的时候执行
				{
					c = _getch();											// 获取键盘信息
					inputbox_1 += c;										// 将输入的内容赋值给inputbox_1
					int width = times_A * textwidth(c);						// 设置宽度
					output(c, 152 + width, 34, BLACK, 32);					// 输出			
					cout << inputbox_1 << endl;
					times_A++;
				}
			//鼠标没有按到第二个输入框处 或 如果鼠标没有被按下 继续执行
			} while (isin(m.x, m.y, 152, 97, 380, 130) == false || m.uMsg != WM_LBUTTONUP);
			//退出循环,点击消息为假
			isinputbox_1click = false;
		}
		//输入框2
		else if (isin(m.x, m.y, 152, 97, 380, 130) && m.uMsg == WM_LBUTTONUP)
		{
			isinputbox_2click = true;
			if (isinputbox_1click == true)
			{
				isinputbox_1click = false;
				setlinecolor(WHITE);
				roundrect(153, 34, 379, 68, 8, 8);
			}
			//鼠标样式修改
			HCURSOR hcur = LoadCursor(NULL, IDC_IBEAM);		// 加载系统预置的鼠标样式
			HWND hwnd = GetHWnd();							// 获取绘图窗口句柄
			SetClassLong(hwnd, GCL_HCURSOR, (long)hcur);	// 设置窗口类的鼠标样式
			setlinecolor(RGB(247, 241, 142));
			roundrect(153, 96, 379, 129, 8, 8);
			char c;															// 保存键盘消息
			FlushConsoleInputBuffer(GetStdHandle(STD_INPUT_HANDLE));		// 清楚输入消息
			FlushMouseMsgBuffer();											// 清楚鼠标消息
			do
			{
				if (_kbhit())												// 监听键盘信息;当有键盘按下的时候执行
				{
					c = _getch();											// 获取键盘信息
					inputbox_2 += c;										// 将输入的内容赋值给inputbox_2
					int width = times_B * textwidth(c);						// 设置宽度
					output(c, 152 + width, 97, BLACK, 32);					// 输出			
					cout << inputbox_2 << endl;
					times_B++;
				}
				//鼠标没有按到第一个输入框处 或 如果鼠标没有被按下 继续执行
			} while (isin(m.x, m.y, 152, 35, 380, 130) == false || m.uMsg != WM_LBUTTONUP);
			//退出循环,点击消息为假
			isinputbox_1click = false;
		}
		//在文本框之外
		else// if ((isout(m.x, m.y, 152, 35, 380, 69) || isout(m.x, m.y, 152, 97, 380, 130)) && m.uMsg == WM_LBUTTONUP)
		{
			isinputbox_1click = false;
			isinputbox_2click = false;
			//鼠标样式修改
			HCURSOR hcur = LoadCursor(NULL, IDC_ARROW);		// 加载系统预置的鼠标样式
			HWND hwnd = GetHWnd();							// 获取绘图窗口句柄
			SetClassLong(hwnd, GCL_HCURSOR, (long)hcur);	// 设置窗口类的鼠标样式
			setlinecolor(WHITE);
			roundrect(153, 34, 379, 68, 8, 8);
			roundrect(153, 96, 379, 129, 8, 8);
		}
	}

 在慢羊羊的建议下进行改动,但仍有问题:

  1. 输出不了文字
  2. 点击后只要移动鼠标,聚焦文本框颜色就消失

以下是我写的代码:(使用多字节字符集编译)

#include <iostream>
#include <easyx.h>
#include <graphics.h>
#include <conio.h>
#include <fstream>
#include <ctime>
#include <Windows.h>
#include <cstdio>
using namespace std;
#define IDC_HAND            MAKEINTRESOURCE(32649)
bool isin(int itemA, int itemB, int left, int top, int right, int bottom)
{
	if (itemA >= left && itemB >= top && itemA <= right && itemB <= bottom)
	{
		return true;
	}
	else
	{
		return false;
	}
}
bool isout(int itemA, int itemB, int left, int top, int right, int bottom)
{
	if (itemA <= left || itemB <= top || itemA >= right || itemB >= bottom)
	{
		return true;
	}
	else
	{
		return false;
	}
}
void output(char str, int x, int y, COLORREF color, int height, int weight = 0, int quailty = ANTIALIASED_QUALITY)
{
	settextcolor(color);
	LOGFONT a;
	gettextstyle(&a);						// 获取当前字体设置
	a.lfHeight = height;					// 设置字体高度为 height
	a.lfQuality = quailty;					// 设置输出效果为 quality
	a.lfWeight = weight;					// 设置字体粗细为 weight
	_tcscpy_s(a.lfFaceName, _T("微软雅黑"));	// 设置字体为 “微软雅黑”
	settextstyle(&a);						// 设置字体样式
	outtextxy(x, y, str);
}
void output(string text, int x, int y, COLORREF color, int height, int weight = 0, int quailty = ANTIALIASED_QUALITY)
{
	char str[10000] = { 0 };
	for (int i = 0; i <= text.length() - 1; i++)
	{
		str[i] = text[i];
	}
	settextcolor(color);
	LOGFONT a;
	gettextstyle(&a);						// 获取当前字体设置
	a.lfHeight = height;					// 设置字体高度为 height
	a.lfQuality = quailty;					// 设置输出效果为 quality
	a.lfWeight = weight;					// 设置字体粗细为 weight
	_tcscpy_s(a.lfFaceName, _T("微软雅黑"));	// 设置字体为 “微软雅黑”
	settextstyle(&a);						// 设置字体样式
	outtextxy(x, y, str);
}
int main()
{
	//初始化画布
	initgraph(800, 800, SHOWCONSOLE); // 创建绘图窗口
	// 获取窗口句柄
	HWND hwnd = GetHWnd();
	// 设置窗口标题文字
	SetWindowText(hwnd, "MiniProgram");
	setbkcolor(WHITE);
	setlinecolor(BLACK);
	settextcolor(BLACK);
	cleardevice();
	setbkmode(TRANSPARENT);
	//字
	output("出题范围:", 25, 34, BLACK, 35);
	//输入框
	setlinecolor(RGB(195, 195, 195));
	roundrect(152, 35, 380, 69, 8, 8);
	//字
	output("题量:", 80, 94, BLACK, 35);
	//输入框
	roundrect(152, 97, 380, 130, 8, 8);
	//生成
	setfillcolor(RGB(34, 177, 76));
	fillrectangle(518, 52, 656, 105);
	output("生成", 558, 60, WHITE, 35);
	//输入
	bool isinputbox_1click = false, isinputbox_2click = false;
	string text1, text2;
	MOUSEMSG m;
	char c;
	while (true)
	{
		//如果有鼠标消息,就获取鼠标
		if (MouseHit)
		{
			m = GetMouseMsg();
		}
		//如果有按键消息,就获取按键
		if (_kbhit())
		{
			c = _getch();
		}
		else
		{
			c = '\0';
		}
		//处理鼠标事件
		if (isin(m.x, m.y, 152, 35, 380, 69) && m.uMsg == WM_LBUTTONUP)		// 判断是否鼠标在按钮区域且被按下
		{
			isinputbox_1click = true;										// 输入框被按下为真
			if (isinputbox_2click == true)									// 判断第二个输入框是否为真
			{
				isinputbox_2click = false;									// 如果为真,使其为假 (为避免两个输入框同时被按下)
				setlinecolor(WHITE);										// 将第二个点击后的提示覆盖
				roundrect(153, 96, 379, 129, 8, 8);
			}
			//鼠标样式修改
			HCURSOR hcur = LoadCursor(NULL, IDC_IBEAM);						// 加载系统预置的鼠标样式-输入
			HWND hwnd = GetHWnd();											// 获取绘图窗口句柄
			SetClassLong(hwnd, GCL_HCURSOR, (long)hcur);					// 设置窗口类的鼠标样式
			setlinecolor(RGB(247, 241, 142));
			roundrect(153, 34, 379, 68, 8, 8);
		}
		else if (isin(m.x, m.y, 152, 97, 380, 130) && m.uMsg == WM_LBUTTONUP)
		{
			isinputbox_2click = true;
			if (isinputbox_1click == true)
			{
				isinputbox_1click = false;
				setlinecolor(WHITE);
				roundrect(153, 34, 379, 68, 8, 8);
			}
			//鼠标样式修改
			HCURSOR hcur = LoadCursor(NULL, IDC_IBEAM);		// 加载系统预置的鼠标样式
			HWND hwnd = GetHWnd();							// 获取绘图窗口句柄
			SetClassLong(hwnd, GCL_HCURSOR, (long)hcur);	// 设置窗口类的鼠标样式
			setlinecolor(RGB(247, 241, 142));
			roundrect(153, 96, 379, 129, 8, 8);
		}
		else
		{
			isinputbox_1click = false;
			isinputbox_2click = false;
			//鼠标样式修改
			HCURSOR hcur = LoadCursor(NULL, IDC_ARROW);		// 加载系统预置的鼠标样式
			HWND hwnd = GetHWnd();							// 获取绘图窗口句柄
			SetClassLong(hwnd, GCL_HCURSOR, (long)hcur);	// 设置窗口类的鼠标样式
			setlinecolor(WHITE);
			roundrect(153, 34, 379, 68, 8, 8);
			roundrect(153, 96, 379, 129, 8, 8);
		}
		//处理按键事件(哪个文本框处于激活状态,按键消息就交给哪个文本框处理)
		if (isinputbox_1click && isinputbox_2click == false)
		{
			text1 += c;
		}
		else if (isinputbox_2click && isinputbox_1click == false)
		{
			text2 += c;
		}
		else
		{
			FlushConsoleInputBuffer(GetStdHandle(STD_INPUT_HANDLE));		// 清楚输入消息
		}
		//绘制文本框(闪烁的光标、内容等)
		if (isinputbox_1click && isinputbox_2click == false)
		{
			output(text1, 152, 34, BLACK, 32);

		}
		else if (isinputbox_2click && isinputbox_1click == false)
		{
			output(text2, 152, 97, BLACK, 32);
		}
		else
		{
			FlushConsoleInputBuffer(GetStdHandle(STD_INPUT_HANDLE));		// 清楚输入消息
		}
		Sleep(1);	// 释放 CPU 占用
	}
}

请问现在应该如何修改?

ava
小俊逸

2020-3-26

0

如果你要用 EasyX 做文本框,可以参考这里:https://qa.codebus.cn/question/127

=====(以下讨论你的代码)=====

你整个程序的逻辑有问题。

你的 while 主循环里面,两个文本框的两大段代码都是重复的。并且,你并不能同时处理鼠标与键盘消息。

主体结构应该是这样的:

while
{
	如果有鼠标消息,就获取鼠标
	如果有按键消息,就获取按键

	处理鼠标事件(例如切换不同的文本框控件)
	处理按键事件(哪个文本框处于激活状态,按键消息就交给哪个文本框处理)

	绘制文本框(闪烁的光标、内容等)

	Sleep(1)	// 释放 CPU 占用
}

补充:

针对你的代码,我做了简单调整。不谈逻辑,只是在你的代码之上做了最小的调整。总的来说,能跑了,但是结构很不合理。

调整后的代码如下:

#include <easyx.h>
#include <conio.h>
#include <ctime>
#include <iostream>
using namespace std;
#define IDC_HAND            MAKEINTRESOURCE(32649)

bool isin(int itemA, int itemB, int left, int top, int right, int bottom)
{
	if (itemA >= left && itemB >= top && itemA <= right && itemB <= bottom)
	{
		return true;
	}
	else
	{
		return false;
	}
}

bool isout(int itemA, int itemB, int left, int top, int right, int bottom)
{
	if (itemA <= left || itemB <= top || itemA >= right || itemB >= bottom)
	{
		return true;
	}
	else
	{
		return false;
	}
}

void output(char str, int x, int y, COLORREF color, int height, int weight = 0, int quailty = ANTIALIASED_QUALITY)
{
	settextcolor(color);
	LOGFONT a;
	gettextstyle(&a);						// 获取当前字体设置
	a.lfHeight = height;					// 设置字体高度为 height
	a.lfQuality = quailty;					// 设置输出效果为 quality
	a.lfWeight = weight;					// 设置字体粗细为 weight
	_tcscpy_s(a.lfFaceName, _T("微软雅黑"));	// 设置字体为 “微软雅黑”
	settextstyle(&a);						// 设置字体样式
	outtextxy(x, y, str);
}

void output(string text, int x, int y, COLORREF color, int height, int weight = 0, int quailty = ANTIALIASED_QUALITY)
{
	char str[10000] = { 0 };
	for (int i = 0; i <= text.length() - 1; i++)
	{
		str[i] = text[i];
	}
	settextcolor(color);
	LOGFONT a;
	gettextstyle(&a);						// 获取当前字体设置
	a.lfHeight = height;					// 设置字体高度为 height
	a.lfQuality = quailty;					// 设置输出效果为 quality
	a.lfWeight = weight;					// 设置字体粗细为 weight
	_tcscpy_s(a.lfFaceName, _T("微软雅黑"));	// 设置字体为 “微软雅黑”
	settextstyle(&a);						// 设置字体样式
	outtextxy(x, y, str);
}

int main()
{
	//初始化画布
	initgraph(800, 800, EW_SHOWCONSOLE); // 创建绘图窗口
	// 获取窗口句柄
	HWND hwnd = GetHWnd();
	// 设置窗口标题文字
	SetWindowText(hwnd, "MiniProgram");
	setbkcolor(WHITE);
	setlinecolor(BLACK);
	settextcolor(BLACK);
	cleardevice();
	setbkmode(TRANSPARENT);
	//字
	output("出题范围:", 25, 34, BLACK, 35);
	//输入框
	setlinecolor(RGB(195, 195, 195));
	roundrect(152, 35, 380, 69, 8, 8);
	//字
	output("题量:", 80, 94, BLACK, 35);
	//输入框
	roundrect(152, 97, 380, 130, 8, 8);
	//生成
	setfillcolor(RGB(34, 177, 76));
	fillrectangle(518, 52, 656, 105);
	output("生成", 558, 60, WHITE, 35);
	//输入
	bool isinputbox_1click = false, isinputbox_2click = false;
	string text1, text2;
	MOUSEMSG m;
	char c;
	while (true)
	{
		//如果有鼠标消息,就获取鼠标
		if (MouseHit())
		{
			m = GetMouseMsg();
			// 处理鼠标点击事件
			if (m.uMsg == WM_LBUTTONUP)
			{
				if (isin(m.x, m.y, 152, 35, 380, 69))		// 判断是否鼠标在按钮区域且被按下
				{
					isinputbox_1click = true;										// 输入框被按下为真
					if (isinputbox_2click == true)									// 判断第二个输入框是否为真
					{
						isinputbox_2click = false;									// 如果为真,使其为假 (为避免两个输入框同时被按下)
						setlinecolor(WHITE);										// 将第二个点击后的提示覆盖
						roundrect(153, 96, 379, 129, 8, 8);
					}
					setlinecolor(RGB(247, 241, 142));
					roundrect(153, 34, 379, 68, 8, 8);
				}
				else if (isin(m.x, m.y, 152, 97, 380, 130))
				{
					isinputbox_2click = true;
					if (isinputbox_1click == true)
					{
						isinputbox_1click = false;
						setlinecolor(WHITE);
						roundrect(153, 34, 379, 68, 8, 8);
					}
					setlinecolor(RGB(247, 241, 142));
					roundrect(153, 96, 379, 129, 8, 8);
				}
				else
				{
					isinputbox_1click = false;
					isinputbox_2click = false;
					setlinecolor(WHITE);
					roundrect(153, 34, 379, 68, 8, 8);
					roundrect(153, 96, 379, 129, 8, 8);
				}
			}
			else if (m.uMsg == WM_MOUSEMOVE) // 鼠标移动事件
			{
				HCURSOR hcur;
				if (isin(m.x, m.y, 152, 35, 380, 69) || isin(m.x, m.y, 152, 97, 380, 130))
					//鼠标样式修改
					hcur = LoadCursor(NULL, IDC_IBEAM);						// 加载系统预置的鼠标样式-输入
				else
					//鼠标样式修改
					hcur = LoadCursor(NULL, IDC_ARROW);		// 加载系统预置的鼠标样式

				HWND hwnd = GetHWnd();							// 获取绘图窗口句柄
				SetClassLong(hwnd, GCL_HCURSOR, (long)hcur);	// 设置窗口类的鼠标样式
			}
		}

		//如果有按键消息,就获取按键
		if (_kbhit())
		{
			c = _getch();
			//处理按键事件(哪个文本框处于激活状态,按键消息就交给哪个文本框处理)
			if (isinputbox_1click && isinputbox_2click == false)
			{
				text1 += c;
			}
			else if (isinputbox_2click && isinputbox_1click == false)
			{
				text2 += c;
			}

			//绘制文本框(闪烁的光标、内容等)
			if (isinputbox_1click && isinputbox_2click == false)
			{
				output(text1, 152, 34, BLACK, 32);

			}
			else if (isinputbox_2click && isinputbox_1click == false)
			{
				output(text2, 152, 97, BLACK, 32);
			}
		}
		else
		{
			c = '\0';
		}

		Sleep(10);	// 释放 CPU 占用
	}
}

PS:真不建议用 MBCS。参考:https://codebus.cn/yangw/about-unicode

ava
慢羊羊

2020-3-26

@小俊逸 已经帮你做了最小的调整,没有大改结构。总得来说,能跑,但是结构很不合理。 -  慢羊羊  2020-4-1
@慢羊羊 好的,谢谢! -  小俊逸  2020-4-2
-1

建议直接用createrwindowex创建一个窗口,再放上编辑框edit控件,数量可放多个,同一个输入窗可输多组参数,可输入中文、符号、数字,也可仅用数字,很为方便,比自建方便多了。

ava
人民万岁

2021-4-30

技术讨论社区
相关提问