├── LICENSE
├── README.md
├── TaskbarSampleExt
├── TaskbarSampleExt.sln
└── TaskbarSampleExt
│ ├── Attributes.cs
│ ├── ComImport.cs
│ ├── DeskBand.cs
│ ├── Interop
│ ├── COLORREF.cs
│ ├── DESKBANDINFO.cs
│ ├── POINT.cs
│ └── RECT.cs
│ ├── Properties
│ └── AssemblyInfo.cs
│ ├── SampleExtension.Designer.cs
│ ├── SampleExtension.cs
│ ├── SampleExtension.resx
│ ├── TaskbarSampleExt.csproj
│ ├── TaskbarSampleExt.snk
│ └── Tests
│ ├── Install Extension.bat
│ ├── Reinstall Extension.bat
│ └── Uninstall Extension.bat
├── screenshot-taskbar-sample-install.png
└── screenshot-taskbar-sample.png
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2017 Patrick Becker
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 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Taskbar Beispiel Erweiterung
2 |
3 | 
4 |
5 | ### Beschreibung
6 |
7 | Mit diesem Beispiel können DeskBand Erweiterungen für Windows 10 erstellt werden, dazu implementiert das Projekt die **IDeskBand2** Schnittstelle.
8 | Es gibt eine Unterstützung für Vertikale Taskbars, Gripper und Transparenz.
9 |
10 | ### Installation der Beispiel Erweiterung
11 |
12 | 
13 |
14 | In den Projektdateien gibt es den Ordner **Test**, dort liegen Batchdateien für die _Installation / Deinstallation / Neuinstallation_ (Debugging).
15 |
16 | Die Batch Dateien verwenden **gacutil** und **regasm** um die Erweiterung zu registrieren. Diese beiden Tools setzen `NETFX 4.6.1 Tools` und `Framework64\v4.0.30319` voraus. Ist Visual Studio 2017 installiert, sind diese Pakete bereits vorhanden.
17 | Sollte eine andere .NET Framework Version installiert sein, einfach die Variable `path_gacutil` und `path_regasm` anpassen.
18 |
19 | Nach dem installieren wird die Erweiterung unter Symbolleisten angezeigt.
20 |
21 | ### Weiter Informationen
22 |
23 | - Die TaskbarSampleExt Assembly ist per **Default** für COM-Komponenten **unsichtbar**, bei der eigenen Erweiterung das Attribute `[ComVisible(true)]` angeben.
24 |
25 |
26 | - Kann die Erweiterung durch ein Problem etc. nicht mehr deinstalliert werden, den folgenden Registry Schlüssel mit der **entsprechenden GUID** entfernen.
27 | ```
28 | Computer\HKEY_CLASSES_ROOT\CLSID\{00000000-0000-0000-0000-000000000000}
29 | ```
30 |
31 | Anschließend die **Developer Command Prompt for VS 2017** Konsole starten.
32 | Mit dem Befehl `gacutil /l TaskbarSampleExt` wird im Cache nach der Assembly gesucht.
33 | Wenn ein Eintrag gefunden wurde, kann dieser durch den Befehl `gacutil /u TaskbarSampleExt` gelöscht werden.
34 |
35 | ## Autor
36 |
37 | * **Patrick Becker** - [GitHub](https://github.com/patbec)
38 |
39 | E-Mail: [git.bec@outlook.de](mailto:git.bec@outlook.de)
40 |
41 | ## Lizenz
42 |
43 | Dieses Projekt ist unter der MIT-Lizenz lizenziert - Weitere Informationen finden Sie in der Datei [LICENSE](LICENSE)
44 |
--------------------------------------------------------------------------------
/TaskbarSampleExt/TaskbarSampleExt.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio 15
4 | VisualStudioVersion = 15.0.26430.16
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TaskbarSampleExt", "TaskbarSampleExt\TaskbarSampleExt.csproj", "{1BC0858E-E1DE-4F97-B8CB-90F731AB07F6}"
7 | EndProject
8 | Global
9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
10 | Debug|Any CPU = Debug|Any CPU
11 | Release|Any CPU = Release|Any CPU
12 | EndGlobalSection
13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
14 | {1BC0858E-E1DE-4F97-B8CB-90F731AB07F6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
15 | {1BC0858E-E1DE-4F97-B8CB-90F731AB07F6}.Debug|Any CPU.Build.0 = Debug|Any CPU
16 | {1BC0858E-E1DE-4F97-B8CB-90F731AB07F6}.Release|Any CPU.ActiveCfg = Release|Any CPU
17 | {1BC0858E-E1DE-4F97-B8CB-90F731AB07F6}.Release|Any CPU.Build.0 = Release|Any CPU
18 | EndGlobalSection
19 | GlobalSection(SolutionProperties) = preSolution
20 | HideSolutionNode = FALSE
21 | EndGlobalSection
22 | EndGlobal
23 |
--------------------------------------------------------------------------------
/TaskbarSampleExt/TaskbarSampleExt/Attributes.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Runtime.InteropServices;
3 |
4 | namespace TaskbarSampleExt
5 | {
6 | ///
7 | /// The display name of the extension and the description for the HelpText(displayed in status bar when menu command selected).
8 | ///
9 | [AttributeUsage(AttributeTargets.Class)]
10 | public class DeskBandInfoAttribute : System.Attribute
11 | {
12 | private string _displayName;
13 | private string _helpText;
14 |
15 | public string DisplayName
16 | {
17 | get { return _displayName; }
18 | }
19 |
20 | public string HelpText
21 | {
22 | get { return _helpText; }
23 | }
24 |
25 | public DeskBandInfoAttribute() { }
26 |
27 | public DeskBandInfoAttribute(string displayName, string helpText)
28 | {
29 | _displayName = displayName;
30 | _helpText = helpText;
31 | }
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/TaskbarSampleExt/TaskbarSampleExt/ComImport.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Runtime.InteropServices;
3 |
4 | namespace TaskbarSampleExt.Interop
5 | {
6 | ///
7 | /// Provides a simple way to support communication between an object and its site in the container.
8 | ///
9 | [ComImport]
10 | [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
11 | [Guid("FC4801A3-2BA9-11CF-A229-00AA003D7352")]
12 | public interface IObjectWithSite
13 | {
14 | ///
15 | /// Enables a container to pass an object a pointer to the interface for its site.
16 | ///
17 | /// A pointer to the IUnknown interface pointer of the site managing this object.
18 | /// If NULL, the object should call Release on any existing site at which point the object no longer knows its site.
19 | void SetSite([In, MarshalAs(UnmanagedType.IUnknown)] Object pUnkSite);
20 |
21 | ///
22 | /// Retrieves the latest site passed using SetSite.
23 | ///
24 | /// The IID of the interface pointer that should be returned in ppvSite.
25 | /// Address of pointer variable that receives the interface pointer requested in riid.
26 | void GetSite(ref Guid riid, [MarshalAs(UnmanagedType.IUnknown)] out Object ppvSite);
27 | }
28 |
29 | ///
30 | /// Exposes a method that is used to communicate focus changes for a user input object contained in the Shell.
31 | ///
32 | [ComImport]
33 | [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
34 | [Guid("F1DB8392-7331-11D0-8C99-00A0C92DBFE8")]
35 | public interface IInputObjectSite
36 | {
37 | ///
38 | /// Informs the browser that the focus has changed.
39 | ///
40 | /// The address of the IUnknown interface of the object gaining or losing the focus.
41 | /// Indicates if the object has gained or lost the focus. If this value is nonzero, the object has gained the focus.
42 | /// If this value is zero, the object has lost the focus.
43 | /// Returns S_OK if the method was successful, or a COM-defined error code otherwise.
44 | [PreserveSig]
45 | Int32 OnFocusChangeIS([MarshalAs(UnmanagedType.IUnknown)] Object punkObj, Int32 fSetFocus);
46 | }
47 |
48 | ///
49 | /// The IOleWindow interface provides methods that allow an application to obtain the handle to the various windows that participate in in-place activation, and also to enter and exit context-sensitive help mode.
50 | ///
51 | [ComImport]
52 | [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
53 | [Guid("00000114-0000-0000-C000-000000000046")]
54 | public interface IOleWindow
55 | {
56 | ///
57 | /// Retrieves a handle to one of the windows participating in in-place activation (frame, document, parent, or in-place object window).
58 | ///
59 | /// A pointer to a variable that receives the window handle.
60 | /// This method returns S_OK on success.
61 | [PreserveSig]
62 | int GetWindow(out IntPtr phwnd);
63 |
64 | ///
65 | /// Determines whether context-sensitive help mode should be entered during an in-place activation session.
66 | ///
67 | /// TRUE if help mode should be entered; FALSE if it should be exited.
68 | /// This method returns S_OK if the help mode was entered or exited successfully, depending on the value passed in fEnterMode.
69 | [PreserveSig]
70 | int ContextSensitiveHelp(bool fEnterMode);
71 | }
72 |
73 | [ComImport]
74 | [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
75 | [Guid("012DD920-7B26-11D0-8CA9-00A0C92DBFE8")]
76 | public interface IDockingWindow : IOleWindow
77 | {
78 | #region IOleWindow
79 |
80 | [PreserveSig]
81 | new int GetWindow(out IntPtr phwnd);
82 |
83 | [PreserveSig]
84 | new int ContextSensitiveHelp(bool fEnterMode);
85 |
86 | #endregion
87 |
88 | ///
89 | /// Instructs the docking window object to show or hide itself.
90 | ///
91 | /// TRUE if the docking window object should show its window.
92 | /// FALSE if the docking window object should hide its window and return its border space by calling SetBorderSpaceDW with zero values.
93 | /// If this method succeeds, it returns S_OK. Otherwise, it returns an HRESULT error code.
94 | [PreserveSig]
95 | int ShowDW([In] bool fShow);
96 |
97 | ///
98 | /// Notifies the docking window object that it is about to be removed from the frame.
99 | /// The docking window object should save any persistent information at this time.
100 | ///
101 | /// Reserved. This parameter should always be zero.
102 | /// If this method succeeds, it returns S_OK. Otherwise, it returns an HRESULT error code.
103 | [PreserveSig]
104 | int CloseDW([In] UInt32 dwReserved);
105 |
106 | ///
107 | /// Notifies the docking window object that the frame's border space has changed.
108 | ///
109 | /// Pointer to a RECT structure that contains the frame's available border space.
110 | /// Pointer to the site's IUnknown interface. The docking window object should call the QueryInterface method for this interface, requesting IID_IDockingWindowSite.
111 | /// The docking window object then uses that interface to negotiate its border space. It is the docking window object's responsibility to release this interface when it is no longer needed.
112 | /// Reserved. This parameter should always be zero.
113 | /// If this method succeeds, it returns S_OK. Otherwise, it returns an HRESULT error code.
114 | [PreserveSig]
115 | int ResizeBorderDW(RECT prcBorder, [In, MarshalAs(UnmanagedType.IUnknown)] IntPtr punkToolbarSite, bool fReserved);
116 | }
117 |
118 | ///
119 | /// Gets information about a band object.
120 | ///
121 | [ComImport]
122 | [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
123 | [Guid("EB0FE172-1A3A-11D0-89B3-00A0C90A90AC")]
124 | public interface IDeskBand : IDockingWindow
125 | {
126 | #region IOleWindow
127 |
128 | [PreserveSig]
129 | new int GetWindow(out IntPtr phwnd);
130 |
131 | [PreserveSig]
132 | new int ContextSensitiveHelp(bool fEnterMode);
133 |
134 | #endregion
135 |
136 | #region IDockingWindow
137 |
138 | [PreserveSig]
139 | new int ShowDW([In] bool fShow);
140 |
141 | [PreserveSig]
142 | new int CloseDW([In] UInt32 dwReserved);
143 |
144 | [PreserveSig]
145 | new int ResizeBorderDW(RECT prcBorder, [In, MarshalAs(UnmanagedType.IUnknown)] IntPtr punkToolbarSite, bool fReserved);
146 |
147 | #endregion
148 |
149 | ///
150 | /// Gets state information for a band object.
151 | ///
152 | /// The identifier of the band, assigned by the container. The band object can retain this value if it is required.
153 | /// The view mode of the band object. One of the following values: DBIF_VIEWMODE_NORMAL, DBIF_VIEWMODE_VERTICAL, DBIF_VIEWMODE_FLOATING, DBIF_VIEWMODE_TRANSPARENT.
154 | /// Pointer to a DESKBANDINFO structure that receives the band information for the object. The dwMask member of this structure indicates the specific information that is being requested.
155 | /// If this method succeeds, it returns S_OK. Otherwise, it returns an HRESULT error code.
156 | [PreserveSig]
157 | int GetBandInfo(UInt32 dwBandID, DESKBANDINFO.DBIF dwViewMode, ref DESKBANDINFO pdbi);
158 | }
159 |
160 | ///
161 | /// Exposes methods to enable and query translucency effects in a deskband object.
162 | ///
163 | [ComImport]
164 | [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
165 | [Guid("79D16DE4-ABEE-4021-8D9D-9169B261D657")]
166 | public interface IDeskBand2 : IDeskBand
167 | {
168 | #region IOleWindow
169 |
170 | [PreserveSig]
171 | new int GetWindow(out IntPtr phwnd);
172 |
173 | [PreserveSig]
174 | new int ContextSensitiveHelp(bool fEnterMode);
175 |
176 | #endregion
177 |
178 | #region IDockingWindow
179 |
180 | [PreserveSig]
181 | new int ShowDW([In] bool fShow);
182 |
183 | [PreserveSig]
184 | new int CloseDW([In] UInt32 dwReserved);
185 |
186 | [PreserveSig]
187 | new int ResizeBorderDW(RECT prcBorder, [In, MarshalAs(UnmanagedType.IUnknown)] IntPtr punkToolbarSite, bool fReserved);
188 |
189 | #endregion
190 |
191 | #region IDeskBand
192 |
193 | [PreserveSig]
194 | new int GetBandInfo(UInt32 dwBandID, DESKBANDINFO.DBIF dwViewMode, ref DESKBANDINFO pdbi);
195 |
196 | #endregion
197 |
198 | ///
199 | /// Indicates the deskband's ability to be displayed as translucent.
200 | ///
201 | /// When this method returns, contains a BOOL indicating ability.
202 | /// If this method succeeds, it returns S_OK. Otherwise, it returns an HRESULT error code.
203 | [PreserveSig]
204 | int CanRenderComposited(out bool pfCanRenderComposited);
205 |
206 | ///
207 | /// Sets the composition state.
208 | ///
209 | /// TRUE to enable the composition state; otherwise, FALSE.
210 | /// If this method succeeds, it returns S_OK. Otherwise, it returns an HRESULT error code.
211 | [PreserveSig]
212 | int SetCompositionState(bool fCompositionEnabled);
213 |
214 | ///
215 | /// Gets the composition state.
216 | ///
217 | /// When this method returns, contains a BOOL that indicates state.
218 | /// If this method succeeds, it returns S_OK. Otherwise, it returns an HRESULT error code.
219 | [PreserveSig]
220 | int GetCompositionState(out bool pfCompositionEnabled);
221 | }
222 | }
223 |
--------------------------------------------------------------------------------
/TaskbarSampleExt/TaskbarSampleExt/DeskBand.cs:
--------------------------------------------------------------------------------
1 | // Copyright(c) 2017 Patrick Becker
2 | //
3 | // Visit the Project page for more information.
4 | // https://github.com/patbec/TaskbarSampleExtension
5 |
6 |
7 | using Microsoft.Win32;
8 | using System;
9 | using System.ComponentModel;
10 | using System.Drawing;
11 | using System.Runtime.InteropServices;
12 | using System.Windows.Forms;
13 | using TaskbarSampleExt.Interop;
14 |
15 | namespace TaskbarSampleExt
16 | {
17 | ///
18 | /// Basic class for a DeskBand object
19 | ///
20 | ///
21 | /// [ComVisible(true)]
22 | /// [Guid("00000000-0000-0000-0000-000000000000")]
23 | /// [DeskBandInfo("Beispiel Erweiterung", "Diese ist eine Beispiel Erweiterung für die Taskleiste.")]
24 | /// public class SampleExtension : DeskBand
25 | /// { /*...*/ }
26 | ///
27 | public class DeskBand : UserControl, IObjectWithSite, IDeskBand2
28 | {
29 |
30 | private const int S_OK = 0;
31 | private const int E_NOTIMPL = unchecked((int)0x80004001);
32 |
33 | protected IInputObjectSite DeskBandSite;
34 |
35 | public DeskBand()
36 | {
37 | InitializeComponent();
38 | }
39 |
40 | private void InitializeComponent()
41 | {
42 | this.Name = "DeskBand";
43 | }
44 |
45 | #region Properties
46 |
47 | ///
48 | /// Title of the band object, displayed by default on the left or top of the object.
49 | ///
50 | [Browsable(true)]
51 | [DefaultValue("")]
52 | public String Title { get; set; }
53 |
54 | ///
55 | /// Minimum size of the band object. Default value of -1 sets no minimum constraint.
56 | ///
57 | [Browsable(true)]
58 | [DefaultValue(typeof(Size), "-1,-1")]
59 | public Size MinSize { get; set; }
60 |
61 | ///
62 | /// Maximum size of the band object. Default value of -1 sets no maximum constraint.
63 | ///
64 | [Browsable(true)]
65 | [DefaultValue(typeof(Size), "-1,-1")]
66 | public Size MaxSize { get; set; }
67 |
68 | ///
69 | /// Minimum vertical size of the band object. Default value of -1 sets no maximum constraint. (Used when the taskbar is aligned vertically.)
70 | ///
71 | [Browsable(true)]
72 | [DefaultValue(typeof(Size), "-1,-1")]
73 | public Size MinSizeVertical { get; set; }
74 |
75 | ///
76 | /// Says that band object's size must be multiple of this size. Defauilt value of -1 does not set this constraint.
77 | ///
78 | [Browsable(true)]
79 | [DefaultValue(typeof(Size), "-1,-1")]
80 | public Size IntegralSize { get; set; }
81 |
82 | #endregion
83 |
84 | #region IObjectWithSite
85 |
86 | public void SetSite([In, MarshalAs(UnmanagedType.IUnknown)] Object pUnkSite)
87 | {
88 | if (DeskBandSite != null)
89 | Marshal.ReleaseComObject(DeskBandSite);
90 |
91 | DeskBandSite = (IInputObjectSite)pUnkSite;
92 | }
93 |
94 | public void GetSite(ref Guid riid, [MarshalAs(UnmanagedType.IUnknown)] out Object ppvSite)
95 | {
96 | ppvSite = DeskBandSite;
97 | }
98 |
99 | #endregion
100 |
101 | #region IDeskBand2
102 |
103 | public virtual int CanRenderComposited(out bool pfCanRenderComposited)
104 | {
105 | pfCanRenderComposited = true;
106 | return S_OK;
107 | }
108 |
109 | public int SetCompositionState(bool fCompositionEnabled)
110 | {
111 | fCompositionEnabled = true;
112 | return S_OK;
113 | }
114 |
115 | public int GetCompositionState(out bool pfCompositionEnabled)
116 | {
117 | pfCompositionEnabled = false;
118 | return S_OK;
119 | }
120 |
121 | public int GetBandInfo(uint dwBandID, DESKBANDINFO.DBIF dwViewMode, ref DESKBANDINFO pdbi)
122 | {
123 | if (pdbi.dwMask.HasFlag(DESKBANDINFO.DBIM.DBIM_MINSIZE))
124 | {
125 | // Support for a vertical taskbar
126 | // Most examples have no support for a vertical taskbar. Who in hell uses their taskbar vertically? Me! Very practical on a 21:9 monitor.
127 | if (dwViewMode.HasFlag(DESKBANDINFO.DBIF.DBIF_VIEWMODE_FLOATING) || dwViewMode.HasFlag(DESKBANDINFO.DBIF.DBIF_VIEWMODE_VERTICAL))
128 | {
129 | pdbi.ptMinSize.Y = this.MinSizeVertical.Width;
130 | pdbi.ptMinSize.X = this.MinSizeVertical.Height;
131 | }
132 | else
133 | {
134 | pdbi.ptMinSize.X = this.MinSize.Width;
135 | pdbi.ptMinSize.Y = this.MinSize.Height;
136 | }
137 | }
138 | if (pdbi.dwMask.HasFlag(DESKBANDINFO.DBIM.DBIM_MAXSIZE))
139 | {
140 | if (dwViewMode.HasFlag(DESKBANDINFO.DBIF.DBIF_VIEWMODE_FLOATING) || dwViewMode.HasFlag(DESKBANDINFO.DBIF.DBIF_VIEWMODE_VERTICAL))
141 | {
142 | pdbi.ptMaxSize.Y = this.MaxSize.Width;
143 | pdbi.ptMaxSize.X = this.MaxSize.Height;
144 | }
145 | else
146 | {
147 | pdbi.ptMaxSize.X = this.MaxSize.Width;
148 | pdbi.ptMaxSize.Y = this.MaxSize.Height;
149 | }
150 | }
151 | if (pdbi.dwMask.HasFlag(DESKBANDINFO.DBIM.DBIM_INTEGRAL))
152 | {
153 | if (dwViewMode.HasFlag(DESKBANDINFO.DBIF.DBIF_VIEWMODE_FLOATING) || dwViewMode.HasFlag(DESKBANDINFO.DBIF.DBIF_VIEWMODE_VERTICAL))
154 | {
155 | pdbi.ptIntegral.Y = this.IntegralSize.Width;
156 | pdbi.ptIntegral.X = this.IntegralSize.Height;
157 | }
158 | else
159 | {
160 | pdbi.ptIntegral.X = this.IntegralSize.Width;
161 | pdbi.ptIntegral.Y = this.IntegralSize.Height;
162 | }
163 | }
164 |
165 | if (pdbi.dwMask.HasFlag(DESKBANDINFO.DBIM.DBIM_ACTUAL))
166 | {
167 | if (dwViewMode.HasFlag(DESKBANDINFO.DBIF.DBIF_VIEWMODE_FLOATING) || dwViewMode.HasFlag(DESKBANDINFO.DBIF.DBIF_VIEWMODE_VERTICAL))
168 | {
169 | pdbi.ptActual.Y = this.Size.Width;
170 | pdbi.ptActual.X = this.Size.Height;
171 | }
172 | else
173 | {
174 | pdbi.ptActual.X = this.Size.Width;
175 | pdbi.ptActual.Y = this.Size.Height;
176 | }
177 | }
178 |
179 | if (pdbi.dwMask.HasFlag(DESKBANDINFO.DBIM.DBIM_TITLE))
180 | {
181 | pdbi.wszTitle = this.Title;
182 | }
183 |
184 | pdbi.dwModeFlags = DESKBANDINFO.DBIMF.DBIMF_ALWAYSGRIPPER | DESKBANDINFO.DBIMF.DBIMF_NORMAL | DESKBANDINFO.DBIMF.DBIMF_VARIABLEHEIGHT;
185 | pdbi.dwMask = pdbi.dwMask | DESKBANDINFO.DBIM.DBIM_BKCOLOR | DESKBANDINFO.DBIM.DBIM_TITLE; // Testen
186 |
187 | return S_OK;
188 | }
189 |
190 | public int GetWindow(out IntPtr phwnd)
191 | {
192 | phwnd = Handle;
193 | return S_OK;
194 | }
195 |
196 | public int ContextSensitiveHelp(bool fEnterMode)
197 | {
198 | return S_OK;
199 | }
200 |
201 | public int ShowDW([In] bool fShow)
202 | {
203 | if (fShow)
204 | Show();
205 | else
206 | Hide();
207 |
208 | return S_OK;
209 | }
210 |
211 | public int CloseDW([In] uint dwReserved)
212 | {
213 | Dispose(true);
214 | return S_OK;
215 | }
216 |
217 | public int ResizeBorderDW(RECT prcBorder, [In, MarshalAs(UnmanagedType.IUnknown)] IntPtr punkToolbarSite, bool fReserved)
218 | {
219 | return E_NOTIMPL;
220 | }
221 |
222 | #endregion
223 |
224 | #region Register / Unregister
225 |
226 | [ComRegisterFunctionAttribute]
227 | public static void Register(Type t)
228 | {
229 | string guid = t.GUID.ToString("B");
230 |
231 | DeskBandInfoAttribute[] deskBandInfo = (DeskBandInfoAttribute[])
232 | t.GetCustomAttributes(typeof(DeskBandInfoAttribute), false);
233 |
234 | // Register only the extension if the attribute DeskBandInfo is used.
235 | if (deskBandInfo.Length == 1)
236 | {
237 | RegistryKey rkClass = Registry.ClassesRoot.CreateSubKey(@"CLSID\" + guid);
238 | RegistryKey rkCat = rkClass.CreateSubKey("Implemented Categories");
239 |
240 | string _displayName = t.Name;
241 | string _helpText = t.Name;
242 |
243 |
244 | if (deskBandInfo[0].DisplayName != null)
245 | {
246 | _displayName = deskBandInfo[0].DisplayName;
247 | }
248 |
249 | if (deskBandInfo[0].HelpText != null)
250 | {
251 | _helpText = deskBandInfo[0].HelpText;
252 | }
253 |
254 | rkClass.SetValue(null, _displayName);
255 | rkClass.SetValue("MenuText", _displayName);
256 | rkClass.SetValue("HelpText", _helpText);
257 |
258 | // TaskBar
259 | rkCat.CreateSubKey("{00021492-0000-0000-C000-000000000046}");
260 |
261 | Console.WriteLine(String.Format("{0} {1} {2}", guid, _displayName, "successfully registered."));
262 | } else {
263 | Console.WriteLine(guid + " has no attributes");
264 | }
265 | }
266 |
267 | [ComUnregisterFunctionAttribute]
268 | public static void Unregister(Type t)
269 | {
270 | string guid = t.GUID.ToString("B");
271 |
272 | DeskBandInfoAttribute[] deskBandInfo = (DeskBandInfoAttribute[])
273 | t.GetCustomAttributes(typeof(DeskBandInfoAttribute), false);
274 |
275 | if (deskBandInfo.Length == 1)
276 | {
277 | string _displayName = t.Name;
278 |
279 | if (deskBandInfo[0].DisplayName != null)
280 | {
281 | _displayName = deskBandInfo[0].DisplayName;
282 | }
283 |
284 | Registry.ClassesRoot.CreateSubKey(@"CLSID").DeleteSubKeyTree(guid);
285 |
286 | Console.WriteLine(String.Format("{0} {1} {2}", guid, _displayName, "successfully removed."));
287 | } else {
288 | Console.WriteLine(guid + " has no attributes");
289 | }
290 | }
291 |
292 | #endregion
293 | }
294 | }
295 |
--------------------------------------------------------------------------------
/TaskbarSampleExt/TaskbarSampleExt/Interop/COLORREF.cs:
--------------------------------------------------------------------------------
1 | // This code snippet was used by SharpShell.
2 | //
3 |
4 | using System.Drawing;
5 | using System.Runtime.InteropServices;
6 |
7 | namespace TaskbarSampleExt.Interop
8 | {
9 | [StructLayout(LayoutKind.Sequential)]
10 | public struct COLORREF
11 | {
12 | public COLORREF(Color color)
13 | {
14 | Dword = (uint)color.R + (((uint)color.G) << 8) + (((uint)color.B) << 16);
15 | }
16 |
17 | public uint Dword;
18 | public Color Color
19 | {
20 | get
21 | {
22 | return Color.FromArgb(
23 | (int)(0x000000FFU & Dword),
24 | (int)(0x0000FF00U & Dword) >> 8,
25 | (int)(0x00FF0000U & Dword) >> 16);
26 | }
27 | }
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/TaskbarSampleExt/TaskbarSampleExt/Interop/DESKBANDINFO.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Runtime.InteropServices;
3 |
4 | namespace TaskbarSampleExt.Interop
5 | {
6 | ///
7 | /// Receives information about a band object. This structure is used with the deprecated IDeskBand::GetBandInfo method.
8 | ///
9 | [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
10 | public struct DESKBANDINFO
11 | {
12 | ///
13 | /// Set of flags that determine which members of this structure are being requested.
14 | ///
15 | ///
16 | /// This will be a combination of the following values:
17 | /// DBIM_MINSIZE ptMinSize is being requested.
18 | /// DBIM_MAXSIZE ptMaxSize is being requested.
19 | /// DBIM_INTEGRAL ptIntegral is being requested.
20 | /// DBIM_ACTUAL ptActual is being requested.
21 | /// DBIM_TITLE wszTitle is being requested.
22 | /// DBIM_MODEFLAGS dwModeFlags is being requested.
23 | /// DBIM_BKCOLOR crBkgnd is being requested.
24 | ///
25 | public DBIM dwMask;
26 |
27 | ///
28 | /// Point structure that receives the minimum size of the band object.
29 | /// The minimum width is placed in the x member and the minimum height
30 | /// is placed in the y member.
31 | ///
32 | public POINT ptMinSize;
33 |
34 | ///
35 | /// Point structure that receives the maximum size of the band object.
36 | /// The maximum height is placed in the y member and the x member is ignored.
37 | /// If there is no limit for the maximum height, (LONG)-1 should be used.
38 | ///
39 | public POINT ptMaxSize;
40 |
41 | ///
42 | /// Point structure that receives the sizing step value of the band object.
43 | /// The vertical step value is placed in the y member, and the x member is ignored.
44 | /// The step value determines in what increments the band will be resized.
45 | ///
46 | ///
47 | /// This member is ignored if dwModeFlags does not contain DBIMF_VARIABLEHEIGHT.
48 | ///
49 | public POINT ptIntegral;
50 |
51 | ///
52 | /// Point structure that receives the ideal size of the band object.
53 | /// The ideal width is placed in the x member and the ideal height is placed in the y member.
54 | /// The band container will attempt to use these values, but the band is not guaranteed to be this size.
55 | ///
56 | public POINT ptActual;
57 |
58 | ///
59 | /// The title of the band.
60 | ///
61 | [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 255)]
62 | public String wszTitle;
63 |
64 | ///
65 | /// A value that receives a set of flags that define the mode of operation for the band object.
66 | ///
67 | ///
68 | /// This must be one or a combination of the following values.
69 | /// DBIMF_NORMAL
70 | /// The band is normal in all respects. The other mode flags modify this flag.
71 | /// DBIMF_VARIABLEHEIGHT
72 | /// The height of the band object can be changed. The ptIntegral member defines the
73 | /// step value by which the band object can be resized.
74 | /// DBIMF_DEBOSSED
75 | /// The band object is displayed with a sunken appearance.
76 | /// DBIMF_BKCOLOR
77 | /// The band will be displayed with the background color specified in crBkgnd.
78 | ///
79 | public DBIMF dwModeFlags;
80 |
81 | ///
82 | /// The background color of the band.
83 | ///
84 | ///
85 | /// This member is ignored if dwModeFlags does not contain the DBIMF_BKCOLOR flag.
86 | ///
87 | public COLORREF crBkgnd;
88 |
89 | ///
90 | /// The view mode of the band object. This is one of the following values.
91 | ///
92 | [Flags]
93 | public enum DBIF
94 | {
95 | ///
96 | /// Band object is displayed in a horizontal band.
97 | ///
98 | DBIF_VIEWMODE_NORMAL = 0x0000,
99 |
100 | ///
101 | /// Band object is displayed in a vertical band.
102 | ///
103 | DBIF_VIEWMODE_VERTICAL = 0x0001,
104 |
105 | ///
106 | /// Band object is displayed in a floating band.
107 | ///
108 | DBIF_VIEWMODE_FLOATING = 0x0002,
109 |
110 | ///
111 | /// Band object is displayed in a transparent band.
112 | ///
113 | DBIF_VIEWMODE_TRANSPARENT = 0x0004
114 | }
115 |
116 | ///
117 | /// The set of flags that determine which members of this structure are being requested by the caller. One or more of the following values:
118 | ///
119 | [Flags]
120 | public enum DBIM
121 | {
122 | ///
123 | /// ptMinSize is requested.
124 | ///
125 | DBIM_MINSIZE = 0x0001,
126 |
127 | ///
128 | /// ptMaxSize is requested.
129 | ///
130 | DBIM_MAXSIZE = 0x0002,
131 |
132 | ///
133 | /// ptIntegral is requested.
134 | ///
135 | DBIM_INTEGRAL = 0x0004,
136 |
137 | ///
138 | /// ptActual is requested.
139 | ///
140 | DBIM_ACTUAL = 0x0008,
141 |
142 | ///
143 | /// wszTitle is requested.
144 | ///
145 | DBIM_TITLE = 0x0010,
146 |
147 | ///
148 | /// dwModeFlags is requested.
149 | ///
150 | DBIM_MODEFLAGS = 0x0020,
151 |
152 | ///
153 | /// crBkgnd is requested.
154 | ///
155 | DBIM_BKCOLOR = 0x0040
156 | }
157 |
158 | ///
159 | /// A value that receives a set of flags that specify the mode of operation for the band object. One or more of the following values:
160 | ///
161 | [Flags]
162 | public enum DBIMF : uint
163 | {
164 | ///
165 | /// The band uses default properties. The other mode flags modify this flag.
166 | ///
167 | DBIMF_NORMAL = 0x0000,
168 |
169 | ///
170 | /// Windows XP and later: The band object is of a fixed sized and position. With this flag, a sizing grip is not displayed on the band object.
171 | ///
172 | DBIMF_FIXED = 0x0001,
173 |
174 | ///
175 | /// DBIMF_FIXEDBMP
176 | /// Windows XP and later: The band object uses a fixed bitmap (.bmp) file as its background. Note that backgrounds are not supported in all cases, so the bitmap may not be seen even when this flag is set.
177 | ///
178 | DBIMF_FIXEDBMP = 0x0004,
179 |
180 | ///
181 | /// The height of the band object can be changed. The ptIntegral member defines the step value by which the band object can be resized.
182 | ///
183 | DBIMF_VARIABLEHEIGHT = 0x0008,
184 |
185 | ///
186 | /// Windows XP and later: The band object cannot be removed from the band container.
187 | ///
188 | DBIMF_UNDELETEABLE = 0x0010,
189 |
190 | ///
191 | /// The band object is displayed with a sunken appearance.
192 | ///
193 | DBIMF_DEBOSSED = 0x0020,
194 |
195 | ///
196 | /// The band is displayed with the background color specified in crBkgnd.
197 | ///
198 | DBIMF_BKCOLOR = 0x0040,
199 |
200 | ///
201 | /// Windows XP and later: If the full band object cannot be displayed (that is, the band object is smaller than ptActual, a chevron is shown to indicate that there are more options available. These options are displayed when the chevron is clicked.
202 | ///
203 | DBIMF_USECHEVRON = 0x0080,
204 |
205 | ///
206 | /// Windows XP and later: The band object is displayed in a new row in the band container.
207 | ///
208 | DBIMF_BREAK = 0x0100,
209 |
210 | ///
211 | /// Windows XP and later: The band object is the first object in the band container.
212 | ///
213 | DBIMF_ADDTOFRONT = 0x0200,
214 |
215 | ///
216 | /// Windows XP and later: The band object is displayed in the top row of the band container.
217 | ///
218 | DBIMF_TOPALIGN = 0x0400,
219 |
220 | ///
221 | /// Windows Vista and later: No sizing grip is ever displayed to allow the user to move or resize the band object.
222 | ///
223 | DBIMF_NOGRIPPER = 0x0800,
224 |
225 | ///
226 | /// Windows Vista and later: A sizing grip that allows the user to move or resize the band object is always shown, even if that band object is the only one in the container.
227 | ///
228 | DBIMF_ALWAYSGRIPPER = 0x1000,
229 |
230 | ///
231 | /// Windows Vista and later: The band object should not display margins.
232 | ///
233 | DBIMF_NOMARGINS = 0x2000
234 | }
235 | }
236 | }
237 |
--------------------------------------------------------------------------------
/TaskbarSampleExt/TaskbarSampleExt/Interop/POINT.cs:
--------------------------------------------------------------------------------
1 | // This code snippet was used by SharpShell.
2 | //
3 | using System.Runtime.InteropServices;
4 |
5 | namespace TaskbarSampleExt.Interop
6 | {
7 | ///
8 | /// The POINT structure defines the x- and y- coordinates of a point.
9 | ///
10 | [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
11 | public struct POINT
12 | {
13 | ///
14 | /// The x-coordinate of the point.
15 | ///
16 | public int X;
17 |
18 | ///
19 | /// The y-coordinate of the point.
20 | ///
21 | public int Y;
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/TaskbarSampleExt/TaskbarSampleExt/Interop/RECT.cs:
--------------------------------------------------------------------------------
1 | using System.Runtime.InteropServices;
2 |
3 | namespace TaskbarSampleExt.Interop
4 | {
5 | [StructLayout(LayoutKind.Sequential)]
6 | public struct RECT
7 | {
8 | public RECT(int left, int top, int right, int bottom)
9 | {
10 | this.left = left;
11 | this.top = top;
12 | this.right = right;
13 | this.bottom = bottom;
14 | }
15 |
16 |
17 | public int left, top, right, bottom;
18 |
19 | public int Width()
20 | {
21 | return right - left;
22 | }
23 |
24 | public int Height()
25 | {
26 | return bottom - top;
27 | }
28 |
29 | public void Offset(int x, int y)
30 | {
31 | left += x;
32 | right += x;
33 | top += y;
34 | bottom += y;
35 | }
36 |
37 | public void Set(int left, int top, int right, int bottom)
38 | {
39 | this.left = left;
40 | this.top = top;
41 | this.right = right;
42 | this.bottom = bottom;
43 | }
44 |
45 | public bool IsEmpty()
46 | {
47 | return Width() == 0 && Height() == 0;
48 | }
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/TaskbarSampleExt/TaskbarSampleExt/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // Allgemeine Informationen über eine Assembly werden über die folgenden
6 | // Attribute gesteuert. Ändern Sie diese Attributwerte, um die Informationen zu ändern,
7 | // die einer Assembly zugeordnet sind.
8 | [assembly: AssemblyTitle("TaskbarSample")]
9 | [assembly: AssemblyDescription("Sample extension for the taskbar")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("")]
12 | [assembly: AssemblyProduct("TaskbarSample")]
13 | [assembly: AssemblyCopyright("")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | // Durch Festlegen von ComVisible auf FALSE werden die Typen in dieser Assembly
18 | // für COM-Komponenten unsichtbar. Wenn Sie auf einen Typ in dieser Assembly von
19 | // COM aus zugreifen müssen, sollten Sie das ComVisible-Attribut für diesen Typ auf "True" festlegen.
20 | [assembly: ComVisible(false)]
21 |
22 | // Die folgende GUID bestimmt die ID der Typbibliothek, wenn dieses Projekt für COM verfügbar gemacht wird
23 | [assembly: Guid("1bc0858e-e1de-4f97-b8cb-90f731ab07f6")]
24 |
25 | // Versionsinformationen für eine Assembly bestehen aus den folgenden vier Werten:
26 | //
27 | // Hauptversion
28 | // Nebenversion
29 | // Buildnummer
30 | // Revision
31 | //
32 | // Sie können alle Werte angeben oder Standardwerte für die Build- und Revisionsnummern verwenden,
33 | // indem Sie "*" wie unten gezeigt eingeben:
34 | // [assembly: AssemblyVersion("1.0.*")]
35 | [assembly: AssemblyVersion("1.0.0.0")]
36 | [assembly: AssemblyFileVersion("1.0.0.0")]
37 |
--------------------------------------------------------------------------------
/TaskbarSampleExt/TaskbarSampleExt/SampleExtension.Designer.cs:
--------------------------------------------------------------------------------
1 | namespace TaskbarSampleExt
2 | {
3 | public partial class SampleExtension
4 | {
5 | ///
6 | /// Erforderliche Designervariable.
7 | ///
8 | private System.ComponentModel.IContainer components = null;
9 |
10 | ///
11 | /// Verwendete Ressourcen bereinigen.
12 | ///
13 | /// True, wenn verwaltete Ressourcen gelöscht werden sollen; andernfalls 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 Vom Komponenten-Designer generierter Code
24 |
25 | ///
26 | /// Erforderliche Methode für die Designerunterstützung.
27 | /// Der Inhalt der Methode darf nicht mit dem Code-Editor geändert werden.
28 | ///
29 | private void InitializeComponent()
30 | {
31 | this.panel1 = new System.Windows.Forms.Panel();
32 | this.label1 = new System.Windows.Forms.Label();
33 | this.panel1.SuspendLayout();
34 | this.SuspendLayout();
35 | //
36 | // panel1
37 | //
38 | this.panel1.Controls.Add(this.label1);
39 | this.panel1.Dock = System.Windows.Forms.DockStyle.Fill;
40 | this.panel1.Location = new System.Drawing.Point(0, 0);
41 | this.panel1.Name = "panel1";
42 | this.panel1.Padding = new System.Windows.Forms.Padding(4);
43 | this.panel1.Size = new System.Drawing.Size(90, 40);
44 | this.panel1.TabIndex = 1;
45 | //
46 | // label1
47 | //
48 | this.label1.Dock = System.Windows.Forms.DockStyle.Fill;
49 | this.label1.Location = new System.Drawing.Point(4, 4);
50 | this.label1.Name = "label1";
51 | this.label1.Size = new System.Drawing.Size(82, 32);
52 | this.label1.TabIndex = 0;
53 | this.label1.Text = "Hello World";
54 | this.label1.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
55 | this.label1.Click += new System.EventHandler(this.HelloWorld_Click);
56 | //
57 | // SampleExtension
58 | //
59 | this.AutoScaleDimensions = new System.Drawing.SizeF(8F, 16F);
60 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
61 | this.Controls.Add(this.panel1);
62 | this.Name = "SampleExtension";
63 | this.Size = new System.Drawing.Size(90, 40);
64 | this.panel1.ResumeLayout(false);
65 | this.ResumeLayout(false);
66 |
67 | }
68 |
69 | #endregion
70 |
71 | private System.Windows.Forms.Panel panel1;
72 | private System.Windows.Forms.Label label1;
73 | }
74 | }
75 |
--------------------------------------------------------------------------------
/TaskbarSampleExt/TaskbarSampleExt/SampleExtension.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Drawing;
3 | using System.Runtime.InteropServices;
4 | using System.Windows.Forms;
5 |
6 | namespace TaskbarSampleExt
7 | {
8 | [ComVisible(true)]
9 | [Guid("B042F593-F406-45A7-8C4A-43DCA5786180")]
10 | [DeskBandInfo("Beispiel Erweiterung", "Diese ist eine Beispiel Erweiterung für die Taskleiste.")]
11 | public partial class SampleExtension : DeskBand
12 | {
13 |
14 | public SampleExtension()
15 | {
16 | this.MinSize = new Size(110, 40);
17 | this.MinSizeVertical = new Size(100, 40);
18 | this.Title = "Beispiel Erweiterung";
19 |
20 | InitializeComponent();
21 | }
22 |
23 | // Sample Code
24 | public bool IsClicked = false;
25 |
26 | private void HelloWorld_Click(object sender, EventArgs e)
27 | {
28 | if (IsClicked == false)
29 | {
30 | label1.Text = "Copyright Patrick Becker";
31 |
32 | } else {
33 | label1.Text = "Hello World";
34 | }
35 |
36 | IsClicked = (IsClicked == false);
37 | }
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/TaskbarSampleExt/TaskbarSampleExt/SampleExtension.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=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
--------------------------------------------------------------------------------
/TaskbarSampleExt/TaskbarSampleExt/TaskbarSampleExt.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | AnyCPU
7 | {1BC0858E-E1DE-4F97-B8CB-90F731AB07F6}
8 | Library
9 | Properties
10 | TaskbarSampleExt
11 | TaskbarSampleExt
12 | v4.5.2
13 | 512
14 |
15 |
16 | true
17 | full
18 | false
19 | bin\Debug\
20 | DEBUG;TRACE
21 | prompt
22 | 4
23 |
24 |
25 | pdbonly
26 | true
27 | bin\Release\
28 | TRACE
29 | prompt
30 | 4
31 |
32 |
33 | true
34 |
35 |
36 | TaskbarSampleExt.snk
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 | UserControl
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 | UserControl
63 |
64 |
65 | SampleExtension.cs
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 | SampleExtension.cs
77 |
78 |
79 |
80 |
--------------------------------------------------------------------------------
/TaskbarSampleExt/TaskbarSampleExt/TaskbarSampleExt.snk:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/patbec/TaskbarSampleExtension/e4b875b79a36d524b8330ccad7dc5e3ccf8ce1f8/TaskbarSampleExt/TaskbarSampleExt/TaskbarSampleExt.snk
--------------------------------------------------------------------------------
/TaskbarSampleExt/TaskbarSampleExt/Tests/Install Extension.bat:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/patbec/TaskbarSampleExtension/e4b875b79a36d524b8330ccad7dc5e3ccf8ce1f8/TaskbarSampleExt/TaskbarSampleExt/Tests/Install Extension.bat
--------------------------------------------------------------------------------
/TaskbarSampleExt/TaskbarSampleExt/Tests/Reinstall Extension.bat:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/patbec/TaskbarSampleExtension/e4b875b79a36d524b8330ccad7dc5e3ccf8ce1f8/TaskbarSampleExt/TaskbarSampleExt/Tests/Reinstall Extension.bat
--------------------------------------------------------------------------------
/TaskbarSampleExt/TaskbarSampleExt/Tests/Uninstall Extension.bat:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/patbec/TaskbarSampleExtension/e4b875b79a36d524b8330ccad7dc5e3ccf8ce1f8/TaskbarSampleExt/TaskbarSampleExt/Tests/Uninstall Extension.bat
--------------------------------------------------------------------------------
/screenshot-taskbar-sample-install.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/patbec/TaskbarSampleExtension/e4b875b79a36d524b8330ccad7dc5e3ccf8ce1f8/screenshot-taskbar-sample-install.png
--------------------------------------------------------------------------------
/screenshot-taskbar-sample.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/patbec/TaskbarSampleExtension/e4b875b79a36d524b8330ccad7dc5e3ccf8ce1f8/screenshot-taskbar-sample.png
--------------------------------------------------------------------------------