그래,이 코드를 완전히 끝내야 할 시간이 없다. (그리고 C#에서는 내가 원하는 바가 없지만 실제로는 지정하지 않았다.) 이것의 기본 전제는 NET Form 내에서 ExplorerBrowser 컨트롤을 호스팅하는 것입니다 (참조를 가져오고 추가해야하는 WindowsAPICodePack 사용). TreeView가 생성 될 때까지 기다렸다가 윈도우를 서브 클래스하여 가로 채기를 허용합니다. 항목 삽입
유감스럽게도이 텍스트는 항목이 무엇인지 직접적으로 알려주지 않으므로 (설정하지 않았기 때문에) insertStruct.lParam
에서 PIDL을 가져 와서 구문 분석해야합니다 의미있는 것으로, 아마 IShellFolder
인터페이스를 사용하십시오. 그런 다음 항목을 선택적으로 제거 할 수 있습니다 (0을 m.Result
으로 반환 함). 그러면 필요한 항목을 가로 챌 수 있습니다. 당신은 거기에 간단한 해결책이 될 것이라고 생각하지만, 당신의 운이 아닌 것 같아요;) 희망이 약간 도움이됩니다.
대체 기능 (호스트 탐색기에서 직접)을 수행 할 수도 있지만 detours과 같은 것을 사용하여 레지스트리 기능을 연결하고 탐색기 컨트롤이 일부 레지스트리 조정이 작동하도록 허용하는보기를 선택적으로 변경합니다. 당신이 탐색기 인스턴스의 IShellFolderViewDual2
또는 IShellFolderViewDual3
인터페이스의 포인터를 검색 할 수있는 경우
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:\\"));
}
}
}
아마 당신이 이것을 원할 이유를 설명 할 수 있습니다. 나는 사용자가 그것을 싫어할 것이라고 생각할 것이다. – PeteT
@ petebob796 : 나는 그것을 사용하여 내가 작업하고있는 프로젝트를 보여주는 특별한 창을 열어 놓을 수있다. 이 프로그램은 시작 메뉴에 "뿌리 낀 모습으로 _____ 폴더를 시작합니다"라는 유틸리티입니다. 그래서 나는 사람들에 대한 설정을 몰래하는 것과 같지 않습니다. –