2013-07-06 12 views
7

Windowsフォルダオプションの設定を実装しているWPF C#プロジェクトがあります。そのうちの1つは、ダブルクリックの代わりに「アイテムを開くためのシングルクリック」です。レジストリキーを変更すると、解決策を見つけたWindowsエクスプローラを更新する必要があります。しかし、デスクトップはリフレッシュされず、手動でリフレッシュしても変更は適用されません。 私はIActiveDesktop :: ApplyChangesメソッドを使用しましたが、機能しませんでした(または多分私は間違いを犯しました)。また、私は、このコードスニペットを使用しましたが、それはまだ私が行った変更を適用しません。デスクトップをリフレッシュ/リロードする方法

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

そして、ここでは、私が勝つExplorerをリフレッシュするために使用完全なコードスニペットです(魔女はこのサイトからです):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); 
      } 
     } 
    } 

。 変更を有効にするには、デスクトップを再ロードする必要がありますか?

+0

すべてのエクスプローラインスタンスを終了して新しいインスタンスを作成しようとするとどうなりますか? – master131

+0

@ master131、それは動作しますが、ユーザーはすべてのエクスプローラウィンドウを失うので、オプションではありません。 – SepehrM

+0

[デスクトップアイコンの表示/非表示]を有効にするにはどうすればよいですか?](http://stackoverflow.com/questions/3326062/how-do-i-make-the-show-hide-desktop -icons-setting-take-effect) –

答えて

2

すべての返信とコメントありがとうございます。私はついにこの問題の回避策を考え出しました。すべてのデスクトップアイコンを非表示にして、再び表示することができます。これにより、デスクトップが強制的にリロードされます。

更新:ウィンドウ8では、SHELLDLL_DefViewは、WorkerWウィンドウの1つの子です。 (代わりにProgmanの)だからここに過ぎのWindows 8および8.1上で動作し、更新されたコードです:

[DllImport("user32.dll", SetLastError = true)] 
    static extern IntPtr FindWindow(string lpClassName, string lpWindowName); 

    [DllImport("user32.dll", SetLastError = true)] 
    static extern IntPtr GetWindow(IntPtr hWnd, GetWindow_Cmd uCmd); 

    [DllImport("user32.dll", CharSet = CharSet.Auto)] 
    static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, IntPtr wParam, IntPtr lParam); 

    enum GetWindow_Cmd : uint 
    { 
     GW_HWNDFIRST = 0, 
     GW_HWNDLAST = 1, 
     GW_HWNDNEXT = 2, 
     GW_HWNDPREV = 3, 
     GW_OWNER = 4, 
     GW_CHILD = 5, 
     GW_ENABLEDPOPUP = 6 
    } 

    private const int WM_COMMAND = 0x111; 

    [DllImport("user32.dll", SetLastError = true)] 
    static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow); 

    private delegate bool EnumWindowsProc(IntPtr hWnd, IntPtr lParam); 

    [DllImport("user32.dll", CharSet = CharSet.Unicode)] 
    private static extern int GetWindowText(IntPtr hWnd, StringBuilder strText, int maxCount); 

    [DllImport("user32.dll", CharSet = CharSet.Unicode)] 
    private static extern int GetWindowTextLength(IntPtr hWnd); 

    [DllImport("user32.dll")] 
    private static extern bool EnumWindows(EnumWindowsProc enumProc, IntPtr lParam); 

    [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)] 
    static extern int GetClassName(IntPtr hWnd, StringBuilder lpClassName, int nMaxCount); 


    public static string GetWindowText(IntPtr hWnd) 
    { 
     int size = GetWindowTextLength(hWnd); 
     if (size++ > 0) 
     { 
      var builder = new StringBuilder(size); 
      GetWindowText(hWnd, builder, builder.Capacity); 
      return builder.ToString(); 
     } 

     return String.Empty; 
    } 

    public static IEnumerable<IntPtr> FindWindowsWithClass(string className) 
    { 
     IntPtr found = IntPtr.Zero; 
     List<IntPtr> windows = new List<IntPtr>(); 

     EnumWindows(delegate(IntPtr wnd, IntPtr param) 
     { 
      StringBuilder cl = new StringBuilder(256); 
      GetClassName(wnd, cl, cl.Capacity); 
      if (cl.ToString() == className && (GetWindowText(wnd) == "" || GetWindowText(wnd) == null)) 
      { 
       windows.Add(wnd); 
      } 
      return true; 
     }, 
        IntPtr.Zero); 

     return windows; 
    } 

    static void ToggleDesktopIcons() 
    { 
     var toggleDesktopCommand = new IntPtr(0x7402); 
     IntPtr hWnd = IntPtr.Zero; 
     if (Environment.OSVersion.Version.Major < 6 || Environment.OSVersion.Version.Minor < 2) //7 and - 
      hWnd = GetWindow(FindWindow("Progman", "Program Manager"), GetWindow_Cmd.GW_CHILD); 
     else 
     { 
      var ptrs = FindWindowsWithClass("WorkerW"); 
      int i = 0; 
      while (hWnd == IntPtr.Zero && i < ptrs.Count()) 
      { 
       hWnd = FindWindowEx(ptrs.ElementAt(i), IntPtr.Zero, "SHELLDLL_DefView", null); 
       i++; 
      } 
     } 
     SendMessage(hWnd, WM_COMMAND, toggleDesktopCommand, IntPtr.Zero); 
    } 

は、今では2回だけデスクトップアイコンを切り替えることができます。これは他の誰かを助け

 ToggleDesktopIcons(); 
     ToggleDesktopIcons(); 

ホープ..

2

この設定を変更するためのコードを掲載していた場合は、返信前に以下の提案に対してテストしています。それは()デスクトップを含むすべてのウィンドウをリフレッシュするので、

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); 

[Credit]

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]

これらが動作しない場合、私に知らせてください。下に来たら、開いているエクスプローラウィンドウをすべて保存し、エクスプローラを終了し、エクスプローラが再起動するのを待ってから、それぞれのエクスプローラウィンドウを開いて再配置してもかまいません。

これが役に立ちます。

+0

ありがとうございますが、残念ながら私のために働いた人はいません。だから、私はデスクトップアイコンを隠して表示することができるとわかった。それは私が望むだけでデスクトップをリロードします。 – SepehrM

+1

@feedwallその場合、デスクトップのハンドルを手に入れ、手動で{F5}キーを送ることができます... – SepehrM

関連する問題