显示默认的右键菜单-Delphi

问题描述 投票:8回答:4

我有一个包含文件列表的列表框。我可以访问列表框中的Windows右键菜单来访问打开,属性,删除和重命名项目吗?

delphi properties menu right-click
4个回答
9
投票

Kermia从JEDI JCL库检查JclShell单元,该单元内部存在一个称为JclShell的函数,该函数显示与文件关联的上下文菜单。此函数封装了对IContextMenu接口的调用,使您的工作更加轻松。

DisplayContextMenu

5
投票

检查function DisplayContextMenu(const Handle: HWND; const FileName: string; Pos: TPoint): Boolean; 接口。但是请注意,Windows Shell不能通过文件名来标识其对象-实际上它们不能是文件。它使用ID的串联,在调用文件上的一些Shell函数之前,您可能需要获取文件所属的ID列表。


3
投票

这里是一个使用列表框的'OnContextPopup'事件的实现示例,该事件在项目目录中填充有文件名,用鼠标右键单击文件名可以启动文件的快捷菜单:

IContextMenu

2
投票

[我建议您在Delphi应用程序中显示像shell这样的控件时,建议使用type TForm1 = class(TForm) ListBox1: TListBox; procedure FormCreate(Sender: TObject); procedure ListBox1ContextPopup(Sender: TObject; MousePos: TPoint; var Handled: Boolean); private protected procedure WndProc(var Msg: TMessage); override; public end; var Form1: TForm1; implementation uses shlobj, comobj; {$R *.dfm} procedure TForm1.FormCreate(Sender: TObject); var SearchRec: TSearchRec; begin ListBox1.Clear; // populate list box with files in the project folder if FindFirst(ExtractFilePath(Application.ExeName) + '*.*', 0, SearchRec) = 0 then repeat ListBox1.Items.Add(SearchRec.Name); until FindNext(SearchRec) <> 0; FindClose(SearchRec); end; var // Required to handle messages for owner drawn items, as in 'SendTo' menu. // Also used as a flag in WndProc to know if we're tracking a shortcut menu. ContextMenu2: IContextMenu2 = nil; procedure TForm1.ListBox1ContextPopup(Sender: TObject; MousePos: TPoint; var Handled: Boolean); var Item: Integer; DeskFolder, Folder: IShellFolder; Eaten, Attributes: ULONG; pIdl, FolderpIdl: PItemIDList; ContextMenu: IContextMenu; Menu: HMENU; Pos: TPoint; Cmd: DWORD; CommandInfo: TCMInvokeCommandInfo; begin Item := (Sender as TListBox).ItemAtPos(MousePos, True); Handled := Item <> -1; if not Handled then Exit; TListBox(Sender).ItemIndex := Item; // IShellFolder for Desktop folder (root) OleCheck(SHGetDesktopFolder(DeskFolder)); // Item ID List for the folder that the file is in Attributes := 0; OleCheck(DeskFolder.ParseDisplayName(Handle, nil, PWideChar(WideString(ExtractFilePath(Application.ExeName))), Eaten, FolderpIdl, Attributes)); // IShellFolder for the folder the file is in OleCheck(DeskFolder.BindToObject(FolderpIdl, nil, IID_IShellFolder, Folder)); CoTaskMemFree(FolderpIdl); // Item ID List for the file, relative to the folder it is in Attributes := 0; OleCheck(Folder.ParseDisplayName(Handle, nil, PWideChar(WideString(ExtractFileName(TListBox(Sender).Items[Item]))), Eaten, pIdl, Attributes)); // IContextMenu for the relative Item ID List OleCheck(Folder.GetUIObjectOf(Handle, 1, pIdl, IID_IContextMenu, nil, ContextMenu)); CoTaskMemFree(pIdl); Menu := CreatePopupMenu; try // Populate our menu with shortcut items OleCheck(ContextMenu.QueryContextMenu(Menu, 0, 1, $7FFF, CMF_EXPLORE)); // ContextMenu2 used in WndProc ContextMenu.QueryInterface(IID_IContextMenu2, ContextMenu2); try Pos := TWinControl(Sender).ClientToScreen(MousePos); // launch the menu Bool(Cmd) := TrackPopupMenu(Menu, TPM_LEFTBUTTON or TPM_RIGHTBUTTON or TPM_RETURNCMD, Pos.X, Pos.Y, 0, Handle, nil); finally // clear so that we don't intervene every owner drawn menu item message in // WndProc ContextMenu2 := nil; end; // Invoke command if we have one if Bool(Cmd) then begin FillChar(CommandInfo, SizeOf(CommandInfo), 0); CommandInfo.cbSize := SizeOf(CommandInfo); CommandInfo.hwnd := Handle; CommandInfo.lpVerb := MakeIntResource(Cmd - 1); CommandInfo.nShow := SW_SHOWNORMAL; OleCheck(ContextMenu.InvokeCommand(CommandInfo)); end; finally DestroyMenu(Menu); end; end; procedure TForm1.WndProc(var Msg: TMessage); begin if ((Msg.Msg = WM_INITMENUPOPUP) or (Msg.Msg = WM_DRAWITEM) or (Msg.Msg = WM_MEASUREITEM)) and Assigned(ContextMenu2) then ContextMenu2.HandleMenuMsg(Msg.Msg, Msg.WParam, Msg.LParam) else inherited; end; 之类的东西。它提供树状视图,列表视图等,可以像Explorer Windows一样将它们连接在一起。它将显示文件的适当图标。我确信它也提供您所谈论的设施。

如果您使用的是现代Unicode Delphi,可能需要进行一些移植工作,但是当我这样做时,事实证明它相对简单。

毫无疑问,还有其他提供shell控件的库,这只是我所熟悉的库。

否则,如果要坚持使用当前的解决方案,最简单的方法就是实施自己的菜单操作。 Open和Properties只是使用适当动词对ShellExecute的简单调用。删除是对DeleteFile的调用,重命名是对MoveFile的调用。

© www.soinside.com 2019 - 2024. All rights reserved.