2010-01-24 233 views
5

根據我在superuser收到的答案,很明顯我必須將以下內容添加到自定義資源管理器窗口啓動器中。我想啓動一個根目錄的資源管理器視圖,並且對於只是該窗口使導航窗格看起來像舊的Windows XP文件夾窗格。我已經在wrote a program中將快捷方式放置在「開始」菜單上的這些文件夾視圖中,因此更改通過啓動程序運行的快捷方式並不重要。操作Windows 7資源管理器導航窗格

這裏的XP文件夾窗格:

Windows XP Explorer Folders Pane

下面是Windows 7的導航窗格:

Windows 7 Explorer Navigation Pane http://www.280z28.org/images/NavigationPaneProblems.png

+1

也許你可以解釋你爲什麼想要這樣做。我想用戶會討厭它。 – PeteT 2010-02-02 15:21:03

+1

@ petebob796:我使用它,所以我可以打開一個特殊的窗口,顯示我正在處理的任何項目。該程序是我在開始菜單上放置的一個實用程序,用於「以帶有根的視圖啓動文件夾_____」,所以它不像我偷偷摸摸地設置人員。 – 2010-02-02 17:48:30

回答

3

好吧,我沒有足夠的時間來完成這段代碼(它是在C#中,我不知道是你想要的,但你沒有真正指定)。它的基本前提是在.NET窗體中使用ExplorerBrowser控件(使用WindowsAPICodePack,您需要獲取並添加引用),等待TreeView被創建並創建窗口的子類以允許我們截取項目插入。

不幸的是,沒有什麼是簡單的,文本並沒有給你一個項目是什麼(因爲他們沒有設置它)的直接想法,你需要做的是從insertStruct.lParam得到PIDL並解析它變成有意義的東西,可能使用IShellFolder界面。然後你可以有選擇地移除物品(通過返回0作爲m.Result),你可以攔截任何你需要的東西。你會認爲會有一個簡單的解決方案,但我猜你的運氣不在;)希望它有一點幫助。

另一種方法可能會做類似(主機瀏覽器直接),但使用像detours鉤子註冊表功能,並選擇性地更改瀏覽器控件獲取允許一些註冊表調整工作的視圖。

using System; 
using System.Collections.Generic; 
using System.ComponentModel; 
using System.Data; 
using System.Drawing; 
using System.Linq; 
using System.Text; 
using System.Windows.Forms; 
using Microsoft.WindowsAPICodePack.Shell; 
using System.Runtime.InteropServices; 

namespace MyExplorer 
{ 
    public partial class Form1 : Form 
    { 
     const int WH_CALLWNDPROC = 4;   
     const int WM_CREATE = 1; 

     public delegate int HookProc(int nCode, IntPtr wParam, IntPtr lParam); 

     [DllImport("user32.dll", CharSet = CharSet.Auto, 
     CallingConvention = CallingConvention.StdCall)] 
     public static extern IntPtr SetWindowsHookEx(int idHook, HookProc lpfn, 
     IntPtr hInstance, int threadId); 

     [DllImport("user32.dll", CharSet = CharSet.Auto, 
     CallingConvention = CallingConvention.StdCall)] 
     public static extern bool UnhookWindowsHookEx(IntPtr hHook); 

     [DllImport("user32.dll", CharSet = CharSet.Auto, 
     CallingConvention = CallingConvention.StdCall)] 
     public static extern int CallNextHookEx(IntPtr hHook, int nCode, 
     IntPtr wParam, IntPtr lParam); 

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

     IntPtr m_hHook; 
     HookProc HookDelegate; 

     struct WindowHookStruct 
     {    
      public IntPtr lParam; 
      public IntPtr wParam; 
      public uint message; 
      public IntPtr hwnd; 
     } 

     public class SubclassTreeView : NativeWindow 
     {   
      const int TV_FIRST = 0x1100; 
      //const int TVM_INSERTITEMA = (TV_FIRST + 0); 
      const int TVM_INSERTITEMW = (TV_FIRST + 50); 

      struct TVINSERTSTRUCTW 
      { 
       public IntPtr hParent; 
       public IntPtr hInsertAfter;  
       /* TVITEMW */ 
       public uint mask; 
       public IntPtr hItem; 
       public uint state; 
       public uint stateMask; 
       public IntPtr pszText; 
       public int cchTextMax; 
       public int iImage; 
       public int iSelectedImage; 
       public int cChildren; 
       public IntPtr lParam; 
      } 

      int count = 0; 

