10

Windows フォルダー オプションの設定を実装する WPF C# プロジェクトがあります。それらの 1 つは、「シングルクリックで項目を開く」(ダブルクリックではなく) です。そのためにレジストリ キーを変更するときは、解決策を見つけた Windows エクスプローラーを更新する必要があります。ただし、デスクトップは更新されず、手動で更新しても変更は適用されません。メソッドを使用しましIActiveDesktop::ApplyChangesたが、機能しませんでした (または、間違えた可能性があります)。このコード スニペットも使用しましたが、行った変更はまだ適用されません。

SHChangeNotify(0x8000000, 0x1000, IntPtr.Zero, IntPtr.Zero);

Windows エクスプローラーを更新するために使用した完全なコード スニペットを次に示します (これはこのサイトからのものです)。

[System.Runtime.InteropServices.DllImport("Shell32.dll")]
    private static extern int SHChangeNotify(int eventId, int flags, IntPtr item1, IntPtr item2);

    public static void RefreshWindowsExplorer()
    {
        // Refresh the desktop
        SHChangeNotify(0x8000000, 0x1000, IntPtr.Zero, IntPtr.Zero);

        // Refresh any open explorer windows
        // based on http://stackoverflow.com/questions/2488727/refresh-windows-explorer-in-win7
        Guid CLSID_ShellApplication = new Guid("13709620-C279-11CE-A49E-444553540000");
        Type shellApplicationType = Type.GetTypeFromCLSID(CLSID_ShellApplication, true);

        object shellApplication = Activator.CreateInstance(shellApplicationType);
        object windows = shellApplicationType.InvokeMember("Windows", System.Reflection.BindingFlags.InvokeMethod, null, shellApplication, new object[] { });

        Type windowsType = windows.GetType();
        object count = windowsType.InvokeMember("Count", System.Reflection.BindingFlags.GetProperty, null, windows, null);
        for (int i = 0; i < (int)count; i++)
        {
            object item = windowsType.InvokeMember("Item", System.Reflection.BindingFlags.InvokeMethod, null, windows, new object[] { i });
            Type itemType = item.GetType();

            // Only refresh Windows Explorer, without checking for the name this could refresh open IE windows
            string itemName = (string)itemType.InvokeMember("Name", System.Reflection.BindingFlags.GetProperty, null, item, null);
            if (itemName == "Windows Explorer")
            {
                itemType.InvokeMember("Refresh", System.Reflection.BindingFlags.InvokeMethod, null, item, null);
            }
        }
    }

これは Windows エクスプローラーでは機能しますが、デスクトップでは機能しません (デスクトップもエクスプローラーに依存するため、これは奇妙です)。変更を有効にするには、デスクトップを再ロードする方法を教えてください。

4

2 に答える 2

3

その設定を変更するコードを投稿した場合は、返信する前に次の提案に対してテストします。

やってみました:

1)上記のコードからステートメントを削除すると、if (itemName == "Windows Explorer")すべてのウィンドウ(デスクトップを含む)が更新されますか?

2) SendMessage WIN32 API 経由で WM_SETTINGCHANGE をブロードキャストしますか?

private const int HWND_BROADCAST = 0xffff;
private const int WM_WININICHANGE = 0x001a, WM_SETTINGCHANGE = 0x001a, INI_INTL = 1;
[DllImport("user32.dll")]
private static extern int SendMessage(int hWnd, uint wMsg, uint wParam, uint lParam);

SendMessage(HWND_BROADCAST, WM_SETTINGCHANGE, 0, INI_INTL);

[クレジット]

3) IActiveDesktop.ApplyChanges

[ComImport]
[Guid("F490EB00-1240-11D1-9888-006097DEACF9")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IActiveDesktop
{
     [PreserveSig]
     int ApplyChanges(AD_Apply dwFlags);
     // [...]
     // Note: There is a lot more to this interface,
     //        please see PInvoke.net link below.
}
private const int AD_APPLY_REFRESH = 4;

IActiveDesktop.ApplyChanges(AD_APPLY_REFRESH);

[PInvoke.net - IActiveDesktop]

これらが機能しない場合は、お知らせください。結局のところ、開いているすべてのエクスプローラーウィンドウとその位置を保存し、エクスプローラーを終了し、エクスプローラーが再起動するのを待ち、各エクスプローラーウィンドウを再度開いて再配置することができます...それが受け入れられる場合.

お役に立てれば。

于 2013-08-05T06:49:52.347 に答える