├── .gitignore
├── Controls
├── ComboBox.cs
├── ListView.cs
└── TreeView.cs
├── EasyExplorer.Designer.cs
├── EasyExplorer.cs
├── EasyExplorer.csproj
├── EasyExplorer.resx
├── EasyExplorer.sln
├── Images
├── BrowseFolders.png
├── BrowserBack.png
├── BrowserForward.png
└── BrowserUp.png
├── LICENSE
├── Properties
├── AssemblyInfo.cs
├── Resources.Designer.cs
└── Resources.resx
├── README.md
├── Shell
├── Interfaces
│ ├── IAdviseSink.cs
│ ├── IContextMenu.cs
│ ├── IDataObject.cs
│ ├── IDragSourceHelper.cs
│ ├── IDropSource.cs
│ ├── IDropTarget.cs
│ ├── IDropTargetHelper.cs
│ ├── IEnumFORMATETC.cs
│ ├── IEnumIDList.cs
│ ├── IEnumSTATSTG.cs
│ ├── IQueryInfo.cs
│ ├── IShellExtInit.cs
│ ├── IShellFolder.cs
│ ├── IStorage.cs
│ └── IStream.cs
├── PIDL.cs
├── ShellAPI.cs
├── ShellBrowser.cs
├── ShellBrowserUpdater.cs
├── ShellHelper.cs
├── ShellImageList.cs
├── ShellItem.cs
└── StreamStorage.cs
├── Website
├── ee1.png
└── ee2.png
└── Wrappers
├── BrowserContextMenuWrappers.cs
├── BrowserDragWrappers.cs
├── BrowserDropWrappers.cs
└── BrowserPluginWrapper.cs
/.gitignore:
--------------------------------------------------------------------------------
1 | ## Ignore Visual Studio temporary files, build results, and
2 | ## files generated by popular Visual Studio add-ons.
3 |
4 | # User-specific files
5 | *.suo
6 | *.user
7 | *.userosscache
8 | *.sln.docstates
9 |
10 | # User-specific files (MonoDevelop/Xamarin Studio)
11 | *.userprefs
12 |
13 | # Build results
14 | [Dd]ebug/
15 | [Dd]ebugPublic/
16 | [Rr]elease/
17 | [Rr]eleases/
18 | x64/
19 | x86/
20 | bld/
21 | [Bb]in/
22 | [Oo]bj/
23 | [Ll]og/
24 |
25 | # Visual Studio 2015 cache/options directory
26 | .vs/
27 | # Uncomment if you have tasks that create the project's static files in wwwroot
28 | #wwwroot/
29 |
30 | # MSTest test Results
31 | [Tt]est[Rr]esult*/
32 | [Bb]uild[Ll]og.*
33 |
34 | # NUNIT
35 | *.VisualState.xml
36 | TestResult.xml
37 |
38 | # Build Results of an ATL Project
39 | [Dd]ebugPS/
40 | [Rr]eleasePS/
41 | dlldata.c
42 |
43 | # DNX
44 | project.lock.json
45 | artifacts/
46 |
47 | *_i.c
48 | *_p.c
49 | *_i.h
50 | *.ilk
51 | *.meta
52 | *.obj
53 | *.pch
54 | *.pdb
55 | *.pgc
56 | *.pgd
57 | *.rsp
58 | *.sbr
59 | *.tlb
60 | *.tli
61 | *.tlh
62 | *.tmp
63 | *.tmp_proj
64 | *.log
65 | *.vspscc
66 | *.vssscc
67 | .builds
68 | *.pidb
69 | *.svclog
70 | *.scc
71 |
72 | # Chutzpah Test files
73 | _Chutzpah*
74 |
75 | # Visual C++ cache files
76 | ipch/
77 | *.aps
78 | *.ncb
79 | *.opendb
80 | *.opensdf
81 | *.sdf
82 | *.cachefile
83 | *.VC.db
84 | *.VC.VC.opendb
85 |
86 | # Visual Studio profiler
87 | *.psess
88 | *.vsp
89 | *.vspx
90 | *.sap
91 |
92 | # TFS 2012 Local Workspace
93 | $tf/
94 |
95 | # Guidance Automation Toolkit
96 | *.gpState
97 |
98 | # ReSharper is a .NET coding add-in
99 | _ReSharper*/
100 | *.[Rr]e[Ss]harper
101 | *.DotSettings.user
102 |
103 | # JustCode is a .NET coding add-in
104 | .JustCode
105 |
106 | # TeamCity is a build add-in
107 | _TeamCity*
108 |
109 | # DotCover is a Code Coverage Tool
110 | *.dotCover
111 |
112 | # NCrunch
113 | _NCrunch_*
114 | .*crunch*.local.xml
115 | nCrunchTemp_*
116 |
117 | # MightyMoose
118 | *.mm.*
119 | AutoTest.Net/
120 |
121 | # Web workbench (sass)
122 | .sass-cache/
123 |
124 | # Installshield output folder
125 | [Ee]xpress/
126 |
127 | # DocProject is a documentation generator add-in
128 | DocProject/buildhelp/
129 | DocProject/Help/*.HxT
130 | DocProject/Help/*.HxC
131 | DocProject/Help/*.hhc
132 | DocProject/Help/*.hhk
133 | DocProject/Help/*.hhp
134 | DocProject/Help/Html2
135 | DocProject/Help/html
136 |
137 | # Click-Once directory
138 | publish/
139 |
140 | # Publish Web Output
141 | *.[Pp]ublish.xml
142 | *.azurePubxml
143 | # TODO: Comment the next line if you want to checkin your web deploy settings
144 | # but database connection strings (with potential passwords) will be unencrypted
145 | *.pubxml
146 | *.publishproj
147 |
148 | # Microsoft Azure Web App publish settings. Comment the next line if you want to
149 | # checkin your Azure Web App publish settings, but sensitive information contained
150 | # in these scripts will be unencrypted
151 | PublishScripts/
152 |
153 | # NuGet Packages
154 | *.nupkg
155 | # The packages folder can be ignored because of Package Restore
156 | **/packages/*
157 | # except build/, which is used as an MSBuild target.
158 | !**/packages/build/
159 | # Uncomment if necessary however generally it will be regenerated when needed
160 | #!**/packages/repositories.config
161 | # NuGet v3's project.json files produces more ignoreable files
162 | *.nuget.props
163 | *.nuget.targets
164 |
165 | # Microsoft Azure Build Output
166 | csx/
167 | *.build.csdef
168 |
169 | # Microsoft Azure Emulator
170 | ecf/
171 | rcf/
172 |
173 | # Windows Store app package directories and files
174 | AppPackages/
175 | BundleArtifacts/
176 | Package.StoreAssociation.xml
177 | _pkginfo.txt
178 |
179 | # Visual Studio cache files
180 | # files ending in .cache can be ignored
181 | *.[Cc]ache
182 | # but keep track of directories ending in .cache
183 | !*.[Cc]ache/
184 |
185 | # Others
186 | ClientBin/
187 | ~$*
188 | *~
189 | *.dbmdl
190 | *.dbproj.schemaview
191 | *.pfx
192 | *.publishsettings
193 | node_modules/
194 | orleans.codegen.cs
195 |
196 | # Since there are multiple workflows, uncomment next line to ignore bower_components
197 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
198 | #bower_components/
199 |
200 | # RIA/Silverlight projects
201 | Generated_Code/
202 |
203 | # Backup & report files from converting an old project file
204 | # to a newer Visual Studio version. Backup files are not needed,
205 | # because we have git ;-)
206 | _UpgradeReport_Files/
207 | Backup*/
208 | UpgradeLog*.XML
209 | UpgradeLog*.htm
210 |
211 | # SQL Server files
212 | *.mdf
213 | *.ldf
214 |
215 | # Business Intelligence projects
216 | *.rdl.data
217 | *.bim.layout
218 | *.bim_*.settings
219 |
220 | # Microsoft Fakes
221 | FakesAssemblies/
222 |
223 | # GhostDoc plugin setting file
224 | *.GhostDoc.xml
225 |
226 | # Node.js Tools for Visual Studio
227 | .ntvs_analysis.dat
228 |
229 | # Visual Studio 6 build log
230 | *.plg
231 |
232 | # Visual Studio 6 workspace options file
233 | *.opt
234 |
235 | # Visual Studio LightSwitch build output
236 | **/*.HTMLClient/GeneratedArtifacts
237 | **/*.DesktopClient/GeneratedArtifacts
238 | **/*.DesktopClient/ModelManifest.xml
239 | **/*.Server/GeneratedArtifacts
240 | **/*.Server/ModelManifest.xml
241 | _Pvt_Extensions
242 |
243 | # Paket dependency manager
244 | .paket/paket.exe
245 | paket-files/
246 |
247 | # FAKE - F# Make
248 | .fake/
249 |
250 | # JetBrains Rider
251 | .idea/
252 | *.sln.iml
253 |
--------------------------------------------------------------------------------
/Controls/ComboBox.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 | using System.Windows.Forms;
5 | using System.Collections;
6 | using System.Drawing;
7 | using System.Runtime.InteropServices;
8 | using ShellDll;
9 | using System.Drawing.Drawing2D;
10 | using System.Globalization;
11 | using System.ComponentModel;
12 |
13 | namespace EasyExplorer
14 | {
15 | #region ComboBox
16 |
17 | ///
18 | /// This is the ComboBox used in the navigationbar. It is extended to show the icons that go with the
19 | /// ShellItems.
20 | ///
21 | internal class ExplorerComboBox : ToolStripComboBox
22 | {
23 | #region Fields
24 |
25 | // The width of the indent of the ComboItems
26 | private int indentWidth = 10;
27 |
28 | // The item for the browser's current selected directory
29 | private ExplorerComboItem currentItem;
30 |
31 | // The class to draw the icon in the textbox area of the ComboBox
32 | private ComboEditWindow editWindow;
33 |
34 | #endregion
35 |
36 | public ExplorerComboBox()
37 | {
38 | ComboBox.DrawMode = DrawMode.OwnerDrawFixed;
39 | ComboBox.DrawItem += new DrawItemEventHandler(ComboBox_DrawItem);
40 | ComboBox.HandleCreated += new EventHandler(ComboBox_HandleCreated);
41 |
42 | ComboBox.MouseDown += new MouseEventHandler(ComboBox_MouseDown);
43 | ComboBox.MouseMove += new MouseEventHandler(ComboBox_MouseMove);
44 | ComboBox.MouseClick += new MouseEventHandler(ComboBox_MouseClick);
45 |
46 | ComboBox.DropDown += new EventHandler(ComboBox_DropDown);
47 | }
48 |
49 | #region Events
50 |
51 | ///
52 | /// This method will change the currentItem field once a new item is selected
53 | ///
54 | protected override void OnSelectedIndexChanged(EventArgs e)
55 | {
56 | base.OnSelectedIndexChanged(e);
57 |
58 | if (ComboBox.SelectedIndex > -1)
59 | currentItem = ComboBox.SelectedItem as ExplorerComboItem;
60 | }
61 |
62 | ///
63 | /// Once the handle has been created a new instance of ComboEditWindow is made to make sure
64 | /// the icons are drawn in the TextBox part of the ComboBox
65 | ///
66 | void ComboBox_HandleCreated(object sender, EventArgs e)
67 | {
68 | editWindow = new ComboEditWindow(this);
69 | }
70 |
71 | ///
72 | /// This method will draw the items of the DropDownList. It will draw the Icon and the text and
73 | /// with the indent that goes with the item
74 | ///
75 | void ComboBox_DrawItem(object sender, DrawItemEventArgs e)
76 | {
77 | if (e.Index == -1)
78 | return;
79 | else
80 | {
81 | ExplorerComboItem item = (ExplorerComboItem)Items[e.Index];
82 |
83 | e.DrawBackground();
84 | e.DrawFocusRectangle();
85 |
86 | int indentOffset = indentWidth * item.Indent;
87 |
88 | int imageYOffset = (e.Bounds.Height - item.Image.Height) / 2;
89 | Point imagePoint = new Point(
90 | e.Bounds.Left + indentOffset + 2,
91 | e.Bounds.Top + imageYOffset);
92 |
93 | Size textSize = e.Graphics.MeasureString(item.Text, Font).ToSize();
94 | int textYOffset = (e.Bounds.Height - textSize.Height) / 2;
95 | Point textPoint = new Point(
96 | e.Bounds.Left + item.Image.Width + indentOffset + 2,
97 | e.Bounds.Top + textYOffset);
98 |
99 | e.Graphics.DrawIcon(item.Image, imagePoint.X, imagePoint.Y);
100 | e.Graphics.DrawString(item.Text, e.Font, new SolidBrush(e.ForeColor), textPoint);
101 | }
102 | }
103 |
104 | ///
105 | /// If the mouse is moved over the icon of the ComboBox this method will change the cursor
106 | /// into an hand to indicate that the icon can be clicked
107 | ///
108 | void ComboBox_MouseMove(object sender, MouseEventArgs e)
109 | {
110 | if (editWindow.ImageRect.Contains(e.Location))
111 | {
112 | Cursor.Current = Cursors.Hand;
113 | }
114 | else if (Cursor.Current == Cursors.Hand)
115 | {
116 | Cursor.Current = Cursors.Default;
117 | }
118 | }
119 |
120 | ///
121 | /// If the mouse is moved over the icon of the ComboBox this method will change the cursor
122 | /// into an hand to indicate that the icon can be clicked
123 | ///
124 | void ComboBox_MouseDown(object sender, MouseEventArgs e)
125 | {
126 | if (editWindow.ImageRect.Contains(e.Location))
127 | Cursor.Current = Cursors.Hand;
128 | }
129 |
130 | ///
131 | /// If the icon of the ComboBox is clicked this method will select all text in the ComboBox
132 | ///
133 | void ComboBox_MouseClick(object sender, MouseEventArgs e)
134 | {
135 | if (editWindow.ImageRect.Contains(e.Location))
136 | SelectAll();
137 | }
138 |
139 | ///
140 | /// This method will make sure that when the ComboBox is dropped down, the width of the DropDownList
141 | /// will be sufficient to fit all items
142 | ///
143 | void ComboBox_DropDown(object sender, EventArgs e)
144 | {
145 | int width = 0;
146 | Graphics gfx = ComboBox.CreateGraphics();
147 | foreach (ExplorerComboItem item in Items)
148 | {
149 | int itemWidth =
150 | gfx.MeasureString(item.Text, Font).ToSize().Width +
151 | item.Image.Width +
152 | indentWidth * item.Indent +
153 | (Items.Count > MaxDropDownItems ? SystemInformation.VerticalScrollBarWidth : 0);
154 |
155 | if (itemWidth > width)
156 | width = itemWidth;
157 | }
158 |
159 | if (width > this.Width)
160 | ComboBox.DropDownWidth = width;
161 | else
162 | ComboBox.DropDownWidth = this.Width;
163 | }
164 |
165 | #endregion
166 |
167 | #region Public
168 |
169 | [Browsable(false)]
170 | public ExplorerComboItem CurrentItem
171 | {
172 | get { return currentItem; }
173 | set { currentItem = value; }
174 | }
175 |
176 | #endregion
177 |
178 | #region ComboEditWindow
179 |
180 | class ComboEditWindow : NativeWindow
181 | {
182 | private const int LEFTMARGIN = 0x1;
183 | private ExplorerComboBox owner;
184 | private Rectangle imageRect;
185 | private int margin = 0;
186 |
187 | ///
188 | /// The native window's original handle is released
189 | /// and the handle of the TextBox is assigned to it.
190 | ///
191 | public ComboEditWindow(ExplorerComboBox owner)
192 | {
193 | this.owner = owner;
194 |
195 | ShellAPI.COMBOBOXINFO info = new ShellAPI.COMBOBOXINFO();
196 | info.cbSize = Marshal.SizeOf(typeof(ShellAPI.COMBOBOXINFO));
197 | ShellAPI.GetComboBoxInfo(owner.ComboBox.Handle, ref info);
198 |
199 | if (!this.Handle.Equals(IntPtr.Zero))
200 | {
201 | this.ReleaseHandle();
202 | }
203 | this.AssignHandle(info.hwndEdit);
204 | }
205 |
206 | public Rectangle ImageRect { get { return imageRect; } }
207 |
208 | ///
209 | /// Set the margin of the TextBox to make room for the icon
210 | ///
211 | /// The margin to set
212 | private void SetMargin(int margin)
213 | {
214 | if (this.margin != margin)
215 | {
216 | this.margin = margin;
217 |
218 | if (owner == null)
219 | return;
220 |
221 | ShellAPI.SendMessage(
222 | this.Handle, ShellAPI.WM.SETMARGINS, LEFTMARGIN,
223 | new IntPtr(margin));
224 | }
225 | }
226 |
227 | ///
228 | /// Whenever the textbox is repainted, this method will draw the icon.
229 | ///
230 | private void DrawImage()
231 | {
232 | if (owner.CurrentItem != null)
233 | {
234 | SetMargin(owner.CurrentItem.Image.Width + 3);
235 |
236 | Icon icon = owner.CurrentItem.Image;
237 | Bitmap image = new Bitmap(icon.Width, icon.Height);
238 |
239 | Graphics imageGfx = Graphics.FromImage(image);
240 | imageRect = new Rectangle(new Point(0, 0), image.Size);
241 | imageGfx.FillRectangle(Brushes.White, imageRect);
242 | imageGfx.DrawIcon(icon, 0, 0);
243 | imageGfx.Flush();
244 |
245 | // Gets a GDI drawing surface from the textbox.
246 | Graphics gfx = Graphics.FromHwnd(this.Handle);
247 |
248 | if (owner.RightToLeft == RightToLeft.Yes)
249 | {
250 | gfx.DrawImage(image, (int)gfx.VisibleClipBounds.Width - icon.Width, 0);
251 | }
252 | else if (owner.RightToLeft == RightToLeft.No)
253 | {
254 | gfx.DrawImage(image, 0, 0);
255 | }
256 |
257 | gfx.Flush();
258 | gfx.Dispose();
259 | }
260 | }
261 |
262 | // Override the WndProc method so that we can redraw the TextBox when the textbox is repainted.
263 | protected override void WndProc(ref Message m)
264 | {
265 | switch (m.Msg)
266 | {
267 | case (int)ShellAPI.WM.PAINT:
268 | base.WndProc(ref m);
269 | DrawImage();
270 | break;
271 | case (int)ShellAPI.WM.LBUTTONDOWN:
272 | base.WndProc(ref m);
273 | DrawImage();
274 | break;
275 | case (int)ShellAPI.WM.KEYDOWN:
276 | base.WndProc(ref m);
277 | DrawImage();
278 | break;
279 | case (int)ShellAPI.WM.KEYUP:
280 | base.WndProc(ref m);
281 | DrawImage();
282 | break;
283 | case (int)ShellAPI.WM.CHAR:
284 | base.WndProc(ref m);
285 | DrawImage();
286 | break;
287 | case (int)ShellAPI.WM.GETTEXTLENGTH:
288 | base.WndProc(ref m);
289 | DrawImage();
290 | break;
291 | case (int)ShellAPI.WM.GETTEXT:
292 | base.WndProc(ref m);
293 | DrawImage();
294 | break;
295 | default:
296 | base.WndProc(ref m);
297 | break;
298 | }
299 | }
300 | }
301 |
302 | #endregion
303 | }
304 |
305 | ///
306 | /// This class represents the items that can be used for the ExplorerComboBox
307 | ///
308 | internal class ExplorerComboItem
309 | {
310 | // The ShellItem that goes with the ComboItem
311 | private ShellItem shellItem;
312 |
313 | // The indent that goes with the ComboItem
314 | private int indent;
315 |
316 | // The Icon that has to be drawn for this ComboItem
317 | private Icon image;
318 |
319 | public ExplorerComboItem(ShellItem shellItem, int indent)
320 | {
321 | this.shellItem = shellItem;
322 | this.indent = indent;
323 | this.image = ShellImageList.GetIcon(shellItem.ImageIndex, true);
324 | }
325 |
326 | #region Properties
327 |
328 | public ShellItem ShellItem { get { return shellItem; } }
329 | public int Indent { get { return indent; } }
330 | public Icon Image { get { return image; } }
331 | public string Text { get { return ShellItem.Text; } }
332 |
333 | #endregion
334 |
335 | public override string ToString()
336 | {
337 | return ShellItem.Path;
338 | }
339 | }
340 |
341 | #endregion
342 | }
--------------------------------------------------------------------------------
/Controls/ListView.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 | using System.Windows.Forms;
5 | using System.Collections;
6 | using System.Drawing;
7 | using System.Runtime.InteropServices;
8 | using ShellDll;
9 | using System.Drawing.Drawing2D;
10 | using System.Globalization;
11 | using System.ComponentModel;
12 |
13 | namespace EasyExplorer
14 | {
15 | #region ListView
16 |
17 | ///
18 | /// This is the ListView used in the Browser control
19 | ///
20 | public class ExplorerListView : ListView
21 | {
22 | #region Fields
23 |
24 | // The arraylist to store the order by which ListViewItems has been selected
25 | private ArrayList selectedOrder;
26 |
27 | private ContextMenu columnHeaderContextMenu;
28 | private bool suspendHeaderContextMenu;
29 | private int columnHeight = 0;
30 |
31 | private ExplorerListSorter sorter;
32 |
33 | #endregion
34 |
35 | public ExplorerListView()
36 | {
37 | OwnerDraw = true;
38 |
39 | HandleCreated += new EventHandler(BrowserListView_HandleCreated);
40 | selectedOrder = new ArrayList();
41 | SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
42 | SetStyle(ControlStyles.AllPaintingInWmPaint, true);
43 |
44 | DrawItem += new DrawListViewItemEventHandler(BrowserListView_DrawItem);
45 | DrawSubItem += new DrawListViewSubItemEventHandler(BrowserListView_DrawSubItem);
46 | DrawColumnHeader += new DrawListViewColumnHeaderEventHandler(BrowserListView_DrawColumnHeader);
47 |
48 | this.Alignment = ListViewAlignment.Left;
49 | sorter = new ExplorerListSorter();
50 | }
51 |
52 | #region Owner Draw
53 |
54 | void BrowserListView_DrawItem(object sender, DrawListViewItemEventArgs e)
55 | {
56 | e.DrawDefault = true;
57 | }
58 |
59 | void BrowserListView_DrawSubItem(object sender, DrawListViewSubItemEventArgs e)
60 | {
61 | e.DrawDefault = true;
62 | }
63 |
64 | void BrowserListView_DrawColumnHeader(object sender, DrawListViewColumnHeaderEventArgs e)
65 | {
66 | e.DrawDefault = true;
67 | columnHeight = e.Bounds.Height;
68 | }
69 |
70 | #endregion
71 |
72 | #region Override
73 |
74 | public new View View
75 | {
76 | get
77 | {
78 | return base.View;
79 | }
80 | set
81 | {
82 | base.View = value;
83 |
84 | if (value == View.Details)
85 | {
86 | foreach (ColumnHeader col in Columns)
87 | if (col.Width == 0)
88 | col.Width = 120;
89 | }
90 | }
91 | }
92 |
93 | protected override void OnItemSelectionChanged(ListViewItemSelectionChangedEventArgs e)
94 | {
95 | if (e.IsSelected)
96 | selectedOrder.Insert(0, e.Item);
97 | else
98 | selectedOrder.Remove(e.Item);
99 |
100 | base.OnItemSelectionChanged(e);
101 | }
102 |
103 | protected override void WndProc(ref Message m)
104 | {
105 | if (this.View == View.Details && columnHeaderContextMenu != null &&
106 | (int)m.Msg == (int)ShellAPI.WM.CONTEXTMENU)
107 | {
108 | if (suspendHeaderContextMenu)
109 | suspendHeaderContextMenu = false;
110 | else
111 | {
112 | int x = (int)ShellHelper.LoWord(m.LParam);
113 | int y = (int)ShellHelper.HiWord(m.LParam);
114 | Point clientPoint = PointToClient(new Point(x, y));
115 |
116 | if (clientPoint.Y <= columnHeight)
117 | columnHeaderContextMenu.Show(this, clientPoint);
118 | }
119 |
120 | return;
121 | }
122 |
123 | base.WndProc(ref m);
124 | }
125 |
126 | #endregion
127 |
128 | #region Events
129 |
130 | ///
131 | /// Once the handle is created we can assign the image lists to the ListView
132 | ///
133 | void BrowserListView_HandleCreated(object sender, EventArgs e)
134 | {
135 | ShellImageList.SetSmallImageList(this);
136 | ShellImageList.SetLargeImageList(this);
137 | }
138 |
139 | #endregion
140 |
141 | #region Public
142 |
143 | [Browsable(false)]
144 | public ArrayList SelectedOrder
145 | {
146 | get { return selectedOrder; }
147 | }
148 |
149 | [Browsable(false)]
150 | public bool SuspendHeaderContextMenu
151 | {
152 | get { return suspendHeaderContextMenu; }
153 | set { suspendHeaderContextMenu = value; }
154 | }
155 |
156 | [Browsable(true)]
157 | public ContextMenu ColumnHeaderContextMenu
158 | {
159 | get { return columnHeaderContextMenu; }
160 | set { columnHeaderContextMenu = value; }
161 | }
162 |
163 | public void SetSorting(bool sorting)
164 | {
165 | if (sorting)
166 | this.ListViewItemSorter = sorter;
167 | else
168 | this.ListViewItemSorter = null;
169 | }
170 |
171 | public void ClearSelections()
172 | {
173 | selectedOrder.Clear();
174 | selectedOrder.Capacity = 0;
175 | }
176 |
177 | public bool GetListItem(ShellItem shellItem, out ListViewItem listItem)
178 | {
179 | listItem = null;
180 |
181 | foreach (ListViewItem item in Items)
182 | {
183 | if (shellItem.Equals(item.Tag))
184 | {
185 | listItem = item;
186 | return true;
187 | }
188 | }
189 |
190 | return false;
191 | }
192 |
193 | #endregion
194 | }
195 |
196 | ///
197 | /// This class is used to sort the ListViewItems in the BrowserListView
198 | ///
199 | internal class ExplorerListSorter : IComparer
200 | {
201 | #region IComparer Members
202 |
203 | ///
204 | /// This method will compare the ShellItems of the ListViewItems to determine the return value for
205 | /// comparing the ListViewItems.
206 | ///
207 | public int Compare(object x, object y)
208 | {
209 | ListViewItem itemX = x as ListViewItem;
210 | ListViewItem itemY = y as ListViewItem;
211 |
212 | if (itemX.Tag != null && itemY.Tag != null)
213 | return ((ShellItem)itemX.Tag).CompareTo(itemY.Tag);
214 | else if (itemX.Tag != null)
215 | return 1;
216 | else if (itemY.Tag != null)
217 | return -1;
218 | else
219 | return 0;
220 | }
221 |
222 | #endregion
223 | }
224 |
225 | #endregion
226 | }
--------------------------------------------------------------------------------
/Controls/TreeView.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 | using System.Windows.Forms;
5 | using System.Collections;
6 | using System.Drawing;
7 | using System.Runtime.InteropServices;
8 | using ShellDll;
9 | using System.Drawing.Drawing2D;
10 | using System.Globalization;
11 | using System.ComponentModel;
12 |
13 | namespace EasyExplorer
14 | {
15 | #region TreeView
16 |
17 | ///
18 | /// This is the TreeView used in the Browser control
19 | ///
20 | public class ExplorerTreeView : TreeView
21 | {
22 | private ExplorerTreeSorter sorter;
23 |
24 | public ExplorerTreeView()
25 | {
26 | HandleCreated += new EventHandler(BrowserTreeView_HandleCreated);
27 |
28 | sorter = new ExplorerTreeSorter();
29 | }
30 |
31 | #region Override
32 |
33 | #endregion
34 |
35 | #region Events
36 |
37 | ///
38 | /// Once the handle is created we can assign the image list to the TreeView
39 | ///
40 | void BrowserTreeView_HandleCreated(object sender, EventArgs e)
41 | {
42 | ShellImageList.SetSmallImageList(this);
43 | }
44 |
45 | #endregion
46 |
47 | #region Public
48 |
49 | public bool GetTreeNode(ShellItem shellItem, out TreeNode treeNode)
50 | {
51 | ArrayList pathList = new ArrayList();
52 |
53 | while (shellItem.ParentItem != null)
54 | {
55 | pathList.Add(shellItem);
56 | shellItem = shellItem.ParentItem;
57 | }
58 | pathList.Add(shellItem);
59 |
60 | pathList.Reverse();
61 |
62 | treeNode = Nodes[0];
63 | for (int i = 1; i < pathList.Count; i++)
64 | {
65 | bool found = false;
66 | foreach (TreeNode node in treeNode.Nodes)
67 | {
68 | if (node.Tag != null && node.Tag.Equals(pathList[i]))
69 | {
70 | treeNode = node;
71 | found = true;
72 | break;
73 | }
74 | }
75 |
76 | if (!found)
77 | {
78 | treeNode = null;
79 | return false;
80 | }
81 | }
82 |
83 | return true;
84 | }
85 |
86 | ///
87 | /// This method will check whether a TreeNode is a parent of another TreeNode
88 | ///
89 | /// The parent TreeNode
90 | /// The child TreeNode
91 | /// true if the parent is a parent of the child, false otherwise
92 | public bool IsParentNode(TreeNode parent, TreeNode child)
93 | {
94 | TreeNode current = child;
95 | while (current.Parent != null)
96 | {
97 | if (current.Parent.Equals(parent))
98 | return true;
99 |
100 | current = current.Parent;
101 | }
102 | return false;
103 | }
104 |
105 | ///
106 | /// This method will check whether a TreeNode is a parent of another TreeNode
107 | ///
108 | /// The parent TreeNode
109 | /// The child TreeNode
110 | /// If the parent is indeed a parent of the child, this will be a path of
111 | /// TreeNodes from the parent to the child including both parent and child
112 | /// true if the parent is a parent of the child, false otherwise
113 | public bool IsParentNode(TreeNode parent, TreeNode child, out TreeNode[] path)
114 | {
115 | ArrayList pathList = new ArrayList();
116 |
117 | TreeNode current = child;
118 | while (current.Parent != null)
119 | {
120 | pathList.Add(current);
121 | if (current.Parent.Equals(parent))
122 | {
123 | pathList.Add(parent);
124 | pathList.Reverse();
125 | path = (TreeNode[])pathList.ToArray(typeof(TreeNode));
126 | return true;
127 | }
128 |
129 | current = current.Parent;
130 | }
131 |
132 | path = null;
133 | return false;
134 | }
135 |
136 | public void SetSorting(bool sorting)
137 | {
138 | if (sorting)
139 | this.TreeViewNodeSorter = sorter;
140 | else
141 | this.TreeViewNodeSorter = null;
142 | }
143 |
144 | #endregion
145 | }
146 |
147 | ///
148 | /// This class is used to sort the TreeNodes in the BrowserTreeView
149 | ///
150 | internal class ExplorerTreeSorter : IComparer
151 | {
152 | #region IComparer Members
153 |
154 | ///
155 | /// This method will compare the ShellItems of the TreeNodes to determine the return value for
156 | /// comparing the TreeNodes.
157 | ///
158 | public int Compare(object x, object y)
159 | {
160 | TreeNode nodeX = x as TreeNode;
161 | TreeNode nodeY = y as TreeNode;
162 |
163 | if (nodeX.Tag != null && nodeY.Tag != null)
164 | return ((ShellItem)nodeX.Tag).CompareTo(nodeY.Tag);
165 | else if (nodeX.Tag != null)
166 | return 1;
167 | else if (nodeY.Tag != null)
168 | return -1;
169 | else
170 | return 0;
171 | }
172 |
173 | #endregion
174 | }
175 |
176 | #endregion
177 | }
--------------------------------------------------------------------------------
/EasyExplorer.Designer.cs:
--------------------------------------------------------------------------------
1 | namespace EasyExplorer
2 | {
3 | partial class Explorer
4 | {
5 | ///
6 | /// Required designer variable.
7 | ///
8 | private System.ComponentModel.IContainer components = null;
9 |
10 | ///
11 | /// Clean up any resources being used.
12 | ///
13 | /// true if managed resources should be disposed; otherwise, false.
14 | protected override void Dispose(bool disposing)
15 | {
16 | if (disposing && (components != null))
17 | {
18 | components.Dispose();
19 | }
20 | base.Dispose(disposing);
21 | }
22 |
23 | #region Component Designer generated code
24 |
25 | ///
26 | /// Required method for Designer support - do not modify
27 | /// the contents of this method with the code editor.
28 | ///
29 | private void InitializeComponent()
30 | {
31 | System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(Explorer));
32 | this.browseSplitter = new System.Windows.Forms.SplitContainer();
33 | this.folderView = new ExplorerTreeView();
34 | this.viewSplitContainer = new System.Windows.Forms.SplitContainer();
35 | this.fileView = new ExplorerListView();
36 | this.browseToolStrip = new System.Windows.Forms.ToolStripContainer();
37 | this.navigationBar = new System.Windows.Forms.ToolStrip();
38 | this.navBackButton = new System.Windows.Forms.ToolStripSplitButton();
39 | this.navForwardButton = new System.Windows.Forms.ToolStripSplitButton();
40 | this.navUpButton = new System.Windows.Forms.ToolStripButton();
41 | this.toolStripSeparator1 = new System.Windows.Forms.ToolStripSeparator();
42 | this.navFoldersButton = new System.Windows.Forms.ToolStripButton();
43 | this.navAddressLabel = new System.Windows.Forms.ToolStripLabel();
44 | this.navAddressBox = new ExplorerComboBox();
45 | this.browseSplitter.Panel1.SuspendLayout();
46 | this.browseSplitter.Panel2.SuspendLayout();
47 | this.browseSplitter.SuspendLayout();
48 | this.viewSplitContainer.Panel2.SuspendLayout();
49 | this.viewSplitContainer.SuspendLayout();
50 | this.browseToolStrip.ContentPanel.SuspendLayout();
51 | this.browseToolStrip.TopToolStripPanel.SuspendLayout();
52 | this.browseToolStrip.SuspendLayout();
53 | this.navigationBar.SuspendLayout();
54 | this.SuspendLayout();
55 | //
56 | // browseSplitter
57 | //
58 | this.browseSplitter.Dock = System.Windows.Forms.DockStyle.Fill;
59 | this.browseSplitter.FixedPanel = System.Windows.Forms.FixedPanel.Panel1;
60 | this.browseSplitter.Location = new System.Drawing.Point(0, 0);
61 | this.browseSplitter.Name = "browseSplitter";
62 | //
63 | // browseSplitter.Panel1
64 | //
65 | this.browseSplitter.Panel1.Controls.Add(this.folderView);
66 | //
67 | // browseSplitter.Panel2
68 | //
69 | this.browseSplitter.Panel2.Controls.Add(this.viewSplitContainer);
70 | this.browseSplitter.Size = new System.Drawing.Size(536, 408);
71 | this.browseSplitter.SplitterDistance = 162;
72 | this.browseSplitter.SplitterWidth = 3;
73 | this.browseSplitter.TabIndex = 0;
74 | this.browseSplitter.MouseDown += new System.Windows.Forms.MouseEventHandler(this.splitter_MouseDown);
75 | this.browseSplitter.MouseMove += new System.Windows.Forms.MouseEventHandler(this.splitter_MouseMove);
76 | this.browseSplitter.MouseUp += new System.Windows.Forms.MouseEventHandler(this.splitter_MouseUp);
77 | //
78 | // folderView
79 | //
80 | this.folderView.Dock = System.Windows.Forms.DockStyle.Fill;
81 | this.folderView.HideSelection = false;
82 | this.folderView.HotTracking = true;
83 | this.folderView.Location = new System.Drawing.Point(0, 0);
84 | this.folderView.Name = "folderView";
85 | this.folderView.ShowLines = false;
86 | this.folderView.ShowRootLines = false;
87 | this.folderView.Size = new System.Drawing.Size(162, 408);
88 | this.folderView.TabIndex = 0;
89 | //
90 | // viewSplitContainer
91 | //
92 | this.viewSplitContainer.Dock = System.Windows.Forms.DockStyle.Fill;
93 | this.viewSplitContainer.FixedPanel = System.Windows.Forms.FixedPanel.Panel2;
94 | this.viewSplitContainer.IsSplitterFixed = true;
95 | this.viewSplitContainer.Location = new System.Drawing.Point(0, 0);
96 | this.viewSplitContainer.Name = "viewSplitContainer";
97 | this.viewSplitContainer.Orientation = System.Windows.Forms.Orientation.Horizontal;
98 | //
99 | // viewSplitContainer.Panel1
100 | //
101 | this.viewSplitContainer.Panel1.BackColor = System.Drawing.Color.White;
102 | this.viewSplitContainer.Panel1Collapsed = true;
103 | this.viewSplitContainer.Panel1MinSize = 0;
104 | //
105 | // viewSplitContainer.Panel2
106 | //
107 | this.viewSplitContainer.Panel2.Controls.Add(this.fileView);
108 | this.viewSplitContainer.Panel2MinSize = 0;
109 | this.viewSplitContainer.Size = new System.Drawing.Size(371, 408);
110 | this.viewSplitContainer.SplitterDistance = 300;
111 | this.viewSplitContainer.TabIndex = 1;
112 | this.viewSplitContainer.Resize += new System.EventHandler(this.viewSplitContainer_Resize);
113 | //
114 | // fileView
115 | //
116 | this.fileView.Alignment = System.Windows.Forms.ListViewAlignment.Left;
117 | this.fileView.AllowColumnReorder = true;
118 | this.fileView.ColumnHeaderContextMenu = null;
119 | this.fileView.Dock = System.Windows.Forms.DockStyle.Fill;
120 | this.fileView.HideSelection = false;
121 | this.fileView.Location = new System.Drawing.Point(0, 0);
122 | this.fileView.Name = "fileView";
123 | this.fileView.OwnerDraw = true;
124 | this.fileView.Size = new System.Drawing.Size(371, 408);
125 | this.fileView.SuspendHeaderContextMenu = false;
126 | this.fileView.TabIndex = 0;
127 | this.fileView.UseCompatibleStateImageBehavior = false;
128 | this.fileView.View = System.Windows.Forms.View.List;
129 | this.fileView.Click += onClickFile;
130 | //
131 | // browseToolStrip
132 | //
133 | //
134 | // browseToolStrip.ContentPanel
135 | //
136 | this.browseToolStrip.ContentPanel.Controls.Add(this.browseSplitter);
137 | this.browseToolStrip.ContentPanel.Size = new System.Drawing.Size(536, 408);
138 | this.browseToolStrip.Dock = System.Windows.Forms.DockStyle.Fill;
139 | this.browseToolStrip.LeftToolStripPanelVisible = false;
140 | this.browseToolStrip.Location = new System.Drawing.Point(0, 0);
141 | this.browseToolStrip.Name = "browseToolStrip";
142 | this.browseToolStrip.RightToolStripPanelVisible = false;
143 | this.browseToolStrip.Size = new System.Drawing.Size(536, 439);
144 | this.browseToolStrip.TabIndex = 1;
145 | this.browseToolStrip.Text = "browseToolStrip";
146 | //
147 | // browseToolStrip.TopToolStripPanel
148 | //
149 | this.browseToolStrip.TopToolStripPanel.Controls.Add(this.navigationBar);
150 | //
151 | // navigationBar
152 | //
153 | this.navigationBar.CanOverflow = false;
154 | this.navigationBar.Dock = System.Windows.Forms.DockStyle.None;
155 | this.navigationBar.GripStyle = System.Windows.Forms.ToolStripGripStyle.Hidden;
156 | this.navigationBar.ImageScalingSize = new System.Drawing.Size(24, 24);
157 | this.navigationBar.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
158 | this.navBackButton,
159 | this.navForwardButton,
160 | this.navUpButton,
161 | this.toolStripSeparator1,
162 | this.navFoldersButton,
163 | this.navAddressLabel,
164 | this.navAddressBox});
165 | this.navigationBar.LayoutStyle = System.Windows.Forms.ToolStripLayoutStyle.HorizontalStackWithOverflow;
166 | this.navigationBar.Location = new System.Drawing.Point(0, 0);
167 | this.navigationBar.Name = "navigationBar";
168 | this.navigationBar.Size = new System.Drawing.Size(536, 31);
169 | this.navigationBar.Stretch = true;
170 | this.navigationBar.TabIndex = 0;
171 | this.navigationBar.Resize += new System.EventHandler(this.navigationBar_Resize);
172 | //
173 | // navBackButton
174 | //
175 | this.navBackButton.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;
176 | this.navBackButton.Enabled = false;
177 | this.navBackButton.Image = global::EasyExplorer.Properties.Resources.BrowserBack;
178 | this.navBackButton.ImageTransparentColor = System.Drawing.Color.Magenta;
179 | this.navBackButton.Name = "navBackButton";
180 | this.navBackButton.Size = new System.Drawing.Size(40, 28);
181 | this.navBackButton.Text = "Back";
182 | this.navBackButton.TextImageRelation = System.Windows.Forms.TextImageRelation.ImageAboveText;
183 | this.navBackButton.ButtonClick += new System.EventHandler(this.navBackForwardButton_ButtonClick);
184 | this.navBackButton.DropDownItemClicked += new System.Windows.Forms.ToolStripItemClickedEventHandler(this.navBackForwardButton_DropDownItemClicked);
185 | //
186 | // navForwardButton
187 | //
188 | this.navForwardButton.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;
189 | this.navForwardButton.Enabled = false;
190 | this.navForwardButton.Image = global::EasyExplorer.Properties.Resources.BrowserForward;
191 | this.navForwardButton.ImageTransparentColor = System.Drawing.Color.Magenta;
192 | this.navForwardButton.Name = "navForwardButton";
193 | this.navForwardButton.Size = new System.Drawing.Size(40, 28);
194 | this.navForwardButton.Text = "Forward";
195 | this.navForwardButton.TextImageRelation = System.Windows.Forms.TextImageRelation.ImageAboveText;
196 | this.navForwardButton.ButtonClick += new System.EventHandler(this.navBackForwardButton_ButtonClick);
197 | this.navForwardButton.DropDownItemClicked += new System.Windows.Forms.ToolStripItemClickedEventHandler(this.navBackForwardButton_DropDownItemClicked);
198 | //
199 | // navUpButton
200 | //
201 | this.navUpButton.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;
202 | this.navUpButton.Image = ((System.Drawing.Image)(resources.GetObject("navUpButton.Image")));
203 | this.navUpButton.ImageTransparentColor = System.Drawing.Color.Magenta;
204 | this.navUpButton.Name = "navUpButton";
205 | this.navUpButton.Size = new System.Drawing.Size(28, 28);
206 | this.navUpButton.Text = "Up";
207 | this.navUpButton.TextImageRelation = System.Windows.Forms.TextImageRelation.ImageAboveText;
208 | this.navUpButton.Click += new System.EventHandler(this.navUpButton_Click);
209 | //
210 | // toolStripSeparator1
211 | //
212 | this.toolStripSeparator1.Name = "toolStripSeparator1";
213 | this.toolStripSeparator1.Size = new System.Drawing.Size(6, 31);
214 | //
215 | // navFoldersButton
216 | //
217 | this.navFoldersButton.Checked = true;
218 | this.navFoldersButton.CheckOnClick = true;
219 | this.navFoldersButton.CheckState = System.Windows.Forms.CheckState.Checked;
220 | this.navFoldersButton.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;
221 | this.navFoldersButton.Image = ((System.Drawing.Image)(resources.GetObject("navFoldersButton.Image")));
222 | this.navFoldersButton.ImageTransparentColor = System.Drawing.Color.Magenta;
223 | this.navFoldersButton.Name = "navFoldersButton";
224 | this.navFoldersButton.Size = new System.Drawing.Size(28, 28);
225 | this.navFoldersButton.Text = "Folders";
226 | this.navFoldersButton.TextImageRelation = System.Windows.Forms.TextImageRelation.ImageAboveText;
227 | this.navFoldersButton.CheckedChanged += new System.EventHandler(this.navFoldersButton_CheckedChanged);
228 | //
229 | // navAddressLabel
230 | //
231 | this.navAddressLabel.MergeIndex = 0;
232 | this.navAddressLabel.Name = "navAddressLabel";
233 | this.navAddressLabel.Overflow = System.Windows.Forms.ToolStripItemOverflow.Never;
234 | this.navAddressLabel.Size = new System.Drawing.Size(46, 28);
235 | this.navAddressLabel.Text = "Address";
236 | //
237 | // navAddressBox
238 | //
239 | this.navAddressBox.AutoCompleteMode = System.Windows.Forms.AutoCompleteMode.Append;
240 | this.navAddressBox.AutoCompleteSource = System.Windows.Forms.AutoCompleteSource.FileSystemDirectories;
241 | this.navAddressBox.AutoSize = false;
242 | this.navAddressBox.CurrentItem = null;
243 | this.navAddressBox.MaxDropDownItems = 14;
244 | this.navAddressBox.MergeIndex = 0;
245 | this.navAddressBox.Name = "navAddressBox";
246 | this.navAddressBox.Size = new System.Drawing.Size(200, 22);
247 | //
248 | // Browser
249 | //
250 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
251 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
252 | this.Controls.Add(this.browseToolStrip);
253 | this.Name = "Browser";
254 | this.Size = new System.Drawing.Size(536, 439);
255 | this.browseSplitter.Panel1.ResumeLayout(false);
256 | this.browseSplitter.Panel2.ResumeLayout(false);
257 | this.browseSplitter.ResumeLayout(false);
258 | this.viewSplitContainer.Panel2.ResumeLayout(false);
259 | this.viewSplitContainer.ResumeLayout(false);
260 | this.browseToolStrip.ContentPanel.ResumeLayout(false);
261 | this.browseToolStrip.TopToolStripPanel.ResumeLayout(false);
262 | this.browseToolStrip.TopToolStripPanel.PerformLayout();
263 | this.browseToolStrip.ResumeLayout(false);
264 | this.browseToolStrip.PerformLayout();
265 | this.navigationBar.ResumeLayout(false);
266 | this.navigationBar.PerformLayout();
267 | this.ResumeLayout(false);
268 |
269 | }
270 |
271 | #endregion
272 |
273 | private System.Windows.Forms.SplitContainer browseSplitter;
274 | public ExplorerTreeView folderView;
275 | public ExplorerListView fileView;
276 | private System.Windows.Forms.ToolStripContainer browseToolStrip;
277 | private System.Windows.Forms.ToolStrip navigationBar;
278 | private System.Windows.Forms.ToolStripLabel navAddressLabel;
279 | private ExplorerComboBox navAddressBox;
280 | private System.Windows.Forms.ToolStripButton navUpButton;
281 | private System.Windows.Forms.ToolStripSeparator toolStripSeparator1;
282 | private System.Windows.Forms.ToolStripButton navFoldersButton;
283 | private System.Windows.Forms.ToolStripSplitButton navBackButton;
284 | private System.Windows.Forms.ToolStripSplitButton navForwardButton;
285 | private System.Windows.Forms.SplitContainer viewSplitContainer;
286 |
287 | }
288 | }
289 |
--------------------------------------------------------------------------------
/EasyExplorer.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Debug
5 | AnyCPU
6 | 8.0.50727
7 | 2.0
8 | {FC8064DF-B0BC-4D03-B1AE-077F3387412C}
9 | Library
10 | Properties
11 | EasyExplorer
12 | EasyExplorer
13 | v2.0
14 |
15 |
16 |
17 |
18 | 2.0
19 | publish\
20 | true
21 | Disk
22 | false
23 | Foreground
24 | 7
25 | Days
26 | false
27 | false
28 | true
29 | 0
30 | 1.0.0.%2a
31 | false
32 | false
33 | true
34 |
35 |
36 |
37 | true
38 | full
39 | false
40 | bin\Debug\
41 | TRACE;DEBUG
42 | prompt
43 | 4
44 | false
45 | true
46 |
47 |
48 | none
49 | true
50 | bin\Release\
51 | TRACE
52 | prompt
53 | 4
54 | false
55 | true
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 | Component
69 |
70 |
71 | Component
72 |
73 |
74 | Component
75 |
76 |
77 | UserControl
78 |
79 |
80 | EasyExplorer.cs
81 |
82 |
83 |
84 |
85 | Component
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 | True
96 | True
97 | Resources.resx
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 | Component
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 | Designer
120 | EasyExplorer.cs
121 |
122 |
123 | Designer
124 | ResXFileCodeGenerator
125 | Resources.Designer.cs
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 | False
144 | .NET Framework 3.5 SP1 Client Profile
145 | false
146 |
147 |
148 | False
149 | .NET Framework 3.5 SP1
150 | true
151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
165 |
--------------------------------------------------------------------------------
/EasyExplorer.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 | text/microsoft-resx
110 |
111 |
112 | 2.0
113 |
114 |
115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
121 | 8, 19
122 |
123 |
124 |
125 |
126 | iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
127 | YQUAAAAgY0hSTQAAeiYAAICEAAD6AAAAgOgAAHUwAADqYAAAOpgAABdwnLpRPAAAA1RJREFUSEvNlGtI
128 | U2EAhpNE1B9NWaVRo/JSVqYVGlHLckjQ/QJRVkRIkX+6X5AMamapkVhSlkUsTa0xymamdLGV4dbKWuq8
129 | nNo6udqGNTEnExbTt/N9tlLGnFZQB94/3znf87zfZRsx4n96ipXFCQG7ecylqgvr/novrVbrQ+ABl33h
130 | l+rdKswS3nqjezP2r4lW5C67GnjOD4IbPETLx2FawRgEH+HXZVSkJ/2xpOR5oYi0dsLnlk/A0qpwLH8Q
131 | jsjcIE3U8RkPq5uqp/yWiGVZX94BXvP466Nocyd8zZMIJL2Yg521MVh1NwJBR/2ZFOnh/cOWkK3h5/hT
132 | eJQ0GAmVIegPXykPV4Rm8hvGp/EavZK82hLzE3PcSgCtD3tXKO0fMomfEoiFWUKaiZkBP5snv4pF5FmB
133 | esitGVl0pYWRwGHXATBxqYXNogarTEFnZzus1nZMPuhNt4TA9zcvGp5AdztWDkcdB87/ld5H6HhXDH1p
134 | LI3kcSLiS8Io/NBb0fAE7+XzZegtGiggsl7pgDEiIPBjH1dQASnmjFlbKHK7ZX0ryIO7OLqzwd6bhQXX
135 | QihcbFqNmbkCWE0KGvK8zvfTuxUwsshKtHONLadcYtPvoXCH/TO3RREUfvrrRioA7DRW06PBBS3ScAUM
136 | ZwA2FR0vN1Bg/xA4cAsiTkDg2V2bMT0tlBsz0pD25Ca6XUFDsUCFFjFszzfBoNzHTbJwaeCi5vKEwp0C
137 | At/6LA7iktXcWD3s1vuDtydWTQG/DvUpMJRGcRMY18PmDpzcIrKC7K6tCDsRhA6dmPtOSeFms4c/v9qr
138 | /oz91V7oyxcDPU3At/MuCU0LwsWeHZidNxmSp1uATye5c7kJvWK72OMP7uWVkaxVtQNt9TlA9x2gK3tA
139 | SPv5kqkULpYt6XtnOEbbtxkUYR4F6kteRvODpbB3tgBfTrokPiMEgXv8UEqa/3hv1yZ73nunmQh08nmA
140 | rRH4kOoSSdlKGFTrYaqKAyObRMGaIoHK+K5sjsf25AMioLfHfANgDsLRuAsdNWthqIhFU0kwyPs66cz7
141 | OkXyUaPmwhqrsXb0kMD9V2CzaMCWxUBTwGsmQG2pUPq+5vBuc0uhaNA7PhQTAZK0qtO3fdHdiRnKnH/+
142 | zXeqYBc+VexsyAAAAABJRU5ErkJggg==
143 |
144 |
145 |
146 |
147 | iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
148 | YQUAAAAgY0hSTQAAeiYAAICEAAD6AAAAgOgAAHUwAADqYAAAOpgAABdwnLpRPAAAAz1JREFUSEvdlWtI
149 | U2EYx40kukBCgZYURVgRXcgQ+1DRhexDFxAiMuhmJIJCKUmgQWCZfqmkIEsNh3dXxkwJvOW8YOJlzul2
150 | tuX04JEds1bmgVGT6b/nPdq8Tlf4pQY/ztn7nvP8n/d5/u97vLz+mx9fdlA5E0C/bFEWaCzYUmdtvXdd
151 | bEuEzayAJKoxxCvBBBdNwPmjB0AZoSDSiRp85jJOc68C382HRwmYlFvVGK2cCMyCTzDaCMjQ3Jhq2rwk
152 | xoEJeyTASoTR164ADimZynNIxlKx34XTkep65o8EuMJNDZCyAOmhjEm5DQ7JTMFEgl3bYLc1Q6gLgWSJ
153 | gk13AXxlsLyCqbhdTVfBxiYMPAWsiXBYYmEsChgvy+9SsSv9H7Lky0iCEk57K+BsoXG1XL55y2XI829F
154 | bwolGwex4gCMhVtm94OJjCnnHqe5eQV0OX5aGO5TJSIhlgWBK9hM2aXNy2DneQi1IZOoQ7KFGbhKps1e
155 | qxszJGGk6RI45XYY8jcAtmS3sMBsr1DDiGHCBgh5gJ2n+xGZ7urLKS4BncLHMNKRIGfPNltX7nqAvyNj
156 | 74qAqD4Ky9sd4IoDZew2LQVhwdomMSeSHvUEX0i8BIL2WahLoCNrZbe9JQqm4l2QrOXozPEFum5AajwL
157 | Xh1Ojvo4niV6CT1RR7BNOQVzAgkwY3CwVIc+m3bMtKev6PleH4bBzlRIPU+gy14DaKIhqPbA6RDoJYXb
158 | 5rqcRgaBpKJkVLA03I6ZZllNpnefUBoMx7ARUmc4OhSr4WglAfVFco6OrPh8YUy3SCAXPe9PKAYGOnyn
159 | CbSlLe0Xaq8A3+plq2qzVuFrTai8IvwspebRdSG4WDhtj2EuD3s0a8M1v1hiZaeoUHUGXL4f2jOXg1ft
160 | pRWZqGcPPEN/k8xwOH9QUAfMKcBELB9ux4jGkiBNhncfX36Ssia3iOQONzj74iHpr0GsPw6uyB/6Nx4e
161 | 76xkcnk+5ZBx4l04uGgMtZyDUE7nUME6sKR0yt0VH2si7/brc47Nqr27w4m9yLxu10RgsOoI+JKd0Gb7
162 | GNk4y5K5xNpduu+vv3gsEEPz0seoLzuVyTcnXZ2zth59DP71h34BWgsbUN6O8WoAAAAASUVORK5CYII=
163 |
164 |
165 |
--------------------------------------------------------------------------------
/EasyExplorer.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio 2012
4 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EasyExplorer", "EasyExplorer.csproj", "{FC8064DF-B0BC-4D03-B1AE-077F3387412C}"
5 | EndProject
6 | Global
7 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
8 | Debug|Any CPU = Debug|Any CPU
9 | Release|Any CPU = Release|Any CPU
10 | EndGlobalSection
11 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
12 | {FC8064DF-B0BC-4D03-B1AE-077F3387412C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
13 | {FC8064DF-B0BC-4D03-B1AE-077F3387412C}.Debug|Any CPU.Build.0 = Debug|Any CPU
14 | {FC8064DF-B0BC-4D03-B1AE-077F3387412C}.Release|Any CPU.ActiveCfg = Release|Any CPU
15 | {FC8064DF-B0BC-4D03-B1AE-077F3387412C}.Release|Any CPU.Build.0 = Release|Any CPU
16 | EndGlobalSection
17 | GlobalSection(SolutionProperties) = preSolution
18 | HideSolutionNode = FALSE
19 | EndGlobalSection
20 | EndGlobal
21 |
--------------------------------------------------------------------------------
/Images/BrowseFolders.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/robinrodricks/EasyExplorer/4b74fe2fc01b20a414cede7e8f776d4dcccc8ccd/Images/BrowseFolders.png
--------------------------------------------------------------------------------
/Images/BrowserBack.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/robinrodricks/EasyExplorer/4b74fe2fc01b20a414cede7e8f776d4dcccc8ccd/Images/BrowserBack.png
--------------------------------------------------------------------------------
/Images/BrowserForward.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/robinrodricks/EasyExplorer/4b74fe2fc01b20a414cede7e8f776d4dcccc8ccd/Images/BrowserForward.png
--------------------------------------------------------------------------------
/Images/BrowserUp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/robinrodricks/EasyExplorer/4b74fe2fc01b20a414cede7e8f776d4dcccc8ccd/Images/BrowserUp.png
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2016 Harsh Gupta
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | [assembly: AssemblyTitle("EasyExplorer")]
9 | [assembly: AssemblyDescription("A Windows Explorer component for .NET apps.")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("EasyExplorer")]
12 | [assembly: AssemblyProduct("EasyExplorer")]
13 | [assembly: AssemblyCopyright("Copyright © EasyExplorer 2016")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | // Setting ComVisible to false makes the types in this assembly not visible
18 | // to COM components. If you need to access a type in this assembly from
19 | // COM, set the ComVisible attribute to true on that type.
20 | [assembly: ComVisible(false)]
21 |
22 | // The following GUID is for the ID of the typelib if this project is exposed to COM
23 | [assembly: Guid("c5ff9b37-3f42-4058-81ec-2d490db59924")]
24 |
25 | // Version information for an assembly consists of the following four values:
26 | //
27 | // Major Version
28 | // Minor Version
29 | // Build Number
30 | // Revision
31 | //
32 | // You can specify all the values or you can default the Revision and Build Numbers
33 | // by using the '*' as shown below:
34 | [assembly: AssemblyVersion("1.4.0.0")]
35 | [assembly: AssemblyFileVersion("1.4.0.0")]
36 |
--------------------------------------------------------------------------------
/Properties/Resources.Designer.cs:
--------------------------------------------------------------------------------
1 | //------------------------------------------------------------------------------
2 | //
3 | // This code was generated by a tool.
4 | // Runtime Version:4.0.30319.34209
5 | //
6 | // Changes to this file may cause incorrect behavior and will be lost if
7 | // the code is regenerated.
8 | //
9 | //------------------------------------------------------------------------------
10 |
11 | namespace EasyExplorer.Properties {
12 | using System;
13 |
14 |
15 | ///
16 | /// A strongly-typed resource class, for looking up localized strings, etc.
17 | ///
18 | // This class was auto-generated by the StronglyTypedResourceBuilder
19 | // class via a tool like ResGen or Visual Studio.
20 | // To add or remove a member, edit your .ResX file then rerun ResGen
21 | // with the /str option, or rebuild your VS project.
22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
25 | internal class Resources {
26 |
27 | private static global::System.Resources.ResourceManager resourceMan;
28 |
29 | private static global::System.Globalization.CultureInfo resourceCulture;
30 |
31 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
32 | internal Resources() {
33 | }
34 |
35 | ///
36 | /// Returns the cached ResourceManager instance used by this class.
37 | ///
38 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
39 | internal static global::System.Resources.ResourceManager ResourceManager {
40 | get {
41 | if (object.ReferenceEquals(resourceMan, null)) {
42 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("EasyExplorer.Properties.Resources", typeof(Resources).Assembly);
43 | resourceMan = temp;
44 | }
45 | return resourceMan;
46 | }
47 | }
48 |
49 | ///
50 | /// Overrides the current thread's CurrentUICulture property for all
51 | /// resource lookups using this strongly typed resource class.
52 | ///
53 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
54 | internal static global::System.Globalization.CultureInfo Culture {
55 | get {
56 | return resourceCulture;
57 | }
58 | set {
59 | resourceCulture = value;
60 | }
61 | }
62 |
63 | ///
64 | /// Looks up a localized resource of type System.Drawing.Bitmap.
65 | ///
66 | internal static System.Drawing.Bitmap BrowseFolders {
67 | get {
68 | object obj = ResourceManager.GetObject("BrowseFolders", resourceCulture);
69 | return ((System.Drawing.Bitmap)(obj));
70 | }
71 | }
72 |
73 | ///
74 | /// Looks up a localized resource of type System.Drawing.Bitmap.
75 | ///
76 | internal static System.Drawing.Bitmap BrowserBack {
77 | get {
78 | object obj = ResourceManager.GetObject("BrowserBack", resourceCulture);
79 | return ((System.Drawing.Bitmap)(obj));
80 | }
81 | }
82 |
83 | ///
84 | /// Looks up a localized resource of type System.Drawing.Bitmap.
85 | ///
86 | internal static System.Drawing.Bitmap BrowserForward {
87 | get {
88 | object obj = ResourceManager.GetObject("BrowserForward", resourceCulture);
89 | return ((System.Drawing.Bitmap)(obj));
90 | }
91 | }
92 |
93 | ///
94 | /// Looks up a localized resource of type System.Drawing.Bitmap.
95 | ///
96 | internal static System.Drawing.Bitmap BrowserUp {
97 | get {
98 | object obj = ResourceManager.GetObject("BrowserUp", resourceCulture);
99 | return ((System.Drawing.Bitmap)(obj));
100 | }
101 | }
102 | }
103 | }
104 |
--------------------------------------------------------------------------------
/Properties/Resources.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 | text/microsoft-resx
110 |
111 |
112 | 2.0
113 |
114 |
115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
121 |
122 | ..\Images\BrowseFolders.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
123 |
124 |
125 | ..\Images\BrowserBack.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
126 |
127 |
128 | ..\Images\BrowserForward.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
129 |
130 |
131 | ..\Images\BrowserUp.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
132 |
133 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # EasyExplorer
2 | EasyExplorer is the easiest way to integrate Windows Explorer functionality into your app. The component is configurable, and events are provided for all user actions such as navigating folders, opening files, etc. All credits go to [Steven Roebert](http://www.codeproject.com/Articles/15059/C-File-Browser) for building this component in 2006.
3 |
4 | ## Screenshots
5 |
6 | ### Folder View
7 |
8 | 
9 |
10 | ### Control Panel View
11 |
12 | 
--------------------------------------------------------------------------------
/Shell/Interfaces/IAdviseSink.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 | using System.Runtime.InteropServices;
5 |
6 | namespace ShellDll
7 | {
8 | [ComImport]
9 | [Guid("0000010f-0000-0000-C000-000000000046")]
10 | [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
11 | public interface IAdviseSink
12 | {
13 | // Advises that data has changed
14 | [PreserveSig]
15 | void OnDataChange(
16 | ref ShellAPI.FORMATETC pformatetcIn,
17 | ref ShellAPI.STGMEDIUM pmedium);
18 |
19 | // Advises that view of object has changed
20 | [PreserveSig]
21 | void OnViewChange(
22 | int dwAspect,
23 | int lindex);
24 |
25 | // Advises that name of object has changed
26 | [PreserveSig]
27 | void OnRename(
28 | IntPtr pmk);
29 |
30 | // Advises that object has been saved to disk
31 | [PreserveSig]
32 | void OnSave();
33 |
34 | // Advises that object has been closed
35 | [PreserveSig]
36 | void OnClose();
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/Shell/Interfaces/IContextMenu.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 | using System.Runtime.InteropServices;
5 |
6 | namespace ShellDll
7 | {
8 | [ComImport()]
9 | [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
10 | [GuidAttribute("000214e4-0000-0000-c000-000000000046")]
11 | public interface IContextMenu
12 | {
13 | // Adds commands to a shortcut menu
14 | [PreserveSig()]
15 | Int32 QueryContextMenu(
16 | IntPtr hmenu,
17 | uint iMenu,
18 | uint idCmdFirst,
19 | uint idCmdLast,
20 | ShellAPI.CMF uFlags);
21 |
22 | // Carries out the command associated with a shortcut menu item
23 | [PreserveSig()]
24 | Int32 InvokeCommand(
25 | ref ShellAPI.CMINVOKECOMMANDINFOEX info);
26 |
27 | // Retrieves information about a shortcut menu command,
28 | // including the help string and the language-independent,
29 | // or canonical, name for the command
30 | [PreserveSig()]
31 | Int32 GetCommandString(
32 | uint idcmd,
33 | ShellAPI.GCS uflags,
34 | uint reserved,
35 | [MarshalAs(UnmanagedType.LPArray)]
36 | byte[] commandstring,
37 | int cch);
38 | }
39 |
40 | [ComImport, Guid("000214f4-0000-0000-c000-000000000046")]
41 | [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
42 | public interface IContextMenu2
43 | {
44 | // Adds commands to a shortcut menu
45 | [PreserveSig()]
46 | Int32 QueryContextMenu(
47 | IntPtr hmenu,
48 | uint iMenu,
49 | uint idCmdFirst,
50 | uint idCmdLast,
51 | ShellAPI.CMF uFlags);
52 |
53 | // Carries out the command associated with a shortcut menu item
54 | [PreserveSig()]
55 | Int32 InvokeCommand(
56 | ref ShellAPI.CMINVOKECOMMANDINFOEX info);
57 |
58 | // Retrieves information about a shortcut menu command,
59 | // including the help string and the language-independent,
60 | // or canonical, name for the command
61 | [PreserveSig()]
62 | Int32 GetCommandString(
63 | uint idcmd,
64 | ShellAPI.GCS uflags,
65 | uint reserved,
66 | [MarshalAs(UnmanagedType.LPWStr)]
67 | StringBuilder commandstring,
68 | int cch);
69 |
70 | // Allows client objects of the IContextMenu interface to
71 | // handle messages associated with owner-drawn menu items
72 | [PreserveSig]
73 | Int32 HandleMenuMsg(
74 | uint uMsg,
75 | IntPtr wParam,
76 | IntPtr lParam);
77 | }
78 |
79 | [ComImport, Guid("bcfce0a0-ec17-11d0-8d10-00a0c90f2719")]
80 | [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
81 | public interface IContextMenu3
82 | {
83 | // Adds commands to a shortcut menu
84 | [PreserveSig()]
85 | Int32 QueryContextMenu(
86 | IntPtr hmenu,
87 | uint iMenu,
88 | uint idCmdFirst,
89 | uint idCmdLast,
90 | ShellAPI.CMF uFlags);
91 |
92 | // Carries out the command associated with a shortcut menu item
93 | [PreserveSig()]
94 | Int32 InvokeCommand(
95 | ref ShellAPI.CMINVOKECOMMANDINFOEX info);
96 |
97 | // Retrieves information about a shortcut menu command,
98 | // including the help string and the language-independent,
99 | // or canonical, name for the command
100 | [PreserveSig()]
101 | Int32 GetCommandString(
102 | uint idcmd,
103 | ShellAPI.GCS uflags,
104 | uint reserved,
105 | [MarshalAs(UnmanagedType.LPWStr)]
106 | StringBuilder commandstring,
107 | int cch);
108 |
109 | // Allows client objects of the IContextMenu interface to
110 | // handle messages associated with owner-drawn menu items
111 | [PreserveSig]
112 | Int32 HandleMenuMsg(
113 | uint uMsg,
114 | IntPtr wParam,
115 | IntPtr lParam);
116 |
117 | // Allows client objects of the IContextMenu3 interface to
118 | // handle messages associated with owner-drawn menu items
119 | [PreserveSig]
120 | Int32 HandleMenuMsg2(
121 | uint uMsg,
122 | IntPtr wParam,
123 | IntPtr lParam,
124 | IntPtr plResult);
125 | }
126 | }
127 |
--------------------------------------------------------------------------------
/Shell/Interfaces/IDataObject.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 | using System.Runtime.InteropServices;
5 |
6 | namespace ShellDll
7 | {
8 | [ComImport]
9 | [Guid("0000010e-0000-0000-C000-000000000046")]
10 | [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
11 | public interface IDataObject
12 | {
13 | // Renders the data described in a FORMATETC structure
14 | // and transfers it through the STGMEDIUM structure
15 | [PreserveSig]
16 | Int32 GetData(
17 | ref ShellAPI.FORMATETC pformatetcIn,
18 | ref ShellAPI.STGMEDIUM pmedium);
19 |
20 | // Renders the data described in a FORMATETC structure
21 | // and transfers it through the STGMEDIUM structure allocated by the caller
22 | [PreserveSig]
23 | Int32 GetDataHere(
24 | ref ShellAPI.FORMATETC pformatetcIn,
25 | ref ShellAPI.STGMEDIUM pmedium);
26 |
27 | // Determines whether the data object is capable of
28 | // rendering the data described in the FORMATETC structure
29 | [PreserveSig]
30 | Int32 QueryGetData(
31 | ref ShellAPI.FORMATETC pformatetc);
32 |
33 | // Provides a potentially different but logically equivalent FORMATETC structure
34 | [PreserveSig]
35 | Int32 GetCanonicalFormatEtc(
36 | ref ShellAPI.FORMATETC pformatetc,
37 | ref ShellAPI.FORMATETC pformatetcout);
38 |
39 | // Provides the source data object with data described by a
40 | // FORMATETC structure and an STGMEDIUM structure
41 | [PreserveSig]
42 | Int32 SetData(
43 | ref ShellAPI.FORMATETC pformatetcIn,
44 | ref ShellAPI.STGMEDIUM pmedium,
45 | bool frelease);
46 |
47 | // Creates and returns a pointer to an object to enumerate the
48 | // FORMATETC supported by the data object
49 | [PreserveSig]
50 | Int32 EnumFormatEtc(
51 | int dwDirection,
52 | ref IEnumFORMATETC ppenumFormatEtc);
53 |
54 | // Creates a connection between a data object and an advise sink so
55 | // the advise sink can receive notifications of changes in the data object
56 | [PreserveSig]
57 | Int32 DAdvise(
58 | ref ShellAPI.FORMATETC pformatetc,
59 | ref ShellAPI.ADVF advf,
60 | ref IAdviseSink pAdvSink,
61 | ref int pdwConnection);
62 |
63 | // Destroys a notification previously set up with the DAdvise method
64 | [PreserveSig]
65 | Int32 DUnadvise(
66 | int dwConnection);
67 |
68 | // Creates and returns a pointer to an object to enumerate the current advisory connections
69 | [PreserveSig]
70 | Int32 EnumDAdvise(
71 | ref object ppenumAdvise);
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/Shell/Interfaces/IDragSourceHelper.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 | using System.Runtime.InteropServices;
5 |
6 | namespace ShellDll
7 | {
8 | [ComImport]
9 | [GuidAttribute("DE5BF786-477A-11d2-839D-00C04FD918D0")]
10 | [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
11 | public interface IDragSourceHelper
12 | {
13 | // Initializes the drag-image manager for a windowless control
14 | [PreserveSig]
15 | Int32 InitializeFromBitmap(
16 | ref ShellAPI.SHDRAGIMAGE pshdi,
17 | IntPtr pDataObject);
18 |
19 | // Initializes the drag-image manager for a control with a window
20 | [PreserveSig]
21 | Int32 InitializeFromWindow(
22 | IntPtr hwnd,
23 | ref ShellAPI.POINT ppt,
24 | IntPtr pDataObject);
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/Shell/Interfaces/IDropSource.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 | using System.Runtime.InteropServices;
5 | using System.Windows.Forms;
6 |
7 | namespace ShellDll
8 | {
9 | [ComImport]
10 | [GuidAttribute("00000121-0000-0000-C000-000000000046")]
11 | [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
12 | public interface IDropSource
13 | {
14 | // Determines whether a drag-and-drop operation should continue
15 | [PreserveSig]
16 | Int32 QueryContinueDrag(
17 | bool fEscapePressed,
18 | ShellAPI.MK grfKeyState);
19 |
20 | // Gives visual feedback to an end user during a drag-and-drop operation
21 | [PreserveSig]
22 | Int32 GiveFeedback(
23 | DragDropEffects dwEffect);
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/Shell/Interfaces/IDropTarget.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 | using System.Runtime.InteropServices;
5 | using System.Windows.Forms;
6 |
7 | namespace ShellDll
8 | {
9 | [ComImport]
10 | [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
11 | [Guid("00000122-0000-0000-C000-000000000046")]
12 | public interface IDropTarget
13 | {
14 | // Determines whether a drop can be accepted and its effect if it is accepted
15 | [PreserveSig]
16 | Int32 DragEnter(
17 | IntPtr pDataObj,
18 | ShellAPI.MK grfKeyState,
19 | ShellAPI.POINT pt,
20 | ref DragDropEffects pdwEffect);
21 |
22 | // Provides target feedback to the user through the DoDragDrop function
23 | [PreserveSig]
24 | Int32 DragOver(
25 | ShellAPI.MK grfKeyState,
26 | ShellAPI.POINT pt,
27 | ref DragDropEffects pdwEffect);
28 |
29 | // Causes the drop target to suspend its feedback actions
30 | [PreserveSig]
31 | Int32 DragLeave();
32 |
33 | // Drops the data into the target window
34 | [PreserveSig]
35 | Int32 DragDrop(
36 | IntPtr pDataObj,
37 | ShellAPI.MK grfKeyState,
38 | ShellAPI.POINT pt,
39 | ref DragDropEffects pdwEffect);
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/Shell/Interfaces/IDropTargetHelper.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 | using System.Runtime.InteropServices;
5 | using System.Windows.Forms;
6 |
7 | namespace ShellDll
8 | {
9 | [ComImport]
10 | [GuidAttribute("4657278B-411B-11d2-839A-00C04FD918D0")]
11 | [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
12 | public interface IDropTargetHelper
13 | {
14 | // Notifies the drag-image manager that the drop target's IDropTarget::DragEnter method has been called
15 | [PreserveSig]
16 | Int32 DragEnter(
17 | IntPtr hwndTarget,
18 | IntPtr pDataObject,
19 | ref ShellAPI.POINT ppt,
20 | DragDropEffects dwEffect);
21 |
22 | // Notifies the drag-image manager that the drop target's IDropTarget::DragLeave method has been called
23 | [PreserveSig]
24 | Int32 DragLeave();
25 |
26 | // Notifies the drag-image manager that the drop target's IDropTarget::DragOver method has been called
27 | [PreserveSig]
28 | Int32 DragOver(
29 | ref ShellAPI.POINT ppt,
30 | DragDropEffects dwEffect);
31 |
32 | // Notifies the drag-image manager that the drop target's IDropTarget::Drop method has been called
33 | [PreserveSig]
34 | Int32 Drop(
35 | IntPtr pDataObject,
36 | ref ShellAPI.POINT ppt,
37 | DragDropEffects dwEffect);
38 |
39 | // Notifies the drag-image manager to show or hide the drag image
40 | [PreserveSig]
41 | Int32 Show(
42 | bool fShow);
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/Shell/Interfaces/IEnumFORMATETC.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 | using System.Runtime.InteropServices;
5 |
6 | namespace ShellDll
7 | {
8 | [ComImport]
9 | [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
10 | [Guid("00000103-0000-0000-C000-000000000046")]
11 | public interface IEnumFORMATETC
12 | {
13 | // Retrieves the specified number of FORMATETC structures in the enumeration
14 | // sequence and advances the current position by the number of items retrieved
15 | [PreserveSig]
16 | int GetNext(
17 | int celt,
18 | ref ShellAPI.FORMATETC rgelt,
19 | ref int pceltFetched);
20 |
21 | // Skips over the specified number of elements in the enumeration sequence
22 | [PreserveSig]
23 | int Skip(int celt);
24 |
25 | // Returns to the beginning of the enumeration sequence
26 | [PreserveSig]
27 | int Reset();
28 |
29 | // Creates a new item enumeration object with the same contents and state as the current one
30 | [PreserveSig]
31 | int Clone(
32 | ref IEnumFORMATETC ppenum);
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/Shell/Interfaces/IEnumIDList.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Runtime.InteropServices;
3 |
4 | namespace ShellDll
5 | {
6 | [ComImportAttribute()]
7 | [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
8 | [Guid("000214F2-0000-0000-C000-000000000046")]
9 | public interface IEnumIDList
10 | {
11 | // Retrieves the specified number of item identifiers in the enumeration
12 | // sequence and advances the current position by the number of items retrieved
13 | [PreserveSig()]
14 | Int32 Next(
15 | int celt,
16 | out IntPtr rgelt,
17 | out int pceltFetched);
18 |
19 | // Skips over the specified number of elements in the enumeration sequence
20 | [PreserveSig()]
21 | Int32 Skip(
22 | int celt);
23 |
24 | // Returns to the beginning of the enumeration sequence
25 | [PreserveSig()]
26 | Int32 Reset();
27 |
28 | // Creates a new item enumeration object with the same contents and state as the current one
29 | [PreserveSig()]
30 | Int32 Clone(
31 | out IEnumIDList ppenum);
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/Shell/Interfaces/IEnumSTATSTG.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 | using System.Runtime.InteropServices;
5 |
6 | namespace ShellDll
7 | {
8 | [ComImport]
9 | [Guid("0000000d-0000-0000-C000-000000000046")]
10 | [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
11 | public interface IEnumSTATSTG
12 | {
13 | // The user needs to allocate an STATSTG array whose size is celt.
14 | [PreserveSig]
15 | uint Next(
16 | uint celt,
17 | [MarshalAs(UnmanagedType.LPArray)]
18 | out ShellAPI.STATSTG[] rgelt,
19 | out uint pceltFetched);
20 |
21 | [PreserveSig]
22 | void Skip(uint celt);
23 |
24 | [PreserveSig]
25 | void Reset();
26 |
27 | [PreserveSig]
28 | IEnumSTATSTG Clone();
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/Shell/Interfaces/IQueryInfo.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 | using System.Runtime.InteropServices;
5 |
6 | namespace ShellDll
7 | {
8 | [ComImport()]
9 | [Guid("00021500-0000-0000-C000-000000000046")]
10 | [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
11 | public interface IQueryInfo
12 | {
13 | [PreserveSig]
14 | Int32 GetInfoTip(
15 | ShellAPI.QITIPF dwFlags,
16 | [MarshalAs(UnmanagedType.LPWStr)]
17 | out string ppwszTip);
18 |
19 | [PreserveSig]
20 | Int32 GetInfoFlags(
21 | out IntPtr pdwFlags);
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/Shell/Interfaces/IShellExtInit.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 | using System.Runtime.InteropServices;
5 |
6 | namespace ShellDll
7 | {
8 | [ComImport()]
9 | [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
10 | [GuidAttribute("000214e8-0000-0000-c000-000000000046")]
11 | public interface IShellExtInit
12 | {
13 | [PreserveSig()]
14 | int Initialize(
15 | IntPtr pidlFolder,
16 | IntPtr lpdobj,
17 | uint hKeyProgID);
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/Shell/Interfaces/IShellFolder.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Runtime.InteropServices;
3 |
4 | namespace ShellDll
5 | {
6 | [ComImport]
7 | [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
8 | [Guid("000214E6-0000-0000-C000-000000000046")]
9 | public interface IShellFolder
10 | {
11 | // Translates a file object's or folder's display name into an item identifier list.
12 | // Return value: error code, if any
13 | [PreserveSig]
14 | Int32 ParseDisplayName(
15 | IntPtr hwnd,
16 | IntPtr pbc,
17 | [MarshalAs(UnmanagedType.LPWStr)]
18 | string pszDisplayName,
19 | ref uint pchEaten,
20 | out IntPtr ppidl,
21 | ref ShellAPI.SFGAO pdwAttributes);
22 |
23 | // Allows a client to determine the contents of a folder by creating an item
24 | // identifier enumeration object and returning its IEnumIDList interface.
25 | // Return value: error code, if any
26 | [PreserveSig]
27 | Int32 EnumObjects(
28 | IntPtr hwnd,
29 | ShellAPI.SHCONTF grfFlags,
30 | out IntPtr enumIDList);
31 |
32 | // Retrieves an IShellFolder object for a subfolder.
33 | // Return value: error code, if any
34 | [PreserveSig]
35 | Int32 BindToObject(
36 | IntPtr pidl,
37 | IntPtr pbc,
38 | ref Guid riid,
39 | out IntPtr ppv);
40 |
41 | // Requests a pointer to an object's storage interface.
42 | // Return value: error code, if any
43 | [PreserveSig]
44 | Int32 BindToStorage(
45 | IntPtr pidl,
46 | IntPtr pbc,
47 | ref Guid riid,
48 | out IntPtr ppv);
49 |
50 | // Determines the relative order of two file objects or folders, given their
51 | // item identifier lists. Return value: If this method is successful, the
52 | // CODE field of the HRESULT contains one of the following values (the code
53 | // can be retrived using the helper function GetHResultCode): Negative A
54 | // negative return value indicates that the first item should precede
55 | // the second (pidl1 < pidl2).
56 |
57 | // Positive A positive return value indicates that the first item should
58 | // follow the second (pidl1 > pidl2). Zero A return value of zero
59 | // indicates that the two items are the same (pidl1 = pidl2).
60 | [PreserveSig]
61 | Int32 CompareIDs(
62 | IntPtr lParam,
63 | IntPtr pidl1,
64 | IntPtr pidl2);
65 |
66 | // Requests an object that can be used to obtain information from or interact
67 | // with a folder object.
68 | // Return value: error code, if any
69 | [PreserveSig]
70 | Int32 CreateViewObject(
71 | IntPtr hwndOwner,
72 | Guid riid,
73 | out IntPtr ppv);
74 |
75 | // Retrieves the attributes of one or more file objects or subfolders.
76 | // Return value: error code, if any
77 | [PreserveSig]
78 | Int32 GetAttributesOf(
79 | uint cidl,
80 | [MarshalAs(UnmanagedType.LPArray)]
81 | IntPtr[] apidl,
82 | ref ShellAPI.SFGAO rgfInOut);
83 |
84 | // Retrieves an OLE interface that can be used to carry out actions on the
85 | // specified file objects or folders.
86 | // Return value: error code, if any
87 | [PreserveSig]
88 | Int32 GetUIObjectOf(
89 | IntPtr hwndOwner,
90 | uint cidl,
91 | [MarshalAs(UnmanagedType.LPArray)]
92 | IntPtr[] apidl,
93 | ref Guid riid,
94 | IntPtr rgfReserved,
95 | out IntPtr ppv);
96 |
97 | // Retrieves the display name for the specified file object or subfolder.
98 | // Return value: error code, if any
99 | [PreserveSig()]
100 | Int32 GetDisplayNameOf(
101 | IntPtr pidl,
102 | ShellAPI.SHGNO uFlags,
103 | IntPtr lpName);
104 |
105 | // Sets the display name of a file object or subfolder, changing the item
106 | // identifier in the process.
107 | // Return value: error code, if any
108 | [PreserveSig]
109 | Int32 SetNameOf(
110 | IntPtr hwnd,
111 | IntPtr pidl,
112 | [MarshalAs(UnmanagedType.LPWStr)]
113 | string pszName,
114 | ShellAPI.SHGNO uFlags,
115 | out IntPtr ppidlOut);
116 | }
117 | }
118 |
--------------------------------------------------------------------------------
/Shell/Interfaces/IStorage.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 | using System.Runtime.InteropServices;
5 |
6 | namespace ShellDll
7 | {
8 | [ComImport]
9 | [Guid("0000000b-0000-0000-C000-000000000046")]
10 | [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
11 | public interface IStorage
12 | {
13 | [PreserveSig]
14 | Int32 CreateStream(
15 | [MarshalAs(UnmanagedType.LPWStr)]
16 | string pwcsName,
17 | ShellAPI.STGM grfMode,
18 | int reserved1,
19 | int reserved2,
20 | out IntPtr ppstm);
21 |
22 | [PreserveSig]
23 | Int32 OpenStream(
24 | [MarshalAs(UnmanagedType.LPWStr)]
25 | string pwcsName,
26 | IntPtr reserved1,
27 | ShellAPI.STGM grfMode,
28 | int reserved2,
29 | out IntPtr ppstm);
30 |
31 | [PreserveSig]
32 | Int32 CreateStorage(
33 | [MarshalAs(UnmanagedType.LPWStr)]
34 | string pwcsName,
35 | ShellAPI.STGM grfMode,
36 | int reserved1,
37 | int reserved2,
38 | out IntPtr ppstg);
39 |
40 | [PreserveSig]
41 | Int32 OpenStorage(
42 | [MarshalAs(UnmanagedType.LPWStr)]
43 | string pwcsName,
44 | IStorage pstgPriority,
45 | ShellAPI.STGM grfMode,
46 | IntPtr snbExclude,
47 | int reserved,
48 | out IntPtr ppstg);
49 |
50 | [PreserveSig]
51 | Int32 CopyTo(
52 | int ciidExclude,
53 | ref Guid rgiidExclude,
54 | IntPtr snbExclude,
55 | IStorage pstgDest);
56 |
57 | [PreserveSig]
58 | Int32 MoveElementTo(
59 | [MarshalAs(UnmanagedType.LPWStr)]
60 | string pwcsName,
61 | IStorage pstgDest,
62 | [MarshalAs(UnmanagedType.LPWStr)]
63 | string pwcsNewName,
64 | ShellAPI.STGMOVE grfFlags);
65 |
66 | [PreserveSig]
67 | Int32 Commit(
68 | ShellAPI.STGC grfCommitFlags);
69 |
70 | [PreserveSig]
71 | Int32 Revert();
72 |
73 | [PreserveSig]
74 | Int32 EnumElements(
75 | int reserved1,
76 | IntPtr reserved2,
77 | int reserved3,
78 | out IntPtr ppenum);
79 |
80 | [PreserveSig]
81 | Int32 DestroyElement(
82 | [MarshalAs(UnmanagedType.LPWStr)]
83 | string pwcsName);
84 |
85 | [PreserveSig]
86 | Int32 RenameElement(
87 | [MarshalAs(UnmanagedType.LPWStr)]
88 | string pwcsOldName,
89 | [MarshalAs(UnmanagedType.LPWStr)]
90 | string pwcsNewName);
91 |
92 | [PreserveSig]
93 | Int32 SetElementTimes(
94 | [MarshalAs(UnmanagedType.LPWStr)]
95 | string pwcsName,
96 | ShellAPI.FILETIME pctime,
97 | ShellAPI.FILETIME patime,
98 | ShellAPI.FILETIME pmtime);
99 |
100 | [PreserveSig]
101 | Int32 SetClass(
102 | ref Guid clsid);
103 |
104 | [PreserveSig]
105 | Int32 SetStateBits(
106 | int grfStateBits,
107 | int grfMask);
108 |
109 | [PreserveSig]
110 | Int32 Stat(
111 | out ShellAPI.STATSTG pstatstg,
112 | ShellAPI.STATFLAG grfStatFlag);
113 | }
114 | }
115 |
--------------------------------------------------------------------------------
/Shell/Interfaces/IStream.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 | using System.Runtime.InteropServices;
5 | using System.IO;
6 |
7 | namespace ShellDll
8 | {
9 | [ComImport]
10 | [Guid("0000000c-0000-0000-C000-000000000046")]
11 | [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
12 | public interface IStream
13 | {
14 | // Reads a specified number of bytes from the stream object into memory
15 | // starting at the current seek pointer
16 | [PreserveSig]
17 | Int32 Read(
18 | [MarshalAs(UnmanagedType.LPArray)]
19 | byte[] pv,
20 | int cb,
21 | IntPtr pcbRead);
22 |
23 | // Writes a specified number of bytes into the stream object starting at
24 | // the current seek pointer
25 | [PreserveSig]
26 | Int32 Write(
27 | [MarshalAs(UnmanagedType.LPArray)]
28 | byte[] pv,
29 | int cb,
30 | IntPtr pcbWritten);
31 |
32 | // Changes the seek pointer to a new location relative to the beginning
33 | // of the stream, the end of the stream, or the current seek pointer
34 | [PreserveSig]
35 | Int32 Seek(
36 | long dlibMove,
37 | SeekOrigin dwOrigin,
38 | IntPtr plibNewPosition);
39 |
40 | // Changes the size of the stream object
41 | [PreserveSig]
42 | Int32 SetSize(
43 | long libNewSize);
44 |
45 | // Copies a specified number of bytes from the current seek pointer in
46 | // the stream to the current seek pointer in another stream
47 | [PreserveSig]
48 | Int32 CopyTo(
49 | IStream pstm,
50 | long cb,
51 | IntPtr pcbRead,
52 | IntPtr pcbWritten);
53 |
54 | // Ensures that any changes made to a stream object open in transacted
55 | // mode are reflected in the parent storage object
56 | [PreserveSig]
57 | Int32 Commit(
58 | ShellAPI.STGC grfCommitFlags);
59 |
60 | // Discards all changes that have been made to a transacted stream since
61 | // the last call to IStream::Commit
62 | [PreserveSig]
63 | Int32 Revert();
64 |
65 | // Restricts access to a specified range of bytes in the stream. Supporting
66 | // this functionality is optional since some file systems do not provide it
67 | [PreserveSig]
68 | Int32 LockRegion(
69 | long libOffset,
70 | long cb,
71 | ShellAPI.LOCKTYPE dwLockType);
72 |
73 | // Removes the access restriction on a range of bytes previously restricted
74 | // with IStream::LockRegion
75 | [PreserveSig]
76 | Int32 UnlockRegion(
77 | long libOffset,
78 | long cb,
79 | ShellAPI.LOCKTYPE dwLockType);
80 |
81 | // Retrieves the STATSTG structure for this stream
82 | [PreserveSig]
83 | Int32 Stat(
84 | out ShellAPI.STATSTG pstatstg,
85 | ShellAPI.STATFLAG grfStatFlag);
86 |
87 | // Creates a new stream object that references the same bytes as the original
88 | // stream but provides a separate seek pointer to those bytes
89 | [PreserveSig]
90 | Int32 Clone(
91 | out IntPtr ppstm);
92 | }
93 | }
94 |
--------------------------------------------------------------------------------
/Shell/PIDL.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 | using System.Runtime.InteropServices;
5 | using System.Collections;
6 |
7 | namespace ShellDll
8 | {
9 | internal class PIDL : IEnumerable
10 | {
11 | private IntPtr pidl = IntPtr.Zero;
12 |
13 | #region Constructors
14 |
15 | public PIDL(IntPtr pidl, bool clone)
16 | {
17 | if (clone)
18 | this.pidl = ILClone(pidl);
19 | else
20 | this.pidl = pidl;
21 | }
22 |
23 | public PIDL(PIDL pidl, bool clone)
24 | {
25 | if (clone)
26 | this.pidl = ILClone(pidl.Ptr);
27 | else
28 | this.pidl = pidl.Ptr;
29 | }
30 |
31 | #endregion
32 |
33 | #region Public
34 |
35 | public IntPtr Ptr { get { return pidl; } }
36 |
37 | public void Append(IntPtr appendPidl)
38 | {
39 | IntPtr newPidl = ILCombine(pidl, appendPidl);
40 |
41 | Marshal.FreeCoTaskMem(pidl);
42 | pidl = newPidl;
43 | }
44 |
45 | public void Insert(IntPtr insertPidl)
46 | {
47 | IntPtr newPidl = ILCombine(insertPidl, pidl);
48 |
49 | Marshal.FreeCoTaskMem(pidl);
50 | pidl = newPidl;
51 | }
52 |
53 | public static bool IsEmpty(IntPtr pidl)
54 | {
55 | if (pidl == IntPtr.Zero)
56 | return true;
57 |
58 | byte[] bytes = new byte[2];
59 | Marshal.Copy(pidl, bytes, 0, 2);
60 | int size = bytes[0] + bytes[1] * 256;
61 | return (size <= 2);
62 | }
63 |
64 | public static bool SplitPidl(IntPtr pidl, out IntPtr parent, out IntPtr child)
65 | {
66 | parent = ILClone(pidl);
67 | child = ILClone(ILFindLastID(pidl));
68 |
69 | if (!ILRemoveLastID(parent))
70 | {
71 | Marshal.FreeCoTaskMem(parent);
72 | Marshal.FreeCoTaskMem(child);
73 | return false;
74 | }
75 | else
76 | {
77 | return true;
78 | }
79 | }
80 |
81 | public static void Write(IntPtr pidl)
82 | {
83 | StringBuilder path = new StringBuilder(256);
84 | ShellAPI.SHGetPathFromIDList(pidl, path);
85 | Console.Out.WriteLine("Pidl: {0}", path);
86 | }
87 |
88 | public static void WriteBytes(IntPtr pidl)
89 | {
90 | int size = Marshal.ReadByte(pidl, 0) + Marshal.ReadByte(pidl, 1) * 256 - 2;
91 |
92 | for (int i = 0; i < size; i++)
93 | {
94 | Console.Out.WriteLine(Marshal.ReadByte(pidl, i + 2));
95 | }
96 |
97 | Console.Out.WriteLine(Marshal.ReadByte(pidl, size + 2));
98 | Console.Out.WriteLine(Marshal.ReadByte(pidl, size + 3));
99 | }
100 |
101 | public void Free()
102 | {
103 | if (pidl != IntPtr.Zero)
104 | {
105 | Marshal.FreeCoTaskMem(pidl);
106 | pidl = IntPtr.Zero;
107 | }
108 | }
109 |
110 | #endregion
111 |
112 | #region Shell
113 |
114 | private static int ItemIDSize(IntPtr pidl)
115 | {
116 | if (!pidl.Equals(IntPtr.Zero))
117 | {
118 | byte[] buffer = new byte[2];
119 | Marshal.Copy(pidl, buffer, 0, 2);
120 | return buffer[1] * 256 + buffer[0];
121 | }
122 | else
123 | return 0;
124 | }
125 |
126 | private static int ItemIDListSize(IntPtr pidl)
127 | {
128 | if (pidl.Equals(IntPtr.Zero))
129 | return 0;
130 | else
131 | {
132 | int size = ItemIDSize(pidl);
133 | int nextSize = Marshal.ReadByte(pidl, size) + (Marshal.ReadByte(pidl, size + 1) * 256);
134 | while (nextSize > 0)
135 | {
136 | size += nextSize;
137 | nextSize = Marshal.ReadByte(pidl, size) + (Marshal.ReadByte(pidl, size + 1) * 256);
138 | }
139 |
140 | return size;
141 | }
142 | }
143 |
144 | // Clones an ITEMIDLIST structure
145 | public static IntPtr ILClone(IntPtr pidl)
146 | {
147 | int size = ItemIDListSize(pidl);
148 |
149 | byte[] bytes = new byte[size + 2];
150 | Marshal.Copy(pidl, bytes, 0, size);
151 |
152 | IntPtr newPidl = Marshal.AllocCoTaskMem(size + 2);
153 | Marshal.Copy(bytes, 0, newPidl, size + 2);
154 |
155 | return newPidl;
156 | }
157 |
158 | // Clones the first SHITEMID structure in an ITEMIDLIST structure
159 | public static IntPtr ILCloneFirst(IntPtr pidl)
160 | {
161 | int size = ItemIDSize(pidl);
162 |
163 | byte[] bytes = new byte[size + 2];
164 | Marshal.Copy(pidl, bytes, 0, size);
165 |
166 | IntPtr newPidl = Marshal.AllocCoTaskMem(size + 2);
167 | Marshal.Copy(bytes, 0, newPidl, size + 2);
168 |
169 | return newPidl;
170 | }
171 |
172 | // Gets the next SHITEMID structure in an ITEMIDLIST structure
173 | public static IntPtr ILGetNext(IntPtr pidl)
174 | {
175 | int size = ItemIDSize(pidl);
176 | IntPtr nextPidl = new IntPtr((int)pidl + size);
177 | return nextPidl;
178 | }
179 |
180 | // Returns a pointer to the last SHITEMID structure in an ITEMIDLIST structure
181 | public static IntPtr ILFindLastID(IntPtr pidl)
182 | {
183 | IntPtr ptr1 = pidl;
184 | IntPtr ptr2 = ILGetNext(ptr1);
185 |
186 | while (ItemIDSize(ptr2) > 0)
187 | {
188 | ptr1 = ptr2;
189 | ptr2 = ILGetNext(ptr1);
190 | }
191 |
192 | return ptr1;
193 | }
194 |
195 | // Removes the last SHITEMID structure from an ITEMIDLIST structure
196 | public static bool ILRemoveLastID(IntPtr pidl)
197 | {
198 | IntPtr lastPidl = ILFindLastID(pidl);
199 |
200 | if (lastPidl != pidl)
201 | {
202 | int newSize = (int)lastPidl - (int)pidl + 2;
203 | Marshal.ReAllocCoTaskMem(pidl, newSize);
204 | Marshal.Copy(new byte[] { 0, 0 }, 0, new IntPtr((int)pidl + newSize - 2), 2);
205 |
206 | return true;
207 | }
208 | else
209 | return false;
210 | }
211 |
212 | // Combines two ITEMIDLIST structures
213 | public static IntPtr ILCombine(IntPtr pidl1, IntPtr pidl2)
214 | {
215 | int size1 = ItemIDListSize(pidl1);
216 | int size2 = ItemIDListSize(pidl2);
217 |
218 | IntPtr newPidl = Marshal.AllocCoTaskMem(size1 + size2 + 2);
219 | byte[] bytes = new byte[size1 + size2 + 2];
220 |
221 | Marshal.Copy(pidl1, bytes, 0, size1);
222 | Marshal.Copy(pidl2, bytes, size1, size2);
223 |
224 | Marshal.Copy(bytes, 0, newPidl, bytes.Length);
225 |
226 | return newPidl;
227 | }
228 |
229 | #endregion
230 |
231 | #region IEnumerable Members
232 |
233 | public IEnumerator GetEnumerator()
234 | {
235 | return new PIDLEnumerator(pidl);
236 | }
237 |
238 | #endregion
239 |
240 | #region Override
241 |
242 | public override bool Equals(object obj)
243 | {
244 | try
245 | {
246 | if (obj is IntPtr)
247 | return ShellAPI.ILIsEqual(this.Ptr, (IntPtr)obj);
248 | if (obj is PIDL)
249 | return ShellAPI.ILIsEqual(this.Ptr, ((PIDL)obj).Ptr);
250 | else
251 | return false;
252 | }
253 | catch (Exception)
254 | {
255 | return false;
256 | }
257 | }
258 |
259 | public override int GetHashCode()
260 | {
261 | return pidl.GetHashCode();
262 | }
263 |
264 | #endregion
265 |
266 | public class PIDLEnumerator : IEnumerator
267 | {
268 | private IntPtr pidl;
269 | private IntPtr currentPidl;
270 | private IntPtr clonePidl;
271 | private bool start;
272 |
273 | public PIDLEnumerator(IntPtr pidl)
274 | {
275 | start = true;
276 | this.pidl = pidl;
277 | currentPidl = pidl;
278 | clonePidl = IntPtr.Zero;
279 | }
280 |
281 | #region IEnumerator Members
282 |
283 | public object Current
284 | {
285 | get
286 | {
287 | if (clonePidl != IntPtr.Zero)
288 | {
289 | Marshal.FreeCoTaskMem(clonePidl);
290 | clonePidl = IntPtr.Zero;
291 | }
292 |
293 | clonePidl = PIDL.ILCloneFirst(currentPidl);
294 | return clonePidl;
295 | }
296 | }
297 |
298 | public bool MoveNext()
299 | {
300 | if (clonePidl != IntPtr.Zero)
301 | {
302 | Marshal.FreeCoTaskMem(clonePidl);
303 | clonePidl = IntPtr.Zero;
304 | }
305 |
306 | if (start)
307 | {
308 | start = false;
309 | return true;
310 | }
311 | else
312 | {
313 | IntPtr newPidl = ILGetNext(currentPidl);
314 |
315 | if (!PIDL.IsEmpty(newPidl))
316 | {
317 | currentPidl = newPidl;
318 | return true;
319 | }
320 | else
321 | return false;
322 | }
323 | }
324 |
325 | public void Reset()
326 | {
327 | start = true;
328 | currentPidl = pidl;
329 |
330 | if (clonePidl != IntPtr.Zero)
331 | {
332 | Marshal.FreeCoTaskMem(clonePidl);
333 | clonePidl = IntPtr.Zero;
334 | }
335 | }
336 |
337 | #endregion
338 | }
339 | }
340 | }
341 |
--------------------------------------------------------------------------------
/Shell/ShellBrowser.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 | using System.Runtime.InteropServices;
5 | using System.Collections;
6 | using System.Threading;
7 | using System.ComponentModel;
8 | using EasyExplorer;
9 |
10 | namespace ShellDll {
11 | public class ShellBrowser : Component {
12 | public Explorer Browser;
13 |
14 | private ShellItem desktopItem;
15 | private string mydocsName, mycompName, sysfolderName, mydocsPath;
16 |
17 | private ShellBrowserUpdater updater;
18 |
19 | private ArrayList browsers;
20 | private ShellItemUpdateCondition updateCondition;
21 |
22 | internal event ShellItemUpdateEventHandler ShellItemUpdate;
23 |
24 |
25 |
26 | public ShellBrowser(Explorer browse) {
27 | Browser = browse;
28 | InitVars();
29 | browsers = new ArrayList();
30 | updateCondition = new ShellItemUpdateCondition();
31 | updater = new ShellBrowserUpdater(this);
32 | }
33 |
34 | private void InitVars() {
35 | IntPtr tempPidl;
36 | ShellAPI.SHFILEINFO info;
37 |
38 | //My Computer
39 | info = new ShellAPI.SHFILEINFO();
40 | tempPidl = IntPtr.Zero;
41 | ShellAPI.SHGetSpecialFolderLocation(IntPtr.Zero, ShellAPI.CSIDL.DRIVES, out tempPidl);
42 |
43 | ShellAPI.SHGetFileInfo(tempPidl, 0, ref info, ShellAPI.cbFileInfo,
44 | ShellAPI.SHGFI.PIDL | ShellAPI.SHGFI.DISPLAYNAME | ShellAPI.SHGFI.TYPENAME);
45 |
46 | sysfolderName = info.szTypeName;
47 | mycompName = info.szDisplayName;
48 | Marshal.FreeCoTaskMem(tempPidl);
49 | //
50 |
51 | //Dekstop
52 | tempPidl = IntPtr.Zero;
53 | ShellAPI.SHGetSpecialFolderLocation(IntPtr.Zero, ShellAPI.CSIDL.DESKTOP, out tempPidl);
54 | IntPtr desktopFolderPtr;
55 | ShellAPI.SHGetDesktopFolder(out desktopFolderPtr);
56 | desktopItem = new ShellItem(this, tempPidl, desktopFolderPtr);
57 | //
58 |
59 | //My Documents
60 | uint pchEaten = 0;
61 | ShellAPI.SFGAO pdwAttributes = 0;
62 | desktopItem.ShellFolder.ParseDisplayName(
63 | IntPtr.Zero,
64 | IntPtr.Zero,
65 | "::{450d8fba-ad25-11d0-98a8-0800361b1103}",
66 | ref pchEaten,
67 | out tempPidl,
68 | ref pdwAttributes);
69 |
70 | info = new ShellAPI.SHFILEINFO();
71 | ShellAPI.SHGetFileInfo(tempPidl, 0, ref info, ShellAPI.cbFileInfo,
72 | ShellAPI.SHGFI.PIDL | ShellAPI.SHGFI.DISPLAYNAME);
73 |
74 | mydocsName = info.szDisplayName;
75 | Marshal.FreeCoTaskMem(tempPidl);
76 |
77 | StringBuilder path = new StringBuilder(ShellAPI.MAX_PATH);
78 | ShellAPI.SHGetFolderPath(
79 | IntPtr.Zero, ShellAPI.CSIDL.PERSONAL,
80 | IntPtr.Zero, ShellAPI.SHGFP.TYPE_CURRENT, path);
81 | mydocsPath = path.ToString();
82 | //
83 | }
84 |
85 | #region ShellBrowser Update
86 |
87 | internal void OnShellItemUpdate(object sender, ShellItemUpdateEventArgs e) {
88 | if (ShellItemUpdate != null) {
89 | ShellItemUpdate(sender, e);
90 | }
91 | }
92 |
93 | #endregion
94 |
95 | #region Utility Methods
96 |
97 | internal ShellItem GetShellItem(PIDL pidlFull) {
98 | ShellItem current = DesktopItem;
99 | if (pidlFull.Ptr == IntPtr.Zero)
100 | return current;
101 |
102 | foreach (IntPtr pidlRel in pidlFull) {
103 | int index;
104 | if ((index = current.IndexOf(pidlRel)) > -1) {
105 | current = current[index];
106 | } else {
107 | current = null;
108 | break;
109 | }
110 | }
111 |
112 | return current;
113 | }
114 |
115 | internal ShellItem[] GetPath(ShellItem item) {
116 | ArrayList pathList = new ArrayList();
117 |
118 | ShellItem currentItem = item;
119 | while (currentItem.ParentItem != null) {
120 | pathList.Add(currentItem);
121 | currentItem = currentItem.ParentItem;
122 | }
123 | pathList.Add(currentItem);
124 | pathList.Reverse();
125 |
126 | return (ShellItem[])pathList.ToArray(typeof(ShellItem));
127 | }
128 |
129 | #endregion
130 |
131 | #region Properties
132 |
133 | internal ShellItem DesktopItem { get { return desktopItem; } }
134 |
135 | internal string MyDocumentsName { get { return mydocsName; } }
136 | internal string MyComputerName { get { return mycompName; } }
137 | internal string SystemFolderName { get { return sysfolderName; } }
138 |
139 | internal string MyDocumentsPath { get { return mydocsPath; } }
140 |
141 | internal ShellItemUpdateCondition UpdateCondition { get { return updateCondition; } }
142 |
143 | internal ArrayList Browsers { get { return browsers; } }
144 |
145 | #endregion
146 | }
147 |
148 | #region ShellItemUpdate
149 |
150 | internal delegate void ShellItemUpdateEventHandler(object sender, ShellItemUpdateEventArgs e);
151 |
152 | internal enum ShellItemUpdateType {
153 | Created,
154 | IconChange,
155 | Updated,
156 | Renamed,
157 | Deleted,
158 | MediaChange
159 | }
160 |
161 | internal class ShellItemUpdateEventArgs : EventArgs {
162 | ShellItem oldItem, newItem;
163 | ShellItemUpdateType type;
164 |
165 | public ShellItemUpdateEventArgs(
166 | ShellItem oldItem,
167 | ShellItem newItem,
168 | ShellItemUpdateType type) {
169 | this.oldItem = oldItem;
170 | this.newItem = newItem;
171 | this.type = type;
172 | }
173 |
174 | public ShellItem OldItem { get { return oldItem; } }
175 | public ShellItem NewItem { get { return newItem; } }
176 | public ShellItemUpdateType UpdateType { get { return type; } }
177 | }
178 |
179 | #endregion
180 | }
--------------------------------------------------------------------------------
/Shell/ShellBrowserUpdater.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 | using System.Windows.Forms;
5 | using System.Runtime.InteropServices;
6 |
7 | namespace ShellDll
8 | {
9 | internal class ShellBrowserUpdater : NativeWindow
10 | {
11 | #region Fields
12 |
13 | private ShellBrowser br;
14 | private uint notifyId = 0;
15 |
16 | #endregion
17 |
18 | public ShellBrowserUpdater(ShellBrowser br)
19 | {
20 | this.br = br;
21 | CreateHandle(new CreateParams());
22 |
23 | ShellAPI.SHChangeNotifyEntry entry = new ShellAPI.SHChangeNotifyEntry();
24 | entry.pIdl = br.DesktopItem.PIDLRel.Ptr;
25 | entry.Recursively = true;
26 |
27 | notifyId = ShellAPI.SHChangeNotifyRegister(
28 | this.Handle,
29 | ShellAPI.SHCNRF.InterruptLevel | ShellAPI.SHCNRF.ShellLevel,
30 | ShellAPI.SHCNE.ALLEVENTS | ShellAPI.SHCNE.INTERRUPT,
31 | ShellAPI.WM.SH_NOTIFY,
32 | 1,
33 | new ShellAPI.SHChangeNotifyEntry[] { entry });
34 | }
35 |
36 | ~ShellBrowserUpdater()
37 | {
38 | if (notifyId > 0)
39 | {
40 | ShellAPI.SHChangeNotifyDeregister(notifyId);
41 | GC.SuppressFinalize(this);
42 | }
43 | }
44 |
45 | protected override void WndProc(ref Message m)
46 | {
47 | if (m.Msg == (int)ShellAPI.WM.SH_NOTIFY)
48 | {
49 | ShellAPI.SHNOTIFYSTRUCT shNotify =
50 | (ShellAPI.SHNOTIFYSTRUCT)Marshal.PtrToStructure(m.WParam, typeof(ShellAPI.SHNOTIFYSTRUCT));
51 |
52 | //Console.Out.WriteLine("Event: {0}", (ShellAPI.SHCNE)m.LParam);
53 | //if (shNotify.dwItem1 != IntPtr.Zero)
54 | //PIDL.Write(shNotify.dwItem1);
55 | //if (shNotify.dwItem2 != IntPtr.Zero)
56 | //PIDL.Write(shNotify.dwItem2);
57 |
58 | switch ((ShellAPI.SHCNE)m.LParam)
59 | {
60 | #region File Changes
61 |
62 | case ShellAPI.SHCNE.CREATE:
63 | #region Create Item
64 | {
65 | if (!PIDL.IsEmpty(shNotify.dwItem1))
66 | {
67 | IntPtr parent, child, relative;
68 | PIDL.SplitPidl(shNotify.dwItem1, out parent, out child);
69 |
70 | PIDL parentPIDL = new PIDL(parent, false);
71 | ShellItem parentItem = br.GetShellItem(parentPIDL);
72 | if (parentItem != null && parentItem.FilesExpanded && !parentItem.SubFiles.Contains(child))
73 | {
74 | ShellAPI.SHGetRealIDL(
75 | parentItem.ShellFolder,
76 | child,
77 | out relative);
78 | parentItem.AddItem(new ShellItem(br, parentItem, relative));
79 | }
80 |
81 | Marshal.FreeCoTaskMem(child);
82 | parentPIDL.Free();
83 | }
84 | }
85 | #endregion
86 | break;
87 |
88 | case ShellAPI.SHCNE.RENAMEITEM:
89 | #region Rename Item
90 | {
91 | if (!PIDL.IsEmpty(shNotify.dwItem1) && !PIDL.IsEmpty(shNotify.dwItem2))
92 | {
93 | ShellItem item = br.GetShellItem(new PIDL(shNotify.dwItem1, true));
94 | if (item != null)
95 | item.Update(shNotify.dwItem2, ShellItemUpdateType.Renamed);
96 | }
97 | }
98 | #endregion
99 | break;
100 |
101 | case ShellAPI.SHCNE.DELETE:
102 | #region Delete Item
103 | {
104 | if (!PIDL.IsEmpty(shNotify.dwItem1))
105 | {
106 | IntPtr parent, child;
107 | PIDL.SplitPidl(shNotify.dwItem1, out parent, out child);
108 |
109 | PIDL parentPIDL = new PIDL(parent, false);
110 | ShellItem parentItem = br.GetShellItem(parentPIDL);
111 | if (parentItem != null && parentItem.SubFiles.Contains(child))
112 | parentItem.RemoveItem(parentItem.SubFiles[child]);
113 |
114 | Marshal.FreeCoTaskMem(child);
115 | parentPIDL.Free();
116 | }
117 | }
118 | #endregion
119 | break;
120 |
121 | case ShellAPI.SHCNE.UPDATEITEM:
122 | #region Update Item
123 | {
124 | if (!PIDL.IsEmpty(shNotify.dwItem1))
125 | {
126 | ShellItem item = br.GetShellItem(new PIDL(shNotify.dwItem1, true));
127 | if (item != null)
128 | {
129 | Console.Out.WriteLine("Item: {0}", item);
130 | item.Update(IntPtr.Zero, ShellItemUpdateType.Updated);
131 | item.Update(IntPtr.Zero, ShellItemUpdateType.IconChange);
132 | }
133 | }
134 | }
135 | #endregion
136 | break;
137 |
138 | #endregion
139 |
140 | #region Folder Changes
141 |
142 | case ShellAPI.SHCNE.MKDIR:
143 | case ShellAPI.SHCNE.DRIVEADD:
144 | case ShellAPI.SHCNE.DRIVEADDGUI:
145 | #region Make Directory
146 | {
147 | if (!PIDL.IsEmpty(shNotify.dwItem1))
148 | {
149 | IntPtr parent, child, relative;
150 | PIDL.SplitPidl(shNotify.dwItem1, out parent, out child);
151 |
152 | PIDL parentPIDL = new PIDL(parent, false);
153 | ShellItem parentItem = br.GetShellItem(parentPIDL);
154 | if (parentItem != null && parentItem.FoldersExpanded && !parentItem.SubFolders.Contains(child))
155 | {
156 | ShellAPI.SHGetRealIDL(
157 | parentItem.ShellFolder,
158 | child,
159 | out relative);
160 |
161 | IntPtr shellFolderPtr;
162 | if (parentItem.ShellFolder.BindToObject(
163 | relative,
164 | IntPtr.Zero,
165 | ref ShellAPI.IID_IShellFolder,
166 | out shellFolderPtr) == ShellAPI.S_OK)
167 | {
168 | parentItem.AddItem(new ShellItem(br, parentItem, relative, shellFolderPtr));
169 | }
170 | else
171 | Marshal.FreeCoTaskMem(relative);
172 | }
173 |
174 | Marshal.FreeCoTaskMem(child);
175 | parentPIDL.Free();
176 | }
177 | }
178 | #endregion
179 | break;
180 |
181 | case ShellAPI.SHCNE.RENAMEFOLDER:
182 | #region Rename Directory
183 | {
184 | if (!PIDL.IsEmpty(shNotify.dwItem1) && !PIDL.IsEmpty(shNotify.dwItem2))
185 | {
186 | ShellItem item = br.GetShellItem(new PIDL(shNotify.dwItem1, false));
187 | if (item != null)
188 | {
189 | //Console.Out.WriteLine("Update: {0}", item);
190 | item.Update(shNotify.dwItem2, ShellItemUpdateType.Renamed);
191 | }
192 | }
193 | }
194 | #endregion
195 | break;
196 |
197 | case ShellAPI.SHCNE.RMDIR:
198 | case ShellAPI.SHCNE.DRIVEREMOVED:
199 | #region Remove Directory
200 | {
201 | if (!PIDL.IsEmpty(shNotify.dwItem1))
202 | {
203 | IntPtr parent, child;
204 | PIDL.SplitPidl(shNotify.dwItem1, out parent, out child);
205 |
206 | PIDL parentPIDL = new PIDL(parent, false);
207 | ShellItem parentItem = br.GetShellItem(parentPIDL);
208 | if (parentItem != null && parentItem.SubFolders.Contains(child))
209 | parentItem.RemoveItem(parentItem.SubFolders[child]);
210 |
211 | Marshal.FreeCoTaskMem(child);
212 | parentPIDL.Free();
213 | }
214 | }
215 | #endregion
216 | break;
217 |
218 | case ShellAPI.SHCNE.UPDATEDIR:
219 | case ShellAPI.SHCNE.ATTRIBUTES:
220 | #region Update Directory
221 | {
222 | if (!PIDL.IsEmpty(shNotify.dwItem1))
223 | {
224 | ShellItem item = br.GetShellItem(new PIDL(shNotify.dwItem1, true));
225 | if (item != null)
226 | {
227 | item.Update(IntPtr.Zero, ShellItemUpdateType.Updated);
228 | item.Update(IntPtr.Zero, ShellItemUpdateType.IconChange);
229 | }
230 | }
231 | }
232 | #endregion
233 | break;
234 |
235 | case ShellAPI.SHCNE.MEDIAINSERTED:
236 | case ShellAPI.SHCNE.MEDIAREMOVED:
237 | #region Media Change
238 | {
239 | if (!PIDL.IsEmpty(shNotify.dwItem1))
240 | {
241 | ShellItem item = br.GetShellItem(new PIDL(shNotify.dwItem1, true));
242 | if (item != null)
243 | item.Update(IntPtr.Zero, ShellItemUpdateType.MediaChange);
244 | }
245 | }
246 | #endregion
247 | break;
248 |
249 | #endregion
250 |
251 | #region Other Changes
252 |
253 | case ShellAPI.SHCNE.ASSOCCHANGED:
254 | #region Update Images
255 | {
256 |
257 | }
258 | #endregion
259 | break;
260 |
261 | case ShellAPI.SHCNE.NETSHARE:
262 | case ShellAPI.SHCNE.NETUNSHARE:
263 | break;
264 |
265 | case ShellAPI.SHCNE.UPDATEIMAGE:
266 | UpdateRecycleBin();
267 | break;
268 |
269 | #endregion
270 | }
271 | }
272 |
273 | base.WndProc(ref m);
274 | }
275 |
276 | private void UpdateRecycleBin()
277 | {
278 | ShellItem recycleBin = br.DesktopItem["Recycle Bin"];
279 | if (recycleBin != null)
280 | recycleBin.Update(IntPtr.Zero, ShellItemUpdateType.IconChange);
281 | }
282 | }
283 | }
284 |
--------------------------------------------------------------------------------
/Shell/ShellHelper.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 | using System.Windows.Forms;
5 | using System.Runtime.InteropServices;
6 |
7 | namespace ShellDll
8 | {
9 | internal static class ShellHelper
10 | {
11 | #region Low/High Word
12 |
13 | ///
14 | /// Retrieves the High Word of a WParam of a WindowMessage
15 | ///
16 | /// The pointer to the WParam
17 | /// The unsigned integer for the High Word
18 | public static uint HiWord(IntPtr ptr)
19 | {
20 | if (((uint)ptr & 0x80000000) == 0x80000000)
21 | return ((uint)ptr >> 16);
22 | else
23 | return ((uint)ptr >> 16) & 0xffff;
24 | }
25 |
26 | ///
27 | /// Retrieves the Low Word of a WParam of a WindowMessage
28 | ///
29 | /// The pointer to the WParam
30 | /// The unsigned integer for the Low Word
31 | public static uint LoWord(IntPtr ptr)
32 | {
33 | return (uint)ptr & 0xffff;
34 | }
35 |
36 | #endregion
37 |
38 | #region IStream/IStorage
39 |
40 | public static bool GetIStream(ShellItem item, out IntPtr streamPtr, out IStream stream)
41 | {
42 | if (item.ParentItem.ShellFolder.BindToStorage(
43 | item.PIDLRel.Ptr,
44 | IntPtr.Zero,
45 | ref ShellAPI.IID_IStream,
46 | out streamPtr) == ShellAPI.S_OK)
47 | {
48 | stream = (IStream)Marshal.GetTypedObjectForIUnknown(streamPtr, typeof(IStream));
49 | return true;
50 | }
51 | else
52 | {
53 | stream = null;
54 | streamPtr = IntPtr.Zero;
55 | return false;
56 | }
57 | }
58 |
59 | public static bool GetIStorage(ShellItem item, out IntPtr storagePtr, out IStorage storage)
60 | {
61 | if (item.ParentItem.ShellFolder.BindToStorage(
62 | item.PIDLRel.Ptr,
63 | IntPtr.Zero,
64 | ref ShellAPI.IID_IStorage,
65 | out storagePtr) == ShellAPI.S_OK)
66 | {
67 | storage = (IStorage)Marshal.GetTypedObjectForIUnknown(storagePtr, typeof(IStorage));
68 | return true;
69 | }
70 | else
71 | {
72 | storage = null;
73 | storagePtr = IntPtr.Zero;
74 | return false;
75 | }
76 | }
77 |
78 | #endregion
79 |
80 | #region Drag/Drop
81 |
82 | ///
83 | /// This method will use the GetUIObjectOf method of IShellFolder to obtain the IDataObject of a
84 | /// ShellItem.
85 | ///
86 | /// The item for which to obtain the IDataObject
87 | /// A pointer to the returned IDataObject
88 | /// the IDataObject the ShellItem
89 | public static IntPtr GetIDataObject(ShellItem[] items)
90 | {
91 | ShellItem parent = items[0].ParentItem != null ? items[0].ParentItem : items[0];
92 |
93 | IntPtr[] pidls = new IntPtr[items.Length];
94 | for (int i = 0; i < items.Length; i++)
95 | pidls[i] = items[i].PIDLRel.Ptr;
96 |
97 | IntPtr dataObjectPtr;
98 | if (parent.ShellFolder.GetUIObjectOf(
99 | IntPtr.Zero,
100 | (uint)pidls.Length,
101 | pidls,
102 | ref ShellAPI.IID_IDataObject,
103 | IntPtr.Zero,
104 | out dataObjectPtr) == ShellAPI.S_OK)
105 | {
106 | return dataObjectPtr;
107 | }
108 | else
109 | {
110 | return IntPtr.Zero;
111 | }
112 | }
113 |
114 | ///
115 | /// This method will use the GetUIObjectOf method of IShellFolder to obtain the IDropTarget of a
116 | /// ShellItem.
117 | ///
118 | /// The item for which to obtain the IDropTarget
119 | /// A pointer to the returned IDropTarget
120 | /// the IDropTarget from the ShellItem
121 | public static bool GetIDropTarget(ShellItem item, out IntPtr dropTargetPtr, out ShellDll.IDropTarget dropTarget)
122 | {
123 | ShellItem parent = item.ParentItem != null ? item.ParentItem : item;
124 |
125 | if (parent.ShellFolder.GetUIObjectOf(
126 | IntPtr.Zero,
127 | 1,
128 | new IntPtr[] { item.PIDLRel.Ptr },
129 | ref ShellAPI.IID_IDropTarget,
130 | IntPtr.Zero,
131 | out dropTargetPtr) == ShellAPI.S_OK)
132 | {
133 | dropTarget =
134 | (ShellDll.IDropTarget)Marshal.GetTypedObjectForIUnknown(dropTargetPtr, typeof(ShellDll.IDropTarget));
135 |
136 | return true;
137 | }
138 | else
139 | {
140 | dropTarget = null;
141 | dropTargetPtr = IntPtr.Zero;
142 | return false;
143 | }
144 | }
145 |
146 | public static bool GetIDropTargetHelper(out IntPtr helperPtr, out IDropTargetHelper dropHelper)
147 | {
148 | if (ShellAPI.CoCreateInstance(
149 | ref ShellAPI.CLSID_DragDropHelper,
150 | IntPtr.Zero,
151 | ShellAPI.CLSCTX.INPROC_SERVER,
152 | ref ShellAPI.IID_IDropTargetHelper,
153 | out helperPtr) == ShellAPI.S_OK)
154 | {
155 | dropHelper =
156 | (IDropTargetHelper)Marshal.GetTypedObjectForIUnknown(helperPtr, typeof(IDropTargetHelper));
157 |
158 | return true;
159 | }
160 | else
161 | {
162 | dropHelper = null;
163 | helperPtr = IntPtr.Zero;
164 | return false;
165 | }
166 | }
167 |
168 | public static DragDropEffects CanDropClipboard(ShellItem item)
169 | {
170 | IntPtr dataObject;
171 | ShellAPI.OleGetClipboard(out dataObject);
172 |
173 | IntPtr targetPtr;
174 | ShellDll.IDropTarget target;
175 |
176 | DragDropEffects retVal = DragDropEffects.None;
177 | if (GetIDropTarget(item, out targetPtr, out target))
178 | {
179 | #region Check Copy
180 | DragDropEffects effects = DragDropEffects.Copy;
181 | if (target.DragEnter(
182 | dataObject,
183 | ShellAPI.MK.CONTROL,
184 | new ShellAPI.POINT(0, 0),
185 | ref effects) == ShellAPI.S_OK)
186 | {
187 | if (effects == DragDropEffects.Copy)
188 | retVal |= DragDropEffects.Copy;
189 |
190 | target.DragLeave();
191 | }
192 | #endregion
193 |
194 | #region Check Move
195 | effects = DragDropEffects.Move;
196 | if (target.DragEnter(
197 | dataObject,
198 | ShellAPI.MK.SHIFT,
199 | new ShellAPI.POINT(0, 0),
200 | ref effects) == ShellAPI.S_OK)
201 | {
202 | if (effects == DragDropEffects.Move)
203 | retVal |= DragDropEffects.Move;
204 |
205 | target.DragLeave();
206 | }
207 | #endregion
208 |
209 | #region Check Lick
210 | effects = DragDropEffects.Link;
211 | if (target.DragEnter(
212 | dataObject,
213 | ShellAPI.MK.ALT,
214 | new ShellAPI.POINT(0, 0),
215 | ref effects) == ShellAPI.S_OK)
216 | {
217 | if (effects == DragDropEffects.Link)
218 | retVal |= DragDropEffects.Link;
219 |
220 | target.DragLeave();
221 | }
222 | #endregion
223 |
224 | Marshal.ReleaseComObject(target);
225 | Marshal.Release(targetPtr);
226 | }
227 |
228 | return retVal;
229 | }
230 |
231 | #endregion
232 |
233 | #region QueryInfo
234 |
235 | public static bool GetIQueryInfo(ShellItem item, out IntPtr iQueryInfoPtr, out IQueryInfo iQueryInfo)
236 | {
237 | ShellItem parent = item.ParentItem != null ? item.ParentItem : item;
238 |
239 | if (parent.ShellFolder.GetUIObjectOf(
240 | IntPtr.Zero,
241 | 1,
242 | new IntPtr[] { item.PIDLRel.Ptr },
243 | ref ShellAPI.IID_IQueryInfo,
244 | IntPtr.Zero,
245 | out iQueryInfoPtr) == ShellAPI.S_OK)
246 | {
247 | iQueryInfo =
248 | (IQueryInfo)Marshal.GetTypedObjectForIUnknown(iQueryInfoPtr, typeof(IQueryInfo));
249 |
250 | return true;
251 | }
252 | else
253 | {
254 | iQueryInfo = null;
255 | iQueryInfoPtr = IntPtr.Zero;
256 | return false;
257 | }
258 | }
259 |
260 | #endregion
261 | }
262 | }
263 |
--------------------------------------------------------------------------------
/Shell/ShellImageList.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Text;
3 | using System.Windows.Forms;
4 | using System.Collections;
5 | using System.Threading;
6 | using System.Drawing;
7 | using System.Runtime.InteropServices;
8 |
9 | namespace ShellDll
10 | {
11 | public static class ShellImageList
12 | {
13 | private static IntPtr smallImageListHandle, largeImageListHandle;
14 | private static Hashtable imageTable;
15 |
16 | private const int TVSIL_NORMAL = 0;
17 | private const int TVSIL_SMALL = 1;
18 |
19 | static ShellImageList()
20 | {
21 | imageTable = new Hashtable();
22 |
23 | ShellAPI.SHGFI flag = ShellAPI.SHGFI.USEFILEATTRIBUTES | ShellAPI.SHGFI.SYSICONINDEX | ShellAPI.SHGFI.SMALLICON;
24 | ShellAPI.SHFILEINFO shfiSmall = new ShellAPI.SHFILEINFO();
25 | smallImageListHandle = ShellAPI.SHGetFileInfo(".txt", ShellAPI.FILE_ATTRIBUTE.NORMAL, ref shfiSmall, ShellAPI.cbFileInfo, flag);
26 |
27 | flag = ShellAPI.SHGFI.USEFILEATTRIBUTES | ShellAPI.SHGFI.SYSICONINDEX | ShellAPI.SHGFI.LARGEICON;
28 | ShellAPI.SHFILEINFO shfiLarge = new ShellAPI.SHFILEINFO();
29 | largeImageListHandle = ShellAPI.SHGetFileInfo(".txt", ShellAPI.FILE_ATTRIBUTE.NORMAL, ref shfiLarge, ShellAPI.cbFileInfo, flag);
30 | }
31 |
32 | internal static void SetIconIndex(ShellItem item, int index, bool SelectedIcon)
33 | {
34 | bool HasOverlay = false; //true if it's an overlay
35 | int rVal = 0; //The returned Index
36 |
37 | ShellAPI.SHGFI dwflag = ShellAPI.SHGFI.SYSICONINDEX | ShellAPI.SHGFI.PIDL | ShellAPI.SHGFI.ICON;
38 | ShellAPI.FILE_ATTRIBUTE dwAttr = 0;
39 | //build Key into HashTable for this Item
40 | int Key = index * 256;
41 | if (item.IsLink)
42 | {
43 | Key = Key | 1;
44 | dwflag = dwflag | ShellAPI.SHGFI.LINKOVERLAY;
45 | HasOverlay = true;
46 | }
47 | if (item.IsShared)
48 | {
49 | Key = Key | 2;
50 | dwflag = dwflag | ShellAPI.SHGFI.ADDOVERLAYS;
51 | HasOverlay = true;
52 | }
53 | if (SelectedIcon)
54 | {
55 | Key = Key | 4;
56 | dwflag = dwflag | ShellAPI.SHGFI.OPENICON;
57 | HasOverlay = true; //not really an overlay, but handled the same
58 | }
59 |
60 | if (imageTable.ContainsKey(Key))
61 | {
62 | rVal = (int)imageTable[Key];
63 | }
64 | else if (!HasOverlay && !item.IsHidden) //for non-overlay icons, we already have
65 | {
66 | rVal = (int)System.Math.Floor((double)Key / 256); // the right index -- put in table
67 | imageTable[Key] = rVal;
68 | }
69 | else //don't have iconindex for an overlay, get it.
70 | {
71 | if (item.IsFileSystem & !item.IsDisk & !item.IsFolder)
72 | {
73 | dwflag = dwflag | ShellAPI.SHGFI.USEFILEATTRIBUTES;
74 | dwAttr = dwAttr | ShellAPI.FILE_ATTRIBUTE.NORMAL;
75 | }
76 |
77 | PIDL pidlFull = item.PIDLFull;
78 |
79 | ShellAPI.SHFILEINFO shfiSmall = new ShellAPI.SHFILEINFO();
80 | ShellAPI.SHGetFileInfo(pidlFull.Ptr, dwAttr, ref shfiSmall, ShellAPI.cbFileInfo, dwflag | ShellAPI.SHGFI.SMALLICON);
81 |
82 | ShellAPI.SHFILEINFO shfiLarge = new ShellAPI.SHFILEINFO();
83 | ShellAPI.SHGetFileInfo(pidlFull.Ptr, dwAttr, ref shfiLarge, ShellAPI.cbFileInfo, dwflag | ShellAPI.SHGFI.LARGEICON);
84 |
85 | Marshal.FreeCoTaskMem(pidlFull.Ptr);
86 |
87 | lock (imageTable)
88 | {
89 | rVal = ShellAPI.ImageList_ReplaceIcon(smallImageListHandle, -1, shfiSmall.hIcon);
90 | ShellAPI.ImageList_ReplaceIcon(largeImageListHandle, -1, shfiLarge.hIcon);
91 | }
92 |
93 | ShellAPI.DestroyIcon(shfiSmall.hIcon);
94 | ShellAPI.DestroyIcon(shfiLarge.hIcon);
95 | imageTable[Key] = rVal;
96 | }
97 |
98 | if (SelectedIcon)
99 | item.SelectedImageIndex = rVal;
100 | else
101 | item.ImageIndex = rVal;
102 | }
103 |
104 | public static Icon GetIcon(int index, bool small)
105 | {
106 | IntPtr iconPtr;
107 |
108 | if (small)
109 | iconPtr = ShellAPI.ImageList_GetIcon(smallImageListHandle, index, ShellAPI.ILD.NORMAL);
110 | else
111 | iconPtr = ShellAPI.ImageList_GetIcon(largeImageListHandle, index, ShellAPI.ILD.NORMAL);
112 |
113 | if (iconPtr != IntPtr.Zero)
114 | {
115 | Icon icon = Icon.FromHandle(iconPtr);
116 | Icon retVal = (Icon)icon.Clone();
117 | ShellAPI.DestroyIcon(iconPtr);
118 | return retVal;
119 | }
120 | else
121 | return null;
122 | }
123 |
124 | internal static IntPtr SmallImageList { get { return smallImageListHandle; } }
125 | internal static IntPtr LargeImageList { get { return largeImageListHandle; } }
126 |
127 | #region Set Small Handle
128 |
129 | internal static void SetSmallImageList(TreeView treeView)
130 | {
131 | ShellAPI.SendMessage(treeView.Handle, ShellAPI.WM.TVM_SETIMAGELIST, TVSIL_NORMAL, smallImageListHandle);
132 | }
133 |
134 | internal static void SetSmallImageList(ListView listView)
135 | {
136 | ShellAPI.SendMessage(listView.Handle, ShellAPI.WM.LVM_SETIMAGELIST, TVSIL_SMALL, smallImageListHandle);
137 | }
138 |
139 | #endregion
140 |
141 | #region Set Large Handle
142 |
143 | internal static void SetLargeImageList(ListView listView)
144 | {
145 | ShellAPI.SendMessage(listView.Handle, ShellAPI.WM.LVM_SETIMAGELIST, TVSIL_NORMAL, largeImageListHandle);
146 | }
147 |
148 | #endregion
149 | }
150 | }
151 |
--------------------------------------------------------------------------------
/Shell/StreamStorage.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 | using EasyExplorer;
5 | using System.IO;
6 | using System.Runtime.InteropServices;
7 |
8 | namespace ShellDll
9 | {
10 | internal class StreamStorageProvider : IFileInfoProvider, IDirInfoProvider
11 | {
12 | #region Fields
13 |
14 | private ShellItem providerItem;
15 | private FileAccess fileAccess;
16 |
17 | #endregion
18 |
19 | public StreamStorageProvider(FileAccess fileAccess)
20 | {
21 | this.fileAccess = fileAccess;
22 | }
23 |
24 | #region Free
25 |
26 | internal void ReleaseStorage()
27 | {
28 | dirInfoRetrieved = false;
29 | }
30 |
31 | internal void ReleaseStream()
32 | {
33 | if (tempStreamReader != null)
34 | {
35 | tempStreamReader.CloseStream();
36 | tempStreamReader = null;
37 | }
38 |
39 | if (tempParentStorage != null)
40 | {
41 | Marshal.ReleaseComObject(tempParentStorage);
42 | Marshal.Release(tempParentStoragePtr);
43 | tempParentStorage = null;
44 | }
45 | }
46 |
47 | #endregion
48 |
49 | #region IFileInfoProvider Members
50 |
51 | private ShellStreamReader tempStreamReader;
52 | private IStorage tempParentStorage;
53 | private IntPtr tempParentStoragePtr;
54 |
55 | public ShellAPI.STATSTG GetFileInfo()
56 | {
57 | if (tempStreamReader != null)
58 | return tempStreamReader.StreamInfo;
59 | else if (providerItem != null)
60 | {
61 | if (tempParentStorage == null)
62 | ShellHelper.GetIStorage(providerItem.ParentItem, out tempParentStoragePtr, out tempParentStorage);
63 |
64 | tempStreamReader = new ShellStreamReader(providerItem, tempParentStorage, fileAccess);
65 | return tempStreamReader.StreamInfo;
66 | }
67 | else
68 | throw new Exception("Not possible to retrieve the STATSTG.");
69 | }
70 |
71 | public Stream GetFileStream()
72 | {
73 | if (tempStreamReader != null)
74 | return tempStreamReader;
75 | else if (providerItem != null)
76 | {
77 | if (tempParentStorage == null)
78 | ShellHelper.GetIStorage(providerItem.ParentItem, out tempParentStoragePtr, out tempParentStorage);
79 |
80 | tempStreamReader = new ShellStreamReader(providerItem, tempParentStorage, fileAccess);
81 | return tempStreamReader;
82 | }
83 | else
84 | throw new Exception("Not possible to open a filestream.");
85 | }
86 |
87 | #endregion
88 |
89 | #region IDirInfoProvider Members
90 |
91 | private ShellAPI.STATSTG dirInfo;
92 | private bool dirInfoRetrieved = false;
93 |
94 | public ShellAPI.STATSTG GetDirInfo()
95 | {
96 | if (dirInfoRetrieved)
97 | return dirInfo;
98 | else if (providerItem != null)
99 | {
100 | IntPtr tempPtr;
101 | IStorage tempStorage;
102 |
103 | if (ShellHelper.GetIStorage(providerItem, out tempPtr, out tempStorage))
104 | {
105 | tempStorage.Stat(out dirInfo, ShellAPI.STATFLAG.NONAME);
106 | Marshal.ReleaseComObject(tempStorage);
107 | Marshal.Release(tempPtr);
108 | }
109 | else
110 | throw new Exception("Not possible to retrieve the STATSTG.");
111 |
112 | dirInfoRetrieved = true;
113 | return dirInfo;
114 | }
115 | else
116 | throw new Exception("Not possible to retrieve the STATSTG.");
117 | }
118 |
119 | #endregion
120 |
121 | #region Properties
122 |
123 | public ShellItem ProviderItem
124 | {
125 | get { return providerItem; }
126 | set { providerItem = value; }
127 | }
128 |
129 | public FileAccess FileAccess
130 | {
131 | get { return fileAccess; }
132 | set { fileAccess = value; }
133 | }
134 |
135 | #endregion
136 | }
137 |
138 | public class ShellStreamReader : Stream, IDisposable
139 | {
140 | #region Fields
141 |
142 | private ShellItem shellItem;
143 |
144 | private IntPtr streamPtr;
145 | private IStream stream;
146 |
147 | private bool canRead, canWrite;
148 |
149 | private ShellAPI.STATSTG streamInfo;
150 | private bool streamInfoRead = false;
151 |
152 | private long currentPos;
153 |
154 | private bool disposed = false;
155 |
156 | #endregion
157 |
158 | internal ShellStreamReader(ShellItem shellItem, IStorage parentStorage, FileAccess access)
159 | {
160 | this.shellItem = shellItem;
161 |
162 | OpenStream(parentStorage, ref access);
163 |
164 | this.canRead = (access == FileAccess.Read || access == FileAccess.ReadWrite);
165 | this.canWrite = (access == FileAccess.Write || access == FileAccess.ReadWrite);
166 | currentPos = 0;
167 | }
168 |
169 | ~ShellStreamReader()
170 | {
171 | CloseStream();
172 | }
173 |
174 | #region Stream Members
175 |
176 | public override bool CanRead
177 | {
178 | get { return canRead; }
179 | }
180 |
181 | public override bool CanSeek
182 | {
183 | get { return true; }
184 | }
185 |
186 | public override bool CanWrite
187 | {
188 | get { return canWrite; }
189 | }
190 |
191 | public override void Flush()
192 | {
193 |
194 | }
195 |
196 | public override long Length
197 | {
198 | get
199 | {
200 | if (CanRead)
201 | return StreamInfo.cbSize;
202 | else
203 | return 0;
204 | }
205 | }
206 |
207 | public override long Position
208 | {
209 | get
210 | {
211 | return currentPos;
212 | }
213 | set
214 | {
215 | Seek(value, SeekOrigin.Begin);
216 | }
217 | }
218 |
219 | public override int Read(byte[] buffer, int offset, int count)
220 | {
221 | if (CanRead)
222 | {
223 | byte[] readBytes = new byte[count];
224 |
225 | IntPtr readNrPtr = Marshal.AllocCoTaskMem(32);
226 | stream.Read(readBytes, count, readNrPtr);
227 |
228 | int readNr = (int)Marshal.PtrToStructure(readNrPtr, typeof(Int32));
229 | Marshal.FreeCoTaskMem(readNrPtr);
230 |
231 | Array.Copy(readBytes, 0, buffer, offset, readNr);
232 | currentPos += readNr;
233 | return readNr;
234 | }
235 | else
236 | return 0;
237 | }
238 |
239 | public override void SetLength(long value)
240 | {
241 | if (CanWrite)
242 | stream.SetSize(value);
243 | }
244 |
245 | public override void Write(byte[] buffer, int offset, int count)
246 | {
247 | if (CanWrite)
248 | {
249 | byte[] writeBytes = new byte[count];
250 | Array.Copy(buffer, offset, writeBytes, 0, count);
251 |
252 | IntPtr writtenNrPtr = Marshal.AllocCoTaskMem(64);
253 | stream.Write(writeBytes, count, writtenNrPtr);
254 |
255 | long writtenNr = (long)Marshal.PtrToStructure(writtenNrPtr, typeof(Int64));
256 | Marshal.FreeCoTaskMem(writtenNrPtr);
257 |
258 | currentPos += writtenNr;
259 | }
260 | }
261 |
262 | public override long Seek(long offset, SeekOrigin origin)
263 | {
264 | if (CanSeek)
265 | {
266 | IntPtr newPosPtr = Marshal.AllocCoTaskMem(64);
267 | stream.Seek(offset, origin, newPosPtr);
268 |
269 | long newPos = (long)Marshal.PtrToStructure(newPosPtr, typeof(Int64));
270 | Marshal.FreeCoTaskMem(newPosPtr);
271 |
272 | return (currentPos = newPos);
273 | }
274 | else
275 | return -1;
276 | }
277 |
278 | #endregion
279 |
280 | #region IDisposable Members
281 |
282 | void IDisposable.Dispose()
283 | {
284 | if (!disposed)
285 | {
286 | disposed = true;
287 |
288 | if (stream != null)
289 | {
290 | Marshal.ReleaseComObject(stream);
291 | stream = null;
292 | }
293 |
294 | if (streamPtr != IntPtr.Zero)
295 | {
296 | Marshal.Release(streamPtr);
297 | streamPtr = IntPtr.Zero;
298 | }
299 |
300 | GC.SuppressFinalize(this);
301 | }
302 | }
303 |
304 | #endregion
305 |
306 | #region Open/Close Stream
307 |
308 | public override void Close()
309 | {
310 |
311 | }
312 |
313 | internal void CloseStream()
314 | {
315 | base.Close();
316 |
317 | if (stream != null)
318 | {
319 | Marshal.ReleaseComObject(stream);
320 | Marshal.Release(streamPtr);
321 | }
322 | }
323 |
324 | internal ShellAPI.STATSTG StreamInfo
325 | {
326 | get
327 | {
328 | if (!streamInfoRead)
329 | {
330 | stream.Stat(out streamInfo, ShellAPI.STATFLAG.NONAME);
331 | streamInfoRead = true;
332 | }
333 | return streamInfo;
334 | }
335 | }
336 |
337 | private void OpenStream(IStorage parentStorage, ref FileAccess access)
338 | {
339 | ShellAPI.STGM grfmode = ShellAPI.STGM.SHARE_DENY_WRITE;
340 |
341 | switch (access)
342 | {
343 | case FileAccess.ReadWrite:
344 | grfmode |= ShellAPI.STGM.READWRITE;
345 | break;
346 |
347 | case FileAccess.Write:
348 | grfmode |= ShellAPI.STGM.WRITE;
349 | break;
350 | }
351 |
352 | if (parentStorage != null)
353 | {
354 | if (parentStorage.OpenStream(
355 | shellItem.Text + (shellItem.IsLink ? ".lnk" : string.Empty),
356 | IntPtr.Zero,
357 | grfmode,
358 | 0,
359 | out streamPtr) == ShellAPI.S_OK)
360 | {
361 | stream = (IStream)Marshal.GetTypedObjectForIUnknown(streamPtr, typeof(IStream));
362 | }
363 | else if (access != FileAccess.Read)
364 | {
365 | if (parentStorage.OpenStream(
366 | shellItem.Text + (shellItem.IsLink ? ".lnk" : string.Empty),
367 | IntPtr.Zero,
368 | ShellAPI.STGM.SHARE_DENY_WRITE,
369 | 0,
370 | out streamPtr) == ShellAPI.S_OK)
371 | {
372 | access = FileAccess.Read;
373 | stream = (IStream)Marshal.GetTypedObjectForIUnknown(streamPtr, typeof(IStream));
374 | }
375 | else
376 | throw new IOException(String.Format("Can't open stream: {0}", shellItem));
377 | }
378 | else
379 | throw new IOException(String.Format("Can't open stream: {0}", shellItem));
380 | }
381 | else
382 | {
383 | access = FileAccess.Read;
384 |
385 | if (!ShellHelper.GetIStream(shellItem, out streamPtr, out stream))
386 | throw new IOException(String.Format("Can't open stream: {0}", shellItem));
387 | }
388 | }
389 |
390 | #endregion
391 | }
392 | }
393 |
--------------------------------------------------------------------------------
/Website/ee1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/robinrodricks/EasyExplorer/4b74fe2fc01b20a414cede7e8f776d4dcccc8ccd/Website/ee1.png
--------------------------------------------------------------------------------
/Website/ee2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/robinrodricks/EasyExplorer/4b74fe2fc01b20a414cede7e8f776d4dcccc8ccd/Website/ee2.png
--------------------------------------------------------------------------------
/Wrappers/BrowserContextMenuWrappers.cs:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/robinrodricks/EasyExplorer/4b74fe2fc01b20a414cede7e8f776d4dcccc8ccd/Wrappers/BrowserContextMenuWrappers.cs
--------------------------------------------------------------------------------
/Wrappers/BrowserDragWrappers.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 | using ShellDll;
5 | using System.Runtime.InteropServices;
6 | using System.Windows.Forms;
7 | using System.Drawing;
8 |
9 | namespace EasyExplorer
10 | {
11 | ///
12 | /// This class takes care of every drag operation in a BrowserTreeView
13 | ///
14 | internal class BrowserTVDragWrapper : IDropSource, IDisposable
15 | {
16 | #region Fields
17 |
18 | // The browser for which to do the drag work
19 | private Explorer br;
20 |
21 | // The pointer to the IDataObject being dragged
22 | private IntPtr dataObjectPtr;
23 |
24 | // The mouseButtons state when a drag starts
25 | private MouseButtons startButton;
26 |
27 | // A bool to indicate whether this class has been disposed
28 | private bool disposed = false;
29 |
30 | // The events that will be raised when a drag starts and when it ends
31 | public event DragEnterEventHandler DragStart;
32 | public event EventHandler DragEnd;
33 |
34 | #endregion
35 |
36 | ///
37 | /// Registers the TreeView.ItemDrag to receive the event when an item is being dragged
38 | ///
39 | /// The browser for which to support the drag
40 | public BrowserTVDragWrapper(Explorer br)
41 | {
42 | this.br = br;
43 | br.FolderView.ItemDrag += new ItemDragEventHandler(ItemDrag);
44 | }
45 |
46 | ~BrowserTVDragWrapper()
47 | {
48 | ((IDisposable)this).Dispose();
49 | }
50 |
51 | #region Generated Events
52 |
53 | ///
54 | /// The event that is being raised when a drag starts
55 | ///
56 | /// the DragEnterEventArgs for the event
57 | private void OnDragStart(DragEnterEventArgs e)
58 | {
59 | if (DragStart != null)
60 | DragStart(this, e);
61 | }
62 |
63 | ///
64 | /// The event that is being raised when a drag ends
65 | ///
66 | /// the EventArgs for the event
67 | private void OnDragEnd(EventArgs e)
68 | {
69 | if (DragEnd != null)
70 | DragEnd(this, e);
71 | }
72 |
73 | #endregion
74 |
75 | #region IDropSource Members
76 |
77 | ///
78 | /// This method initialises the dragging of a TreeNode
79 | ///
80 | void ItemDrag(object sender, ItemDragEventArgs e)
81 | {
82 | ReleaseCom();
83 |
84 | startButton = e.Button;
85 | ShellItem item = (ShellItem)((TreeNode)e.Item).Tag;
86 | dataObjectPtr = ShellHelper.GetIDataObject(new ShellItem[] { item });
87 |
88 | if (dataObjectPtr != IntPtr.Zero)
89 | {
90 | DragDropEffects effects;
91 | OnDragStart(new DragEnterEventArgs((item.ParentItem != null ? item.ParentItem : item), br.FolderView));
92 | ShellAPI.DoDragDrop(dataObjectPtr, this, DragDropEffects.Copy | DragDropEffects.Link | DragDropEffects.Move, out effects);
93 | OnDragEnd(new EventArgs());
94 | }
95 | }
96 |
97 | public int QueryContinueDrag(bool fEscapePressed, ShellAPI.MK grfKeyState)
98 | {
99 | if (fEscapePressed)
100 | return ShellAPI.DRAGDROP_S_CANCEL;
101 | else
102 | {
103 | if ((startButton & MouseButtons.Left) != 0 && (grfKeyState & ShellAPI.MK.LBUTTON) == 0)
104 | return ShellAPI.DRAGDROP_S_DROP;
105 | else if ((startButton & MouseButtons.Right) != 0 && (grfKeyState & ShellAPI.MK.RBUTTON) == 0)
106 | return ShellAPI.DRAGDROP_S_DROP;
107 | else
108 | return ShellAPI.S_OK;
109 | }
110 | }
111 |
112 | public int GiveFeedback(DragDropEffects dwEffect)
113 | {
114 | return ShellAPI.DRAGDROP_S_USEDEFAULTCURSORS;
115 | }
116 |
117 | #endregion
118 |
119 | #region IDisposable Members
120 |
121 | ///
122 | /// If not disposed, dispose the class
123 | ///
124 | public void Dispose()
125 | {
126 | if (!disposed)
127 | {
128 | ReleaseCom();
129 | GC.SuppressFinalize(this);
130 |
131 | disposed = true;
132 | }
133 | }
134 |
135 | ///
136 | /// Release the IDataObject and free's the allocated memory
137 | ///
138 | private void ReleaseCom()
139 | {
140 | if (dataObjectPtr != IntPtr.Zero)
141 | {
142 | Marshal.Release(dataObjectPtr);
143 | dataObjectPtr = IntPtr.Zero;
144 | }
145 | }
146 |
147 | #endregion
148 | }
149 |
150 | ///
151 | /// This class takes care of every drag operation in a BrowserListView
152 | ///
153 | internal class BrowserLVDragWrapper : IDropSource, IDisposable
154 | {
155 | #region Fields
156 |
157 | // The browser for which to do the drag work
158 | private Explorer br;
159 |
160 | // The pointer to the IDataObject being dragged
161 | private IntPtr dataObjectPtr;
162 |
163 | // The mouseButtons state when a drag starts
164 | private MouseButtons startButton;
165 |
166 | // A bool to indicate whether this class has been disposed
167 | private bool disposed = false;
168 |
169 | // The events that will be raised when a drag starts and when it ends
170 | public event DragEnterEventHandler DragStart;
171 | public event EventHandler DragEnd;
172 |
173 | #endregion
174 |
175 | ///
176 | /// Registers the ListView.ItemDrag to receive the event when an item is being dragged
177 | ///
178 | /// The browser for which to support the drag
179 | public BrowserLVDragWrapper(Explorer br)
180 | {
181 | this.br = br;
182 | br.FileView.ItemDrag += new ItemDragEventHandler(ItemDrag);
183 | }
184 |
185 | ~BrowserLVDragWrapper()
186 | {
187 | ((IDisposable)this).Dispose();
188 | }
189 |
190 | #region Generated Events
191 |
192 | ///
193 | /// The event that is being raised when a drag starts
194 | ///
195 | /// the DragEnterEventArgs for the event
196 | private void OnDragStart(DragEnterEventArgs e)
197 | {
198 | if (DragStart != null)
199 | DragStart(this, e);
200 | }
201 |
202 | ///
203 | /// The event that is being raised when a drag ends
204 | ///
205 | /// the EventArgs for the event
206 | private void OnDragEnd(EventArgs e)
207 | {
208 | if (DragEnd != null)
209 | DragEnd(this, e);
210 | }
211 |
212 | #endregion
213 |
214 | #region IDropSource Members
215 |
216 | ///
217 | /// This method initialises the dragging of a ListViewItem
218 | ///
219 | void ItemDrag(object sender, ItemDragEventArgs e)
220 | {
221 | ReleaseCom();
222 |
223 | startButton = e.Button;
224 |
225 | ShellItem[] items = new ShellItem[br.FileView.SelectedItems.Count];
226 | for (int i = 0; i < br.FileView.SelectedItems.Count; i++)
227 | {
228 | items[i] = (ShellItem)br.FileView.SelectedItems[i].Tag;
229 | }
230 |
231 | dataObjectPtr = ShellHelper.GetIDataObject(items);
232 |
233 | if (dataObjectPtr != IntPtr.Zero)
234 | {
235 | DragDropEffects effects;
236 | OnDragStart(new DragEnterEventArgs((items[0].ParentItem != null ? items[0].ParentItem : items[0]), br.FileView));
237 | ShellAPI.DoDragDrop(dataObjectPtr, this, DragDropEffects.Copy | DragDropEffects.Link | DragDropEffects.Move, out effects);
238 | OnDragEnd(new EventArgs());
239 | }
240 | }
241 |
242 | public int QueryContinueDrag(bool fEscapePressed, ShellAPI.MK grfKeyState)
243 | {
244 | if (fEscapePressed)
245 | return ShellAPI.DRAGDROP_S_CANCEL;
246 | else
247 | {
248 | if ((startButton & MouseButtons.Left) != 0 && (grfKeyState & ShellAPI.MK.LBUTTON) == 0)
249 | return ShellAPI.DRAGDROP_S_DROP;
250 | else if ((startButton & MouseButtons.Right) != 0 && (grfKeyState & ShellAPI.MK.RBUTTON) == 0)
251 | return ShellAPI.DRAGDROP_S_DROP;
252 | else
253 | return ShellAPI.S_OK;
254 | }
255 | }
256 |
257 | public int GiveFeedback(DragDropEffects dwEffect)
258 | {
259 | return ShellAPI.DRAGDROP_S_USEDEFAULTCURSORS;
260 | }
261 |
262 | #endregion
263 |
264 | #region IDisposable Members
265 |
266 | ///
267 | /// If not disposed, dispose the class
268 | ///
269 | public void Dispose()
270 | {
271 | if (!disposed)
272 | {
273 | ReleaseCom();
274 | GC.SuppressFinalize(this);
275 |
276 | disposed = true;
277 | }
278 | }
279 |
280 | ///
281 | /// Release the IDataObject and free's the allocated memory
282 | ///
283 | private void ReleaseCom()
284 | {
285 | if (dataObjectPtr != IntPtr.Zero)
286 | {
287 | Marshal.Release(dataObjectPtr);
288 | dataObjectPtr = IntPtr.Zero;
289 | }
290 | }
291 |
292 | #endregion
293 | }
294 |
295 | #region Event Classes
296 |
297 | internal delegate void DragEnterEventHandler(object sender, DragEnterEventArgs e);
298 |
299 | internal class DragEnterEventArgs : EventArgs
300 | {
301 | private ShellItem parent;
302 | private Control dragStartControl;
303 |
304 | public DragEnterEventArgs(ShellItem parent, Control dragStartControl)
305 | {
306 | this.parent = parent;
307 | this.dragStartControl = dragStartControl;
308 | }
309 |
310 | public ShellItem Parent { get { return parent; } }
311 | public Control DragStartControl { get { return dragStartControl; } }
312 | }
313 |
314 | #endregion
315 | }
316 |
--------------------------------------------------------------------------------
/Wrappers/BrowserDropWrappers.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 | using ShellDll;
5 | using System.Runtime.InteropServices;
6 | using System.Windows.Forms;
7 | using System.Drawing;
8 |
9 | namespace EasyExplorer
10 | {
11 | ///
12 | /// This class takes care of every drop operation in a BrowserTreeView
13 | ///
14 | internal class BrowserTVDropWrapper : ShellDll.IDropTarget, IDisposable
15 | {
16 | #region Fields
17 |
18 | // The browser for which to do the drop work
19 | private Explorer br;
20 |
21 | private IntPtr treeViewHandle;
22 |
23 | // The current IDropTarget the cursor is over and the pointers to the target and dataobject
24 | private ShellDll.IDropTarget dropTarget;
25 | private IntPtr dropTargetPtr;
26 | private IntPtr dropDataObject;
27 |
28 | private IDropTargetHelper dropHelper;
29 | private IntPtr dropHelperPtr;
30 |
31 | // The current node the cursor is over to drop on
32 | private TreeNode dropNode;
33 |
34 | // The last selected node from the browser
35 | // This is to remember which node to select after drop has completed
36 | private TreeNode lastSelectedNode;
37 |
38 | // The parent ShellItems of the drop- and dragitem
39 | private ShellItem parentDropItem, parentDragItem;
40 |
41 | // The mouse and keys state when a drag enter occurs
42 | private ShellAPI.MK mouseButtons;
43 |
44 | // A bool to indicate whether this class has been disposed
45 | private bool disposed = false;
46 |
47 | // The event for when a drop is occuring
48 | public event DropEventHandler Drop;
49 |
50 | #endregion
51 |
52 | ///
53 | /// Registers the TreeView for drag/drop operations and uses this class as the IDropTarget
54 | ///
55 | /// The browser for which to support the drop
56 | public BrowserTVDropWrapper(Explorer br)
57 | {
58 | this.br = br;
59 |
60 | treeViewHandle = br.FolderView.Handle;
61 | ShellAPI.RegisterDragDrop(treeViewHandle, this);
62 |
63 | br.FolderView.HandleCreated += new EventHandler(FolderView_HandleCreated);
64 | br.FolderView.HandleDestroyed += new EventHandler(FolderView_HandleDestroyed);
65 |
66 | ShellHelper.GetIDropTargetHelper(out dropHelperPtr, out dropHelper);
67 | }
68 |
69 | ~BrowserTVDropWrapper()
70 | {
71 | ((IDisposable)this).Dispose();
72 | }
73 |
74 | #region Handle Changes
75 |
76 | void FolderView_HandleCreated(object sender, EventArgs e)
77 | {
78 | treeViewHandle = br.FolderView.Handle;
79 | ShellAPI.RegisterDragDrop(treeViewHandle, this);
80 | }
81 |
82 | void FolderView_HandleDestroyed(object sender, EventArgs e)
83 | {
84 | ShellAPI.RevokeDragDrop(br.FolderView.Handle);
85 | }
86 |
87 | #endregion
88 |
89 | #region Public
90 |
91 | ///
92 | /// This ShellItem is the parent item of the item being currently dragged. This field is used
93 | /// to check whether an item is being moved to it's original folder. If this is the case, we don't
94 | /// have to do anything, cause the item is allready there.
95 | ///
96 | public ShellItem ParentDragItem
97 | {
98 | get { return parentDragItem; }
99 | set { parentDragItem = value; }
100 | }
101 |
102 | #endregion
103 |
104 | #region Generated Events
105 |
106 | ///
107 | /// This event will be raised whenever a drop occurs on the TreeView.
108 | ///
109 | /// The DropEventArgs for the event
110 | private void OnDrop(DropEventArgs e)
111 | {
112 | if (Drop != null)
113 | Drop(this, e);
114 | }
115 |
116 | #endregion
117 |
118 | #region IDropTarget Members
119 |
120 | public int DragEnter(IntPtr pDataObj, ShellAPI.MK grfKeyState, ShellAPI.POINT pt, ref DragDropEffects pdwEffect)
121 | {
122 | mouseButtons = grfKeyState;
123 |
124 | br.FolderView.Focus();
125 | br.SelectionChange = false;
126 | lastSelectedNode = br.FolderView.SelectedNode;
127 |
128 | ReleaseCom();
129 |
130 | dropDataObject = pDataObj;
131 |
132 | #region Get DropItem
133 |
134 | Point point = br.FolderView.PointToClient(new Point(pt.x, pt.y));
135 | TreeViewHitTestInfo hitTest = br.FolderView.HitTest(point);
136 |
137 | dropNode = hitTest.Node;
138 | br.FolderView.SelectedNode = dropNode;
139 |
140 | if (dropNode != null)
141 | {
142 | ShellItem item = (ShellItem)dropNode.Tag;
143 | parentDropItem = item;
144 |
145 | if (ShellHelper.GetIDropTarget(item, out dropTargetPtr, out dropTarget))
146 | {
147 | dropTarget.DragEnter(pDataObj, grfKeyState, pt, ref pdwEffect);
148 | }
149 | }
150 |
151 | #endregion
152 |
153 | if (dropHelper != null)
154 | dropHelper.DragEnter(br.Handle, pDataObj, ref pt, pdwEffect);
155 |
156 | return ShellAPI.S_OK;
157 | }
158 |
159 | public int DragOver(ShellAPI.MK grfKeyState, ShellAPI.POINT pt, ref DragDropEffects pdwEffect)
160 | {
161 | bool reset = false;
162 |
163 | #region Get DropItem
164 |
165 | Point point = br.FolderView.PointToClient(new Point(pt.x, pt.y));
166 | TreeViewHitTestInfo hitTest = br.FolderView.HitTest(point);
167 | if (!TreeNode.Equals(dropNode, hitTest.Node))
168 | {
169 | if (dropTarget != null)
170 | dropTarget.DragLeave();
171 |
172 | ReleaseCom();
173 |
174 | dropNode = hitTest.Node;
175 | br.FolderView.SelectedNode = dropNode;
176 |
177 | if (dropNode == null)
178 | {
179 | pdwEffect = DragDropEffects.None;
180 |
181 | if (dropHelper != null)
182 | dropHelper.DragOver(ref pt, pdwEffect);
183 |
184 | return ShellAPI.S_OK;
185 | }
186 | else
187 | {
188 | ShellItem item = (ShellItem)dropNode.Tag;
189 | parentDropItem = item;
190 |
191 | ShellHelper.GetIDropTarget(item, out dropTargetPtr, out dropTarget);
192 | reset = true;
193 | }
194 | }
195 | else if (dropNode == null)
196 | {
197 | if (dropTarget != null)
198 | dropTarget.DragLeave();
199 |
200 | ReleaseCom();
201 |
202 | dropNode = null;
203 | br.SelectedNode = null;
204 |
205 | pdwEffect = DragDropEffects.None;
206 |
207 | if (dropHelper != null)
208 | dropHelper.DragOver(ref pt, pdwEffect);
209 |
210 | return ShellAPI.S_OK;
211 | }
212 |
213 | #endregion
214 |
215 | if (dropTarget != null)
216 | {
217 | if (reset)
218 | dropTarget.DragEnter(dropDataObject, grfKeyState, pt, ref pdwEffect);
219 | else
220 | dropTarget.DragOver(grfKeyState, pt, ref pdwEffect);
221 | }
222 | else
223 | pdwEffect = DragDropEffects.None;
224 |
225 | if (dropHelper != null)
226 | dropHelper.DragOver(ref pt, pdwEffect);
227 |
228 | return ShellAPI.S_OK;
229 | }
230 |
231 | public int DragLeave()
232 | {
233 | ResetDrop();
234 | if (dropTarget != null)
235 | {
236 | dropTarget.DragLeave();
237 |
238 | ReleaseCom();
239 | dropDataObject = IntPtr.Zero;
240 | }
241 |
242 | if (dropHelper != null)
243 | dropHelper.DragLeave();
244 |
245 | return ShellAPI.S_OK;
246 | }
247 |
248 | public int DragDrop(IntPtr pDataObj, ShellAPI.MK grfKeyState, ShellAPI.POINT pt, ref DragDropEffects pdwEffect)
249 | {
250 | OnDrop(new DropEventArgs(mouseButtons, br.FolderView));
251 |
252 | if (!((mouseButtons & ShellAPI.MK.RBUTTON) != 0 ||
253 | grfKeyState == ShellAPI.MK.CONTROL ||
254 | grfKeyState == ShellAPI.MK.ALT ||
255 | grfKeyState == (ShellAPI.MK.CONTROL | ShellAPI.MK.SHIFT)) && ShellItem.Equals(parentDragItem, parentDropItem))
256 | {
257 | ResetDrop();
258 | ReleaseCom();
259 | pdwEffect = DragDropEffects.None;
260 |
261 | if (dropHelper != null)
262 | dropHelper.DragLeave();
263 |
264 | return ShellAPI.S_OK;
265 | }
266 |
267 | ResetDrop();
268 | if (dropTarget != null)
269 | {
270 | dropTarget.DragDrop(pDataObj, grfKeyState, pt, ref pdwEffect);
271 |
272 | ReleaseCom();
273 | dropDataObject = IntPtr.Zero;
274 | }
275 |
276 | if (dropHelper != null)
277 | dropHelper.Drop(pDataObj, ref pt, pdwEffect);
278 |
279 | return ShellAPI.S_OK;
280 | }
281 |
282 | ///
283 | /// Reset all fields to the default values and release the IDropTarget
284 | ///
285 | private void ResetDrop()
286 | {
287 | if (dropNode != null)
288 | {
289 | dropNode = null;
290 | parentDropItem = null;
291 | }
292 |
293 | if (lastSelectedNode != null)
294 | br.FolderView.SelectedNode = lastSelectedNode;
295 |
296 | br.SelectionChange = true;
297 | }
298 |
299 | #endregion
300 |
301 | #region IDisposable Members
302 |
303 | ///
304 | /// If not disposed, dispose the class
305 | ///
306 | public void Dispose()
307 | {
308 | if (!disposed)
309 | {
310 | DisposeDropWrapper();
311 | GC.SuppressFinalize(this);
312 |
313 | disposed = true;
314 | }
315 | }
316 |
317 | ///
318 | /// Revokes the TreeView from getting drop messages and releases the IDropTarget
319 | ///
320 | private void DisposeDropWrapper()
321 | {
322 | ReleaseCom();
323 |
324 | if (dropHelper != null)
325 | {
326 | Marshal.ReleaseComObject(dropHelper);
327 | }
328 | }
329 |
330 | ///
331 | /// Release the IDropTarget and free's the allocated memory
332 | ///
333 | private void ReleaseCom()
334 | {
335 | if (dropTarget != null)
336 | {
337 | Marshal.ReleaseComObject(dropTarget);
338 |
339 | dropTarget = null;
340 | dropHelperPtr = IntPtr.Zero;
341 | }
342 | }
343 |
344 | #endregion
345 | }
346 |
347 | ///
348 | /// This class takes care of every drop operation in a BrowserListView
349 | ///
350 | internal class BrowserLVDropWrapper : ShellDll.IDropTarget, IDisposable
351 | {
352 | #region Fields
353 |
354 | // The browser for which to do the drop work
355 | private Explorer br;
356 |
357 | private IntPtr listViewHandle;
358 |
359 | // The current IDropTarget the cursor is over and the pointers to the target and dataobject
360 | private ShellDll.IDropTarget dropTarget;
361 | private IntPtr dropTargetPtr;
362 | private IntPtr dropDataObject;
363 |
364 | private IDropTargetHelper dropHelper;
365 | private IntPtr dropHelperPtr;
366 |
367 | // The current ListViewItem the cursor is over to drop on
368 | private ListViewItem dropListItem;
369 |
370 | // The selected state from the dropListItem before the cursor moved over it
371 | private bool wasSelected;
372 |
373 | // The parent ShellItems of the drop- and dragitem
374 | private ShellItem parentDropItem, parentDragItem;
375 |
376 | // The mouse and keys state and DragDropEffects when a drag enter occurs
377 | private ShellAPI.MK mouseButtons;
378 | private DragDropEffects startEffects;
379 |
380 | // A bool to indicate whether this class has been disposed
381 | private bool disposed = false;
382 |
383 | // The event for when a drop is occuring
384 | public event DropEventHandler Drop;
385 |
386 | #endregion
387 |
388 | ///
389 | /// Registers the ListView for drag/drop operations and uses this class as the IDropTarget
390 | ///
391 | /// The browser for which to support the drop
392 | public BrowserLVDropWrapper(Explorer br)
393 | {
394 | this.br = br;
395 |
396 | listViewHandle = br.FileView.Handle;
397 | ShellAPI.RegisterDragDrop(listViewHandle, this);
398 |
399 | br.FileView.HandleCreated += new EventHandler(FileView_HandleCreated);
400 | br.FileView.HandleDestroyed += new EventHandler(FileView_HandleDestroyed);
401 |
402 | ShellHelper.GetIDropTargetHelper(out dropHelperPtr, out dropHelper);
403 | }
404 |
405 | ~BrowserLVDropWrapper()
406 | {
407 | ((IDisposable)this).Dispose();
408 | }
409 |
410 | #region Handle Changes
411 |
412 | void FileView_HandleCreated(object sender, EventArgs e)
413 | {
414 | listViewHandle = br.FileView.Handle;
415 | ShellAPI.RegisterDragDrop(listViewHandle, this);
416 | }
417 |
418 | void FileView_HandleDestroyed(object sender, EventArgs e)
419 | {
420 | ShellAPI.RevokeDragDrop(listViewHandle);
421 | }
422 |
423 | #endregion
424 |
425 | #region Public
426 |
427 | ///
428 | /// This ShellItem is the parent item of the item being currently dragged. This field is used
429 | /// to check whether an item is being moved to it's original folder. If this is the case, we don't
430 | /// have to do anything, cause the item is allready there.
431 | ///
432 | public ShellItem ParentDragItem
433 | {
434 | get { return parentDragItem; }
435 | set { parentDragItem = value; }
436 | }
437 |
438 | #endregion
439 |
440 | #region Generated Events
441 |
442 | ///
443 | /// This event will be raised whenever a drop occurs on the ListView.
444 | ///
445 | /// The DropEventArgs for the event
446 | private void OnDrop(DropEventArgs e)
447 | {
448 | if (Drop != null)
449 | Drop(this, e);
450 | }
451 |
452 | #endregion
453 |
454 | #region IDropTarget Members
455 |
456 | public int DragEnter(IntPtr pDataObj, ShellAPI.MK grfKeyState, ShellAPI.POINT pt, ref DragDropEffects pdwEffect)
457 | {
458 | mouseButtons = grfKeyState;
459 | startEffects = pdwEffect;
460 |
461 | br.FileView.Focus();
462 | br.SelectionChange = false;
463 | ReleaseCom();
464 |
465 | dropDataObject = pDataObj;
466 |
467 | #region Get DropItem
468 | Point point = br.FileView.PointToClient(new Point(pt.x, pt.y));
469 | ListViewHitTestInfo hitTest = br.FileView.HitTest(point);
470 | if (hitTest.Item != null &&
471 | (br.FileView.View != View.Details || hitTest.SubItem == null || hitTest.Item.Name == hitTest.SubItem.Name) &&
472 | (hitTest.Location == ListViewHitTestLocations.Image ||
473 | hitTest.Location == ListViewHitTestLocations.Label ||
474 | hitTest.Location == ListViewHitTestLocations.StateImage))
475 | {
476 | dropListItem = hitTest.Item;
477 |
478 | wasSelected = dropListItem.Selected;
479 | dropListItem.Selected = true;
480 |
481 | ShellItem item = (ShellItem)dropListItem.Tag;
482 | parentDropItem = item;
483 |
484 | ShellHelper.GetIDropTarget(item, out dropTargetPtr, out dropTarget);
485 | }
486 | else
487 | {
488 | dropListItem = null;
489 | parentDropItem = br.SelectedItem;
490 | ShellHelper.GetIDropTarget(br.SelectedItem, out dropTargetPtr, out dropTarget);
491 | }
492 | #endregion
493 |
494 | if (dropTarget != null)
495 | dropTarget.DragEnter(pDataObj, grfKeyState, pt, ref pdwEffect);
496 |
497 | if (dropHelper != null)
498 | dropHelper.DragEnter(br.Handle, pDataObj, ref pt, pdwEffect);
499 |
500 | return ShellAPI.S_OK;
501 | }
502 |
503 | public int DragOver(ShellAPI.MK grfKeyState, ShellAPI.POINT pt, ref DragDropEffects pdwEffect)
504 | {
505 | bool reset = false;
506 |
507 | #region Get DropItem
508 |
509 | Point point = br.FileView.PointToClient(new Point(pt.x, pt.y));
510 | ListViewHitTestInfo hitTest = br.FileView.HitTest(point);
511 | if (hitTest.Item != null &&
512 | (br.FileView.View != View.Details || hitTest.SubItem == null || hitTest.Item.Name == hitTest.SubItem.Name) &&
513 | (hitTest.Location == ListViewHitTestLocations.Image ||
514 | hitTest.Location == ListViewHitTestLocations.Label ||
515 | hitTest.Location == ListViewHitTestLocations.StateImage))
516 | {
517 | if (!hitTest.Item.Equals(dropListItem))
518 | {
519 | if (dropTarget != null)
520 | dropTarget.DragLeave();
521 |
522 | ReleaseCom();
523 |
524 | if (dropListItem != null)
525 | dropListItem.Selected = wasSelected;
526 |
527 | dropListItem = hitTest.Item;
528 | wasSelected = dropListItem.Selected;
529 | dropListItem.Selected = true;
530 |
531 | ShellItem item = (ShellItem)dropListItem.Tag;
532 | parentDropItem = item;
533 |
534 | ShellHelper.GetIDropTarget(item, out dropTargetPtr, out dropTarget);
535 | reset = true;
536 | }
537 | }
538 | else
539 | {
540 | if (dropListItem != null)
541 | {
542 | if (dropTarget != null)
543 | dropTarget.DragLeave();
544 |
545 | ReleaseCom();
546 |
547 | dropListItem.Selected = wasSelected;
548 |
549 | dropListItem = null;
550 | parentDropItem = br.SelectedItem;
551 |
552 | ShellHelper.GetIDropTarget(br.SelectedItem, out dropTargetPtr, out dropTarget);
553 | reset = true;
554 | }
555 | }
556 |
557 | #endregion
558 |
559 | if (dropTarget != null)
560 | {
561 | if (reset)
562 | dropTarget.DragEnter(dropDataObject, grfKeyState, pt, ref pdwEffect);
563 | else
564 | dropTarget.DragOver(grfKeyState, pt, ref pdwEffect);
565 | }
566 | else
567 | pdwEffect = DragDropEffects.None;
568 |
569 | if (dropHelper != null)
570 | dropHelper.DragOver(ref pt, pdwEffect);
571 |
572 | return ShellAPI.S_OK;
573 | }
574 |
575 | public int DragLeave()
576 | {
577 | ResetDrop();
578 | if (dropTarget != null)
579 | {
580 | dropTarget.DragLeave();
581 |
582 | ReleaseCom();
583 | dropDataObject = IntPtr.Zero;
584 | }
585 |
586 | if (dropHelper != null)
587 | dropHelper.DragLeave();
588 |
589 | return ShellAPI.S_OK;
590 | }
591 |
592 | public int DragDrop(IntPtr pDataObj, ShellAPI.MK grfKeyState, ShellAPI.POINT pt, ref DragDropEffects pdwEffect)
593 | {
594 | OnDrop(new DropEventArgs(mouseButtons, br.FileView));
595 |
596 | if (!((mouseButtons & ShellAPI.MK.RBUTTON) != 0 ||
597 | grfKeyState == ShellAPI.MK.CONTROL ||
598 | grfKeyState == ShellAPI.MK.ALT ||
599 | grfKeyState == (ShellAPI.MK.CONTROL | ShellAPI.MK.SHIFT)) && ShellItem.Equals(parentDragItem, parentDropItem))
600 | {
601 | ResetDrop();
602 | ReleaseCom();
603 | pdwEffect = DragDropEffects.None;
604 |
605 | if (dropHelper != null)
606 | dropHelper.Drop(pDataObj, ref pt, pdwEffect);
607 |
608 | return ShellAPI.S_OK;
609 | }
610 |
611 | ResetDrop();
612 | if (dropTarget != null)
613 | {
614 | dropTarget.DragDrop(pDataObj, grfKeyState, pt, ref pdwEffect);
615 |
616 | ReleaseCom();
617 | dropDataObject = IntPtr.Zero;
618 | }
619 |
620 | if (dropHelper != null)
621 | dropHelper.Drop(pDataObj, ref pt, pdwEffect);
622 |
623 | return ShellAPI.S_OK;
624 | }
625 |
626 | ///
627 | /// Reset all fields to the default values and release the IDropTarget
628 | ///
629 | private void ResetDrop()
630 | {
631 | if (dropListItem != null)
632 | {
633 | dropListItem.Selected = wasSelected;
634 | dropListItem = null;
635 | parentDropItem = null;
636 | }
637 |
638 | br.SelectionChange = true;
639 | }
640 |
641 | #endregion
642 |
643 | #region IDisposable Members
644 |
645 | ///
646 | /// If not disposed, dispose the class
647 | ///
648 | public void Dispose()
649 | {
650 | if (!disposed)
651 | {
652 | DisposeDropWrapper();
653 | GC.SuppressFinalize(this);
654 |
655 | disposed = true;
656 | }
657 | }
658 |
659 | ///
660 | /// Revokes the ListView from getting drop messages and releases the IDropTarget
661 | ///
662 | private void DisposeDropWrapper()
663 | {
664 | ReleaseCom();
665 |
666 | if (dropHelper != null)
667 | {
668 | Marshal.ReleaseComObject(dropHelper);
669 | }
670 | }
671 |
672 | ///
673 | /// Release the IDropTarget and free's the allocated memory
674 | ///
675 | private void ReleaseCom()
676 | {
677 | if (dropTarget != null)
678 | {
679 | Marshal.ReleaseComObject(dropTarget);
680 |
681 | dropTarget = null;
682 | dropHelperPtr = IntPtr.Zero;
683 | }
684 | }
685 |
686 | #endregion
687 | }
688 |
689 | #region Event Classes
690 |
691 | internal delegate void DropEventHandler(object sender, DropEventArgs e);
692 |
693 | internal class DropEventArgs : EventArgs
694 | {
695 | private ShellAPI.MK mouseButtons;
696 | private Control dragStartControl;
697 |
698 | public DropEventArgs(ShellAPI.MK mouseButtons, Control dragStartControl)
699 | {
700 | this.mouseButtons = mouseButtons;
701 | this.dragStartControl = dragStartControl;
702 | }
703 |
704 | public ShellAPI.MK MouseButtons { get { return mouseButtons; } }
705 | public Control DragStartControl { get { return dragStartControl; } }
706 | }
707 |
708 | #endregion
709 | }
710 |
--------------------------------------------------------------------------------
/Wrappers/BrowserPluginWrapper.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 | using System.Collections;
5 | using ShellDll;
6 | using System.Reflection;
7 | using System.Windows.Forms;
8 | using System.IO;
9 | using System.Globalization;
10 | using System.Security.Policy;
11 | using System.Drawing;
12 | using System.ComponentModel;
13 |
14 | namespace EasyExplorer
15 | {
16 | public class BrowserPluginWrapper : Component
17 | {
18 | #region Fields
19 |
20 | private ArrayList columnPlugins;
21 | private ArrayList viewPlugins;
22 | private ArrayList contextPlugins;
23 |
24 | #endregion
25 |
26 | public BrowserPluginWrapper()
27 | {
28 | columnPlugins = new ArrayList();
29 | viewPlugins = new ArrayList();
30 | contextPlugins = new ArrayList();
31 |
32 | LoadPlugins();
33 | }
34 |
35 | private void LoadPlugins()
36 | {
37 | string pluginPath = Application.StartupPath + @"\plugins";
38 |
39 | if (Directory.Exists(pluginPath))
40 | {
41 | string[] files = Directory.GetFiles(pluginPath, "*.dll");
42 |
43 | foreach (string file in files)
44 | {
45 | try
46 | {
47 | Assembly plugin = Assembly.LoadFile(file);
48 |
49 | Type[] types = plugin.GetTypes();
50 |
51 | foreach (Type type in types)
52 | {
53 | try
54 | {
55 | IBrowserPlugin browserPlugin =
56 | plugin.CreateInstance(type.ToString()) as IBrowserPlugin;
57 |
58 | if (browserPlugin != null)
59 | {
60 | if (browserPlugin is IColumnPlugin)
61 | columnPlugins.Add(browserPlugin);
62 |
63 | if (browserPlugin is IViewPlugin)
64 | viewPlugins.Add(browserPlugin);
65 |
66 | //if (browserPlugin is IContextPlugin)
67 | //contextPlugins.Add(browserPlugin);
68 | }
69 | }
70 | catch (Exception) { }
71 | }
72 | }
73 | catch (Exception) { }
74 | }
75 | }
76 | }
77 |
78 | #region Properties
79 |
80 | public ArrayList ColumnPlugins { get { return columnPlugins; } }
81 | public ArrayList ViewPlugins { get { return viewPlugins; } }
82 | public ArrayList ContextPlugins { get { return contextPlugins; } }
83 |
84 | #endregion
85 | }
86 |
87 | #region Plugins
88 |
89 | public interface IBrowserPlugin
90 | {
91 | string Name { get; }
92 | string Info { get; }
93 | }
94 |
95 | public interface IColumnPlugin : IBrowserPlugin
96 | {
97 | string[] ColumnNames { get; }
98 |
99 | HorizontalAlignment GetAlignment(string columnName);
100 |
101 | string GetFolderInfo(IDirInfoProvider provider, string columnName, ShellItem item);
102 | string GetFileInfo(IFileInfoProvider provider, string columnName, ShellItem item);
103 | }
104 |
105 | public interface IViewPlugin : IBrowserPlugin
106 | {
107 | string ViewName { get; }
108 | Control ViewControl { get; }
109 |
110 | void FolderSelected(IDirInfoProvider provider, ShellItem item);
111 | void FileSelected(IFileInfoProvider provider, ShellItem item);
112 | void Reset();
113 | }
114 |
115 | /*public interface IContextPlugin : IBrowserPlugin
116 | {
117 | string MenuText { get; }
118 | Icon MenuIcon { get; }
119 | string MenuInfo { get; }
120 |
121 | string[] Extensions { get; }
122 |
123 | void MenuSelected(IFileInfoProvider2 streamProvider, IDirectoryInfoProvider2 storageProvider, ShellItem[] items);
124 | }*/
125 |
126 | #region Provider Interfaces
127 |
128 | public interface IDirInfoProvider
129 | {
130 | ShellAPI.STATSTG GetDirInfo();
131 | }
132 |
133 | public interface IFileInfoProvider
134 | {
135 | ShellAPI.STATSTG GetFileInfo();
136 | Stream GetFileStream();
137 | }
138 |
139 | public interface IDirectoryInfoProvider2 : IDirInfoProvider
140 | {
141 | IStorage GetDirInfo(ShellItem item);
142 | }
143 |
144 | public interface IFileInfoProvider2 : IFileInfoProvider
145 | {
146 | IStream GetFileInfo(ShellItem item);
147 | Stream GetFileStream(ShellItem item);
148 | }
149 |
150 | #endregion
151 |
152 | #endregion
153 | }
154 |
--------------------------------------------------------------------------------