Delphi:如何本地化菜单快捷方式的描述?

Delphi:如何本地化菜单快捷方式的描述?,delphi,localization,internationalization,keyboard-shortcuts,shortcut,Delphi,Localization,Internationalization,Keyboard Shortcuts,Shortcut,有没有办法获得快捷方式(如Ctrl+Z)的本地化描述,以便在英语系统上运行应用程序时获得“Ctrl+Z”,在德语系统上获得“Strg+Z” VCL函数ShortCutToText没有国际化。API函数GetKeyNameText稍好一些,但仍然不够完美:如果将德语XP的区域设置切换为英语(美国),它仍然会生成德语文本。此外,结果是在首都,这是丑陋的 澄清:我知道如何用自定义版本替换ShortcuttText或Smkc*资源字符串。但要使用它,我需要翻译的字符串。我想从操作系统(或类似系统)上获得

有没有办法获得快捷方式(如Ctrl+Z)的本地化描述,以便在英语系统上运行应用程序时获得“Ctrl+Z”,在德语系统上获得“Strg+Z”

VCL函数ShortCutToText没有国际化。API函数GetKeyNameText稍好一些,但仍然不够完美:如果将德语XP的区域设置切换为英语(美国),它仍然会生成德语文本。此外,结果是在首都,这是丑陋的

澄清:我知道如何用自定义版本替换ShortcuttText或Smkc*资源字符串。但要使用它,我需要翻译的字符串。我想从操作系统(或类似系统)上获得这些

更新:看起来微软希望开发人员自己翻译-见2。在里面引述:

例如,要将CTRL+O指定给“文件”菜单上的“打开”命令, 修改菜单项的标题,使其如下所示:

打开\tCtrl+O

菜单编辑器中的菜单项将更新以反映新的标题 当你打字的时候


请注意,快捷方式是手动附加到标题中的。

ShortCutToText使用MenuKeyCaps数组。这不能直接修改(因为它是在菜单单元的实现中),但数组中填充了资源字符串,可以使用各种翻译工具进行翻译

您需要转换consts.pas中的SmkcCtrl resourcestring常量(取决于您的Delphi版本)

[编辑]

或者你可以下载,我也创建了hook函数,并用你自己的函数替换它们。然后,您可以编写一个重写,调用常规的ShortCutToText函数,并在菜单不知道的情况下将文本“Ctrl”替换为“Strg”(反之亦然)。 但我会把它作为最后的手段,因为我认为最好只是翻译资源。如果您想使用钩子,请下载并包含该单元,并在任何单元中添加以下代码(如果您愿意,可以使用单独的新单元)


它将用您喜欢的任何文本替换快捷方式文本中的Ctrl键,而无需更改任何其他代码。

我将回答我自己的问题,这样我就可以接受一些东西:看起来微软希望开发人员自己翻译-参见2。在里面引述:

例如,要将CTRL+O指定给“文件”菜单上的“打开”命令, 修改菜单项的标题,使其如下所示:

打开\tCtrl+O

菜单编辑器中的菜单项将更新以反映新的标题 当你打字的时候


请注意,快捷方式是手动添加到标题中的。

我认为这意味着在使用非英语键盘的Delphi系统中,所有者绘制的菜单将被错误地绘制,因为menus.pas中的代码使用
ShortCutToText
。大卫:这就是我为什么要问的原因——我们的非德国客户抱怨他们菜单中的Strg+Z等。他们至少需要Ctrl+Z,或者——当然更好——用他们自己的语言进行等效。甚至对于非所有者绘制的菜单(D2007),也会发生这种情况。此外,如果他们停止使用所有者绘制菜单(因为Vista不需要所有者绘制来绘制glyphs)然后系统会把它整理出来。@Ulrich很容易找到代码,用自己制作的版本替换
ShortCutToText
,使用Ctrl+而不是Strg+,但我猜你已经知道了。@Ulrich By owner draw我指的是Menus.pas中的Embarcadero代码-我不是指你画的。非所有者绘制应由系统绘制,因此应正确国际化。感谢链接。:-)在一个可以忽略不计的延迟之后:-)我刚刚开始使用BigProcHook解决方案,因为我们希望在运行时进行转换(HookResourceString),而这不适用于VCL实现,因为MenuKeyCaps是字符串的
数组。再次感谢!
uses
  BigProcHook, Menus;

var
  FHook: TBigProcHook;

// The replacement function
function MyShortCutToText(ShortCut: TShortCut): string;
begin
  FHook.Hooked := False;
  try
    Result := ShortCutToText(ShortCut);
    Result := StringReplace(Result, 'Ctrl', 'Whatever', []);
  finally
    FHook.Hooked := True;
  end;
end;

initialization
  FHook := TBigProcHook.Create(@ShortCutToText, @MyShortCutToText);
finalization
  FHook.Hooked := False;
  FHook.Free;
end.