Delphi Tips 
-----------------------------

キーワード:ShellApi

>> Index

12/31 リンクファイルから参照先のファイル名を得る
09/27 エクスプローラからファイルをドラッグ&ドロップする
09/26 ファイルを削除してゴミ箱に移動させたい。
09/20 エクスプローラのように、アプリケーションにブラウザページをつくりたい。
09/19 インターネット エクスプローラを起動したい/その情報を取得したい
09/02 Windowsの「ファイルの検索」ダイアログをプログラムから使いたい
08/26 ダイヤラを呼び出す。(TAPI32.DLLの使用)
02/08 TDDEClientConvで最初の行しか実行されない?
02/08 DDeClientConv を使ってスタートメニューにアイコンを登録
02/08 Windowsの「ファイルの検索ダイアログ」を表示させる
02/08 自作アプリで作ったオブジェクトを他のアプリに貼り付けたい

最終更新: 6901 日前

0099  D1   D2   D3   D4   D5   D6   D7   3.1   95   98    作成: 1999/02/08 osamu rev 1.2
   B1   B3   B4   B5   B6   B7   NT3   NT4   2K   XP  更新: 2005/12/31 長山 編集
リンクファイルから参照先のファイル名を得る

IShellLinkを使用すれば出来ます。

    CoInitialize(NULL);

    HRESULT HR;
    IShellLink *psl;
    IPersistFile *ppf;
    WideChar wsz[MAX_PATH];
    char szGotPath[MAX_PATH];
    WIN32_FIND_DATA wfd;

    HR = CoCreateInstance(CLSID_ShellLink, NULL,
                CLSCTX_INPROC_SERVER, IID_IShellLink, (void **)&psl);
    if(SUCCEEDED(HR)){
        HR = psl->QueryInterface(IID_IPersistFile, (void **)&ppf);
        if(SUCCEEDED(HR)){
            MultiByteToWideChar(CP_ACP, 0, "ショートカット.lnk", -1,
                    wsz, MAX_PATH );
            HR = ppf->Load( wsz, STGM_READ );
                if(SUCCEEDED(HR)){
                    HR = psl->Resolve(Application->Handle, SLR_ANY_MATCH);
                    if(SUCCEEDED(HR)){
                        HR = psl->GetPath(szGotPath, MAX_PATH,
                                (WIN32_FIND_DATA *)&wfd, SLGP_SHORTPATH );
                        Edit2->Text = szGotPath;
                    }
                }
            }
            ppf->Release();
        }
        psl->Release();
    }
    CoUninitialize();



Delphi翻訳版 (関数です)

uses
  Windows, SysUtils, ShlObj, ActiveX, ComObj;
  
const IID_IPersistFile: TGUID= (D1:$0000010B;D2:$0000;D3:$0000;D4:($C0,$00,$00,$00,$00,$00,$00,$46));

function ExtractStringFromLinkFile( Target:TFileName ): String;
var
    R   : HRESULT;
    SL  : IShellLink;
    PF  : IPersistFile;
    Wrk : array[0..MAX_PATH] of WideChar;
    Path: array[0..MAX_PATH] of Char;
    WFD : WIN32_FIND_DATA;
begin
    Result := '';
    CoInitialize( NIL );

    R := CoCreateInstance( CLSID_ShellLink, NIL, CLSCTX_INPROC_SERVER, IID_IShellLinkA, SL );
    if Succeeded( R ) then
    begin
        R := SL.QueryInterface( IID_IPersistFile, PF );
        if Succeeded( R ) then
        begin
            MultiByteToWideChar( CP_ACP, 0, PChar(Target), -1, Wrk, MAX_PATH );
            R := PF.Load( Wrk, STGM_READ );
            if Succeeded( R ) then
            begin
                R := SL.Resolve( 0{Application.Handle}, SLR_ANY_MATCH );
                if Succeeded( R ) then
                begin
                    SL.GetPath( Path, MAX_PATH, WFD, SLGP_SHORTPATH );
                    Result := Path;
                end;
            end;
        end;
    end;

    CoUninitialize;
end;
参照: [builder:5475] <Windows> <ファイル>

