Jor*_*ton 3 c++ c++builder tmemo
我目前正在使用 C++Builder 创建一个将文本复制到用户剪贴板的应用程序。我已经放置了一个TMemo控件,我想将其包含在一个const char *变量中,如下面的代码所示:
const char* output = TMemo1->Text;
Run Code Online (Sandbox Code Playgroud)
当我编译程序时它抛出错误
没有从“Vcl::Controls::TCaption”(又名“System::UnicodeString”)到“const char *”的可行转换
以下是将文本复制到剪贴板的代码:
const char* output = TMemo1->Text; // Error here
const size_t len = strlen(output) + 1;
HGLOBAL hMem = GlobalAlloc(GMEM_MOVEABLE, len);
memcpy(GlobalLock(hMem), output, len);
GlobalUnlock(hMem);
OpenClipboard(0);
EmptyClipboard();
SetClipboardData(CF_TEXT, hMem);
CloseClipboard();
Run Code Online (Sandbox Code Playgroud)
该Text属性返回一个UnicodeString对象,而不是const char*指针。并且没有从UnicodeString到 的隐式转换const char*(您也不想要一个)。因此,您必须手动转换数据,例如使用WideCharToMultiByte()(或等效方法),例如:
UnicodeString text = TMemo1->Text;
const size_t len = WideCharToMultiByte(CP_ACP, 0, text.c_str(), -1, NULL, 0, NULL, NULL);
HGLOBAL hMem = GlobalAlloc(GMEM_MOVEABLE, len);
if (hMem)
{
char *output = (char*) GlobalLock(hMem);
WideCharToMultiByte(CP_ACP, 0, text.c_str(), -1, output, len, NULL, NULL);
GlobalUnlock(hMem);
if (OpenClipboard(0))
{
EmptyClipboard();
if (SetClipboardData(CF_TEXT, hMem))
hMem = NULL;
CloseClipboard();
}
if (hMem)
GlobalFree(hMem);
}
Run Code Online (Sandbox Code Playgroud)
或者,您可以将TMemo的文本保存到 anAnsiString并让 RTL 为您处理转换,例如:
AnsiString output = TMemo1->Text; // <-- automatic conversion from UTF-16 to ANSI
const size_t len = (output.Length() + 1) * sizeof(System::AnsiChar);
HGLOBAL hMem = GlobalAlloc(GMEM_MOVEABLE, len);
if (hMem)
{
memcpy(GlobalLock(hMem), output.c_str(), len);
GlobalUnlock(hMem);
if (OpenClipboard(0))
{
EmptyClipboard();
if (SetClipboardData(CF_TEXT, hMem))
hMem = NULL;
CloseClipboard();
}
if (hMem)
GlobalFree(hMem);
}
Run Code Online (Sandbox Code Playgroud)
但是,由于您正在处理 Unicode 文本,因此应该使用 格式CF_UNICODETEXT而不是CF_TEXT. 这样,您根本不需要转换UnicodeString数据,您可以按原样存储它(如果CF_TEXT之后有人从剪贴板请求,剪贴板本身将为您转换文本),例如:
#include <System.SysUtils.hpp> // for ByteLength()
UnicodeString output = TMemo1->Text;
const size_t len = ByteLength(output) + sizeof(System::WideChar);
HGLOBAL hMem = GlobalAlloc(GMEM_MOVEABLE, len);
if (hMem)
{
memcpy(GlobalLock(hMem), output.c_str(), len);
GlobalUnlock(hMem);
if (OpenClipboard(0))
{
EmptyClipboard();
if (SetClipboardData(CF_UNICODETEXT, hMem))
hMem = NULL;
CloseClipboard();
}
if (hMem)
GlobalFree(hMem);
}
Run Code Online (Sandbox Code Playgroud)
话虽如此,你正在让自己的事情变得比你需要的更困难。VCL 有一个TClipboard类可以为您处理所有这些细节,例如:
#include <Vcl.Clipbrd.hpp>
Clipboard()->AsText = TMemo1->Text;
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
624 次 |
| 最近记录: |