delphi - 如何退出就地编辑器并在 Delphi 中处理按钮?

标签 delphi button inplace-editing

在我的 Delphi 2009 应用程序中,我有这个窗口:

enter image description here

它有一个 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/

相关文章:

android - 如何为按钮选择器设置不同的主题?

linux - 使用非 GNU awk 保存修改

delphi - 如何使用Delphi标准确认对话框但带有复选框 "Don'不要再问我“?

Delphi,如何在TList中释放记录

delphi - 将 URL 修剪为根

delphi - 如何从 TEdit 获取 FastReport (Delphi) 的数据?

html - Border-Box 100% 宽度计算 - 文本不适合

javascript - 使用angularjs更改按钮样式

ruby - 如何使用 Ruby 的命令行就地编辑模式从文本文件中删除行