我有一个ANSI项目。我需要将CDialog派生类的标题栏设置为Unicode文本。
BOOL CMyDialog::OnInitDialog()
{
CDialog::OnInitDialog();
::SetWindowTextW(GetSafeHwnd(), PathFindFileNameW(filename));
return TRUE; // return TRUE unless you set the focus to a control
// EXCEPTION: OCX Property Pages should return FALSE
}
字符串
然而,当Unicode文本包含非ANSI字符时,它们显示为问号。我得到了类似“?.doc”的东西。我在静态控件中也有类似的问题,但奇怪的是,在编辑框中SetWindowTextW可以工作。
哦,这个项目是一个大的遗留项目,不能转换为Unicode。
6条答案
按热度按时间n6lpvg4x1#
SetWindowText()/SetWindowTextA()和SetWindowTextW()实际上都是WM_SETTEXT,这是在创建多字节/Ansi窗口时需要进行代码页转换的少数消息之一。这意味着消息没有W和A版本。
即便如此,在Vista/Win7的标题栏中显示Unicode还是很容易的。你所需要做的就是拦截窗口中的WM_SETTEXT消息,并将参数传递给DefWindowProcW(),而不是通常的DefWindowProcA/DefWindowProc()。这是因为内部所有窗口实际上都是Unicode。
请注意,如果只是简单地将参数传递给DefWindowProcW(),那么必须绝对确保参数确实指向wchar_t字符串。
在我自己的例子中,所有的字符串都被假设为UTF-8字符。这意味着正常的ANSI字符串仍然像以前一样工作。当我在窗口中拦截WM_SETTEXT消息时,我使用MultiByteToWideChar()将UTF-8字符转换为wchar_t,然后显式地将结果传递给DefWindowProcW()。
好的副作用是,它也将显示Unicode字符的显示器上。
XP有一个问题,即标题栏不正确显示,即使是在屏幕上。
jckbn6z72#
汤姆纳尔逊的答案可能是最好的,但我只是找到了另一个快速解决方案,并认为我会分享:
字符串
如果没有最后一行,我们在调试时会得到Assert错误,尽管单击Ignore似乎不会引起问题,Release模式也会正常运行。MFC对我们很多人来说仍然是一个谜,所以希望这段代码是合理的。
xsuvu9jc3#
如果你不能将项目转换为Unicode,那么你只能接受这些限制。你的对话框是一个ANSI对话框。如果你喜欢,你可以使用
SetWindowTextW
,但是当系统想要绘制对话框时,它将使用ANSI API来获取窗口文本。它将使用ANSI文本绘制GDI函数来执行绘制。如果你想要一个Unicode对话框,你需要为Unicode编译。50few1ms4#
Microsoft定义了许多不同风格的API函数。有三个版本的
PathFindFileName()
(未指定,由编译器设置。ANSI,如您在您的情况下所说。),PathFindFileNameW()
(Unicode)和PathFindFileNameA()
(ANSI)。Here是在MSDN上的描述。我认为你需要将你的行改为这样(最终你也需要处理
filename
):字符串
你说你从一个Unicode类派生,因此你不能使用下面的代码。这将是一个纯ANSI项目:
型
或者,如果一切都不明确:
型
ztigrdn85#
另外,您可以直接调用DefWindowProcW(handle,WM_SETTEXT,0,(LPARAM)L”缺省值”);
3pmvbmvn6#
除了上面关于
SetWindowTextA
的正确答案外,作为类似问题的一般解决方案,您可以将Unicode字符串分配给CString
,它将为您执行转换,然后使用CString。这很可能发生在编辑框的后台。通常,如果您不指定MFC下函数的Unicode或ANSI特定变体,你会得到更可移植的代码,它可以与任何一个一起工作。