在 Unicode 中转换变量
Converting variables in Unicode
我是一个Javascript开发人员,所以请放轻松!我正在尝试编写一个C++补丁以在框架上启用打印。我正在使用Unicode进行编译,根据我的研究,这就是让我搞砸的原因。
我认为这是一件相对简单的事情,我过于复杂了。应用程序具有包含当前打印机名称的std::string
。脚本首先检查它是否未设置(如果是,则利用输出LPTSTR
的GetDefaultPrinter
)。最后,脚本采用比std::string
或LPTSTR
,并将其转换为CreateDC
的LPCTSTR
。
这是我的代码:
std::string PrinterName = window->getPrinter();
LPDWORD lPrinterNameLength;
LPWSTR szPrinterName;
LPCTSTR PrinterHandle;
if (PrinterName == "unset") {
GetDefaultPrinter( szPrinterName, &lPrinterNameLength );
PrinterHandle = szPrinterName; //Note sure the best way to convert here
} else {
PrinterHandle = PrinterName.c_str();
}
HDC hdc = CreateDC( L"WINSPOOL ", PrinterHandle, NULL, NULL);
编译时,我只收到转换错误。如
无法将参数 2 从 LPDWORD * 转换为 LPDWORD (GetDefaultPrinter)
和
无法从"const char *"转换为"LPCTSTR"(在 PrinterHandle = PrinterName.c_str() 行上)
我对此做了相当多的研究,但还没有提出具体的解决方案。
任何帮助将不胜感激!
即使您是为"Unicode"(宽字符字符串)编译的,也可以调用 API 函数的"ANSI"(窄字符字符串)版本。 Windows将为您进行转换,并在幕后调用宽字符版本。
例如,对于大多数Windows API(如CreateDC
),实际上没有具有该名称的函数。 相反,有一个名为 CreateDC
的宏扩展到 CreateDCA
或 CreateDCW
,这是实际的函数名称。 当您针对"Unicode"进行编译时,宏将扩展到-W
版本(这是所有现代操作系统版本中的本机版本)。 没有什么可以阻止您显式调用任一版本,无论您是否针对 Unicode 进行编译。 在大多数情况下,-A
版本会简单地为您将窄字符串转换为宽字符串,然后调用相应的-W
版本。 (这里有一些与创建窗口相关的警告,但我认为它们不适用于 DC。
std::string PrinterName = window->getPrinter();
if (PrinterName == "unset") {
char szPrinterName[MAX_PATH]; // simplified for illustration
DWORD cchPrinterNameLength = ARRAYSIZE(szPrinterName);
GetDefaultPrinterA(szPrinterName, &cchPrinterNameLength);
PrinterName = szPrinterName;
}
HDC hdc = CreateDCA("WINSPOOL", PrinterName.c_str(), NULL, NULL);
首先,正如评论中提到的,正确的方法是做一个DWORD
并传递地址:
DWORD lpPrinterNameLength;
...
GetDefaultPrinter(..., &lpPrinterNameLength);
为什么这样是这样,以便它可以使用和更改一个数字:
在输入时,指定 pszBuffer 缓冲区的大小(以字符为单位)。输出时,接收打印机名称字符串的大小(以字符为单位),包括终止空字符。
它只需要一个DWORD
,但该函数会更改传入的变量中的数字,因此该函数需要更改变量的地址,以便这些更改反映回调用方。
其次,由于window->getPrinter()
返回一个窄字符串,并且您使用的是UNICODE
,这使得函数采用宽字符串,因此您应该从窄字符串转换为宽字符串。有几种方法可以做到这一点(例如ildjarn评论中提到的非常简单的方法),甚至这个方法在C++11中也稍微好一点,尽管前面提到的注释更适用于它,但我将使用MultiByteToWideChar
和C++03:
std::wstring narrowToWide(const std::string &narrow) {
std::vector<wchar_t> wide;
int length = MultiByteToWideChar(CP_ACP, MB_ERR_INVALID_CHARS, narrow.c_str(), -1, NULL, 0);
if (!length) {
//error
}
wide.resize(length);
if (!MultiByteToWideChar(CP_ACP, MB_ERR_INVALID_CHARS, narrow.c_str(), -1, &wide[0], length)) {
//error, should probably check that the number of characters written is consistent as well
}
return std::wstring(wide.begin(), wide.end());
}
...
std::wstring PrinterName = narrowToWide(window->getPrinter());
//rest is same, but should be L"unset"
CreateDC( L"WINSPOOL ", PrinterHandle, NULL, NULL);
- 如何在保持其值的同时将 c++ 无符号字符变量转换为 char 变量
- 是否可以将已经初始化的变量转换为 void*?
- C++字符串类如何将一个变量转换为另一个变量?
- std::chrono::time_point 从变量转换时编译器错误
- std::变量转换构造函数行为
- 尝试将字符串变量转换为布尔值会导致 "true" 和 "false" 都等于 0
- C++将字符变量转换为字符串变量将返回 ASCII 值
- 将大端序的 32 位变量转换为小端序
- 在代码优化过程中,C++11编译器是否会在可能的情况下将局部变量转换为右值
- 有符号浮点变量转换为无符号DWORD
- 将初始变量转换为已声明的变量
- 将C++字符串变量转换为long
- 如何将DWORD或char*类型的变量转换为LPCWSTR
- 如何在 c++ 中将包含时间的字符串变量转换为time_t类型
- C++变量转换为模板参数
- 将 [char] 变量转换为 [int],然后再转换回 [char]
- 如何将 int 变量转换为 ASCII 单词
- 将c++类的私有变量转换为公有变量
- 将变量转换为const
- 如何将方法返回的接口变量转换为对象