      protected override void WndProc(ref Message m) 
      {     
       bool bHandled = false;        

       switch (m.Msg) 
       { 
        case TVM_INSERTITEMW:       
         TVINSERTSTRUCTW insertStruct = (TVINSERTSTRUCTW)Marshal.PtrToStructure(m.LParam, typeof(TVINSERTSTRUCTW)); 

         /* Change text to prove a point */ 
         string name = String.Format("{0:X} {1} Hello", insertStruct.hParent.ToInt64(), count++); 
         insertStruct.pszText = Marshal.StringToBSTR(name); 
         insertStruct.cchTextMax = name.Length+1; 
         Marshal.StructureToPtr(insertStruct, m.LParam, false);       

         /* insertStruct.lParam is a pointer to a IDL, 
          use IShellFolder::GetDisplayNameOf to pull out a sensible 
          name to work out what to hide */ 
         /* Uncomment this code to delete the entry */ 
         //bHandled = true; 
         //m.Result = IntPtr.Zero;             
         break; 
       } 

       if (!bHandled) 
       { 
        base.WndProc(ref m); 
       } 
      } 
     } 

     /* Not complete structure, don't need it */ 
     struct MSG 
     { 
      public IntPtr hwnd; 
      public uint message; 
      public IntPtr wParam; 
      public IntPtr lParam; 
     } 

     SubclassTreeView sc = null; 

     public Form1() 
     { 
      InitializeComponent(); 
      HookDelegate = new HookProc(HookWindowProc); 
      m_hHook = SetWindowsHookEx(WH_CALLWNDPROC, HookDelegate, (IntPtr)0, AppDomain.GetCurrentThreadId()); 
     } 

     int HookWindowProc(int nCode, IntPtr wParam, IntPtr lParam) 
     {   
      if (nCode < 0) 
      { 
       return CallNextHookEx(m_hHook, nCode, wParam, lParam); 
      } 
      else 
      { 

       WindowHookStruct hookInfo = (WindowHookStruct)Marshal.PtrToStructure(lParam, typeof(WindowHookStruct)); 
       StringBuilder sb = new StringBuilder(1024); 

       if (hookInfo.message == WM_CREATE) 
       { 
        if (GetClassName(hookInfo.hwnd, sb, 1024) > 0) 
        { 
         System.Diagnostics.Debug.WriteLine(sb.ToString()); 
         if (sb.ToString() == "SysTreeView32") 
         { 
          sc = new SubclassTreeView(); 
          sc.AssignHandle(hookInfo.hwnd); 
          UnhookWindowsHookEx(m_hHook); 
         } 
        } 
       } 

       return CallNextHookEx(m_hHook, nCode, wParam, lParam);     
      } 
     } 

     private void Form1_Load(object sender, EventArgs e) 
     {       
      explorerBrowser1.Navigate(ShellLink.FromParsingName("C:\\")); 
     } 
    } 
} 
+0

謝謝,看起來這可能是一個可行的解決方案。 – 2010-02-03 01:37:44

+0

嗨我已經使用這段代碼,它工作正常。但我怎樣才能在探險家中隱藏不同的痛苦。即。導航疼痛。它也隱藏在右上角的搜索區域。可以顯示搜索選項嗎? – 2013-08-20 16:35:40

-1

這是不可能在Win 7做你問什麼,即自定義資源管理器窗口的外觀,以便從資源管理器的單個實例中除去文件夾樹視圖中的導航窗格中的所有項目(庫,收藏等)。您可以通過在4個地方修改註冊表來做到這一點,就像您可能已經發現的那樣,將其作爲系統範圍的設置。或者更簡單地說,您可以在資源管理器屬性窗口中的導航窗格中設置「顯示所有文件夾」(如果您還好,「收藏夾」鏈接仍然存在)。但是,這些都是系統範圍的設置,並且會影響所有資源管理器窗口。

對不起,我知道這並不能幫助您解決問題,但系統範圍設置是您從導航窗格中刪除這些項目的唯一選項。 (順便說一句,你並不孤單 - 有很多人喜歡XP資源管理器視圖)。

+1

我知道這個答案適用於標準的Windows設置,但你確定它適用於所有的Shell接口?在這一點上,我正在尋找對窗口進行編程操作。 (在某些情況下,資源管理器本身必須檢查Windows設置,這意味着在最糟糕的情況下,它可以通過將它的調用掛接到註冊表來操縱。) – 2010-02-02 17:46:19

+0

是的,我一直在檢查註冊表中的任何上帝模式,並且沒有發現任何符合這些規格的東西。對於Win7的組策略設置尚未完整記錄(AFAIK),所以這是我一直在尋找的另一個領域,因爲GP通常對管理員來說更加可配置。似乎奇怪的是,MSFT會從用戶設置配置的角度將這個視圖全部刪除。我會繼續做更多的搜索,但我不相信結果會等於這個觀點。 – 2010-02-02 18:46:18

+2

我猜測答案在於COM接口。 – 2010-02-02 18:57:23

0

如果你可以檢索一個指向資源管理器實例的IShellFolderViewDual2IShellFolderViewDual3接口,那麼ViewOptions方法讓你指定SFVVO_WIN95CLASSIC

相關問題