0218  D1   D2   D3   D4   D5   D6   D7   3.1   95   98    作成: 1999/08/26 西坂良幸 rev 1.2
   B1   B3   B4   B5   B6   B7   NT3   NT4   2K   XP  更新: 1999/09/27 西坂良幸 編集
エクスプローラからファイルをドラッグ&ドロップする

一度はやってみたいんですよね。MLでも多いスレッドです。
「Delphi2.0Q&A120選」(大野元久著)にもあります。

WM_DropFilesメッセージを捕まえて、DragQueryFile関数で処理するわけですが、受け取る側のスタイルを準備しなければなりません。
これは、一般的なフォームのOnCreateイベントで
DragAcceptFiles(Handle,True);
を使うよりも、CreateParamsをオーバーライドするのがベターだそうです。

// 定義部
 type
  TForm1 = class(TForm)
  ・・省略・・
  private
    procedure CreateParams(var Params: TCreateParams);override;
    procedure WMDropFiles(Var Msg: TWMDropFiles); Message WM_DropFiles;
  public
  end;

// 実装部
procedure TForm1.CreateParams(var Params: TCreateParams);
begin
  inherited CreateParams(Params);
  // 受け取れる準備をする
  Params.ExStyle := Params.EXStyle or WS_EX_ACCEPTFILES;
end;

// ファイル1個の場合−−メモに読み込ませる。
procedure TForm1.WMDropFiles(Var Msg: TWMDropFiles);
Var
  FileName: Array[0..MAX_PATH] of Char;
Begin
  Count := DragQueryFile(Msg.Drop, 0, FileName, SizeOf(FileName));
  Memo1.Lines.LoadFromFile(String(FileName));
  DragFinish(Msg.Drop);
End;

//今度は複数の場合−−リストボックスにファイル名
procedure TForm1.WMDropFiles(Var Msg: TWMDropFiles);
Var
  FileName: Array[0..MAX_PATH] of Char;
  i, Count: integer;
Begin
  ListBox1.Items.clear;
  // 第二パラメータを-1にするとドロップ数が取得できる
  Count := DragQueryFile(Msg.Drop, DWord(-1), FileName, SizeOf(FileName));
  for i := 0 to count - 1 do
  begin
    DragQueryFile(Msg.Drop, i, FileName, SizeOf(FileName));
    ListBox1.items.add(String(FileName));
  end;
  DragFinish(Msg.Drop);
End;

最後のDragFinishを忘れないように。
参照: [Delphi-ML:3137] [Delphi-ML:8536] [Delphi-ML:31274] <Windows> <ファイル>

0275  D1   D2   D3   D4   D5   D6   D7   3.1   95   98    作成: 1999/09/26 西坂良幸 rev 1.1
   B1   B3   B4   B5   B6   B7   NT3   NT4   2K   XP  更新: 1999/09/26 西坂良幸 編集
ファイルを削除してゴミ箱に移動させたい。

SHFileOperation関数を使えば、ファイル単位でもフォルダーごとでもゴミ箱に移動させることができます。
注意事項としては、必ずフルパスでなければならないということです。

ちょっと変な関数名ですが・・・

Uses Shellapi;

procedure SendToRecycleBin(FileList: TStrings; Dlg: boolean);
var
  LpFileOp:TSHFILEOPSTRUCT;
  FileNames: string;
  i: integer;
begin
  if FileList.Count = 0 then exit;
  // #0をデリミタとした文字列を作る
  for i := 0 to FileList.Count - 1 do
    FileNames := FileNames + FileList[i] + #0;
  // ターミネイタにもう一度#0をつける
  FileNames := FileNames + #0;
  with LpFileOp do
  begin
    Wnd := Application.Handle;
    wFunc := FO_DELETE;
    pFrom := PChar(FileNames);
    pTo:= nil;
    fFlags := FOF_ALLOWUNDO;
    if not Dlg then fFlags := fFlags or FOF_SILENT;
    hNameMappings := nil;
    lpszProgressTitle := nil;
  end;
  SHFileOperation(LpFileOp);
end;

// テスト
procedure TForm1.Button1Click(Sender: TObject);
var
  Flist :TStrings;
