S L Bentall
S L Bentall

Reputation: 257

TDBEdit PopupMenu Default Behaviour

There appears to be a change in behaviour between Delphi 5 (yes I know it is very old) and Delphi 10.1 when a TDBEdit control that does NOT have its PupupMenu property set is selected and the Right Mouse Button is clicked. In Delphi 5 TDBEdit's parent controls PopupMenu is presented (assuming of course it has one) but in Delphi 10.1 a 'standard' Windows context menu is presented ['Undo', 'Cut', ... 'Right to left Reading order' etc.].

How can I get Delphi 10.1 to use a TDBEdit control's parent control's PopupMenu if it does not have one explicitly set. The application being migrated has hundereds of forms each with tens of TDBEdit controls and the thought of having to explicitly set each of their PopupMenu properties to that of thire parent control is more than a little daunting!

Upvotes: 1

Views: 196

Answers (1)

MartynA
MartynA

Reputation: 30735

You can do a simple (or, you may say, simplistic) run-time fix for this by using the OnActiveFormChange event of your application's Screen object.

It's probably easiest to put most of the necessary code in a datamodule which is Used by at least your main form.

For example add the following methods to the datamodule:

Uses [...] Forms, DBCtrls;

procedure TdmPopUp.ActiveFormChange(Sender: TObject);
begin
  FixUpDBEdits(Screen.ActiveForm);
end;

procedure TdmPopUp.FixUpDBEdits(AForm : TForm);

  procedure FixUpDBEdit(ADBEdit : TDBEdit);
  begin
    if ADBEdit.PopupMenu = Nil then
      if ADBEdit.PopupMenu <> AForm.PopupMenu then
        ADBEdit.PopupMenu := AForm.PopupMenu
  end;

  procedure FixUpDBEditsInner(AComponent : TComponent);
  var
    i : Integer;
  begin
    if AComponent is TDBEdit then
      FixUpDBEdit(TDBEdit(AComponent));
    for i := 0 to AComponent.ComponentCount - 1 do
      if AComponent.Components[i] is TDBEdit then
        FixUpDBEdit(TDBEdit(AComponent.Components[i]));
  end;

begin
  FixUpDBEditsInner(AForm);
end;

Then, all the additional code you need can go in your main form's OnCreate and OnDestroy:

procedure TForm1.FormDestroy(Sender: TObject);
begin
  Screen.OnActiveFormChange := Nil;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  Screen.OnActiveFormChange := dmPopUp.ActiveFormChange;
end;

Obviously the "hard work" is done in the FixUpDBEdit sub-procedure in the datamodule. My version simply checks that the DBEdit's PopUpMenu is not nil (in case it has been explicitly set to something), that it isn't already set to the enclosing form's PopUpMenu and then assigns it to the form's. This hasn't been soak-tested and may require some finessing, but hopefully should get you going.

Upvotes: 3

Related Questions