Tengo un Listbox que contiene una lista de archivos. ¿puedo acceder al menú contextual de Windows en el cuadro de lista para acceder a los elementos abrir, propiedades, eliminar y cambiar el nombre?Mostrar el menú predeterminado del botón derecho del mouse - Delphi
Respuesta
Kermia Compruebe la unidad JclShell
de la biblioteca JEDI JCL, dentro de esta unidad existe una función llamada DisplayContextMenu
que muestra el menú contextual asociado a un archivo. esta función encapsula las llamadas a la interfaz IContextMenu y hace que su trabajo sea más fácil.
function DisplayContextMenu(const Handle: HWND; const FileName: string;
Pos: TPoint): Boolean;
Recomendaría mirar algo como tpShellShock cuando quiera mostrar controles tipo caparazón en su aplicación Delphi. Ofrece vistas en árbol, listas de vistas, etc. que se pueden conectar de manera similar a Windows Explorer. Mostrará los íconos apropiados para los archivos. Estoy seguro de que ofrece las instalaciones de las que también hablas.
Puede que necesite algún trabajo de transferencia si está en un Unicode Delphi moderno, pero cuando lo he hecho, resultó ser relativamente sencillo.
Sin duda hay otras bibliotecas que ofrecen controles de shell, este es el único con el que estoy familiarizado.
De lo contrario, si desea seguir con su solución actual, es más fácil implementar sus propias acciones de menú. Abrir y Propiedades son simples llamadas a ShellExecute con el verbo apropiado. Eliminar es una llamada a DeleteFile y Rename es una llamada a MoveFile.
Compruebe la interfaz IContextMenu. Pero tenga en cuenta que el shell de Windows no identifica sus objetos por nombre de archivo, en realidad no podrían ser archivos. Utiliza una concatenación de identificadores, y es posible que necesite obtener la lista de identificación de elementos que se le asigna a un archivo antes de invocar algunas funciones de shell en él.
Parece que le permite enumerar lo que el shell considera que está en el menú contextual. A medida que lo lea, igual necesitará llenar el menú usted mismo, y luego invocar comandos a través de esta interfaz en respuesta a los eventos Delphi OnClick. ¿Es eso correcto? –
+1 Sin duda parece una buena forma de implementar los controladores OnClick. –
Sí, tienes que crear el menú (al menos te permite usar cualquier tipo de menú que prefieras), de todos modos te da el comando que cada elemento admite y te permite invocar el comando correcto como lo define el intérprete de comandos. Tampoco funciona en archivos, aunque eso va más allá de la pregunta del usuario. –
Aquí es un ejemplo de implementación utilizando caso de un cuadro de lista, que se rellena con nombres de archivo en el directorio del proyecto del 'OnContextPopup', para poner en marcha el menú contextual de un archivo cuando se hace clic derecho en su nombre:
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. menú contextual con el botón derecho del mouse para datagridview
- 2. Menú contextual del botón derecho en la bandeja del sistema
- 3. Cómo agregar un elemento de menú al menú contextual predeterminado del botón derecho
- 4. Jquery/JS prevenir menú del botón derecho en los navegadores
- 5. Menú contextual de Stardand en el widget de texto de Python TKinter cuando se presiona el botón derecho del mouse
- 6. XUL: la creación de un elemento del menú contextual del botón derecho sólo hipervínculos
- 7. jQuery menú del botón
- 8. Qt4: eventos del botón del mouse de QTableView no detectados
- 9. Acceso al icono del dock Opciones de menú del botón derecho con AppleScript
- 10. ¿Cómo cambio el cursor del mouse cuando el botón izquierdo del mouse está presionado?
- 11. Evento de vinculación al clic derecho del mouse
- 12. Cómo enlazar con el botón derecho del mouse, haga clic en knockoutJs?
- 13. JEl comportamiento del botón derecho como en cualquier Filebrowser
- 14. Botón Agregar al lado derecho del encabezado
- 15. Ocultar las opciones predeterminadas en el menú contextual del botón derecho en flex
- 16. Detección de clic con el botón derecho del mouse en forma de SVG en JavaScript no funciona
- 17. ¿Cómo puedo mostrar NSMenu en el cursor del mouse?
- 18. Delphi agregar elemento de menú en Windows Explorer clic derecho
- 19. Cómo mostrar un menú contextual al hacer clic con el botón derecho en un elemento de menú
- 20. haga clic derecho en el menú contextual jquery
- 21. jQuery Menú contextual con el botón derecho Ayuda!
- 22. ¿Agregar al menú contextual del navegador?
- 23. Botón del mouse presionado NSMenu en 10.5
- 24. Intercambiando los botones izquierdo y derecho del mouse en .NET
- 25. NotifyIcon.BalloonTipClich evento y botones del mouse
- 26. Cómo personalizar el botón del menú y los elementos del menú
- 27. ¿Cómo configuro la cantidad de elementos en el menú del búfer del mouse en Emacs?
- 28. Qt - Hoja de estilo para el botón personalizado del mouse sobre el botón y el botón
- 29. Intellij haga clic derecho en los problemas del menú contextual en Ubuntu
- 30. Disparador clic con el botón derecho
+1 ¿Qué pasa como el parámetro Handle? ¿Para qué se usa esto? –
@David puede pasar el control de su formulario, este identificador se utiliza en el 'IContextMenu.InvokeCommand' que recibe una estructura' CMINVOKECOMMANDINFO' http://msdn.microsoft.com/en-us/library/bb773215%28v= vs.85% 29.aspx. – RRUZ
¿Hay alguna versión más reciente de esta unidad? (para Delphi 2010) – Kermia