begin
  Flist := TStringlist.Create;
  try
    Flist.Add('C:\Program Files\Borland\Delphi 4\Projects\*.~df');
    Flist.Add('C:\Program Files\Borland\Delphi 4\Projects\*.~pa');
    SendToRecycleBin(FList, true);
  finally
    Flist.free;
  end;
end;
参照: [Delphi-ML:3443] [Delphi-ML:5005] <Windows> <ファイル>

0266  D1   D2   D3   D4   D5   D6   D7   3.1   95   98    作成: 1999/09/19 西坂良幸 rev 1.2
   B1   B3   B4   B5   B6   B7   NT3   NT4   2K   XP  更新: 1999/09/20 西坂良幸 編集
エクスプローラのように、アプリケーションにブラウザページをつくりたい。

本来なら、DelphiにあるHRMLコンポーネント等を使うんでしょうが、これも、D4まででは、結局AktiveXなので、オフィス97をお持ちの方は、Webブラウザコントロール(WebBrowser)を使うととても簡単です。

これは、オフィス97のCD-ROM
 \VALUPACK\ACCESS\WEBHELP\Webrowse.hlpに
Web ブラウザ コントロールとして、詳しい解説があります。
この実体は、Shdocvw.dll というDLLファイルです。

メニューで[コンポーネント|ActiveXコントロールの取り込み]を開いて下さい。
ダイアログのリストに、Microsoft Internet Contorols(version 1.??) というのがあります。
無かったら、Windows\Systemディレクトリの、Shdocvw.dllを探して追加して下さい。
クラス名の欄に、TWebBrowser_V1、TWebBrowser と表示されたら、インストール実行で、パレットのActiveXページにコンポーネントがインストールされます。

ページ切り替えは省略しますが、
フォームにこのコンポーネントを貼り付け、Alignを決めます。

procedure TForm1.FormShow(Sender: TObject);
begin
  WebBrowser1.GoHome;
end;

とすれば、Web表示が出来上がりです。

URLを指定するときは、Navigate、やNavigate2 メソッドを使います

たとえば、URLがファイル(*.htm)なら、

procedure TForm1.Button1Click(Sender: TObject);
var
 url: WideString;
 flg,Tmp: OleVariant;
begin
  if OpenDialog1.Execute then
  begin
    url := OpenDialog1.FileName;
    flg := 0;
    WebBrowser1.Navigate(url, flg, Tmp, Tmp, Tmp);
  end;
end;


メソッドや、プロパティの詳細は、上記のヘルプファイルを見て下さい。
264番のインターネットエクスプローラオブジェクトと似通っているようです。
参照: [Delphi-ML:25232] [Delphi-ML:37104] <その他Windows関連> <WWW> <Windows> <通信>

0264  D1   D2   D3   D4   D5   D6   D7   3.1   95   98    作成: 1999/09/19 西坂良幸 rev 1.2
   B1   B3   B4   B5   B6   B7   NT3   NT4   2K   XP  更新: 1999/09/19 西坂良幸 編集
インターネット エクスプローラを起動したい/その情報を取得したい

オフィス97のCD-ROM
 \VALUPACK\ACCESS\WEBHELP\Webrowse.hlpに
InternetExPlorerオブジェクトの詳しい解説があります。
これを使うと、OLE オートメーションを利用してインターネット エクスプローラのインスタンスを作成し、操作することができます。

このオブジェクトはComObj.pas で定義されているCreateOleObject関数で使えます。
変数とメソッドを定義し、
  private
    IExp:Olevariant;
  public
    procedure ExecuteIE(Url: String = '');


uses ActiveX,ComObj;

procedure TForm1.ExecuteIE(Url: String = '');
begin
  if IUnKnown(IExp) = nil then
  begin
    IExp := CreateOleObject('InternetExplorer.Application');
    IExp.Height:=400;
    IExp.Width:=600;
    IExp.MenuBar:=1;
    IExp.StatusBar:=1;
    IExp.ToolBar:=1;
    IExp.Visible:=true;
  end;
  if Url = '' then
    IExp.Gohome
  else
    IExp.Navigate(Url);
end;

