将 Vcl::Controls::TCaption 又名 (System::UnicodeString) 转换为 const char *

2024-01-18

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

const char* output = TMemo1->Text;

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

没有从“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();

The Text属性返回一个UnicodeString对象,而不是const char*指针。并且没有隐式转换UnicodeString to const char*(你也不想要一个)。因此,您必须手动转换数据,例如使用WideCharToMultiByte() https://learn.microsoft.com/en-us/windows/win32/api/stringapiset/nf-stringapiset-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_TEXT之后从剪贴板中,剪贴板本身会为您转换文本 https://learn.microsoft.com/en-us/windows/win32/dataxchg/clipboard-formats#synthesized-clipboard-formats), eg:

#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 http://docwiki.embarcadero.com/Libraries/en/Vcl.Clipbrd.TClipboard为您处理所有这些细节的类,例如:

#include <Vcl.Clipbrd.hpp>

Clipboard()->AsText = TMemo1->Text;
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

将 Vcl::Controls::TCaption 又名 (System::UnicodeString) 转换为 const char * 的相关文章

随机推荐