⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 shellbrowserupdater.cs

📁 C#界面编程
💻 CS
字号:
using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;

namespace ShellDll
{
    internal class ShellBrowserUpdater : NativeWindow
    {
        #region Fields

        private ShellBrowser br;
        private uint notifyId = 0;

        #endregion

        public ShellBrowserUpdater(ShellBrowser br)
        {
            this.br = br;
            CreateHandle(new CreateParams());

            ShellAPI.SHChangeNotifyEntry entry = new ShellAPI.SHChangeNotifyEntry();
            entry.pIdl = br.DesktopItem.PIDLRel.Ptr;
            entry.Recursively = true;

            notifyId = ShellAPI.SHChangeNotifyRegister(
                this.Handle,
                ShellAPI.SHCNRF.InterruptLevel | ShellAPI.SHCNRF.ShellLevel,
                ShellAPI.SHCNE.ALLEVENTS | ShellAPI.SHCNE.INTERRUPT,
                ShellAPI.WM.SH_NOTIFY,
                1,
                new ShellAPI.SHChangeNotifyEntry[] { entry });
        }

        ~ShellBrowserUpdater()
        {
            if (notifyId > 0)
            {
                ShellAPI.SHChangeNotifyDeregister(notifyId);
                GC.SuppressFinalize(this);
            }
        }

