3

私の Delphi 2009 アプリケーションには、次のウィンドウがあります。

ここに画像の説明を入力

TTabSheet を持つ TPageControl と、すべてのシートで動作する下部のボタンがあります。

TTabSheet の左側には TElXTree (LMD によるツリー/グリッド コンポーネント) があり、TTabSheet の右側には、このシートだけに固有のボタンを含む TPanel があります。

TElXTree で行を選択し、いずれかのボタン セットのいずれかのボタンをクリックすると、すべてのボタンが正常に機能します。

TElXTree 内で、"Text" というラベルの付いた列は、TElXtree に付属の Inplace-Editor で編集できます。テキストをクリックすると、編集モードになります。

編集モードで、TElXTree の任意の場所 (チェックボックスなど) をクリックすると、エディターが終了し、コマンドが処理されます (つまり、チェックボックスをオンまたはオフにします)。ただし、編集モードでは、ボタンのいずれかのセットのいずれかのボタンをクリックすると、単にインプレース エディターが終了し、ボタンは処理されません。次に、そのボタンを処理するには、もう一度ボタンをクリックする必要があります。

これらのボタンの 1 つをクリックして、インプレース エディターを終了し、ボタンを処理できるようにする、ここで行っていない、または理解していない簡単なことはありますか?


ファローアップ:

@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;
4

2 に答える 2

1

それは確かにバグのように見えます。考えられる 2 つの (厄介な) 回避策:

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;

注: これは、コンポーネントの動作を変更するため、推奨されません。マウスをグリッドの外に置くだけで、インプレース エディターが閉じます。しかし、他のソリューションに他の人を連れてくるかもしれないので、私はそれを追加しました.

于 2011-06-28T19:41:21.603 に答える
0

フォーカスの問題である可能性があります。フォームの OnExit OnEnter メソッドで記述したコードを見てください。

于 2011-06-28T14:04:53.037 に答える