我有一個包含文件列表的列表框。我可以訪問列表框中的Windows右鍵菜單來訪問打開,屬性,刪除和重命名項目嗎?顯示默認的右鍵菜單 - Delphi
回答
Kermia從JEDI JCL庫檢查JclShell
單元,本單元內部存在一個名爲DisplayContextMenu
的函數,它顯示與文件關聯的上下文菜單。這個函數將對IContextMenu接口的調用封裝起來,使你的工作變得更容易。
function DisplayContextMenu(const Handle: HWND; const FileName: string;
Pos: TPoint): Boolean;
當你想在你的Delphi應用程序中顯示類似控件的shell時,我建議你看看類似tpShellShock的東西。它提供了樹視圖,列表視圖等,它們可以像Explorer Windows一樣連接在一起。它將顯示文件的相應圖標。我相信它也提供了你所談論的設施。
如果您使用的是現代Unicode Delphi,那麼可能需要一些移植工作,但是當我這樣做時,它證明是相對簡單的。
毫無疑問,還有其他的庫提供了shell控件,這只是我熟悉的一個。
否則,如果您想堅持使用您當前的解決方案,那麼實現您自己的菜單操作是最容易的。打開和屬性只是簡單的調用ShellExecute與適當的動詞。 Delete是對DeleteFile的調用,Rename是對MoveFile的調用。
檢查IContextMenu接口。但請注意,Windows shell不會通過文件名識別它的對象 - 實際上它們不能是文件。它使用ID的串聯,並且您可能需要在調用其上的某些shell函數之前獲取文件所支持的項目ID列表。
看起來像它可以讓你枚舉shell認爲是在上下文菜單中。在我閱讀它時,您仍然需要自己填充菜單,然後通過此界面調用命令來響應Delphi OnClick事件。那是對的嗎? – 2011-03-12 11:45:19
+1當然看起來是實現OnClick處理程序的好方法。 – 2011-03-12 13:38:51
是的,你必須創建菜單(至少它允許你使用任何你喜歡的菜單),無論如何它給你每個元素支持的命令,並讓你調用shell定義的正確命令。它只對文件不起作用,儘管這超出了用戶的問題。 – 2011-03-12 15:17:33
下面是使用一個列表框,它是在項目目錄中填入文件名的「OnContextPopup」事件,啓動的文件的快捷菜單上的名字時,右鍵單擊一個實現示例:
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;
- 1. 如何從Delphi 2010中的默認右鍵菜單中刪除項目?
- 2. 右鍵單擊後不顯示菜單
- 3. 如何禁用瀏覽器的默認右鍵單擊菜單
- 4. 在WPF GridView中默認的右鍵單擊上下文菜單
- 5. 右鍵菜單不顯示在Firefox(smartgwt)
- 6. 抑制瀏覽器默認右鍵單擊菜單 - 優化?
- 7. 抑制datagridview中的默認右鍵菜單vb.net
- 8. 如何自定義windows默認的右鍵彈出菜單
- 9. UIButton默認點擊右鍵菜單點擊導航條
- 10. 右鍵點擊默認silverlight上下文菜單
- 11. 如何正確顯示的基於Internet Explorer的右鍵菜單
- 12. 菜單左,右鍵菜單
- 13. 從左到右顯示從右到左的菜單子菜單
- 14. 顯示SWT TableItem的右鍵單擊菜單?
- 15. Tampermonkey - 右鍵菜單
- 16. QTreeWidget右鍵菜單
- 17. NSWindow - 右鍵菜單
- 18. 在flex中的右鍵單擊上下文菜單中隱藏默認選項
- 19. 右鍵單擊菜單項並顯示選項
- 20. 在WinRT中顯示彈出式右鍵單擊樣式菜單
- 21. Java JList右鍵單擊Linux(Ubuntu 12.04)沒有顯示菜單
- 22. JList右鍵單擊顯示菜單(使用,放下,取消)
- 23. NSStatusItem右鍵單擊菜單
- 24. NSEvent單擊右鍵菜單
- 25. DataGridView右鍵菜單/複製示例?
- 26. 如何右鍵單擊菜單項時顯示上下文菜單
- 27. 默認表單不顯示
- 28. Raphael:禁用右鍵單擊默認上下文菜單不起作用
- 29. 如何將菜單項添加到默認右鍵單擊devexpress treelist
- 30. 如何在cimg顯示窗口中顯示右鍵單擊菜單?
+1你作爲Handle參數傳遞了什麼?它是幹什麼用的? – 2011-03-12 19:22:52
@David你可以傳遞你的表單的句柄,這個句柄用在'IContextMenu.InvokeCommand'中,它接收'CMINVOKECOMMANDINFO'結構http://msdn.microsoft.com/en-us/library/bb773215%28v= vs.85%29.aspx。 – RRUZ 2011-03-12 19:48:29
這個單位有任何更新的版本? (德爾福2010) – Kermia 2011-03-13 09:39:50