我正在Delphi XE3中编写一个支持英语和希伯来语的应用程序。
当我更改当前语言(使用 Alt + Shift )时,在某些文本编辑器(TEdit等)的编辑模式下,插入符号(文本光标)图标不会像在其他已知应用程序(Office,Chrome等)中的编辑器那样改变新的方向
对于那些不了解不同插入符号图标的人,这里有他们的图像:
Left-to-right (English) caret icon和Right-to-left (Hebrew) caret icon。
只有当我将焦点更改为另一个组件,然后在编辑模式下返回上一个编辑器时,它才会显示与当前语言方向对应的正确插入符号图标。
在使用Delphi XE3之前,我使用过Delphi 7,它运行良好。 此外,我尝试过DevExpress文本编辑器,他们也有同样的问题。
答案 0 :(得分:0)
我不确定过去可能有什么用处或可能有什么改变,但下面的内容应该有效。似乎WM_INPUTLANGCHANGE
是一个滑溜的信息,几乎不可能通过覆盖WndProc
或甚至使用Application.HookMainWindow
挂钩来可靠地捕捉(有一篇关于它的好文章here)。另请注意,这只是希伯来语键盘的一个示例 - 它不会捕获所有从右到左的键盘(如果需要,您显然需要添加它们)。
const HEBREW_KEYBOARD = $40D0000;
var gLangHook: HHOOK = 0;
function LangHookProc(Code: Integer; wParam: WPARAM;
lParam: LPARAM): LRESULT; stdcall;
begin
if (Code = HC_ACTION) and
(PCWPStruct(lParam)^.message = WM_INPUTLANGCHANGE) then
begin
if (PCWPStruct(lParam)^.lParam and $FFFF0000) = HEBREW_KEYBOARD then
Application.BiDiMode := bdRightToLeft
else
Application.BiDiMode := bdLeftToRight;
end;
Result := CallNextHookEx(gLangHook, Code, wParam, lParam);
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
gLangHook := SetWindowsHookEx(WH_CALLWNDPROC, @LangHookProc, HInstance,
GetCurrentThreadId);
if gLangHook = 0 then
RaiseLastOSError;
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
if gLangHook <> 0 then
begin
UnhookWindowsHookEx(gLangHook);
gLangHook := 0;
end;
end;
这里我设置了应用程序的BiDiMode - 如果所有孩子都有ParentBiDiMode := true
,那么所有控件都应该切换到从右到左模式。当然,你可以随心所欲地处理这个 - 我认为这是困难的部分。
答案 1 :(得分:0)
是否是像@J ...建议的Delphi XE3错误,或者机器特定的错误,我还是遇到了它。
我没有找到一个明确的解决方案,而是一个很好的解决方法
注意:此解决方案仅适用于DevExpress编辑器,因为事件被TWinControl后代捕获。
这是代码:
procedure OnChangeLanguageEvent(var Msg: TMessage); message CM_INPUTLANGCHANGE;
procedure TForm1.OnChangeLanguageEvent(var Msg: TMessage);
begin
Screen.ActiveControl.Perform(WM_KILLFOCUS,0,0);
Screen.ActiveControl.Perform(WM_SETFOCUS,0,0);
inherited;
end;
在这个程序中,我抓住了事件CM_INPUTLANGCHANGE
,当我这样做时,我会暂时失去焦点并重新获得当前活动控件的焦点。这模拟了我之前所说的,只有当我将焦点更改为另一个组件,然后在编辑模式下返回上一个编辑器时,它才会显示正确的插入符号。
我真的不喜欢这个解决方案,因为它并没有真正解决任何问题,但它对我的需求很好。
欢迎您提出其他想法:)