Управление панелью навигации Windows 7 Explorer - PullRequest
5 голосов
/ 24 января 2010

Исходя из ответов, которые я получил в superuser , ясно, что мне придется добавить следующее в пользовательскую панель запуска Explorer. Я хочу запустить представление с рутированным проводником, и для только это окно сделает панель навигации похожей на панель старых папок Windows XP. Я уже написал программу для размещения ярлыков для этих представлений папок в меню «Пуск», поэтому изменение ярлыков для запуска через средство запуска является тривиальным.

Вот панель папок XP:

Windows XP Explorer Folders Pane

Вот панель навигации Windows 7:

Windows 7 Explorer Navigation Pane
(источник: 280z28.org )

Ответы [ 3 ]

3 голосов
/ 03 февраля 2010

Хорошо, у меня нет времени, чтобы полностью закончить этот код (и это на C #, я не знаю, что вы хотите, но вы на самом деле не указали). Основной предпосылкой этого является размещение элемента управления ExplorerBrowser в .NET Form (с использованием WindowsAPICodePack , который вам потребуется для получения и добавления ссылки), подождите, пока TreeView не будет создан, и создайте подклассы окна. чтобы позволить нам перехватить вставки элемента.

К сожалению, ничего не бывает простым, текст не дает вам прямого представления о том, что это за элемент (потому что они его не устанавливают), что вам нужно сделать, это получить PIDL из insertStruct.lParam и выполнить синтаксический анализ. это во что-то значимое, вероятно, с использованием интерфейса IShellFolder. Затем вы можете выборочно удалять элементы (возвращая 0 как m.Result), и вы можете перехватывать все, что вам нужно. Вы могли бы подумать, что будет простое решение, но я думаю, что ваша удача не в этом;) Надеюсь, это поможет немного.

Альтернативой может быть аналогичное (непосредственно проводник хоста), но использование чего-то вроде обхода для перехвата функций реестра и выборочного изменения представления, которое получает элемент управления обозревателя, позволяя некоторым настройкам реестра работать.

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 голосов
/ 03 февраля 2010

Если вы можете получить указатель на интерфейс IShellFolderViewDual2 или IShellFolderViewDual3 экземпляра Explorer, то метод ViewOptions позволяет указать SFVVO_WIN95CLASSIC.

0 голосов
/ 02 февраля 2010

В Win 7 невозможно выполнить то, что вы просите, то есть настроить внешний вид окна Проводника, чтобы удалить все элементы (Библиотеки, Избранное и т. Д.) Из панели навигации, кроме представления дерева папок, один экземпляр Explorer. Вы можете сделать это, как вы, возможно, обнаружили, в качестве общесистемного параметра, изменив реестр в 4 местах. В качестве альтернативы и проще, вы можете установить «Показать все папки» в навигационной панели в окнах свойств Проводника (если у вас все в порядке со ссылкой «Избранное», которая все еще там). Однако оба эти параметра относятся к общесистемным настройкам и влияют на все окна проводника.

Извините, я знаю, что это не даст вам того, что вам нужно, но общесистемные настройки - ваши единственные варианты удаления этих элементов из панели навигации. (Кстати, вы здесь не одиноки - многие предпочитают представление XP Explorer).

...