Mostrar el cuadro de diálogo "Abrir con..."

4689 vistas

Puede que en algún momento necesitemos mostrar el cuadro de diálogo "Abrir con..." que se abre cuando un usuario intenta ejecutar un fichero sin tener asociada la extensión a ninguna aplicación. Lamentablemente no hay ninguna función del API de Windows clásica para ello.

Este cuadro de diálogo está implementado en la DLL shell32.dll y sólo es usada por la shell misma. Sin embargo es posible llamarlo de forma sencilla mediante ShellExecute.

Aquà mostramos un procedimiento que efectua esta operación para el nombre de un fichero pasado por parámetro:



delphi
  1. uses
  2.   SysUtils, ShellAPI, Windows;
  3.  
  4. procedure OpenWith(const Filename: string);
  5. { llama al cuadro de diálogo "Abrir con..." para el fichero pasado por parámetro }
  6. begin
  7.   ShellExecute(0, 'open', 'rundll32.exe',
  8.     PChar('shell32.dll,OpenAs_RunDLL ' + Filename),
  9.     PChar(ExtractFilePath(Filename)), SW_SHOWNORMAL);
  10. end;



Esta función se usa amenudo después de haber intentado abrir un fichero con ShellExecute. Veamos una función que realiza las dos llamadas si son necesarias, claro:



delphi
  1. uses
  2.   SysUtils, ShellAPI, Windows;
  3.  
  4. function OpenFile(const Filename: string; const Handle: THandle = 0): boolean;
  5. { intenta abrir el fichero pasado por parámetro con el programa asociado a su
  6.   extensión (si lo hay). En caso de que no existiera asociación, mostrarÃa
  7.   el cuadro de diálogo "Abrir con..." }
  8. var
  9.   errCode: Cardinal;
  10.   filePath: string;
  11. begin
  12.   { guardamos la ruta para evitar tener que hacerlo 2 veces }
  13.   filePath := ExtractFilePath(Filename);
  14.  
  15.   { intentamos abrir el archivo }
  16.   errCode := ShellExecute(Handle, 'Open', PChar(Filename), '',
  17.     PChar(filePath), SW_SHOWNORMAL);
  18.  
  19.   { si la tentativa termina con el código SE_ERR_NOASSOC, quiere decir que no hay programa asociado }
  20.   if errCode = SE_ERR_NOASSOC then
  21.     { en este caso, mostramos el diálogo }
  22.     errCode := ShellExecute(0, 'open', 'rundll32.exe',
  23.           PChar('shell32.dll,OpenAs_RunDLL ' + Filename),
  24.           PChar(filePath), SW_SHOWNORMAL);
  25.  
  26.   { si el código revuelto por ShellExecute es superior a 32 indica que la operación ha tenido éxito, sino es un código de error }
  27.   Result := errCode > 32;
  28. end;