Frage

Ich habe eine TActionManager und ein TActionMainMenuBar, und ich weiß, wie man eine TActionClientItem für jede MRU-Datei in der Hauptmenüleiste hinzuzufügen. Aber habe ich eine separate Aktion für jede MRU-Datei in der Liste erstellen? Oder ist es eine Möglichkeit, nur eine Aktion zu erstellen, und irgendwie einen Tag oder etwas zu dem Ereignis OnExecute Basis der Aktion übergeben, auf der MRU-Datei geklickt wurde?

Delphi Hilfe sagt: „Für weitere Informationen über MRU-Listen, Beispielcode und Methoden für die Aktionen in Listen zu finden, finden Sie FindItemByAction und FindItemByCaption in der Online-Hilfe.“ Aber ich kann nicht alles in diesen Themen finden, die hilfreich ist, und schon gar nicht Beispielcode. Ich möchte wirklich vermeiden, dass eine dritte Partei Komponente dieses zu erhalten getan.

War es hilfreich?

Lösung

Sie werden über einen separaten TAction zu jedem Menüpunkt haben ohnehin so, dass sie unterschiedliche Caption Werte haben können. Aber Sie haben keine separaten OnExecute Event-Handler haben. Der Event-Handler wird einen Verweis auf die Aktion in seinen Sender Parametern erhalten. Verwenden Sie die Tag Eigenschaft des Absenders in einer Liste, in der die Dateinamen gehalten werden verweisen. (Verwenden Sie die Caption Eigenschaft nicht, welche Datei geöffnet zu entdecken,., Dass einengt Sie tun nette Dinge wie Beschleuniger Hinzufügen oder Abkürzen unhandlich Pfade)

Das ist, was die Dokumentation setzt voraus, würden Sie auch tun. FindItemByAction kehrt die erste Element, dass die gegebene Aktion ist an. Wenn Sie eine einzelne Aktion auf alle Ihre MRU Menüpunkte anbringen, dann werden Sie nicht in der Lage sein, diese Funktion zu verwenden, um Ihnen zu sagen, welches Menü ausgewählt wurde. Auf der anderen Seite würde der Menüpunkt nicht hält mehr Informationen als die damit verbundene Aktion würde, so dass ich keinen Grund zu sehen für den Menüpunkt sowieso sehen. Verwenden Sie einfach die Informationen aus der Aktion direkt an.

Andere Tipps

Ich verwende Code wie folgt, aber man kann es sich um einige klopfen müssen. Das einzige, was fehlt, sehr offensichtlich ist IAbbreviatedFileName, die im Wesentlichen der Windows-API-Funktion PathCompactPath einpackt. Sie werden eine Möglichkeit, sehr lange Dateinamen abkürzen wollen und das ist meine bevorzugte Wahl. Es tut uns so großen Dump-Code, aber jemand kann etwas Gebrauch innerhalb finden!

type
  TFileAwareMenuItem = class(TMenuItem)
  private
    FFileName: string;
  public
    property FileName: string read FFileName write FFilename;
  end;

  TMRU = class
  private
    FParent: array of TMenuItem;
    FMenuItemStart: array of TMenuItem;
    FMenuItemFinish: array of TMenuItem;
    FMenuCount: Integer;
    FRegistryKey: string;
    FOwner: TCustomForm;
    FMRUFileNames: TStringList;
    FAction: TAction;
    function GetCount: Integer;
    function GetItem(Index: Integer): string;
    procedure SetAction(Value: TAction);
    procedure Read;
    procedure Write;
    procedure UpdateMenu;
  public
    constructor Create(const RegistrySubKey: string; const Owner: TCustomForm);
    destructor Destroy; override;
    procedure RegisterBoundingMenuItems(Start, Finish: TMenuItem);
    procedure Add(const FileName: string);
    procedure Delete(ItemNum: Integer);
    property Count: Integer read GetCount;
    property Action: TAction read FAction write SetAction;
    property Items[Index: Integer]: string read GetItem; default;
  end;

const
  MRUSize=9;
  AppRegistryKey='??put your apps registry key here??';

var
  Registry: TRegistry;

constructor TMRU.Create(const RegistrySubKey: string; const Owner: TCustomForm);
begin
  inherited Create;
  FRegistryKey := Format('%s\%s', [AppRegistryKey, RegistrySubKey]);
  FOwner := Owner;
  FMRUFileNames := TStringList.Create;
  Read;
end;

destructor TMRU.Destroy;
begin
  Write;
  FreeAndNil(FMRUFileNames);
  inherited;
