2010-01-24 30 views
5

De acuerdo con las respuestas que recibí en superuser, está claro que tendré que agregar lo siguiente a un iniciador de ventana Explorer personalizado. Quiero iniciar una vista del explorador rooteado, y para solo esa ventana hace que el panel de navegación se parezca al antiguo panel de carpetas de Windows XP. Ya tengo wrote a program para colocar accesos directos a estas vistas de carpeta en el Menú de Inicio, por lo que cambiar los accesos directos para ejecutar a través de un iniciador es trivial.Manipular el panel de navegación del Explorador de Windows 7

Aquí está el panel de carpetas XP:

Windows XP Explorer Folders Pane

Aquí está el Windows 7 Panel de navegación:

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

+1

Quizás podría explicar por qué querría hacer esto. Creo que un usuario lo odiaría. – PeteT

+1

@ petebob796: Lo uso para que pueda abrir una ventana especial que muestre el proyecto en el que estoy trabajando. El programa es una utilidad que coloco en el menú de inicio para "abrir la carpeta _____ con una vista rooteada", por lo que no es como si estuviera escabulléndole la configuración a las personas. –

Respuesta

3

Bien, no tengo tiempo para terminar completamente este código (y está en C#, que no tengo idea de qué es lo que quieres, pero en realidad no especificaste). La premisa básica de esto es alojar el control ExplorerBrowser dentro de un formulario .NET (usando el WindowsAPICodePack que deberá obtener y agregar una referencia), esperar hasta que se haya creado el TreeView y crear una subclasificación de la ventana para permitirnos interceptar el insertaciones de elementos.

Lamentablemente, nada es simple, el texto no le da una idea directa de lo que es el artículo (porque no lo configuran), lo que tendría que hacer es obtener el PIDL del insertStruct.lParam y analizarlo en algo significativo, probablemente usando la interfaz IShellFolder. Luego puede eliminar elementos selectivamente (devolviendo 0 como m.Result) y puede interceptar cualquier otra cosa que necesite. Pensarías que habría una solución simple pero supongo que tu suerte no está;) Espero que ayude un poco.

Una alternativa podría ser similar (explorador de host directamente) pero use algo como detours para enganchar las funciones de registro y cambiar selectivamente la vista que el control del explorador obtiene permitiendo que algunos ajustes de registro funcionen.

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

Gracias, parece que esto podría ser una solución viable. –

+0

Hola, he usado este código y funciona bien. Pero ¿cómo puedo ocultar los diferentes dolores en el explorador? es decir. Dolor de navegación También se oculta el área de búsqueda en la parte superior derecha. ¿Es posible mostrar la opción de búsqueda? –

-1

No es posible en Windows 7 para hacer lo que estás pidiendo, es decir, personalice la apariencia de la ventana del Explorador para eliminar todos los elementos (Bibliotecas, Favoridades, etc.) del panel de navegación, a excepción de la vista de árbol Carpetas, para una sola instancia del Explorador. Puede hacerlo, como habrá descubierto, como una configuración de todo el sistema, modificando el registro en 4 lugares. De forma alternativa y más simple, puede configurar "Mostrar todas las carpetas" en el panel de navegación en las ventanas de propiedades del Explorer (si está de acuerdo con que el enlace "Favoritos" aún esté allí). Sin embargo, ambos son ajustes de todo el sistema y afectarán a todas las ventanas del Explorador.

Lo siento, sé que esto no te da lo que buscas, pero la configuración de todo el sistema es tu única opción para eliminar estos elementos del panel de navegación. (Por cierto, no estás solo aquí; hay muchas personas que prefieren la vista XP Explorer).

+1

Sé que esta respuesta se aplica a la configuración estándar de Windows, pero ¿está seguro de que se aplica a todas las interfaces de Shell? En este punto, estoy buscando hacer una manipulación programática de la ventana. (En algún momento Explorer tiene que verificar la configuración de Windows, lo que significa que en el peor de los casos podría manipularse conectando sus llamadas al registro). –

+0

Sí, he estado buscando los modos de Dios en el registro y tengo no se encontró ninguno que cumpla con estas especificaciones. La configuración de la directiva de grupo para Win7 aún no está completamente documentada (AFAIK), por lo que es otra área que he estado buscando ya que GP generalmente es mucho más configurable para los administradores. Parece extraño que MSFT elimine esta vista desde el punto de vista de la configuración del usuario. Seguiré buscando un poco más, pero no estoy seguro de que los resultados sean iguales a esta vista. –

+2

Supongo que la respuesta se encuentra en las interfaces COM. –

0

Si se puede recuperar un puntero a la interfaz IShellFolderViewDual2 o IShellFolderViewDual3 de la instancia Explorer, entonces el método ViewOptions permite especificar SFVVO_WIN95CLASSIC.

Cuestiones relacionadas