// ホームで起動
procedure TForm1.Button1Click(Sender: TObject);
begin
  ExecuteIE;
end;

// URLを指定して起動
procedure TForm1.Button2Click(Sender: TObject);
begin
  ExecuteIE('http://www2.big.or.jp/~osamu/Delphi/Tips');
end;

// インターネット エクスプローラを終了するには、Quit メソッドを使用します。
procedure TForm1.Button3Click(Sender: TObject);
begin
  if IUnKnown(IExp) <> nil then
  begin
    IExp.Quit;
    IExp:= Unassigned;
  end;
end;


便利なプロパティやメソッドがたくさんあります。
参照: <その他Windows関連> <Windows>

0079  D1   D2   D3   D4   D5   D6   D7   3.1   95   98    作成: 1999/02/08 osamu rev 1.2
   B1   B3   B4   B5   B6   B7   NT3   NT4   2K   XP  更新: 1999/09/02 西坂良幸 編集
Windowsの「ファイルの検索」ダイアログをプログラムから使いたい

「ファイルの検索」ダイアログを出すには、DDEを使います。

フォームに TDdeClientConv コンポーネント(Systemタブ)を乗っけて、

procedure TForm1.Button1Click(Sender: TObject);
var
  Macro:string;
begin
  DdeClientConv1.SetLink('Folders','AppProperties');
  DdeClientConv1.ServiceApplication:='Explorer';
  DdeClientConv1.OpenLink;
  Macro := Format('[FindFolder("%S")]', ['D:\Delphi 3']);
  DdeClientConv1.ExecuteMacro(PChar(Macro),False);
  DdeClientConv1.CloseLink;
end;

てなふうにします。D:\Delphi 3 フォルダがカレントになります。
ちなみにどこで見つけたかというと、レジストリの

 HKEY_CLASSES_ROOT\Directory\shell\find\ddeexec

です。

なお、終了させる場合は

procedure TForm1.Button2Click(Sender: TObject);
var
 hDialog;
begin
 hDialog:=FindWindow('#32770',nil); {ダイヤログのハンドル}
 SendMessage(hDialog, WM_CLOSE, 0, 0);  {終了}
end;


が簡単でいいでしょう。
参照: [Delphi-ML:20377] <その他Windows関連> <Windows> <ダイアログ>

0206  D1   D2   D3   D4   D5   D6   D7   3.1   95   98    作成: 1999/08/18 西坂良幸 rev 1.3
   B1   B3   B4   B5   B6   B7   NT3   NT4   2K   XP  更新: 1999/08/26 西坂良幸 編集
ダイヤラを呼び出す。(TAPI32.DLLの使用)


TAPI32.DLLのtapiRequestMakeCall関数を呼び出します。


function tapiRequestMakeCall(pDestAddress,pAppName,pCalledParty,pComment: PChar): LongInt; stdcall; external 'TAPI32.DLL';

procedure CallDialar(Number, DName , Comment : string);
begin
  tapiRequestMakeCall(pChar(Number),
    PChar(Application.Title), pChar(DName), PChar(Comment));
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  CallDialar('06-5556-1234', '山田太郎', '');
end;


で、ダイアラが起動します。


本格的にTAPIを使う場合は、Tapi32.dll用の定義ユニットが必要です。

なお、TAPIの定義ユニットは、
外国製ですが、
 d_tapi.zip (28K)のTapi.pas
 tapid3.zip (28K)のTapih.pasなどがあります。

これらは、桜島子宮さんの ページ
http://www.kobira.co.jp/sakura/d_net_RasAPI.htm

からダウンロードできます。
参照: [Delphi-ML:6833] [Delphi-ML:17807] [Delphi-ML:41356] <Windows>

0084  D1   D2   D3   D4   D5   D6   D7   3.1   95   98    作成: 1999/02/08 osamu rev 1.1
   B1   B3   B4   B5   B6   B7   NT3   NT4   2K   XP  更新: 1999/02/08 osamu 編集
TDDEClientConvで最初の行しか実行されない?

TDDEClientConv を使って、ステップ実行を行うとちゃんとマクロは実行されるのですが、そのまま実行すると、最初のコマンドのみ実行してその後が実行されません。