end;

procedure TMRU.RegisterBoundingMenuItems(Start, Finish: TMenuItem);
begin
  inc(FMenuCount);
  SetLength(FParent, FMenuCount);
  SetLength(FMenuItemStart, FMenuCount);
  SetLength(FMenuItemFinish, FMenuCount);

  FMenuItemStart[FMenuCount-1] := Start;
  FMenuItemFinish[FMenuCount-1] := Finish;
  Assert(Start.Parent=Finish.Parent);
  FParent[FMenuCount-1] := Start.Parent;

  UpdateMenu;
end;

procedure TMRU.UpdateMenu;
var
  Intf: IAbbreviatedFileName;
  i, j: Integer;
  FileName: string;
  NewMenuItem: TFileAwareMenuItem;
begin
  Intf := FOwner as IAbbreviatedFileName;
  for i := 0 to FMenuCount-1 do begin
    j := FMenuItemStart[i].MenuIndex+1;
    while j<FMenuItemFinish[i].MenuIndex do begin
      FParent[i][j].Free;
    end;
    for j := 0 to Count-1 do begin
      NewMenuItem := TFileAwareMenuItem.Create(FMenuItemStart[i].Owner);
      NewMenuItem.Action := Action;
      NewMenuItem.FileName := FMRUFileNames[j];
      FileName := ReplaceString(Intf.AbbreviatedFileName(NewMenuItem.FileName, False), '&', '&&');
      NewMenuItem.Caption := Format('&%d. %s', [j+1, FileName]);
      FParent[i].Insert(FMenuItemFinish[i].MenuIndex, NewMenuItem);
    end;
    FMenuItemStart[i].Visible := (Count>0) and (FMenuItemStart[i].MenuIndex>0);
    FMenuItemFinish[i].Visible := (FMenuItemFinish[i].MenuIndex<FParent[i].Count-1);
  end;
end;

procedure TMRU.Read;
var
  i: Integer;
  s: string;
begin
  if Registry.OpenKey(HKEY_CURRENT_USER, FRegistryKey) then begin
    FMRUFileNames.Clear;
    for i := 0 to MRUSize-1 do begin
      s := Registry.ReadString(IntToStr(i+1), '');
      if s<>'' then begin
        FMRUFileNames.Add(s);
      end;
    end;
    UpdateMenu;
    Registry.CloseKey;
  end;
end;

procedure TMRU.Write;
var
  i: Integer;
  ValueName: string;
begin
  if Registry.OpenKey(HKEY_CURRENT_USER, FRegistryKey, KEY_ALL_ACCESS, True) then begin
    Registry.WriteInteger('Size', MRUSize);
    for i := 0 to MRUSize-1 do begin
      ValueName := IntToStr(i+1);
      if i<Count then begin
        Registry.WriteString(ValueName, FMRUFileNames.Strings[i]);
      end else begin
        if Registry.ValueExists(ValueName) then begin
          Registry.DeleteValue(ValueName);
        end;
      end;
    end;
    Registry.CloseKey;
  end;
end;

function TMRU.GetCount: Integer;
begin
  Result := Min(FMRUFileNames.Count, MRUSize);
end;

function TMRU.GetItem(Index: Integer): string;
begin
  Result := FMRUFileNames[Index];
end;

procedure TMRU.SetAction(Value: TAction);
begin
  if Value<>FAction then begin
    FAction := Value;
    UpdateMenu;
  end;
end;

procedure TMRU.Add(const FileName: string);
var
  i, Index: Integer;
begin
  Index := -1;
  for i := 0 to FMRUFileNames.Count-1 do begin
    if FileNamesEqual(FileName, FMRUFileNames[i]) then begin
      Index := i;
      break;
    end;
  end;

  if Index<>-1 then begin
    FMRUFileNames.Move(Index, 0);
  end else begin
    FMRUFileNames.Insert(0, FileName);
    if FMRUFileNames.Count>MRUSize then begin
      FMRUFileNames.Delete(FMRUFileNames.Count-1);
    end;
  end;

  UpdateMenu;
  Write;
end;

procedure TMRU.Delete(ItemNum: Integer);
begin
  FMRUFileNames.Delete(ItemNum);
  UpdateMenu;
end;

initialization
  Registry := TRegistry.Create;
  if not Registry.KeyExists(AppRegistryKey) then begin
    Registry.CreateKey(AppRegistryKey);
  end;

finalization
  FreeAndNil(Registry);
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top