我正在尝试用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不是宏,它是一种的typedef对char,并且是无条件的(存在等效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[],你将无法传递buffer给Save()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)
| 归档时间: |
|
| 查看次数: |
4760 次 |
| 最近记录: |