これは2.0からのバグです。3.0/3.1用のパッチを当てると直ると思います。

http://www.dataweb.nl/~r.p.sterkenburg/bugsall.htmが詳しいです。
日本語版でも通用する個所が多いです。参考にしてみて下さい。

1)必要なったらTDDEClientConvをCreate
2)マクロを実行
3)用が済んだらFree
で逃げられます。
参照: [Delphi-ML:19657] <その他Windows関連> <System> <Windows> <バグ> <コンポーネント >

0105  D1   D2   D3   D4   D5   D6   D7   3.1   95   98    作成: 1999/02/08 osamu rev 1.1
   B1   B3   B4   B5   B6   B7   NT3   NT4   2K   XP  更新: 1999/02/08 osamu 編集
DDeClientConv を使ってスタートメニューにアイコンを登録

3.1 のプログラムマネージャのときと同じですね。
DDEClientConv をフォームに置いて以下のようにします。

var strGroup:String;
    strExeName:String;
    strPrgName:String;
    Temp:String;
begin
    strGroup   := 'グループ名';
    strPrgName := 'ソフト名';
    strExeName := Application.ExeName;

    if not DDEClientConv1.SetLink('PROGMAN','PROGMAN') then begin
        ShowMessage('ショートカットの制作に失敗しました。');
    end else try
        {グループの作成}
        Temp := '[CreateGroup(' + strGroup  + ')]';
        DDEClientConv1.ExecuteMacro(PChar(Temp),False);

        {グループの表示}
        Temp :=  '[ShowGroup(' + strGroup  + ',1)]';
        DDEClientConv1.ExecuteMacro(PChar(Temp),False);

        {アイテムの作成}
        Temp :=  '[AddItem("' + strExeName + '","' + strPrgName + '")]';
        DDEClientConv1.ExecuteMacro(PChar(Temp),False);

        ShowMessage('ショートカットを作成しました。');
    finally
        DDEClientConv1.CloseLink;
    end;
end;
参照: [Delphi-ML:21012] <その他Windows関連> <Windows> <スタートメニュー> <配布>

0028  D1   D2   D3   D4   D5   D6   D7   3.1   95   98    作成: 1999/02/08 osamu rev 1.1
   B1   B3   B4   B5   B6   B7   NT3   NT4   2K   XP  更新: 1999/02/08 osamu 編集
Windowsの「ファイルの検索ダイアログ」を表示させる

ファイルの検索ダイアログを出すには、DDEを使います。

フォームに TDdeClientConv コンポーネント(Systemタブ)を乗っけて、

procedure TForm1.Button1Click(Sender: TObject);
var
  Macro:string;
begin
  DdeClientConv1.SetLink('Folders','AppProperties');
  DdeClientConv1.ServiceApplication:='Explorer';
  DdeClientConv1.OpenLink;
  Macro := Format('[FindFolder("%S")]', ['D:\Delphi 3']);
  DdeClientConv1.ExecuteMacro(PChar(Macro),False);
  DdeClientConv1.CloseLink;
end;

てなふうにします。D:\Delphi 3 フォルダがカレントになります。
ちなみにどこで見つけたかというと、レジストリの

 HKEY_CLASSES_ROOT\Directory\shell\find\ddeexec

です。
参照: [Delphi-ML:20377] <その他Windows関連> <Windows> <ダイアログ>

0037  D1   D2   D3   D4   D5   D6   D7   3.1   95   98    作成: 1999/02/08 osamu rev 1.1
   B1   B3   B4   B5   B6   B7   NT3   NT4   2K   XP  更新: 1999/02/08 osamu 編集
自作アプリで作ったオブジェクトを他のアプリに貼り付けたい

自作アプリを OLE サーバにして他のアプリに貼り付けられるデータを作成する方法が Inside Windows の、98年4月号「Delphi の神託」に出ているそうです。
参照: [Delphi-ML:18525] <その他Windows関連> <Windows>

[新規作成] [最新の情報に更新]

How To
Lounge
KeyWords

Tips
Delphi
Home
Osamu Takeuchi osamu@big.or.jp