Delphi Programming / Object Pascal
サイトのトップページへ リンクのページへ ロゴマーク
[掲載 2014年06月03日] [更新 2017年06月29日] Delphi サンプルプログラム集
   
098_ドラッグ & ドロップでアプリを起動してファイルを表示
動作確認等 Windows 7 U64(SP1) + Delphi XE(UP1) Pro
098_DragDropStartApp.zip [1,107 KB] 2017年06月29日版 (EXE 同梱)







01_ドラッグ & ドロップでアプリを起動してファイルを表示


EXE ファイル,あるいは EXE ファイルのショートカット (アプリのショートカット) に,エクスプローラ等から,ドラッグ & ドロップでアプリを起動して,そのファイルを表示するサンプルです.

Delphi のショートカットに,プロジェクトファイルをドラッグ & ドロップすると,そのプロジェクトを開くことができます.それと同じような動作するアプリを作成する際の参考です.
この機能を実装するには,例えば,メインフォームの OnCreate イベント等で,コマンドラインパラメータを処理します.コマンドラインのパラメータとは,アプリをコマンドラインで起動する際に,指定する起動オプションのことです.


本ページのサンプルは (コマンドライン) パラメータが 1 つだけを処理しています.複数のパラメータを扱う例として,例えば以下のサンプルがあります.


[備考]
アプリケーションの起動中に,エクスプローラ等からファイル名をドラッグ & ドロップした場合は,いわゆるドラッグ & ドロップとしての処理となります.
アプリケーションのショートカットにドラッグ & ドロップした場合は,コマンドラインパラメータとしての処理を行います.パラメータの区切りは半角の空白文字です.



図1
設計時画面
  • TImage を 1 つ配置

コンパイルしたら,EXE のショートカットをデスクトップ等に作成します.このショートカットに,エクスプローラの画像ファイル,あるいは,ブラウザの画像をドラッグ & ドロップします.すると,その画像をフォームに配置した TImage で表示します.

TImage で表示できない画像ファイルをドラッグ & ドロップした場合は,[画像が不正です] のダイアログが表示されます.画像以外のファイルの場合もアプリは起動しますが,何も表示しません.


図2
アプリのショートカットを作成
図3
そのショートカットに,画像ファイルをドラッグ & ドロップ
図4
画像が表示される

リスト1
アプリのショートカットに,画像ファイルをドラッグ & ドロップして起動
起動パラメータ (起動オプション) が 1 つの場合
unit Unit1;

interface

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

type
  TForm1 = class(TForm)
    Image1: TImage;
    procedure FormCreate(Sender: TObject);
  private
    { Private 宣言 }
  public
    { Public 宣言 }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

//=============================================================================
//  フォーム生成時の処理
//  起動パラメータ(起動オプション・引数)が1つの場合の例
//
//  2番目のパラメータの値はParamStr(2)
//  3番目のパラメータの値はParamStr(3)
//  n番目のパラメータの値はParamStr(n)
//  のように受け取る
//  該当するパラメータが存在しない場合は,取得結果は空白文字列となる
//=============================================================================
procedure TForm1.FormCreate(Sender: TObject);
var
  StrText : String;
  WIC     : TWICImage;
begin
  Image1.Left := 0;
  Image1.Top  := 0;
  Image1.AutoSize    := True;
  Image1.Transparent := True;

  //起動時の引数が1つの時だけ,その値を取得して処理
  if ParamCount = 1 then begin
    //1番名のパラメータ(引数)の値を取得(パラメータは文字列で受け取る)
    StrText := ParamStr(1);

    WIC := TWICImage.Create;
    try
      WIC.LoadFromFile(StrText);
      Image1.Picture.Assign(WIC);
    finally
      WIC.Free;
    end;
  end;
end;

end.




02_実行中のアプリにドラッグ & ドロップでファイルを表示


アプリの実行中にドラッグ & ドロップでファイル名を受け取るには DragAcceptFiles で受け入れを設定して,WM_DROPFILES メッセージで受信します.
メッセージの受信には TApplicationEvents コンポーネントを使用すると便利です.

本サンプルは,管理者権限で実行するとドラッグ & ドロップは機能しません.




図5
設計時画面
  • TImage を 1 つ配置
  • メッセージの受信用に TApplicationEvents コンポーネントを配置

リスト2
実行中のアプリにドラッグ & ドロップでファイルを表示
unit Unit1;

interface

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

type
  TForm1 = class(TForm)
    Image1: TImage;
    ApplicationEvents1: TApplicationEvents;
    procedure FormCreate(Sender: TObject);
    procedure ApplicationEvents1Message(var Msg: tagMSG; var Handled: Boolean);
  private
    { Private 宣言 }
  public
    { Public 宣言 }
  end;