        protected override void WndProc(ref Message m)
        {
            if (m.Msg == (int)ShellAPI.WM.SH_NOTIFY)
            {
                ShellAPI.SHNOTIFYSTRUCT shNotify =
                    (ShellAPI.SHNOTIFYSTRUCT)Marshal.PtrToStructure(m.WParam, typeof(ShellAPI.SHNOTIFYSTRUCT));

                //Console.Out.WriteLine("Event: {0}", (ShellAPI.SHCNE)m.LParam);
                //if (shNotify.dwItem1 != IntPtr.Zero)
                    //PIDL.Write(shNotify.dwItem1);
                //if (shNotify.dwItem2 != IntPtr.Zero)
                    //PIDL.Write(shNotify.dwItem2);

                switch ((ShellAPI.SHCNE)m.LParam)
                {
                    #region File Changes

                    case ShellAPI.SHCNE.CREATE:
                        #region Create Item
                        {
                            if (!PIDL.IsEmpty(shNotify.dwItem1))
                            {
                                IntPtr parent, child, relative;
                                PIDL.SplitPidl(shNotify.dwItem1, out parent, out child);

                                PIDL parentPIDL = new PIDL(parent, false);
                                ShellItem parentItem = br.GetShellItem(parentPIDL);
                                if (parentItem != null && parentItem.FilesExpanded && !parentItem.SubFiles.Contains(child))
                                {
                                    ShellAPI.SHGetRealIDL(
                                        parentItem.ShellFolder,
                                        child,
                                        out relative);
                                    parentItem.AddItem(new ShellItem(br, parentItem, relative));
                                }
                                    
                                Marshal.FreeCoTaskMem(child);
                                parentPIDL.Free();
                            }
                        }
                        #endregion
                        break;

                    case ShellAPI.SHCNE.RENAMEITEM:
                        #region Rename Item
                        {
                            if (!PIDL.IsEmpty(shNotify.dwItem1) && !PIDL.IsEmpty(shNotify.dwItem2))
                            {
                                ShellItem item = br.GetShellItem(new PIDL(shNotify.dwItem1, true));
                                if (item != null)
                                    item.Update(shNotify.dwItem2, ShellItemUpdateType.Renamed);
                            }
                        }
                        #endregion
                        break;

                    case ShellAPI.SHCNE.DELETE:
                        #region Delete Item
                        {
                            if (!PIDL.IsEmpty(shNotify.dwItem1))
                            {
                                IntPtr parent, child;
                                PIDL.SplitPidl(shNotify.dwItem1, out parent, out child);

                                PIDL parentPIDL = new PIDL(parent, false);
                                ShellItem parentItem = br.GetShellItem(parentPIDL);
                                if (parentItem != null && parentItem.SubFiles.Contains(child))
                                    parentItem.RemoveItem(parentItem.SubFiles[child]);

                                Marshal.FreeCoTaskMem(child);
                                parentPIDL.Free();
                            }
                        }
                        #endregion
                        break;

                    case ShellAPI.SHCNE.UPDATEITEM:
                        #region Update Item
                        {
                            if (!PIDL.IsEmpty(shNotify.dwItem1))
                            {
                                ShellItem item = br.GetShellItem(new PIDL(shNotify.dwItem1, true));
                                if (item != null)
                                {
                                    Console.Out.WriteLine("Item: {0}", item);
                                    item.Update(IntPtr.Zero, ShellItemUpdateType.Updated);
                                    item.Update(IntPtr.Zero, ShellItemUpdateType.IconChange);
                                }
                            }
                        }
                        #endregion
                        break;

                    #endregion

                    #region Folder Changes

                    case ShellAPI.SHCNE.MKDIR:                        
                    case ShellAPI.SHCNE.DRIVEADD:
                    case ShellAPI.SHCNE.DRIVEADDGUI:                        
                        #region Make Directory
                        {
                            if (!PIDL.IsEmpty(shNotify.dwItem1))
                            {
                                IntPtr parent, child, relative;
                                PIDL.SplitPidl(shNotify.dwItem1, out parent, out child);

                                PIDL parentPIDL = new PIDL(parent, false);
                                ShellItem parentItem = br.GetShellItem(parentPIDL);
                                if (parentItem != null && parentItem.FoldersExpanded && !parentItem.SubFolders.Contains(child))
                                {
                                    ShellAPI.SHGetRealIDL(
                                        parentItem.ShellFolder,
                                        child,
                                        out relative);

                                    IntPtr shellFolderPtr;
                                    if (parentItem.ShellFolder.BindToObject(
                                                relative,
                                                IntPtr.Zero,
                                                ref ShellAPI.IID_IShellFolder,
                                                out shellFolderPtr) == ShellAPI.S_OK)
                                    {
                                        parentItem.AddItem(new ShellItem(br, parentItem, relative, shellFolderPtr));
                                    }
                                    else
                                        Marshal.FreeCoTaskMem(relative);
                                }

                                Marshal.FreeCoTaskMem(child);
                                parentPIDL.Free();
                            }
                        }
                        #endregion
                        break;

                    case ShellAPI.SHCNE.RENAMEFOLDER:
                        #region Rename Directory
                        {
                            if (!PIDL.IsEmpty(shNotify.dwItem1) && !PIDL.IsEmpty(shNotify.dwItem2))
                            {
                                ShellItem item = br.GetShellItem(new PIDL(shNotify.dwItem1, false));
                                if (item != null)
                                {
                                    //Console.Out.WriteLine("Update: {0}", item);
                                    item.Update(shNotify.dwItem2, ShellItemUpdateType.Renamed);
                                }
                            }
                        }
                        #endregion
                        break;

                    case ShellAPI.SHCNE.RMDIR:
                    case ShellAPI.SHCNE.DRIVEREMOVED:
                        #region Remove Directory
                        {
                            if (!PIDL.IsEmpty(shNotify.dwItem1))
                            {
                                IntPtr parent, child;
                                PIDL.SplitPidl(shNotify.dwItem1, out parent, out child);

                                PIDL parentPIDL = new PIDL(parent, false);
                                ShellItem parentItem = br.GetShellItem(parentPIDL);
                                if (parentItem != null && parentItem.SubFolders.Contains(child))
                                    parentItem.RemoveItem(parentItem.SubFolders[child]);

                                Marshal.FreeCoTaskMem(child);
                                parentPIDL.Free();
                            }
                        }
                        #endregion
                        break;

                    case ShellAPI.SHCNE.UPDATEDIR:
                    case ShellAPI.SHCNE.ATTRIBUTES:
                        #region Update Directory
                        {
                            if (!PIDL.IsEmpty(shNotify.dwItem1))
                            {
                                ShellItem item = br.GetShellItem(new PIDL(shNotify.dwItem1, true));
                                if (item != null)
                                {
                                    item.Update(IntPtr.Zero, ShellItemUpdateType.Updated);
                                    item.Update(IntPtr.Zero, ShellItemUpdateType.IconChange);
                                }
                            }
                        }
                        #endregion
                        break;

                    case ShellAPI.SHCNE.MEDIAINSERTED:
                    case ShellAPI.SHCNE.MEDIAREMOVED:
                        #region Media Change
                        {
                            if (!PIDL.IsEmpty(shNotify.dwItem1))
                            {
                                ShellItem item = br.GetShellItem(new PIDL(shNotify.dwItem1, true));
                                if (item != null)
                                    item.Update(IntPtr.Zero, ShellItemUpdateType.MediaChange);
                            }
                        }
                        #endregion
                        break;

                    #endregion

                    #region Other Changes

                    case ShellAPI.SHCNE.ASSOCCHANGED:
                        #region Update Images
                        {
                            
                        }
                        #endregion
                        break;

                    case ShellAPI.SHCNE.NETSHARE:
                    case ShellAPI.SHCNE.NETUNSHARE:
                        break;

                    case ShellAPI.SHCNE.UPDATEIMAGE:
                        UpdateRecycleBin();
                        break;

                    #endregion
                }
            }

            base.WndProc(ref m);
        }

        private void UpdateRecycleBin()
        {
            ShellItem recycleBin = br.DesktopItem["Recycle Bin"];
            if (recycleBin != null)
                recycleBin.Update(IntPtr.Zero, ShellItemUpdateType.IconChange);
        }
    }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -