我有第一次使用 Visual C++ 版本 1.52 开发的代码(工作和自学)。几年前,我使用 Visual Studio 对其进行了修改并使其正常工作。我现在使用 Visual Studio 2022 再次尝试,但无法让 SetWindowText 函数像以前一样工作。它确实更改了父窗口标题文本,但它是官样文章。我认为这是一个 UNICODE 问题,但到目前为止还无法解决迷宫般的解释。它是在向导生成的 MFC 文档中设置的。我正在包括该功能。有什么建议吗?
void CTICTACView::Game()
{
CWnd* p_Wnd = GetParent();
const char* capt = "TIC TAC TOE";
const char* gm = "GAME!";
if (!game)
p_Wnd->SetWindowText((LPCTSTR)capt);
else
p_Wnd->SetWindowText((LPCTSTR)gm);
}
在零碎地构建出弗兰肯斯坦之后,这就是我最终开始工作的地方。谢谢大家。
void CTICTACView::Game()
{
CWnd* p_Wnd = GetParent();
const wchar_t* capt =_T("TIC TAC TOE");
const wchar_t* gm = _T("GAME!");
if (!game)
p_Wnd->SetWindowText((LPCWSTR)capt);
else
p_Wnd->SetWindowText((LPCWSTR)gm);
}
最佳答案
虽然最后的修订版可以在 Unicode 项目中工作,但它仍然不太好。它确实有点“弗兰肯斯坦”,因为它混合了类型和定义。 wchar_t
是 C++ 类型(尽管是实现定义的),而整个 T
机制是 Microsoft 特定的并且基于预处理器定义。根据编译器选项,T 定义为 W(对于 Unicode)或 A(或者什么都不定义)(对于 ANSI)。这适用于类型(例如 LPCTSTR
->LPCWSTR/LPCSTR
)和函数(例如 SetWindowText()
->SetWindowTextW()/SetWindowTextA()
)。另外,为什么要使用类型转换呢?因此,为了保持一致,我建议修改您的代码,如下所示:
A.显式 Unicode 实现
void CTICTACView::Game()
{
CWnd* p_Wnd = GetParent();
const wchar_t* capt = L"TIC TAC TOE"; // you could also use WCHAR
const wchar_t* gm = L"GAME!";
if (!game)
p_Wnd->SetWindowTextW(capt);
else
p_Wnd->SetWindowTextW(gm);
}
即使使用多字节 (ANSI) 选项,上述代码也可以工作,因为所有类型和调用都是明确的 Unicode。它始终会调用 SetWindowText()
的宽版本并传递宽字符串。如果项目是使用多字节字符选项编译的,则该函数(而不是编译器!)将根据系统的默认代码页将字符串转换为 ANSI。
B.使用“T”(条件)定义
void CTICTACView::Game()
{
CWnd* p_Wnd = GetParent();
const TCHAR* capt =_T("TIC TAC TOE"); // You could also use LPCTSTR instead of TCHAR*
const TCHAR* gm = _T("GAME!");
if (!game)
p_Wnd->SetWindowText(capt);
else
p_Wnd->SetWindowText(gm);
}
上面的代码应该适用于 Unicode 和 ANSI 选项。在 Unicode 情况下,字符串将被定义为宽字符串,并且将调用宽版本的 SetWindowText()
,而在 ANSI 情况下,字符串和函数调用都将是 ANSI。在任何一种情况下都不会发生转换。
此外,代码可以得到相当多的整合:
void CTICTACView::Game()
{
GetParent()->SetWindowText(game ? _T("GAME!") : _T("TIC TAC TOE"));
}
关于visual-c++ - 为什么 SetWindowText 不再起作用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71769064/