You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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钩子拦截对话框创建过程,遍历控件替换文本。

  1. 在Vcl.Dialogs.pas的TCommonFileDialog类中添加钩子相关声明:
type
  TCommonFileDialog = class(TComponent)
  private
    FCBTProc: TFNHookProc;
    FHookHandle: HHOOK;
    procedure HookDialog;
    procedure UnhookDialog;
  protected
    function DoExecute: Boolean; override;
    // ... 保留原有成员
  end;
  1. 实现钩子回调函数:
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;
  1. 实现钩子的挂载与卸载方法:
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;
  1. 修改DoExecute方法,在对话框创建前挂载钩子:
function TCommonFileDialog.DoExecute: Boolean;
begin
  HookDialog;
  try
    Result := inherited DoExecute;
  finally
    UnhookDialog;
  end;
end;

注意事项

  • 不同Windows版本的对话框控件ID、文本可能存在差异,需在目标系统调试确认控件信息,确保翻译匹配准确。
  • 若程序仅支持Vista及以上系统,可结合IFileDialogCustomize接口补充自定义控件,但系统默认控件文本仍需依赖钩子或资源替换方案。

内容的提问来源于stack exchange,提问作者SOLID Developper

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 00:15:29