_T和L在C++中的含义是什么?如何传递它们?

Men*_*hif -4 c++

我正在尝试用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);
Run Code Online (Sandbox Code Playgroud)

我试图让程序每次使用不同的名称保存位图文件.问题是,除非我使用_T符号,否则最后一行不起作用,当我确实使用符号时_T,它不会占用缓冲区并且说"标识符"Lbuffer"未定义".这是什么意思?我需要在哪里放置这个L标志?为什么?另外,有没有更好的方法将位图保存到文件而不使用此_T符号?

我试着看一下,在https://msdn.microsoft.com/en-us/library/dybsewaf.aspx上他们说这是关于Unicode的.为什么我需要这个函数的Unicode?

Rem*_*eau 10

_T(),它的Win32等效TEXT(),是预处理器宏,它们分别在输入值前面加上Lif _UNICODE或者UNICODE被定义.

这些宏仅用于字符/字符串文字.您不能将它们与变量一起使用.所以_T(buffer)不是有效的代码.这就是为什么你得到一个identifer "Lbuffer" not defined错误(_UNICODE显然在你的项目中定义).

如果_UNICODE/ UNICODE定义,_T("literal")TEXT("literal")由编译器为被评价L"literal"-一个宽字符串文字类型的wchar_t[].

如果_UNICODE/ UNICODE没有定义,_T("literal")以及TEXT("literal")由编译器为被评价"literal"-一个窄字符串文字类型的char[].

CHAR不是宏,它是一种的typedefchar,并且是无条件的(存在等效WCHAR于类型定义wchar_t).

因此,这一行:

CHAR buffer[100] = _T("this is a literal string");
Run Code Online (Sandbox Code Playgroud)

被评估为:

// 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!
Run Code Online (Sandbox Code Playgroud)

// when _UNICODE is not defined
char buffer[100] = "this is a literal string"; // OK
Run Code Online (Sandbox Code Playgroud)

如果你想使用_T()/ TEXT(),你必须使用_TCHAR/ TCHAR而不是CHAR匹配:

_TCHAR buffer[100] = _T("this is a literal string");
Run Code Online (Sandbox Code Playgroud)

_TCHAR/ TCHAR_UNICODE/ UNICODE-sensitive预处理器#define.当_UNICODE/ UNICODE被定义时,他们决定wchar_t,否则他们决定char:

// when _UNICODE is defined
wchar_t buffer[100] = L"this is a literal string"; // OK
Run Code Online (Sandbox Code Playgroud)

// when _UNICODE is not defined
char buffer[100] = "this is a literal string"; // OK
Run Code Online (Sandbox Code Playgroud)

sprint()仅适用于char数据.该wchar_t版本是swprintf(),和_TCHAR/ TCHAR版本是_stprintf():

char buffer[100];
sprintf(buffer, "this is a literal string", 1); // OK
Run Code Online (Sandbox Code Playgroud)

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

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

CImage::Save()接受一个LPCTSTR输入. LPCTSTR是一个typedefconst TCHAR*,因此解析为何const wchar_t*UNICODE定义,否则解析为const char*.因为它是UNICODE敏感的,但你buffer总是一个char[],你将无法传递bufferSave()if UNICODE定义.您需要使用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);    
Run Code Online (Sandbox Code Playgroud)