エクスプローラのフォルダを変更する方法

解決


manbon  2010-04-08 23:16:50  No: 38220

あるフォルダをエクスプローラで起動するには、
ShellExecute(Handle, nil, PChar('C:\Temp'), nil, nil, SW_SHOW);
などでできますが、既に起動しているエクスプローラのフォルダを変更することは可能でしょうか?

例えば、現在 C:\ が選択されている状態とすると、これを C:\Temp が
選択されているように変更したいのです。
なお、エクスプローラは1つだけ起動しているものとします。


KHE00221  2010-04-09 08:17:27  No: 38221

クラス名とか調べるの面倒だから
とりあえず

C:\  から  D:\ に変更

procedure TForm1.Button1Click(Sender: TObject);
var
    OwnerHandle,I1,I2,J1,J2: HWND;
    Buffer: array[0..255] of Char;
    Input : array[0..0] of TInput;

    procedure KeybdInput(VK:Byte;dwFlags:DWORD);
    begin
      with Input[0] do
      begin
        Itype          := INPUT_KEYBOARD;
        ki.wVk         := VK;
        ki.wScan       := MapVirtualKey(VK,0);
        ki.dwFlags     := KEYEVENTF_EXTENDEDKEY or dwFlags;
        ki.time        := 0;
        ki.dwExtraInfo := GetMessageExtraInfo;
      end;
    end;

    function Find(Index: Integer; OwnerHandle: HWND): Boolean;
    var
        A1,A2: Integer;
    begin
      A1 := 0;
      A2 := 1;
      while A2 <> 0 do
      begin
        A2 := FindWindowEx (OwnerHandle , A1 ,nil,nil);
        if A2 <> 0 then
        begin
          SendMessage (A2,WM_GETTEXT,SizeOf(Buffer),Integer(@Buffer));
          if StrPas(Buffer) = 'C:\' then
          begin
            StrPCopy(Buffer,'D:\');
            SendMessage (A2,WM_SETFOCUS,0,0);
            SendMessage (A2,WM_SETTEXT,0,Integer(@Buffer));
            KeybdInput (13,0);
            Windows.SendInput (1,Input[0],SizeOf(Input[0]));
          end;
          Find(Index+1,A2);
        end
        else
        begin
        end;
        A1 := A2;
      end;

    end;

begin
    ShellExecute(Handle, nil, PChar('C:\'), nil, nil, SW_SHOW);
    Sleep(3000);
    OwnerHandle := FindWindow (nil,'WindowsXP 80GB (C:)'); //適当に
    if OwnerHandle <> 0 then
    begin
      I1 := 0;
      I2 := 1;
      while I2 <> 0 do
      begin
        I2 := FindWindowEx (OwnerHandle, I1 ,nil,nil);
        if I2 <> 0 then
        begin
          Buffer := 'AAAA2222';
          SendMessage (I2,WM_SETTEXT,Integer(@Buffer),0);
          Memo1.Lines.Add ('#1');
          Find(2,OwnerHandle);
        end
        else
        begin
        end;
        I1 := I2;
      end;
    end
    else
    begin
    end;

end;


KHE00221  2010-04-09 08:18:57  No: 38222

>Buffer := 'AAAA2222';
>SendMessage (I2,WM_SETTEXT,Integer(@Buffer),0);
>Memo1.Lines.Add ('#1');

気にしないように


KHE00221  2010-04-09 08:27:03  No: 38223

IE上の ComboBox のハンドルを取得して

//フォーカスを当てる
SendMessage (A2,WM_SETFOCUS,0,0); 

//テキストを代える
SendMessage (A2,WM_SETTEXT,0,Integer(@Buffer));

//RETRUN (ENTER) を押す
KeybdInput (13,0);
Windows.SendInput (1,Input[0],SizeOf(Input[0]));


manbon  2010-04-09 18:51:16  No: 38224

KHE00221さん、ありがとうございます。
なかなかコードは理解できないのですが、
動作はばっちりでした。
これからじっくりコードを調べさせて貰います。


KHE00221  2010-04-10 03:48:18  No: 38225

これでOK

    ShellExecute(Handle, nil, PChar('C:\'), nil, nil, SW_SHOW);
    Sleep(3000);
    OwnerHandle := FindWindow (nil,'WindowsXP 80GB (C:)'); //適当に
    if OwnerHandle <> 0 then
    begin
      Find (2,OwnerHandle);
    end;


KHE00221  2010-04-10 03:50:17  No: 38226

Find の Index は階層見るためにつけてただけでいらない


KHE00221  2010-04-10 03:57:54  No: 38227

//SendMessage (A2,WM_GETTEXT,SizeOf(Buffer),Integer(@Buffer));
//if StrPas(Buffer) = 'C:\' then

GetClassName(A2,Buffer,SizeOf(Buffer));
if StrPas(Buffer) = 'ComboBoxEx32' then

に変更


KHE00221  2010-04-10 04:10:37  No: 38228

なんどのあれですが

これでOKかな

    function Find(OwnerHandle: HWND): Boolean;
    var
        A1,A2: Integer;
    begin
      A1 := 0;
      A2 := 1;
      while A2 <> 0 do
      begin
        A2 := FindWindowEx (OwnerHandle , A1 ,nil,nil);

        if OwnerHandle = 0 then //Top の Class名を保存しておく
        begin
          GetClassName(A2,Buffer,SizeOf(Buffer));
          OwnerWindowClassName := StrPas(Buffer);
        end;

        if A2 <> 0 then
        begin
          GetClassName(A2,Buffer,SizeOf(Buffer));
          if StrPas(Buffer) = 'ComboBoxEx32' then
          begin
            if OwnerWindowClassName = 'CabinetWClass' then // IE の クラス名
            begin
              StrPCopy(Buffer,'D:\');
              SendMessage (A2,WM_SETFOCUS,0,0);
              SendMessage (A2,WM_SETTEXT,0,Integer(@Buffer));
              KeybdInput (13,0);
              Windows.SendInput (1,Input[0],SizeOf(Input[0]));
              Memo1.Lines.Add ('#');
            end;
          end;
          Find(A2);
        end
        else
        begin
        end;
        A1 := A2;
      end;

    end;

begin

    ShellExecute(Handle, nil, PChar('C:\'), nil, nil, SW_SHOW);
    Sleep(3000);
    Find (0);


Mr.XRAY  2010-04-18 22:51:36  No: 38229

みなさん,こんにちは.Mr.XRAYです.

以前TShellコンポーネントを使用したサンプルを作成したことがあります.
これを使用したテストをしてみました.
こんなやり方もあるという参考になれば,

06_TShellWindows 表示中のエクスプローラを操作
http://mrxray.on.coocan.jp/Delphi/plSamples/945_ExplorerTest.htm#06


manbon  2010-04-19 19:48:14  No: 38230

KHE00221さん、Mr.XRAYさん、ありがとうございます。
解決を押していたので、見落とすところでした(^^;

お二方のコードで、したいことがばっちり出来ました。
ただ、理解はなかなかできていません・・・
難しいというか、知識が無いと、雰囲気くらいしか
分からないのが情けないところです・・・

丁度、エクスプローラで選択しているファイルのパスを
取得して、そのファイルに対して色々操作を行いたいと
調べ物をしていた最中でしたので、とても助かりました。

コードでは1ファイルのみを対象にされていましたので、
複数ファイル用に以下のように変更してみました。
ありがとうございました。

if SHFolderView.SelectedItems.Count >0 then begin
  for iw := 0 to Pred(SHFolderView.SelectedItems.Count) do begin
    Memo1.Lines.Add(SHFolderView.SelectedItems.Item(iw).Path);
  end;
end;


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加