フォルダオプションの変更を反映

解決


ofZ  2007-11-12 19:32:08  No: 28374

エクスプローラーのフォルダオプションは、たぶんここに記録されています
Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced

この中のオプションを変更し、エクスプローラーの表示を更新するには
どのようにしたらいいのでしょう?

レジストリを直接変更して、SHChangeNotifyを使ってみましたが、反映されず
SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_FLUSH,〜

SHChangeNotify(SHCNE_ALLEVENTS, SHCNF_FLUSH,〜

SendMessageTimeoutでブロードキャストしてもだめ
var retVal:DWORD;
SendMessageTimeout(HWND_BROADCAST, WM_SETTINGCHANGE, 0, 
     Integer(PChar('Environment')), SMTO_ABORTIFHUNG, 5000, retVal);

コツコツファイル名を変更するとき等、拡張子を消したり、隠しファイルを
消したりして作業するほうがラクなときがあるのですが、いちいちダイアログを
開くのはめんどくさくなってきまして、一発で変更できる方法を探しています。


Fusa  2007-11-14 21:50:30  No: 28375

すでに、ご検討しているかと思いますが
エクスプローラを開いてGUIで操作するのと同じことを
アプリケーションからおこなってみてはいかがでしょうか?

エレガントとはほど遠い解決策ですが...


ofZ  2007-11-20 18:35:10  No: 28376

> エレガントとはほど遠い解決策ですが...
最終的には、これでも・・・と考えていましたが、もう少しねばってみました。

WinSight32で、メッセージをつかまえて、くさいメッセージを捕まえイカで実行
exprHnd := FindWindow('ExploreWClass', nil);
if exprHnd <> 0 then PostMessage(exprHnd, WM_COMMAND, $A220, 0);

「WM_COMMAND」+「A220」でGoogle検索にひっかかったページにも同じコトが記載
http://www.geocities.jp/eco21426/Tips/Miscellaneous.htm

【結果】
IDEからの実行→反応しない???
エクスプローラから実行→反応しない???
    再度実行し、設定を更新せずメッセージだけ飛ばすと反応あり

何度か繰り返すと、まったく反応なし・・・

【結論】
わからん
窓の手+Win高速化PC++窓使いの友 あたりで、Windows設定をいろいろ変更しているから、
そこに原因があるのかもしれない?

【確認用のコード】
TButtonとTCheckBoxを一個置いて、Button1,CheckBox1とする
CheckBox1のOn/Offで、拡張子の表示有無、隠しファイル等の表示有無が
切り替わる(はず)のコード

procedure TForm1.Button1Click(Sender: TObject);
const                                      //表示しない  表示する
  RP_HIDDEN     :array[Boolean] of Integer = ($00000002, $00000001);
  RP_HIDEEXT    :array[Boolean] of Integer = ($00000001, $00000000);
var
  reg           :TRegistry;
  exprWnd       :HWND;
begin
  reg := TRegistry.Create(KEY_WRITE);
  try
    reg.RootKey := HKEY_CURRENT_USER;

    {開く}
    if reg.OpenKey(EXP_ADV_KEY, False) then begin
      reg.WriteInteger('hidden', RP_HIDDEN[CheckBox1.Checked]);
      reg.WriteInteger('HideFileExt', RP_HIDEEXT[CheckBox1.Checked]);
      reg.CloseKey;

      exprWnd := FindWindow('ExploreWClass', nil);
      if exprWnd <> 0 then begin
        PostMessage(exprWnd, WM_WININICHANGE, 0, 0);
        PostMessage(exprWnd, WM_COMMAND, $A220, 0);
      end;
    end;

  finally
    reg.Free;
  end;
end;


さなみ  2007-11-21 06:16:27  No: 28377

回答ではありませんが。

http://www.vector.co.jp:80/magazine/softnews/060801/n0608013.html
とあるユーティリティの紹介ページに、以下のような書き込みがありました。
役に立つかどうかわかりませんが。
>開発中に苦労した点
>簡単な操作のように見えますが、なかなかどうして。

>レジストリで現在の状態を確認
>レジストリを直接操作して設定を変更
>アクティブデスクトップの密かな入れ替え
>仮想キーを使っての画面全体の再表示
>Windows 98系のみの特別処理

既に知ってる情報でしたらすいません。


ofZ  2007-11-21 17:23:25  No: 28378

さなみ さん、回答ありがとうございます。

紹介いただいたような単機能ツールがあるとは思っていませんでした。
貴重な情報ありがとうございました。

> >アクティブデスクトップの密かな入れ替え
こちらについて、少し探ってみたいと思います。

このツールでも、時々一回で動作しないことがあるようなので、
MSの魔法でも隠されている気がしないでもありません。


ofZ  2007-11-21 23:34:54  No: 28379

補足
WM_COMMAND + WP=$A220 は、結局、エクスプローラーの「最新の情報に更新(=F5)」を行っているだけなので、
最初から『レジストリ編集+F5で更新されない』状況とまったく同じだと言うことに(今更)気が付いた。
何やってんだ・・・


ofZ  2007-11-22 20:55:31  No: 28380

魔法のコマンド見つけました

参照元
IDEA: Show/ Do not Show Hidden files and folders
ttp://www.donationcoder.com/Forums/bb/index.php?topic=8492.5;wap2

【サンプルプログラム】
フォームにボタンとチェックボックスを置いて
uses Registry を追加
Windows 2000SP4 & XP SP1 で確認

{ExploreWClass or CabinetWClass の検索と更新}
function EnumWinProcUpdate(aHandle: HWND; param: Pointer): BOOL; stdcall;
var
  wName :array [0..79] of Char;
begin
  Result := True;
  GetClassName(aHandle, wName, 80);
  if (StrLIComp(wName, 'ExploreWClass', 80) = 0) or
     (StrLIComp(wName, 'CabinetWClass', 80) = 0) then begin
    SendMessage(aHandle, WM_COMMAND, 28931, 0);
  end;
end;

procedure TMainExpForm.Button1Click(Sender: TObject);
const                                      //表示しない  表示する
  RP_HIDDEN: array[Boolean] of Integer = ($00000002, $00000001);
  RP_HIDEEXT: array[Boolean] of Integer = ($00000001, $00000000);
var
  reg: TRegistry;
begin
  reg := TRegistry.Create(KEY_WRITE);
  try
    reg.RootKey := HKEY_CURRENT_USER;
    if reg.OpenKey(EXP_ADV_KEY, False) then begin
      reg.WriteInteger('hidden', RP_HIDDEN[CheckBox1.Checked]);
      reg.WriteInteger('HideFileExt', RP_HIDEEXT[CheckBox1.Checked]);
      reg.CloseKey;
      {更新}
      EnumChildWindows(0, @EnumWinProcUpdate, 0);
    end;
  finally
    reg.Free;
  end;
end;

【追加】
NTになると、ShellState で保持している模様。
レジストリのインポート・エクスポートで設定を切り換え、
メッセージを飛ばしても効果がないことから、環境依存?
Shell32.dllのバージョン5以降かな?
でも、自分用だからこれでよしと。


Fusa  2007-11-23 07:53:23  No: 28381

読んでてちょっとわくわくする投稿ですね。
お疲れ様でした。


ofZ  2007-11-26 21:42:44  No: 28382

おまけ

Windows 98SE & Windows ME で検証した結果、EnumChildWindows
ではなく、EnumWindows を使用することで、リフレッシュ成功

Windows 95 は未検証だけど、NT4.0 がダメだから、
98/ME/2000/XP で有効のような感じです。


ofZ  2007-11-26 23:59:04  No: 28383

しつこいようだがもう一個

【テスト結果】

OS    IE            Shell32.dllの    ↑コードによる
                        バージョン        リフレッシュ

95OSR2  IE3.x           4.00.1111          ×
        +IE4.0SP1       4.72.3110.6        ○

98SE    IE5.0?         4.72.3612.1700     ○

NT4.0   +IE4.0SP1       4.72.3110.6        ○
        +IE6.0          4.00               ×

バージョンについて参考にしたサイト
ttp://www.runan.net/program/tips/sdk_11_define_WINVER.shtml

【考察】
Shell32.dllのバージョンが4.71以上が必要。
Win95/NT4.0 は、IE4.xをインストールしないと対応できない。

これでおしまい


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

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






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