代码之家  ›  专栏  ›  技术社区  ›  Sam Harwell

操作Windows 7资源管理器导航窗格

  •  5
  • Sam Harwell  · 技术社区  · 15 年前

    根据我在 superuser>上收到的答案,很明显我必须将以下内容添加到自定义资源管理器窗口启动程序中。我想启动一个根资源管理器视图,并且对于 Just that window >strong>Make the navigation pane look like the old windows xp folders pane.我已经在“开始”菜单上写了一个程序,把这些文件夹视图的快捷方式放在“开始”菜单上,所以把快捷方式改成“运行通过启动程序”很简单。

    这是xp文件夹窗格:

    这是Windows 7导航窗格:

    Windows 7 Explorer导航窗格http://www.280z28.org/images/navigationpaneproblems.png >p很明显,我必须将以下内容添加到自定义的浏览器窗口启动程序中。我想启动根资源管理器视图, 就在那个窗口 使导航窗格看起来像旧的Windows XP文件夹窗格。我已经 wrote a program 将这些文件夹视图的快捷方式放置在“开始”菜单上,因此将快捷方式更改为通过启动程序运行是很简单的。

    这是xp文件夹窗格:

    Windows XP Explorer Folders Pane

    以下是Windows 7导航窗格:

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

    3 回复  |  直到 10 年前
        1
  •  3
  •   Jonathon Reinhart    10 年前

    好吧,好吧,我还没有时间完全完成这段代码(它是C语言的,我不知道你想要什么,但你没有具体说明)。其基本前提是在.NET窗体内托管ExplorerBrowser控件(使用 WindowsAPICodePack 您需要获取并添加一个引用),等待TreeView创建完成,并对窗口进行子类化,以便我们截取项目插入。

    不幸的是,没有任何事情是简单的,文本没有给你一个直接的概念是什么项目(因为他们没有设置它),你需要做的是从 insertStruct.lParam 并将其解析为有意义的内容,可能使用 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:\\"));
            }
        }
    }
    
        2
  •  0
  •   Jonathon Reinhart    10 年前

    如果可以检索指向资源管理器实例的指针 IShellFolderViewDual2 IShellFolderViewDual3 接口,然后 ViewOptions 方法允许您指定 SFVVO_WIN95CLASSIC .

        3
  •  -1
  •   Todd Main    15 年前

    在Win 7中,不可能按照您的要求执行操作,即自定义资源管理器窗口的外观,从导航窗格中删除除文件夹树视图以外的所有项目(库、收藏夹等),只针对一个资源管理器实例。您可以通过在4个位置修改注册表来实现这一点,正如您可能已经发现的那样,作为一个系统范围的设置。或者,更简单地说,您可以在资源管理器的属性窗口的导航窗格中设置“显示所有文件夹”(如果您对“收藏夹”链接仍然存在感到满意)。但是,这两种设置都是系统范围的设置,将影响所有资源管理器窗口。

    抱歉,我知道这并不能让你得到你想要的,但是系统范围的设置是你从导航窗格中删除这些项目的唯一选项。(顺便说一句,这里并不是只有你一个人——有很多人更喜欢xp explorer视图)。