文本框粘贴时兼容Unix、Mac换行符的方法源码

本篇文章属于《518抽奖软件开发日志》系列文章的一部分。

我在开发《518抽奖软件》(www.518cj.net)的时候,要在文本框粘贴从别处复制来的名单。发现一个问题,就是一些Unix传过来的多行文本,粘贴后都变成了一行。原来,它的换行符跟Winodws的不一致导致的。解决方法就是,窗口子类化,在新的窗口过程中,专门处理这个粘贴消息,兼容Windows、Mac、Unix三种不同的文本换行符。具体代码如下:

复制代码
void Tapp::subclass_init()
{
	oldProc = (WNDPROC)SetClassLong(GetDlgItem(m_hLoading, IDC_loading_subclass), GCL_WNDPROC, (LONG)Proc_editBox);
}

void Tapp::subclass_remove()
{
	if (oldProc)
	{
		SetClassLong(GetDlgItem(m_hLoading, IDC_loading_subclass), GCL_WNDPROC, (LONG)oldProc);
		oldProc = NULL;
	}
}

static LRESULT CALLBACK Proc_editBox(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
// 在粘贴时,处理换行符不一致
	if (uMsg == WM_PASTE)
	{
		if (!IsClipboardFormatAvailable(CF_UNICODETEXT))
			return 0;
		if (!OpenClipboard(hwnd))
			return 0;

		HGLOBAL h = GetClipboardData(CF_UNICODETEXT);
		if (!h) { CloseClipboard(); return 0; }
		WCHAR* p = (WCHAR*)GlobalLock(h);
		if (!p) { GlobalUnlock(h); CloseClipboard(); return 0; }

		BOOL bSingle = TRUE;
		LONG style = GetWindowLong(hwnd, GWL_STYLE);
		if (style & ES_MULTILINE) bSingle = FALSE;

		//------------------------------------------------- rslt
		wstring rslt;
		for (int i = 0; 1; i++)
		{
			if (p[i] == 0) break;
			else if (p[i] == L'\r')
			{
				if (bSingle) break;
				rslt += L"\r\n";
				if (p[i + 1] == L'\n') i++;
			}
			else if (p[i] == L'\n')
			{
				if (bSingle) break;
				rslt += L"\r\n";
			}
			else rslt += p[i];
		}
		//------------------------------------------------- ↑

		SendMessage(hwnd, EM_REPLACESEL, TRUE, (LPARAM)rslt.c_str());
		GlobalUnlock(h);
		CloseClipboard();
		return 0;
	}
// 支持回车、Tab字符输入
	else if (uMsg == WM_GETDLGCODE && hwnd == hTextBox)
		return DLGC_WANTALLKEYS | DLGC_WANTARROWS | DLGC_WANTCHARS | DLGC_WANTMESSAGE | DLGC_WANTTAB;
// 继续执行旧的窗口过程
	return CallWindowProc(oldProc, hwnd, uMsg, wParam, lParam);
}
相关推荐
智者知已应修善业2 小时前
【51单片机不用数组动态数码管显示字符和LED流水灯】2023-10-3
c++·经验分享·笔记·算法·51单片机
AI进化营-智能译站3 小时前
ROS2 C++开发系列16-智能指针管理传感器句柄|告别ROS2节点内存泄漏与野指针
java·c++·算法·ai
报错小能手3 小时前
好好讲讲移动构造 移动赋值
c++
syker3 小时前
AIFerric深度学习框架:自研全栈AI基础设施的技术全景
开发语言·c++
xvhao20134 小时前
单源、多源最短路
数据结构·c++·算法·深度优先·动态规划·图论·图搜索算法
笑鸿的学习笔记5 小时前
qt-C++语法笔记之Qt Graphics View 框架中的类型辨析完全指南
c++·笔记·qt
山居秋暝LS5 小时前
安装C++版opencv和opencv_contrib
开发语言·c++·opencv
谭欣辰6 小时前
LCS(最长公共子序列)详解
开发语言·c++·算法
Cando学算法6 小时前
鸽笼原理(抽屉原理)
c++·算法·学习方法
郝学胜-神的一滴7 小时前
跨平台动态库与头文件:从原理到命名的深度解析
linux·c++·程序人生·unix·cmake