var
  Form1: TForm1;

implementation

uses
  ShellAPI;

{$R *.dfm}

//=============================================================================
//  フォーム生成時の処理
//  DragAcceptFilesの使用にはusesにShellAPIが必要
//=============================================================================
procedure TForm1.FormCreate(Sender: TObject);
begin
  //ドラッグアンドドロップを許可
  //対象コントロールはSelf(このフォーム)
  DragAcceptFiles(Self.Handle, True);
end;

//=============================================================================
//  TApplicationEventsのOnMessageイベント処理
//  エクスプローラからのファイルのドラッグ・ドロップ処理
//=============================================================================
procedure TForm1.ApplicationEvents1Message(var Msg: tagMSG;
  var Handled: Boolean);
var
  LCount    : Integer;
  LBuffer   : array [0..MAX_PATH-1] of char;
  LFilePath : string;
  WIC       : TWICImage;
begin
  if Msg.message = WM_DROPFILES then begin
    //FormのOnCreateで受入れコントロールを指定はしているが...
    //ドラッグドロップしたファイル数を取得
    LCount := DragQueryFile(Msg.wParam, High(Cardinal), nil, 0);
    if LCount = 1 then begin
      //ドラッグドロップしたファイル名を取得
      DragQueryFile(Msg.WParam, 0, LBuffer, MAX_PATH);
      LFilePath := LBuffer;

      //ドロップが完了したことを伝える
      DragFinish(msg.wParam);

      //ディスクから画像ファイルを読み込んで表示する
      WIC := TWICImage.Create;
      try
        WIC.LoadFromFile(LFilePath);
        Image1.AutoSize := True;
        Image1.Picture.Assign(WIC);
      finally
        WIC.Free;
      end;
    end;
  end;
end;

end.


上のコードではドラッグ & ドロップの受け入れ先をフォーム自身にしていますが,DragAcceptFiles 関数の引数で限定することもできます.また,受け入れ先をフォーム全体にしておいて,メッセージを受信した時に FindDragTarget 関数で限定することもできます.
ただし,本サンプルの場合は TImage が対象のコントロールです.実行中に何らかの画像が表示されていないと TImaage がどこにあるか判定するのが困難ですから,実用的とは言えません.



リスト3
ドラッグ & ドロップの受け入れ先を限定する方法
  if Msg.message = WM_DROPFILES then begin
    if FindDragTarget(Msg.pt, False) <> Image1 then exit;




03_ShellExecute 関数や CreateProcess 関数での起動パラメータ


ドラッグ & ドロップでアプリを起動する際に与えるパラメータは,コマンドラインパラメータ,あるいはコマンドラインの引数,起動パラメータ,起動オプションと言う場合もあります.
これらのパラメータは,ShellExecute 関数や CreateProcess 関数で EXE を起動する際にも,起動パラメータとして指定できます.この後のサンプルの記事を参考にしてください.

上のサンプルは,起動した EXE 側でパラメータを受け取る処理です.
ShellExecute 関数や CreateProcess 関数で EXE を起動する時は,パラメータを与える側の処理ということになります.





04_EXE のショートカットにおける起動パラメータの設定


EXE のショートカットに起動パラメータ (起動オプション,起動パラメータ) を指定しておくには,下図のように [リンク先] で設定します.



図6
EXE のショートカットで起動オプション (起動パラメータ) を設定




05_コマンドプロンプトから EXE を起動する場合


コマンドラインパラメータは,下図のように,コマンドプロンプトからも指定できます.これがコマンドラインパラメータと言われる由来です.
次のコードは,最初のサンプルと同じ画像ファイルを指定して,その画像を表示します.


図7
コマンドライン




06_IDE での実行時にコマンドラインパラメータ ( 実行時引数 ) を設定


通常,プログラムの開発時は IDE(統合開発環境)の元でコンパイルして実行します.
この時,[実行] メニューの [実行時引数] のダイアログで,パラメータを設定すると,これが,実行時のコマンドラインパラメータとなります.


図8
コマンドラインパラメータの設定

本ページの最初のサンプルの実行結果です.画像を,上の図のパラメータの設定で示す場所に置いて実行しています.
[実行] [実行時引数] のダイアログで設定したコマンドラインパラメータは,IDE から実行した場合だけ有効となります.作成した EXE を直接起動した場合は,この設定は無視されます.つまり,この設定は,設計時における動作確認用として使われるだけです.

この設定内容は,プロジェクトには保存されています.プロジェクトファイルを他の方に提供する場合は注意が必要です.



図9
[実行時引数] を設定して IDE から実行した場合
図10
作成した EXE を直接実行した場合
  • [実行時引数] の設定をしないで実行した場合と同じ結果となる