C++ 中的 SetWindowTextW() 辅助函数
Posted
技术标签:
【中文标题】C++ 中的 SetWindowTextW() 辅助函数【英文标题】:SetWindowTextW() helper function in c++ 【发布时间】:2021-05-11 14:14:56 【问题描述】:我想知道是否有比这段代码“更好的方法”来提供 SetWindowText“文本”参数:
wchar_t buffer[20];
Measures10nm.CIE_L = 100.3456f;
Measures10nm.CIE_a = -9.34f;
Measures10nm.CIE_b = -56.56f;
swprintf_s(buffer, 20, L"%.2f", Measures10nm.CIE_L);
SetWindowTextW(hEditCIE_L, buffer);
swprintf_s(buffer, 20, L"%.2f", Measures10nm.CIE_a);
SetWindowTextW(hEditCIE_a, buffer);
swprintf_s(buffer, 20, L"%.2f", Measures10nm.CIE_b);
SetWindowTextW(hEditCIE_b, buffer);
我尝试了一个函数,我可以提供一个浮点数,谁会返回一个 wchar_t,因为这是 SetTextWindow() 需要的参数类型,但我还没有“成功”。我什至不确定这在技术上是否可行,毕竟我一直在尝试各种编码?理想情况下,我想使用的是这样的函数:
SetTextWindow(hEdit, floatToWchar_t(Measures10nm.CIE_L));
但我一直无法编写这样的功能? 我尝试了一些类似的东西:
wchar_t floatToWchar_t(float x)
wchar_t buffer[20];
swprintf_s(buffer, 20, L"%f", x);
return buffer;
但这不起作用,因为 wchar_t 是一个数组,我想。我考虑过使用指向数组的指针,但我无法清楚地概念化如何做到这一点。
感谢任何帮助。请原谅新手的问题...
【问题讨论】:
您可以将buffer
设为静态(static wchar_t buffer[20]
),但这会对调用者不明显的返回值的使用施加限制。 (也可能存在线程问题。)
这里有std::to_wstring,你的最后一段代码尝试了什么。它返回一个std::wstring
,因此您将不得不使用它的.c_str()
成员来获取一个可以传递给SetWindowTextW
的指针。
这样的签名BOOL SetWinTxt(_In_ HWND hWnd, _In_ PCWSTR format, ...);
可能写函数
在 C++ 中,函数签名应该类似于 template <typename... Args> void FormatWindowText(HWND hWnd, wchar_t const* format, Args... args)
。与 C 风格的可变参数函数不同,函数模板保留了类型信息,使得实现可以在编译时验证参数的数量和类型是否与格式字符串匹配。
和template <typename... Args> void FormatWindowText(HWND hWnd, wchar_t const* format, Args... args)
在代码中生成多个函数,不像BOOL SetWinTxt(_In_ HWND hWnd, _In_ PCWSTR format, ...);
- 单个函数
【参考方案1】:
我们在这里讨论的是 C++,所以忘记字符数组并使用 std::wstring
和 C++ 流。
#include <sstream>
std::wstringstream ss; // String-based stream.
float f = 3.14; // Our float.
ss << f; // Output the float to the stream.
SetWindowTextW(hWnd, ss.str().c_str()); // Covert to a `wchar_t` zero-terminated string.
您可以轻松地将其包装在一个函数中。
void SetWindowFloat(HWND hWnd, float f);
如果您需要修改浮点数转换为字符串的方式,请查看iomanip。
【讨论】:
std::wostringstream
会比std::wstringstream
更好。 std::to_wstring()
会更好(除非您需要自定义格式)。
@rveerd // 我的反应和你一样,“这是 c++”和“字符串”应该让我的生活更轻松,但我可以绕过“LPCWSTR lpString”的“烟幕” ”。我用 std::stringstream 做了很多试验,但它不能直接传递给任何 Windows 调用。非常感谢您的帮助!【参考方案2】:
修改为 wstring ....
std::wstring floatToWideString(float x)
wchar_t buffer[20];
swprintf_s(buffer, 20, L"%f", x);
return buffer;
然后
void SetWindowText(HWND hwnd, const std::wstring& s)
SetWindowText(hwnd, s.c_str());
SetWindowText(hwnd, floatToWideString(3.1415f));
...但是您对 SetWindowText 的所有调用都指向同一个 hwnd,您将覆盖那里的内容....它不像是行缓冲区。
更新:
此外,如果您非常倾向于使用 MFC,或者只是使用 <atlstr.h>
,那么有一个 CString 类具有 (LPCTSTR) 转换运算符。
类似:
CStringW floatToWideCString(float x)
CStringW s;
s.Format(_T("%f"), x);
return s;
SetWindowText(hwnd, floatToWideCString(3.14));
【讨论】:
还有函数 std::to_wstring() 将值转换为 wstring。使用它还不够了解您是否可以为其提供小数点后位数的格式。 不,to_wstring()
不允许您自定义格式,它基本上只是std::swprintf(L"%f")
的包装器
@JosephWillcoxson // 首先,非常感谢您的解决方案。我很好奇你为什么在 SetWindowText() 调用中需要字符串长度?我认为调用只需要两个参数。只是好奇:-)
哎呀,我的错。在未安装 WINAPI 且未查找的机器上从内存中工作。是的,只需要一个参数。
@RogerBreton 我想我错误地记住了一个额外的论点。 HDC 函数 TextOut
和 DrawText
有一些长度参数,但 SetWindowText
没有。以上是关于C++ 中的 SetWindowTextW() 辅助函数的主要内容,如果未能解决你的问题,请参考以下文章
C++ 编译时提示:不能将参数 1 从“char [6]”转换为“LPCTSTR”