在我的 Delphi 2009 应用程序中,我有这个窗口:
它有一个 TPageControl,上面有一个 TTabSheet,底部还有可在所有工作表上操作的按钮。
TTabSheet 的左侧是一个 TElXTree(LMD 的树/网格组件),TTabSheet 的右侧是一个 TPanel,其中包含特定于该工作表的按钮。
当我在 TElXTree 中选择一行并单击任一组按钮中的任何按钮时,这些按钮都可以正常工作。
现在,在 TElXTree 中,标记为“文本”的列可以使用 TElXtree 提供的就地编辑器进行编辑。当我单击文本时,它会进入编辑模式。
在编辑模式下,当我单击 TElXTree 中的任意位置(例如复选框上)时,它将退出编辑器并处理命令(即选中或取消选中复选框)。但是,在编辑模式下,当我单击任一组按钮中的任何按钮时,它只会退出就地编辑器并且不会处理该按钮。然后我必须再次单击该按钮才能处理该按钮。
是否有一些我没有做或不理解的简单事情可以让我单击其中一个按钮并允许它退出就地编辑器并处理该按钮?
<小时/>后续:
感谢@NGLN 的回答,我找到了解决方法。我使用了他的 Application.OnMessage 方法,之前我曾在一些拖放代码中使用过该方法。但我必须做出一些改变,这就是我的想法:
procedure TMainForm.AppMessageHandler(var Msg: TMsg; var Handled: Boolean);
var
P: TPoint;
begin
if Msg.message = WM_LBUTTONDOWN then
if Screen.ActiveControl <> nil then
if Screen.ActiveControl.ClassNameIs('TElInpEdit') then
begin
GetCursorPos(P);
{ When in the inplace editor, I need to go to its parent ElXTree }
{ because the ElXTree does not have the problem. }
{ Only components outside the ElXTree do }
with Screen.ActiveControl.Parent do
if not PtInRect(ClientRect, ScreenToClient(P)) then begin
{ The WM_Killfocus didn't work for me, but it gave me this idea: }
{ 1. Complete the operation, and 2. Simulate the mouse click }
InplaceEdit.CompleteOperation(true);
Mouse_Event(MOUSEEVENTF_ABSOLUTE or MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0);
Mouse_Event(MOUSEEVENTF_ABSOLUTE or MOUSEEVENTF_LEFTUP, 0, 0, 0, 0);
{ Then skip the regular handling of this WM_LBUTTONDOWN }
Handled := true;
end;
end;
end;
最佳答案
它确实看起来像一个错误。两种可能的(讨厌的)解决方法:
通过Application.OnMessage:
procedure TMainForm.ApplicationEventsMessage(var Msg: tagMSG;
var Handled: Boolean);
var
P: TPoint;
begin
if Msg.message = WM_LBUTTONDOWN then
if Screen.ActiveControl <> nil then
if Screen.ActiveControl.ClassNameIs('TElInpEdit') then
begin
GetCursorPos(P);
with Screen.ActiveControl do
if not PtInRect(ClientRect, ScreenToClient(P)) then
Perform(WM_KILLFOCUS, 0, 0);
end;
end;
或者对组件进行子类化:
type
TElXTree = class(ElXTree.TElXTree)
private
procedure CMMouseLeave(var Message: TMessage); message CM_MOUSELEAVE;
end;
TForm1 = class(TForm)
ElXTree1: TElXTree;
...
procedure TElXTree.CMMouseLeave(var Message: TMessage);
var
P: TPoint;
begin
GetCursorPos(P);
if not PtInRect(ClientRect, ScreenToClient(P)) then
if Screen.ActiveControl <> nil then
if Screen.ActiveControl.ClassNameIs('TElInpEdit') then
Screen.ActiveControl.Perform(WM_KILLFOCUS, 0, 0);
inherited;
end;
注意:这不是首选,因为它改变了组件的行为:只需将鼠标悬停在网格之外即可关闭就地编辑器。但我添加它是因为它可能会给其他人带来其他解决方案。
关于delphi - 如何退出就地编辑器并在 Delphi 中处理按钮?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6501417/