【问题标题】:What do _T and L mean in C++ and how can I pass them?_T 和 L 在 C++ 中是什么意思,我该如何传递它们?
【发布时间】:2015-03-08 04:28:56
【问题描述】:

我正在尝试用 C++ 构建键盘记录器。 我的键盘记录器的一部分是捕获屏幕。
经过大量搜索后,我决定尝试构建一个来立即了解它是如何工作的。

这是我的屏幕截图代码:

    HDC hdc = GetDC(NULL); // get the desktop device context
    HDC hDest = CreateCompatibleDC(hdc); // create a device context to use yourself

    // get the height and width of the screen
    int height = GetSystemMetrics(SM_CYVIRTUALSCREEN);
    int width = GetSystemMetrics(SM_CXVIRTUALSCREEN);

    // create a bitmap
    HBITMAP hbDesktop = CreateCompatibleBitmap(hdc, width, height);

    // use the previously created device context with the bitmap
    SelectObject(hDest, hbDesktop);

    // copy from the desktop device context to the bitmap device context
    // call this once per 'frame'
    BitBlt(hDest, 0, 0, width, height, hdc, 0, 0, SRCCOPY);

    /*CImage image; // from this code i tried to understand how to save the bitmap
    image.Attach(hbDesktop); 
    image.Save(pathname, Gdiplus::ImageFormatBMP);*/

    CImage image;//this code is what I came up with eventually
    image.Attach(hbDesktop);
    CHAR buffer[100] = _T("this is a literal string");  // THIS IS WHERE MY PROBLEM STARTS 
    sprintf(buffer,_T("this is a literal string"), 1);
    image.Save(_T(buffer), Gdiplus::ImageFormatBMP);

我试图让程序每次都用不同的名称保存位图文件。 问题是最后一行不起作用,除非我使用_T 符号,并且当我放置_T 时,它不会占用缓冲区并显示“标识符“Lbuffer”未定义”。这是什么意思?我需要把这个 L 符号放在哪里,为什么? 另外,有没有更好的方法在不使用_T 符号的情况下将位图保存到文件中?

我试着查了一下,https://msdn.microsoft.com/en-us/library/dybsewaf.aspx 他们说这是关于 Unicode 的。为什么这个功能需要 Unicode?​​p>

【问题讨论】:

  • 对不起,即使看了链接还是没看懂题目,如果有人能用我带来的代码示例给我解释一下,我会很高兴非常感谢各位助手

标签: c++


【解决方案1】:

_T() 及其 Win32 等效项 TEXT()预处理器宏,如果分别定义了 _UNICODEUNICODE,则它们会在输入值前面加上 L

这些宏只能与字符/字符串文字一起使用。您不能将它们与变量一起使用。所以_T(buffer) 不是有效代码。这就是您收到identifer "Lbuffer" not defined 错误的原因(_UNICODE 显然已在您的项目中定义)。

如果定义了_UNICODE/UNICODE,则_T("literal")TEXT("literal") 被编译器评估为L"literal" - wchar_t[] 类型的宽字符串文字。 p>

如果_UNICODE/UNICODE 未定义,则_T("literal")TEXT("literal") 被编译器评估为"literal" - char[] 类型的窄字符串文字

CHAR 不是一个宏,它是chartypedef,并且是无条件的(wchar_t 有一个等效的WCHAR typedef)。

因此,这一行:

CHAR buffer[100] = _T("this is a literal string");

评估如下:

// when _UNICODE is defined
char buffer[100] = L"this is a literal string"; // DOES NOT COMPILE!
// You cannot assign/fill a char[] array with wchar_t data!

// when _UNICODE is not defined
char buffer[100] = "this is a literal string"; // OK

如果你想使用_T()/TEXT(),你必须使用_TCHAR/TCHAR而不是CHAR,这样它们才能匹配:

_TCHAR buffer[100] = _T("this is a literal string");

_TCHAR/TCHAR_UNICODE/UNICODE-敏感预处理器#defines。当_UNICODE/UNICODE 被定义时,它们解析为wchar_t,否则它们解析为char

// when _UNICODE is defined
wchar_t buffer[100] = L"this is a literal string"; // OK

// when _UNICODE is not defined
char buffer[100] = "this is a literal string"; // OK

sprint() 仅适用于 char 数据。 wchar_t 版本为swprintf()_TCHAR/TCHAR 版本为_stprintf()

char buffer[100];
sprintf(buffer, "this is a literal string", 1); // OK

wchar_t buffer[100];
swprintf(buffer, L"this is a literal string", 1); // OK

_TCHAR buffer[100];
_stprintf(buffer, _T("this is a literal string"), 1); // OK

CImage::Save() 接受 LPCTSTR 作为输入。 LPCTSTRconst TCHAR*typedef,因此在定义UNICODE 时解析为const wchar_t*,否则解析为const char*。因为它是UNICODE 敏感的,但您的buffer 始终是char[],如果定义了UNICODE,您将无法将buffer 传递给Save()。您需要改用TCHAR

// In this case, you should use the Win32 macros instead of the C macros.
// It is not good practice to mix C's _T()/_TCHAR macros with Win32 APIs,
// and Win32's TEXT()/TCHAR macros with C APIs, though technically it will
// work fine.  Best to keep the two APIs separate...

TCHAR buffer[100];
_stprintf(buffer, TEXT("filename_%d.bmp"), 1);
image.Save(buffer, Gdiplus::ImageFormatBMP);    

【讨论】:

    猜你喜欢
    • 2011-06-21
    • 2019-12-24
    • 2013-10-06
    • 2017-09-07
    • 1970-01-01
    • 2015-03-07
    • 1970-01-01
    • 2010-11-01
    • 1970-01-01
    相关资源
    最近更新 更多