c++ - 将 Vcl::Controls::TCaption aka (System::UnicodeString) 转换为 const char *

标签 c++ c++builder tmemo

我目前正在使用 C++Builder 创建一个将文本复制到用户剪贴板的应用程序。我已经放置了一个 TMemo控件,我想将其包含在 const char * 中变量如下面的代码所示:

const char* output = TMemo1->Text;

当我编译程序时,它会抛出错误

no viable conversion from 'Vcl::Controls::TCaption' (aka 'System::UnicodeString') to '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();

最佳答案

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);
}

或者,您可以保存 TMemo的文本到 AnsiString并让 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);
}

但是,由于您正在处理 Unicode 文本,因此您应该使用 CF_UNICODETEXT格式而不是 CF_TEXT .这样,您就不需要转换 UnicodeString数据,您可以按原样存储(如果有人随后从剪贴板请求 CF_TEXTthe clipboard itself will convert the text for you ),例如:

#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);
}

话虽如此,你正在让自己的事情变得更难,然后你需要这样做。 VCL 有一个 TClipboard 为您处理所有这些细节的类,例如:
#include <Vcl.Clipbrd.hpp>

Clipboard()->AsText = TMemo1->Text;

关于c++ - 将 Vcl::Controls::TCaption aka (System::UnicodeString) 转换为 const char *,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62294007/

相关文章:

c++ - 简单的 "Hello World"代码没有出现在命令提示符中

c++ - 多次从 ifstream 读取

c++ - 最大似然估计器C/C++类库

delphi - MDI 应用程序在空闲时消耗 100% cpu

c++ - 线程中的 TIdFTP 未触发 Work 方法

c++ - Media Foundation 错误地将静止图像捕获流描述符标记为视频捕获

delphi - 如何在 Firemonkey (FMX) 中无缝循环声音?

delphi - 自动允许 Ctrl+A 选择 TMemo 中的所有内容?

c++ - 在 CodeGear C++ Builder 上有比 TMemo 更快的组件吗?