3
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【Delphi】複数のフォルダを Explorer のタブで開きたい

3
Last updated at Posted at 2026-09-30

はじめに

Windows 11 の Explorer にはタブがあって、グループ毎に開いておくと便利なのですが、間違って閉じちゃったり、離席してる時に Windows Update で閉じられちゃったりすると目も当てられません。そしてグループをタブで開くためのコマンドラインスイッチなんてものはないようです 1。

複数のフォルダを Explorer のタブで開く

それなら、Explorer でタブを追加する方法がシェルオブジェクトとして用意されたりするんじゃないかと探してみましたが、そんなものはないそうです。

で、どのように実現するかと言えば 〔CTRL〕+〔T〕 でタブを新規作成してアドレスバーにパスを入力するらしいです。なんて原始的な...orz

ソースコード

Delphi でユニットを書いてみました。

unit uExplorerTab;

interface

uses
  System.SysUtils, Winapi.Windows, Winapi.Messages, Winapi.ShellAPI, Vcl.Clipbrd;

const
  EXEC_DELAY = 3000;
  OPEN_DELAY = 1500;

procedure OpenFoldersInExplorerTabs(const AFolders: array of string);

implementation

procedure NavigateCurrentTab(const APath: string);
  procedure SendShortcutKey(AKey: WORD);
  begin
    var Inputs: array[0..3] of TInput;
    ZeroMemory(@Inputs, SizeOf(Inputs));
    Inputs[0].Itype      := INPUT_KEYBOARD;
    Inputs[0].ki.wVk     := VK_CONTROL;
    Inputs[1].Itype      := INPUT_KEYBOARD;
    Inputs[1].ki.wVk     := AKey;
    Inputs[2].Itype      := INPUT_KEYBOARD;
    Inputs[2].ki.wVk     := AKey;
    Inputs[2].ki.dwFlags := KEYEVENTF_KEYUP;
    Inputs[3].Itype      := INPUT_KEYBOARD;
    Inputs[3].ki.wVk     := VK_CONTROL;
    Inputs[3].ki.dwFlags := KEYEVENTF_KEYUP;
    SendInput(4, Inputs[0], SizeOf(TInput));
    Sleep(100);
  end;
  procedure SendEnterKey;
  begin
    var Inputs: array[0..1] of TInput;
    ZeroMemory(@Inputs, SizeOf(Inputs));
    Inputs[0].Itype      := INPUT_KEYBOARD;
    Inputs[0].ki.wVk     := VK_RETURN;
    Inputs[1].Itype      := INPUT_KEYBOARD;
    Inputs[1].ki.wVk     := VK_RETURN;
    Inputs[1].ki.dwFlags := KEYEVENTF_KEYUP;
    SendInput(2, Inputs[0], SizeOf(TInput));
    Sleep(100);
  end;
begin
  try
    Clipboard.AsText := APath;
  except
    Sleep(100);
    Clipboard.AsText := APath;
  end;
  SendShortcutKey(Ord('T')); // Ctrl + T
  Sleep(OPEN_DELAY);
  SendShortcutKey(Ord('L')); // Ctrl + L
  SendShortcutKey(Ord('V')); // Ctrl + V
  SendEnterKey;
end;

procedure ForceForegroundWindow(AHwnd: HWND);
begin
  var ForeThread := GetWindowThreadProcessId(GetForegroundWindow, nil);
  var TargetThread := GetWindowThreadProcessId(AHwnd, nil);
  if ForeThread <> TargetThread then
  begin
    AttachThreadInput(ForeThread, TargetThread, True);
    SetForegroundWindow(AHwnd);
    BringWindowToTop(AHwnd);
    AttachThreadInput(ForeThread, TargetThread, False);
  end
  else
    SetForegroundWindow(AHwnd);
end;

procedure OpenFoldersInExplorerTabs(const AFolders: array of string);
begin
  if Length(AFolders) = 0 then
    Exit;
  ShellExecute(0, 'open', 'explorer.exe', PChar('"' + AFolders[0] + '"'), nil, SW_SHOWNORMAL);
  Sleep(EXEC_DELAY);
  for var i := 1 to High(AFolders) do
  begin
    var HExplorerWnd := FindWindow('CabinetWClass', nil);
    if HExplorerWnd <> 0 then
    begin
      ForceForegroundWindow(HExplorerWnd);
      Sleep(100);
      NavigateCurrentTab(AFolders[I]);
    end;
  end;
end;

end.

使い方

使い方はこんな感じになります。存在しないフォルダを開こうとすると、デフォルトではドキュメントフォルダが開くと思います。

  OpenFoldersInExplorerTabs([
    'D:\',
    'C:\Windows',
    'C:\Program Files'
  ]);

コンソールアプリケーションだとこんな感じです。

OpenInTab.dpr
program OpenInTab;
{$APPTYPE CONSOLE}

uses
  System.SysUtils,
  uExplorerTab in 'uExplorerTab.pas';

begin
  if ParamCount = 0 then
    Exit;
  var Folders: array of string;
  SetLength(Folders, ParamCount);
  for var i:=0 to ParamCount-1 do
    Folders[i] := ParamStr(Succ(i));
  OpenFoldersInExplorerTabs(Folders);
end.

パラメータとして指定されたフォルダを一つの Explorer の複数のタブで開きます。

説明

最初の一つを ShellEcecute() で開き、残りは

  1. 〔Ctrl〕+〔T〕 で新しいタブを開く
  2. 〔Ctrl〕+〔L〕 でアドレスバーを全選択する
  3. パスをクリップボードに入れる
  4. 〔Ctrl〕+〔V〕 で貼り付け
  5. 〔Enter〕 でフォルダ移動

ってやってます。

  • 最初の Explorer の起動が遅かったりタブの新規作成に時間が掛かったりするので、大きめの遅延を入れてあります (環境に合わせて EXEC_DELAY と OPEN_DELAY の値を調整してください)
  • Clipboard.AsText への代入に失敗する事があるので、今回は簡易的に 1 度だけリトライするようにしてあります
  • SetForegroundWindow() だけでは前面に来ない事への対処をしてあります
  • keybd_event() を使おうと思ったら、ドキュメントに「SendInput() 使えや!」って書いてあったのでそれに従いました

おわりに

これでグループ化されたフォルダを一度に開けますね。

image.png

See also:

  1. 2026/09 現在。 ↩

3
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?