2010-01-24 2 views
5

In base alle risposte che ho ricevuto allo superuser, è chiaro che dovrò aggiungere quanto segue a un launcher di Finestra Explorer personalizzato. Voglio avviare una vista di esplorazione rooted e per solo quella finestra rendere il riquadro di spostamento simile al vecchio riquadro delle cartelle di Windows XP. Ho già wrote a program di inserire collegamenti a queste viste delle cartelle nel menu Start, quindi la modifica delle scorciatoie da eseguire attraverso un launcher è banale.Manipolazione del pannello di navigazione di Windows 7 Explorer

Ecco il XP cartelle riquadro:

Windows XP Explorer Folders Pane

Ecco il Windows 7 Navigation Pane:

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

+1

Forse potresti spiegare perché vorresti farlo. Penserei che un utente lo odiasse. – PeteT

+1

@ petebob796: Io lo uso così posso avere una finestra speciale aperta che mostra qualunque progetto stia lavorando. Il programma è un'utilità che metto nel menu di avvio per "lanciare la cartella _____ con una vista radicata", quindi non è come se stessi inserendo l'impostazione sulle persone. –

risposta

3

Okay, non ho il tempo di terminare completamente questo codice (ed è in C# che non ho idea di ciò che si desidera, ma in realtà non si specificava). La premessa di base di questo è l'hosting del controllo ExplorerBrowser all'interno di un modulo .NET (utilizzando lo WindowsAPICodePack per il quale è necessario ottenere e aggiungere un riferimento), attendere fino a quando TreeView non è stato creato e sottoclasse la finestra per consentirci di intercettare il inserzioni di oggetti.

Sfortunatamente niente è mai semplice, il testo non ti dà un'idea diretta di cosa sia l'oggetto (perché non lo impostano), quello che dovresti fare è ottenere il PIDL dal insertStruct.lParam e analizzarlo in qualcosa di significativo, probabilmente usando l'interfaccia IShellFolder. È quindi possibile rimuovere selettivamente gli elementi (restituendo 0 come m.Result) e si può intercettare qualsiasi altra cosa è necessario. Penseresti che ci sarebbe una soluzione semplice ma immagino che la tua fortuna non sia in;) Spero che aiuti un po '.

Un'alternativa potrebbe essere simile (host explorer direttamente) ma utilizzare qualcosa come detours per agganciare le funzioni del Registro di sistema e modificare selettivamente la visualizzazione del controllo di Esplora risorse che consente il corretto funzionamento di alcuni dei tweaking del Registro di sistema.

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

Grazie, sembra che questa potrebbe essere una soluzione praticabile. –

+0

Ciao, ho usato questo codice e funziona perfettamente. Ma come posso nascondere i diversi dolori dell'esploratore. vale a dire. Dolore di navigazione. Inoltre nasconde l'area di ricerca in alto a destra. È possibile mostrare l'opzione di ricerca? –

-1

Non è possibile in Windows 7 per fare quello che stai chiedendo, Ad esempio, personalizzare l'aspetto della finestra di Explorer per rimuovere tutti gli elementi (librerie, preferenze, ecc.) dal riquadro di spostamento, ad eccezione della vista ad albero delle cartelle, per una singola istanza di Explorer. Puoi farlo, come potresti aver scoperto, come impostazione a livello di sistema, modificando il registro in 4 punti. In alternativa e più semplicemente, puoi impostare "Mostra tutte le cartelle" nel riquadro di navigazione nelle finestre delle proprietà di Explorer (se stai bene con il link "Preferiti" che è ancora lì). Tuttavia, entrambe sono impostazioni a livello di sistema e interesseranno tutte le finestre di Explorer.

Siamo spiacenti, lo so che questo non ti fa capire cosa stai cercando, ma le impostazioni di sistema sono le uniche opzioni per rimuovere questi elementi dal riquadro di navigazione. (A proposito, non sei solo qui - ci sono molte persone che preferiscono la vista di XP Explorer).

+1

So che questa risposta si applica alle impostazioni standard di Windows, ma sei sicuro che si applichi a tutte le interfacce Shell? A questo punto sto cercando di eseguire una manipolazione programmatica della finestra. (A un certo punto Explorer deve controllare le impostazioni di Windows, il che significa che nel peggiore dei casi potrebbe essere manipolato agganciando le sue chiamate al registro.) –

+0

Sì, ho controllato le eventuali modalità di Dio nel registro e ho non trovato alcuno che risponda a queste specifiche. Le impostazioni di Criteri di gruppo per Win7 non sono ancora completamente documentate (AFAIK), quindi questa è un'altra area che stavo cercando dato che GP di solito è molto più configurabile per gli amministratori. Sembra strano che MSFT rimuova questa vista tutti insieme da un punto di vista della configurazione dell'utente. Continuerò a fare un po 'più di ricerca, ma non sono sicuro che i risultati saranno uguali a questa visione. –

+2

Sto indovinando la risposta sta nel profondo delle interfacce COM. –

0

Se è possibile recuperare un puntatore a un'interfaccia IShellFolderViewDual2 o IShellFolderViewDual3 dell'istanza Explorer, allora il metodo ViewOptions permette di specificare SFVVO_WIN95CLASSIC.