在 MFC 中,没有定义为 CWnd::SetWindowTextA
/CWnd::SetWindowTextW
的方法,但以下代码将根据 Unicode 设置正确编译和运行:
//UNICODE is defined
BOOL CMyDialog::OnInitDialog()
{
CDialogEx::OnInitDialog();
//this line won't compile as expected
//SetWindowTextA(L"ANSI");
//this line compiles, but CWnd::SetWindowTextW doesn't exits
//SetWindowTextW ends up calling CWnd::SetWindowText
SetWindowTextW(L"Unicode");
return TRUE;
}
//UNICODE is not defined
BOOL CMyDialog::OnInitDialog()
{
CDialogEx::OnInitDialog();
//this line compiles, but CWnd::SetWindowTextA doesn't exits!
//SetWindowTextA ends up calling CWnd::SetWindowText
SetWindowTextA("ANSI");
//this line won't compile as expected
//SetWindowTextW(L"Unicode");
return TRUE;
}
根据宏,SetWindowText
映射到 SetWindowTextA
/SetWindowTextW
是有意义的。但我不明白 wnd->SetWindowTextA
/wnd->SetWindowTextW
如何映射回 CWnd::SetWindowText
。
最佳答案
这是 WinUser.h
中宏声明的副作用。它不仅适用于 Windows API 的全局函数声明,还适用于代码中出现的任何其他名为 SetWindowText
的标识符:全局、本地或类范围。
#ifdef UNICODE
#define SetWindowText SetWindowTextW
#else
#define SetWindowText SetWindowTextA
#endif // !UNICODE
因此,任何声明名为 SetWindowText
的方法的 C++ 类都会获得由预处理器隐式转换的所有该方法。
我没有安装 MFC,但我知道 ATL 上的 CWindow 类存在此方法,其定义如下。
class CWindow
{
public:
...
BOOL SetWindowText(_In_z_ LPCTSTR lpszString) throw()
{
ATLASSERT(::IsWindow(m_hWnd));
return ::SetWindowText(m_hWnd, lpszString);
}
...
};
但在编译时,上述代码(用于调试构建)将被预处理器转换为如下所示的内容:
BOOL SetWindowTextW( LPCTSTR lpszString) throw()
{
(void)( (!!((::IsWindow(m_hWnd)))) || (1 != _CrtDbgReportW(2, L"c:\\program files...
return ::SetWindowTextW(m_hWnd, lpszString);
}
具有讽刺意味的是,LPCTSTR 方法参数是类型定义的,而不是宏替换,但您明白了。
如果您有一个足够大的 Windows 应用程序,那么您自己定义的现有 C++ 类之一很有可能具有与 Windows API 匹配的方法或成员变量。并且它也得到同样的待遇。
关于c++ - MFC如何解释SetWindowTextW(LPCTSTR)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53624512/