How can I prevent collateral calls from Colliding / Interacting in Delphi?

I use the standard actions Cut, Copy, Paste in the main menu. They have shortcuts Ctrl-X, Ctrl-Cand Ctrl-V.

When I open a modal form, for example. FindFilesForm.ShowModal, then all the shortcuts work from the form.

But when I open a modeless form, for example. FindFilesForm.Show, then the shortcuts do not work.

I would think that these actions should work if FindFilesForm is an active form. This modality should have nothing to do with it, or am I mistaken in my thoughts?

Never, how can I get shortcuts for working in a non-modal form?


After Carey's answer, I examined it further. This is not a problem with some controls, for example. TMemo or TEdit.

But this is for some others. In particular, those where this occurs include:

  • text in TComboBox
  • text in TFindDialog
  • TElTreeInplaceEdit control, part of LMD ElPack

I will see if there are others and add them to the list.

All this refers to important non-modal forms in my program.

So I still need a solution.


Good. I really need help with this. Thus, this becomes the first question I place the reward on.

My discussion with Carey, which goes through his answer, and the comments there describe my problem in more detail.

And as I mentioned in one of these comments, the related issue seems to be discussed here.

, Ctrl-X, Ctrl-C Ctrl-V TComboBox TFindDialog . , , TElTreeInplaceEdit .

, , . , - .

, , , -, , . , .

, .


Mghie , , OnExecute ActionListUpdate . .

actionlist , , . , Ctrl+A Ctrl-Y , , , . .

, , , IsShortcut. OnExecute, . , , .

, , , , . . ( , , , , 6 .)

+3
3

, : , , Delphi ( ).

: , TMemo TComboBox . . , Ctrl + A, .

TActionList , . , .

Edit . , , , . . , , , .


, TCustomEdit. TEditAction.HandlesTarget() StdActns.pas. , inplace , . , . , - , VCL - . , , , . . , , .

, OnExecute . , "":

procedure TMainForm.EditPaste1Execute(Sender: TObject);
var
  FocusWnd: HWND;
begin
  FocusWnd := GetFocus;
  if IsWindow(FocusWnd) then
    SendMessage(FocusWnd, WM_PASTE, 0, 0);
end;

Cut (WM_CUT) (WM_COPY). . , , . - . , EM_GETSEL, , .

Edit:

, ( Delphi 2009): TWinControl.IsMenuKey() - , . , CM_APPKEYDOWN, , . : , (. TApplication.IsShortCut()). ShowModal() , , , .

Edit:

- , - . , , Enabled , , .

:

procedure TForm1.ActionList1Update(Action: TBasicAction; var Handled: Boolean);
var
  IsEditCtrl, HasSelection, IsReadOnly: boolean;
  FocusCtrl: TWinControl;
  FocusWnd: HWND;
  WndClassName: string;
  SelStart, SelEnd: integer;
  MsgRes: LRESULT;
begin
  if (Action = EditCut1) or (Action = EditCopy1) or (Action = EditPaste1) then
  begin
    IsEditCtrl := False;
    HasSelection := False;
    IsReadOnly := False;

    FocusCtrl := Screen.ActiveControl;
    if (FocusCtrl <> nil) and (FocusCtrl is TCustomEdit) then begin
      IsEditCtrl := True;
      HasSelection := TCustomEdit(FocusCtrl).SelLength > 0;
      IsReadOnly := TCustomEdit(FocusCtrl).ReadOnly;
    end else begin
      FocusWnd := GetFocus;
      if IsWindow(FocusWnd) then begin
        SetLength(WndClassName, 64);
        GetClassName(FocusWnd, PChar(WndClassName), 64);
        WndClassName := PChar(WndClassName);
        if AnsiCompareText(WndClassName, 'EDIT') = 0 then begin
          IsEditCtrl := True;
          SelStart := 0;
          SelEnd := 0;
          MsgRes := SendMessage(FocusWnd, EM_GETSEL, WPARAM(@SelStart),
            LPARAM(@SelEnd));
          HasSelection := (MsgRes <> 0) and (SelEnd > SelStart);
        end;
      end;
    end;

    EditCut1.Enabled := IsEditCtrl and HasSelection and not IsReadOnly;
    EditCopy1.Enabled := IsEditCtrl and HasSelection;
    // don't hit the clipboard three times
    if Action = EditPaste1 then begin
      EditPaste1.Enabled := IsEditCtrl and not IsReadOnly
        and Clipboard.HasFormat(CF_TEXT);
    end;
    Handled := TRUE;
  end;
end;

, , , , , :

IsReadOnly := GetWindowLong(FocusWnd, GWL_STYLE) and ES_READONLY <> 0;

. mghie, , , ,

+2

, StackOverflow. Uwe DelphiPool. borland.public.delphi.objectpascal:

() .

, , :

, . , , .

, , .

Peter Below , , , , .

( ), "ctrl is TCustomFrame" "ctrl is TControl", . , :

public
Function IsShortcut( var Message: TWMKey): Boolean; override;

Function TMyform.IsShortcut( var Message: TWMKey): Boolean; 
Var 
  ctrl: TWinControl; 
  comp: TComponent; 
  i: Integer; 
Begin 
  ctrl := ActiveControl; 
  If ctrl <> Nil Then Begin 
    Repeat 
      ctrl := ctrl.Parent 
    Until (ctrl = nil) or (ctrl Is TControl); 
    If ctrl <> nil Then Begin 
      For i:= 0 To ctrl.componentcount-1 Do Begin 
        comp:= ctrl.Components[i]; 
        If comp Is TCustomActionList Then Begin 
          result := TCustomActionList(comp).IsShortcut( message ); 
          If result Then 
            Exit; 
        End; 
      End;   
    End; 
  End; 
//  inherited; { Originally I had this, but it caused multiple executions }
End;   

.

, , . FrameEnter, . , , Peter .

, , .

mghie edit , .

+3

Delphi 2009 ( 3 4), 64- Vista. Form2 (Form2.Show;). TMemo Form2. Ctrl-X, Ctrl-V Ctrl-C .

, TMainMenu Form2.

, TMainMenu TActionList. "" "", "", "". EditCopy, EditCut EditPaste. , , . , Ctrl-C, Ctrl-X Ctrl-V.

- .

+1
source

Source: https://habr.com/ru/post/1724826/


All Articles