카테고리 없음

[윈도우즈 API] 연결(association)된 프로그램이 없다면 '연결 프로그램' 화면 띄우기

쇼핑스크래퍼3 2023. 8. 30. 08:31
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ShellAPI;

type
  TForm1 = class(TForm)
    OpenDialog1: TOpenDialog;
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

// ShellExecute()의 리턴코드에 대한 메시지
function ShowShellExecuteError(i: integer): String;
begin
  case i of 0: result := 'The operating system is out of memory or resources.';
    ERROR_FILE_NOT_FOUND: result := 'The specified file was not found.';
    ERROR_PATH_NOT_FOUND: result := 'The specified path was not found.';
    ERROR_BAD_FORMAT: result := 'The .EXE file is invalid (non-Win32 .EXE or error in .EXE image).';
    SE_ERR_ACCESSDENIED: result := 'The operating system denied access to the specified file.';
    SE_ERR_ASSOCINCOMPLETE: result := 'The filename association is incomplete or invalid.';
    SE_ERR_DDEBUSY: result := 'The DDE transaction could not be completed because other DDE transactions were being processed.';
    SE_ERR_DDEFAIL: result := 'The DDE transaction failed.';
    SE_ERR_DDETIMEOUT: result := 'The DDE transaction could not be completed because the request timed out.';
    SE_ERR_DLLNOTFOUND: result := 'The specified dynamic-link library was not found.';
    //SE_ERR_FNF          : result:='The specified file was not found.';
    SE_ERR_NOASSOC           : result:='Unbekannter Extender.';
    SE_ERR_OOM: result := 'There was not enough memory to complete the operation.';
    //SE_ERR_PNF          : result:='The specified path was not found.';
    SE_ERR_SHARE: result := 'A sharing violation occurred.';
  end;
end;

procedure ShellExecuteWithDlg(PathName, Parameters: String);
var
  FileName, DirName: String;
  code: integer;
begin
  FileName := ExtractFileName(PathName);
  DirName  := ExtractFilePath(PathName);

  code := ShellExecute(Application.handle,
             Pchar('open'),
             Pchar(FileName),
             Pchar(Parameters),
             Pchar(DirName),
             SW_SHOWNORMAL);
  // 연결(association)된 프로그램이 없다면 '연결 프로그램' 화면 띄우기            
  if code = SE_ERR_NOASSOC then
  begin
    code := ShellExecute(Application.handle,
               Pchar('open'),
               Pchar('rundll32.exe'),
               pchar('shell32.dll,OpenAs_RunDLL '+PathName),
               pchar(DirName),
               SW_SHOWNORMAL);

    // 이 부분에서는 연결 프로그램이 설정된것이므로 ShellExecute() 할 수 있다
    // if code > 32 then
    //   ShellExecute(...);  
  end
  else if code <= 32 then ShowMessage(ShowShellExecuteError(code));
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  if not OpenDialog1.Execute then
    Exit;
  // open할 파일의 전체 path와 parameter  
  ShellExecuteWithDlg(OpenDialog1.FileName, '');
end;

end.