1

我使用SHBrowseForFolder API 在 Windows 中显示文件夹选择对话框。我的应用支持基于最终用户选择的 UI 语言本地化。这是通过使用FindResourceEx API 为特定 LCID 加载所有资源来实现的。

所以我很好奇,有没有办法让 SHBrowseForFolder 荣誉线程的 LCID 选择?或者,以任何其他方式使其显示基于 LCID 的我首选语言的文本?

4

2 回答 2

3

只是好奇,谁在反对它?你们不关心本地化吗?

尽管如此,我想我找到了解决方案。这是在一个单独的线程上向我建议的,它是一个为MessageBoxAPI 设计的 C# 项目,但概念是相同的。SHBrowseForFolder在调用using之前安装线程范围的钩子SetWindowsHookEx(WH_CALLWNDPROCRET),然后捕获WM_INITDIALOG来自钩子过程的通知。从那里只需根据 UI 语言加载您的本地化文本并将其设置为使用 的控件SetDlgItemText,其中hDlg=window 句柄您在挂钩过程中获得,nIDDlgItem=ID 的按钮和需要本地化的文本字段。以下是当前使用的:IDOK=OK 按钮、IDCANCEL=Cancel 按钮、0x3746="Make new folder" 按钮。您还可以通过调用SetWindowText窗口句柄来更改浏览窗口本身的标题。那么当SHBrowseForFolder返回调用UnhookWindowsHookEx以从它解除挂钩。

这种方法有一些缺点。一是它依靠MS来保持浏览窗口的布局。到目前为止,它是相对相同的。因此,您可能需要跟踪 Windows 版本GetVersionEx并相应地进行调整。

其次,您可能需要在添加新文本后调整按钮和标签的大小。但幸运的是,这不是问题。DrawText与标志一起使用DT_CALCRECT可查看新标签的轮廓,然后使用 更改每个控件的大小MoveWindow。请注意,更复杂的方法将涉及完全调整浏览窗口本身的大小。但我会把它留给你。

最后,我想说的是,微软在证明其 UI 本地化的体面手段方面如此蹩脚,这是一种耻辱。有一些 API 据说是为了做到这一点而设计的,仅举几例:

  • SetThreadLocale - 老实说,我不知道它到底做了什么以及它的目的是什么。文档几乎是白痴。

  • SetThreadUILanguage - 尽管已在 Windows XP 中引入,但此 API 仅从 Windows Vista 开始执行某些操作。但是,它仍然只将大约 80% 的 UI 设置为提供的 LCID。例如,SHBrowseForFolder不受它的影响,但可能还有更多。我没有检查其他常用控件。

  • InitMUILanguage - 我不知道这东西是做什么的。它对我的应用程序没有影响...

  • setlocale - 仅影响诸如此类的遗留 C 内容printf。但是,它们都没有用于 UI。

所以给你。它在技术上都不起作用。因此,一名开发人员被迫为 Windows 编写代码(相信我,我会尽快避免),他希望最终用户能够从他们的程序中更改 UI 语言,而无需求助于繁琐的 Windows 用户范围更改语言,留给设计他/她自己的方式来做这件事。微软加油!

最后,对于@HansPassant 上面的建议。我不能让我的用户支付 100 美元以上就可以在我的应用程序 UI 中使用他们的语言。对不起,我不能跌到那么低……

于 2013-06-19T22:17:23.237 回答
3

AFAIK,SHBrowseForFolder()不是本机用户可本地化的。您要准确定位对话框中的哪些文本?您必须为其提供标题,以便您可以提供任何您想要的预本地化文本。

您是否正在尝试本地化按钮标题或其他控件?为此,您必须使用回调功能手动访问和操作对话框控件。

看看切换到IFileOpenDialog界面。至少,它有SetFileNameLabel()方法。SetOkButtonLabel()

于 2013-06-18T20:49:52.803 回答