如何在Delphi 11.1.5中翻译TOpenDialog/TSaveDialog对话框标题?
翻译TOpenDialog与TSaveDialog的解决方案
方法一:直接修改对话框标题
如果仅需修改对话框标题,可直接在Vcl.Dialogs.pas的TFileDialog.Execute方法中替换标题文本。找到该方法的实现,在调用继承方法前将Title属性替换为翻译后的内容:
function TFileDialog.Execute: Boolean; begin // 替换为你的翻译文本,_()为示例翻译函数,可根据实际替换 Self.Title := _('打开文件'); Result := inherited Execute; end; function TSaveDialog.Execute: Boolean; begin Self.Title := _('保存文件'); Result := inherited Execute; end;
方法二:用CBT钩子修改所有控件文本
若需要修改对话框内的按钮(如“打开”“保存”“取消”)、静态文本(如“文件名”“文件类型”),可通过Windows CBT钩子拦截对话框创建过程,遍历控件替换文本。
- 在
Vcl.Dialogs.pas的TCommonFileDialog类中添加钩子相关声明:
type TCommonFileDialog = class(TComponent) private FCBTProc: TFNHookProc; FHookHandle: HHOOK; procedure HookDialog; procedure UnhookDialog; protected function DoExecute: Boolean; override; // ... 保留原有成员 end;
- 实现钩子回调函数:
function CBTProc(nCode: Integer; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall; var I: Integer; hDlg, hCtrl: HWND; CtrlText: array[0..255] of Char; begin Result := CallNextHookEx(0, nCode, wParam, lParam); if nCode = HCBT_ACTIVATE then begin hDlg := HWND(wParam); // 遍历对话框控件 for I := 0 to 100 do // 覆盖常见控件ID范围,可根据实际调整 begin hCtrl := GetDlgItem(hDlg, I); if hCtrl = 0 then Continue; GetWindowText(hCtrl, CtrlText, SizeOf(CtrlText)); // 匹配原文本并替换为翻译内容 if StrComp(CtrlText, 'Open') = 0 then SetWindowText(hCtrl, _('打开')) else if StrComp(CtrlText, 'Save') = 0 then SetWindowText(hCtrl, _('保存')) else if StrComp(CtrlText, 'Cancel') = 0 then SetWindowText(hCtrl, _('取消')) else if StrComp(CtrlText, 'File name:') = 0 then SetWindowText(hCtrl, _('文件名:')) else if StrComp(CtrlText, 'Files of type:') = 0 then SetWindowText(hCtrl, _('文件类型:')); // 可添加更多文本匹配规则 end; // 激活后卸载钩子,避免影响其他对话框 UnhookWindowsHookEx(TCommonFileDialog(Pointer(GetWindowLongPtr(hDlg, GWLP_USERDATA))).FHookHandle); end; end;
- 实现钩子的挂载与卸载方法:
procedure TCommonFileDialog.HookDialog; begin FCBTProc := @CBTProc; FHookHandle := SetWindowsHookEx(WH_CBT, FCBTProc, 0, GetCurrentThreadId); end; procedure TCommonFileDialog.UnhookDialog; begin if FHookHandle <> 0 then begin UnhookWindowsHookEx(FHookHandle); FHookHandle := 0; end; end;
- 修改
DoExecute方法,在对话框创建前挂载钩子:
function TCommonFileDialog.DoExecute: Boolean; begin HookDialog; try Result := inherited DoExecute; finally UnhookDialog; end; end;
注意事项
- 不同Windows版本的对话框控件ID、文本可能存在差异,需在目标系统调试确认控件信息,确保翻译匹配准确。
- 若程序仅支持Vista及以上系统,可结合
IFileDialogCustomize接口补充自定义控件,但系统默认控件文本仍需依赖钩子或资源替换方案。
内容的提问来源于stack exchange,提问作者SOLID Developper
相关产品推荐
相关产品推荐

