gpt4 book ai didi

delphi - 如何在 Delphi 2009 中创建最近使用的文件列表?

转载 作者:行者123 更新时间:2023-12-03 15:47:17 27 4
gpt4 key购买 nike

我有一个 TActionManager 和一个 TActionMainMenuBar,并且我知道如何将每个 MRU 文件的 TActionClientItem 添加到主菜单栏。但是我是否必须为列表中的每个 MRU 文件创建单独的操作?或者有没有一种方法可以只创建一个操作,并根据单击的 MRU 文件以某种方式将标签或其他内容传递给该操作的 OnExecute 事件?

Delphi 的帮助说明:“有关 MRU 列表、示例代码以及在列表中查找操作的方法的更多信息,请参阅在线帮助中的 FindItemByAction 和 FindItemByCaption。”但我在这些主题中找不到任何有用的内容,当然也找不到示例代码。我真的很想避免使用第三方组件来完成此任务。

最佳答案

我使用的代码如下,但您可能需要修改一些代码。唯一明显缺少的是 IAbbreviatedFileName,它本质上封装了 Windows API 函数 PathCompactPath。您需要某种方法来缩写很长的文件名,这是我的首选。抱歉,有这么大的代码转储,但有人可能会在其中找到有用的东西!

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);

关于delphi - 如何在 Delphi 2009 中创建最近使用的文件列表?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4605664/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com