├── screenshot.png ├── Interop.SHDocVw.dll ├── MyExampleProject.snk ├── SampleDeskband ├── packages.config ├── Register │ ├── Register.vcxproj.filters │ ├── Register.vcproj │ └── Register.vcxproj ├── AssemblyInfo.cs ├── SampleDeskband.csproj ├── HelloWorldBar.resx └── HelloWorldBar.cs ├── env.bat ├── SampleDeskbandLib ├── RegisterLib │ ├── RegisterLib.vcxproj.filters │ ├── RegisterLib.vcproj │ └── RegisterLib.vcxproj ├── Attributes.cs ├── SampleDeskbandLib.csproj ├── BandObject.resx ├── ComInterop.cs └── BandObject.cs ├── SampleMediaControlDeskband.sln ├── .gitattributes ├── README.md └── .gitignore /screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/navhaxs/media-control-deskband/HEAD/screenshot.png -------------------------------------------------------------------------------- /Interop.SHDocVw.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/navhaxs/media-control-deskband/HEAD/Interop.SHDocVw.dll -------------------------------------------------------------------------------- /MyExampleProject.snk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/navhaxs/media-control-deskband/HEAD/MyExampleProject.snk -------------------------------------------------------------------------------- /SampleDeskband/packages.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /env.bat: -------------------------------------------------------------------------------- 1 | @echo OFF 2 | title gacutil regasm prompt 3 | 4 | goto check_Permissions 5 | 6 | :check_Permissions 7 | net session >nul 2>&1 8 | if %errorLevel% == 0 ( 9 | REM echo Success: Administrative permissions confirmed. 10 | goto go 11 | ) else ( 12 | echo Please run as Administrator. 13 | ) 14 | 15 | pause >nul 16 | 17 | :go 18 | 19 | doskey gacutil="C:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.6.1 Tools\x64\gacutil.exe" $* 20 | doskey RegAsm="C:\Windows\Microsoft.NET\Framework64\v4.0.30319\RegAsm.exe" $* 21 | doskey k=C:\Windows\System32\taskkill.exe /im explorer.exe /f 22 | 23 | echo Run gacutil to install to GAC, 24 | echo Run regasm to register COM 25 | echo Run k to kill Explorer.exe -------------------------------------------------------------------------------- /SampleDeskband/Register/Register.vcxproj.filters: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | {42d5f52a-aa44-472c-8298-a99faf25d8a1} 6 | cpp;c;cxx;def;odl;idl;hpj;bat;asm 7 | 8 | 9 | {0091c3ed-442a-4403-a5cc-7d8e5f8a3920} 10 | h;hpp;hxx;hm;inl;inc 11 | 12 | 13 | {abbe1886-6062-486f-8ce0-4c9d7ce51ede} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe 15 | 16 | 17 | -------------------------------------------------------------------------------- /SampleDeskbandLib/RegisterLib/RegisterLib.vcxproj.filters: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | {d0b10932-bd24-4f26-b97a-e1d7dc88978a} 6 | cpp;c;cxx;def;odl;idl;hpj;bat;asm 7 | 8 | 9 | {4f0814e1-0498-4762-88ee-0843e01e38f4} 10 | h;hpp;hxx;hm;inl;inc 11 | 12 | 13 | {a0d34d64-d01b-4671-b7b0-d49ca1806e7d} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe 15 | 16 | 17 | -------------------------------------------------------------------------------- /SampleDeskbandLib/Attributes.cs: -------------------------------------------------------------------------------- 1 | // Copyright Pavel Zolnikov, 2002 2 | // 3 | 4 | using System; 5 | using System.Runtime.InteropServices; 6 | using System.Reflection; 7 | 8 | namespace BandObjectLib 9 | { 10 | /// 11 | /// Represents different styles of a band object. 12 | /// 13 | [Flags] 14 | [Serializable] 15 | public enum BandObjectStyle : uint 16 | { 17 | Vertical = 1, 18 | Horizontal = 2, 19 | ExplorerToolbar = 4, 20 | TaskbarToolBar = 8 21 | } 22 | 23 | /// 24 | /// Specifies Style of the band object, its Name(displayed in explorer menu) and HelpText(displayed in status bar when menu command selected). 25 | /// 26 | [AttributeUsage(AttributeTargets.Class)] 27 | public class BandObjectAttribute : System.Attribute 28 | { 29 | public BandObjectAttribute(){} 30 | 31 | public BandObjectAttribute(string name, BandObjectStyle style) 32 | { 33 | Name = name; 34 | Style = style; 35 | } 36 | public BandObjectStyle Style; 37 | public string Name; 38 | public string HelpText; 39 | } 40 | } -------------------------------------------------------------------------------- /SampleDeskbandLib/RegisterLib/RegisterLib.vcproj: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 11 | 12 | 13 | 19 | 21 | 23 | 31 | 33 | 34 | 40 | 42 | 44 | 51 | 53 | 54 | 55 | 56 | 59 | 60 | 63 | 64 | 67 | 68 | 69 | 70 | 71 | 72 | -------------------------------------------------------------------------------- /SampleDeskband/Register/Register.vcproj: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 11 | 12 | 13 | 20 | 22 | 24 | 33 | 35 | 36 | 43 | 45 | 47 | 54 | 56 | 57 | 58 | 59 | 62 | 63 | 66 | 67 | 70 | 71 | 72 | 73 | 74 | 75 | -------------------------------------------------------------------------------- /SampleMediaControlDeskband.sln: -------------------------------------------------------------------------------- 1 | Microsoft Visual Studio Solution File, Format Version 12.00 2 | # Visual Studio 15 3 | VisualStudioVersion = 15.0.27130.2026 4 | MinimumVisualStudioVersion = 10.0.40219.1 5 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SampleDeskband", "SampleDeskband\SampleDeskband.csproj", "{ACCDA683-C6AC-43DD-819F-4C3DE36E6BD7}" 6 | EndProject 7 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SampleDeskbandLib", "SampleDeskbandLib\SampleDeskbandLib.csproj", "{BDB3B670-A17B-483E-954C-52FC2B6FF9D3}" 8 | EndProject 9 | Global 10 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 11 | Debug|Any CPU = Debug|Any CPU 12 | Debug|x86 = Debug|x86 13 | Release|Any CPU = Release|Any CPU 14 | Release|x86 = Release|x86 15 | EndGlobalSection 16 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 17 | {ACCDA683-C6AC-43DD-819F-4C3DE36E6BD7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 18 | {ACCDA683-C6AC-43DD-819F-4C3DE36E6BD7}.Debug|Any CPU.Build.0 = Debug|Any CPU 19 | {ACCDA683-C6AC-43DD-819F-4C3DE36E6BD7}.Debug|x86.ActiveCfg = Debug|Any CPU 20 | {ACCDA683-C6AC-43DD-819F-4C3DE36E6BD7}.Debug|x86.Build.0 = Debug|Any CPU 21 | {ACCDA683-C6AC-43DD-819F-4C3DE36E6BD7}.Release|Any CPU.ActiveCfg = Release|Any CPU 22 | {ACCDA683-C6AC-43DD-819F-4C3DE36E6BD7}.Release|Any CPU.Build.0 = Release|Any CPU 23 | {ACCDA683-C6AC-43DD-819F-4C3DE36E6BD7}.Release|x86.ActiveCfg = Release|Any CPU 24 | {ACCDA683-C6AC-43DD-819F-4C3DE36E6BD7}.Release|x86.Build.0 = Release|Any CPU 25 | {BDB3B670-A17B-483E-954C-52FC2B6FF9D3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 26 | {BDB3B670-A17B-483E-954C-52FC2B6FF9D3}.Debug|Any CPU.Build.0 = Debug|Any CPU 27 | {BDB3B670-A17B-483E-954C-52FC2B6FF9D3}.Debug|x86.ActiveCfg = Debug|Any CPU 28 | {BDB3B670-A17B-483E-954C-52FC2B6FF9D3}.Debug|x86.Build.0 = Debug|Any CPU 29 | {BDB3B670-A17B-483E-954C-52FC2B6FF9D3}.Release|Any CPU.ActiveCfg = Release|Any CPU 30 | {BDB3B670-A17B-483E-954C-52FC2B6FF9D3}.Release|Any CPU.Build.0 = Release|Any CPU 31 | {BDB3B670-A17B-483E-954C-52FC2B6FF9D3}.Release|x86.ActiveCfg = Release|Any CPU 32 | {BDB3B670-A17B-483E-954C-52FC2B6FF9D3}.Release|x86.Build.0 = Release|Any CPU 33 | EndGlobalSection 34 | GlobalSection(SolutionProperties) = preSolution 35 | HideSolutionNode = FALSE 36 | EndGlobalSection 37 | GlobalSection(ExtensibilityGlobals) = postSolution 38 | SolutionGuid = {1109F8CE-2E18-48CD-9E8C-8526D1BC6829} 39 | EndGlobalSection 40 | EndGlobal 41 | -------------------------------------------------------------------------------- /SampleDeskband/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | 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 | // 9 | [assembly: AssemblyTitle("")] 10 | [assembly: AssemblyDescription("")] 11 | [assembly: AssemblyConfiguration("")] 12 | [assembly: AssemblyCompany("")] 13 | [assembly: AssemblyProduct("")] 14 | [assembly: AssemblyCopyright("")] 15 | [assembly: AssemblyTrademark("")] 16 | [assembly: AssemblyCulture("")] 17 | 18 | // 19 | // Version information for an assembly consists of the following four values: 20 | // 21 | // Major Version 22 | // Minor Version 23 | // Build Number 24 | // Revision 25 | // 26 | // You can specify all the values or you can default the Revision and Build Numbers 27 | // by using the '*' as shown below: 28 | 29 | [assembly: AssemblyVersion("1.0.0.0")] 30 | 31 | // 32 | // In order to sign your assembly you must specify a key to use. Refer to the 33 | // Microsoft .NET Framework documentation for more information on assembly signing. 34 | // 35 | // Use the attributes below to control which key is used for signing. 36 | // 37 | // Notes: 38 | // (*) If no key is specified, the assembly is not signed. 39 | // (*) KeyName refers to a key that has been installed in the Crypto Service 40 | // Provider (CSP) on your machine. KeyFile refers to a file which contains 41 | // a key. 42 | // (*) If the KeyFile and the KeyName values are both specified, the 43 | // following processing occurs: 44 | // (1) If the KeyName can be found in the CSP, that key is used. 45 | // (2) If the KeyName does not exist and the KeyFile does exist, the key 46 | // in the KeyFile is installed into the CSP and used. 47 | // (*) In order to create a KeyFile, you can use the sn.exe (Strong Name) utility. 48 | // When specifying the KeyFile, the location of the KeyFile should be 49 | // relative to the project output directory which is 50 | // %Project Directory%\obj\. For example, if your KeyFile is 51 | // located in the project directory, you would specify the AssemblyKeyFile 52 | // attribute as [assembly: AssemblyKeyFile("..\\..\\mykey.snk")] 53 | // (*) Delay Signing is an advanced option - see the Microsoft .NET Framework 54 | // documentation for more information on this. 55 | // 56 | [assembly: AssemblyDelaySign(false)] 57 | [assembly: AssemblyKeyFile(@"..\..\..\MyExampleProject.snk")] 58 | [assembly: AssemblyKeyName("")] 59 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # Set default behavior to automatically normalize line endings. 3 | ############################################################################### 4 | * text=auto 5 | 6 | ############################################################################### 7 | # Set default behavior for command prompt diff. 8 | # 9 | # This is need for earlier builds of msysgit that does not have it on by 10 | # default for csharp files. 11 | # Note: This is only used by command line 12 | ############################################################################### 13 | #*.cs diff=csharp 14 | 15 | ############################################################################### 16 | # Set the merge driver for project and solution files 17 | # 18 | # Merging from the command prompt will add diff markers to the files if there 19 | # are conflicts (Merging from VS is not affected by the settings below, in VS 20 | # the diff markers are never inserted). Diff markers may cause the following 21 | # file extensions to fail to load in VS. An alternative would be to treat 22 | # these files as binary and thus will always conflict and require user 23 | # intervention with every merge. To do so, just uncomment the entries below 24 | ############################################################################### 25 | #*.sln merge=binary 26 | #*.csproj merge=binary 27 | #*.vbproj merge=binary 28 | #*.vcxproj merge=binary 29 | #*.vcproj merge=binary 30 | #*.dbproj merge=binary 31 | #*.fsproj merge=binary 32 | #*.lsproj merge=binary 33 | #*.wixproj merge=binary 34 | #*.modelproj merge=binary 35 | #*.sqlproj merge=binary 36 | #*.wwaproj merge=binary 37 | 38 | ############################################################################### 39 | # behavior for image files 40 | # 41 | # image files are treated as binary by default. 42 | ############################################################################### 43 | #*.jpg binary 44 | #*.png binary 45 | #*.gif binary 46 | 47 | ############################################################################### 48 | # diff behavior for common document formats 49 | # 50 | # Convert binary document formats to text before diffing them. This feature 51 | # is only available from the command line. Turn it on by uncommenting the 52 | # entries below. 53 | ############################################################################### 54 | #*.doc diff=astextplain 55 | #*.DOC diff=astextplain 56 | #*.docx diff=astextplain 57 | #*.DOCX diff=astextplain 58 | #*.dot diff=astextplain 59 | #*.DOT diff=astextplain 60 | #*.pdf diff=astextplain 61 | #*.PDF diff=astextplain 62 | #*.rtf diff=astextplain 63 | #*.RTF diff=astextplain 64 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## C# IDeskBand2 Sample - a Media control Deskband for Windows 7+ 2 | 3 | ![Screenshot](https://raw.githubusercontent.com/navhaxs/media-control-deskband/master/screenshot.png) 4 | 5 | Original source from Pavel Zolnikov's article ["Extending Explorer with Band Objects using .NET and Windows Forms"](http://www.codeproject.com/Articles/2219/Extending-Explorer-with-Band-Objects-using-NET-and), from way back in 2002. See for instructions. 6 | 7 | I then adapted it to the IDeskBand2 interface. 8 | 9 | For this example project, I added some rudimentary media control buttons to the deskband. For this I used SendInput() from [InputSimulator](https://inputsimulator.codeplex.com/). 10 | 11 | This VS project builds with .NET 4.6.1 on Windows 10 x64. 12 | 13 | Clearly most of this project lends itself to Win32 and C++ rather than C#, but this will do for now. Did not achieve native theming (such as button hover styles consistent to msstyles), which may or may not be even possible on Windows 10. 14 | 15 | #### Get started 16 | 17 | 1. Open SampleDeskband.sln in Visual Studio 18 | 19 | 2. Build `BandObjectLib`. `SampleControl` is a dependency and will also get built. 20 | 21 | 3. Follow the installation steps below 22 | 23 | #### Installation 24 | 25 | Follow these commands to install the deskband dll into the GAC - required for .NET assemblies to be loaded as a deskband. This includes any dependency assemblies as well (to my knowledge). 26 | 27 | **Note: The dll must be (re)installed into the GAC each and every time the dll is modified.** 28 | 29 | Start an elevated command prompt, then run `env.bat` which has some aliases set up (you likely will need to edit this file to match exact version numbers on your system) 30 | 31 | (If you built in release mode) cd .\SampleDeskband\bin\Release\ 32 | 33 | (Or, if you built in debug mode) cd .\SampleDeskband\bin\Debug\ 34 | 35 | gacutil.exe /if SampleDeskband.dll 36 | 37 | gacutil.exe /if BandObjectLib.dll 38 | 39 | gacutil.exe /if WindowsInput.dll 40 | 41 | Next, register our main deskband assembly, 42 | 43 | regasm.exe SampleDeskband.dll 44 | 45 | Lastly, restart explorer 46 | 47 | k 48 | 49 | explorer.exe 50 | 51 | ### Notes 52 | 53 | - Launching explorer.exe in an elevated prompt means that explorer.exe will be elevated too. In the past I used to find that calling SendInput from an evelated explorer to a non-evelated Spotify didn't work... but it seems to work ok now? 54 | 55 | - To build `Interop.SHDocVw.dll` - the interop to the "Shell Doc Object and Control Library (SHDocVw.dll)" - use the Type Library Importer tool (tlbimp.exe) with a snk file. I used the MyExampleProject.snk for this example project. 56 | 57 | - If you find a better way to do something, a mistake, or something that could be improved, please do open an issue! 58 | 59 | #### Also see 60 | 61 | * https://github.com/dwmkerr/sharpshell/ 62 | * https://msdn.microsoft.com/en-us/library/bb762064(VS.85).aspx 63 | -------------------------------------------------------------------------------- /SampleDeskband/Register/Register.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | 14 | {E35915FE-ED91-4AE5-B566-F269CD854498} 15 | Win32Proj 16 | 17 | 18 | 19 | Utility 20 | v140 21 | MultiByte 22 | OldSyntax 23 | 24 | 25 | Utility 26 | v140 27 | MultiByte 28 | OldSyntax 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | <_ProjectFileVersion>14.0.25431.1 42 | 43 | 44 | Debug\ 45 | Debug\ 46 | 47 | 48 | Release\ 49 | Release\ 50 | 51 | 52 | 53 | cd $(ProjectDir)..\bin\Debug 54 | 55 | gacutil /if SampleBars.dll 56 | regasm SampleBars.dll 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | cd $(ProjectDir)..\bin\Release 65 | 66 | gacutil /if SampleBars.dll 67 | regasm SampleBars.dll 68 | 69 | 70 | 71 | 72 | 73 | {accda683-c6ac-43dd-819f-4c3de36e6bd7} 74 | false 75 | 76 | 77 | 78 | 79 | 80 | -------------------------------------------------------------------------------- /SampleDeskbandLib/RegisterLib/RegisterLib.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | 14 | {E35915FE-ED91-4AE5-B566-F269CD854498} 15 | Win32Proj 16 | 17 | 18 | 19 | Utility 20 | v140 21 | MultiByte 22 | 23 | 24 | Utility 25 | v140 26 | MultiByte 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | <_ProjectFileVersion>14.0.25431.1 40 | 41 | 42 | Debug\ 43 | Debug\ 44 | 45 | 46 | Release\ 47 | Release\ 48 | 49 | 50 | 51 | cd $(ProjectDir)..\bin\Debug 52 | 53 | "C:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.6 Tools\x64\gacutil.exe" /if BandObjectLib.dll 54 | "C:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.6 Tools\x64\gacutil.exe" /if Interop.SHDocVw.dll 55 | 56 | 57 | 58 | 59 | 60 | 61 | cd $(ProjectDir)..\bin\Release 62 | 63 | gacutil /if BandObjectLib.dll 64 | gacutil /if Interop.SHDocVw.dll 65 | 66 | 67 | 68 | 69 | 70 | {bdb3b670-a17b-483e-954c-52fc2b6ff9d3} 71 | false 72 | 73 | 74 | 75 | 76 | 77 | -------------------------------------------------------------------------------- /SampleDeskbandLib/SampleDeskbandLib.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Local 5 | 7.0.9466 6 | 1.0 7 | {BDB3B670-A17B-483E-954C-52FC2B6FF9D3} 8 | Debug 9 | AnyCPU 10 | 11 | 12 | SampleDeskbandLib 13 | ..\MyExampleProject.snk 14 | JScript 15 | Grid 16 | IE50 17 | false 18 | Library 19 | SampleDeskband 20 | 21 | 22 | 23 | v4.6.1 24 | 25 | 26 | 0.0 27 | 28 | 29 | 30 | bin\Debug\ 31 | false 32 | 285212672 33 | false 34 | 35 | DEBUG;TRACE 36 | 37 | true 38 | 4096 39 | false 40 | false 41 | false 42 | false 43 | 4 44 | full 45 | prompt 46 | false 47 | 48 | 49 | bin\Release\ 50 | false 51 | 285212672 52 | false 53 | 54 | TRACE 55 | 56 | false 57 | 4096 58 | true 59 | false 60 | false 61 | false 62 | 4 63 | none 64 | prompt 65 | false 66 | 67 | 68 | true 69 | 70 | 71 | 72 | System 73 | 74 | 75 | System.Drawing 76 | 77 | 78 | System.Windows.Forms 79 | 80 | 81 | 82 | 83 | Code 84 | 85 | 86 | UserControl 87 | 88 | 89 | Code 90 | 91 | 92 | BandObject.cs 93 | 94 | 95 | 96 | 97 | {EAB22AC0-30C1-11CF-A7EB-0000C05BAE0B} 98 | 1 99 | 1 100 | 0 101 | tlbimp 102 | False 103 | False 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | -------------------------------------------------------------------------------- /.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 | cmd.exe 10 | cmd.exe.lnk 11 | reg.bat 12 | WindowsFormsApplication1/ 13 | 14 | # User-specific files (MonoDevelop/Xamarin Studio) 15 | *.userprefs 16 | 17 | # Build results 18 | [Dd]ebug/ 19 | [Dd]ebugPublic/ 20 | [Rr]elease/ 21 | [Rr]eleases/ 22 | [Xx]64/ 23 | [Xx]86/ 24 | [Bb]uild/ 25 | bld/ 26 | [Bb]in/ 27 | [Oo]bj/ 28 | 29 | # Visual Studio 2015 cache/options directory 30 | .vs/ 31 | # Uncomment if you have tasks that create the project's static files in wwwroot 32 | #wwwroot/ 33 | 34 | # MSTest test Results 35 | [Tt]est[Rr]esult*/ 36 | [Bb]uild[Ll]og.* 37 | 38 | # NUNIT 39 | *.VisualState.xml 40 | TestResult.xml 41 | 42 | # Build Results of an ATL Project 43 | [Dd]ebugPS/ 44 | [Rr]eleasePS/ 45 | dlldata.c 46 | 47 | # DNX 48 | project.lock.json 49 | artifacts/ 50 | 51 | *_i.c 52 | *_p.c 53 | *_i.h 54 | *.ilk 55 | *.meta 56 | *.obj 57 | *.pch 58 | *.pdb 59 | *.pgc 60 | *.pgd 61 | *.rsp 62 | *.sbr 63 | *.tlb 64 | *.tli 65 | *.tlh 66 | *.tmp 67 | *.tmp_proj 68 | *.log 69 | *.vspscc 70 | *.vssscc 71 | .builds 72 | *.pidb 73 | *.svclog 74 | *.scc 75 | 76 | # Chutzpah Test files 77 | _Chutzpah* 78 | 79 | # Visual C++ cache files 80 | ipch/ 81 | *.aps 82 | *.ncb 83 | *.opendb 84 | *.opensdf 85 | *.sdf 86 | *.cachefile 87 | *.VC.db 88 | 89 | # Visual Studio profiler 90 | *.psess 91 | *.vsp 92 | *.vspx 93 | *.sap 94 | 95 | # TFS 2012 Local Workspace 96 | $tf/ 97 | 98 | # Guidance Automation Toolkit 99 | *.gpState 100 | 101 | # ReSharper is a .NET coding add-in 102 | _ReSharper*/ 103 | *.[Rr]e[Ss]harper 104 | *.DotSettings.user 105 | 106 | # JustCode is a .NET coding add-in 107 | .JustCode 108 | 109 | # TeamCity is a build add-in 110 | _TeamCity* 111 | 112 | # DotCover is a Code Coverage Tool 113 | *.dotCover 114 | 115 | # NCrunch 116 | _NCrunch_* 117 | .*crunch*.local.xml 118 | nCrunchTemp_* 119 | 120 | # MightyMoose 121 | *.mm.* 122 | AutoTest.Net/ 123 | 124 | # Web workbench (sass) 125 | .sass-cache/ 126 | 127 | # Installshield output folder 128 | [Ee]xpress/ 129 | 130 | # DocProject is a documentation generator add-in 131 | DocProject/buildhelp/ 132 | DocProject/Help/*.HxT 133 | DocProject/Help/*.HxC 134 | DocProject/Help/*.hhc 135 | DocProject/Help/*.hhk 136 | DocProject/Help/*.hhp 137 | DocProject/Help/Html2 138 | DocProject/Help/html 139 | 140 | # Click-Once directory 141 | publish/ 142 | 143 | # Publish Web Output 144 | *.[Pp]ublish.xml 145 | *.azurePubxml 146 | 147 | # TODO: Un-comment the next line if you do not want to checkin 148 | # your web deploy settings because they may include unencrypted 149 | # passwords 150 | #*.pubxml 151 | *.publishproj 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 directory 174 | AppPackages/ 175 | BundleArtifacts/ 176 | 177 | # Visual Studio cache files 178 | # files ending in .cache can be ignored 179 | *.[Cc]ache 180 | # but keep track of directories ending in .cache 181 | !*.[Cc]ache/ 182 | 183 | # Others 184 | ClientBin/ 185 | [Ss]tyle[Cc]op.* 186 | ~$* 187 | *~ 188 | *.dbmdl 189 | *.dbproj.schemaview 190 | *.pfx 191 | *.publishsettings 192 | node_modules/ 193 | orleans.codegen.cs 194 | 195 | # RIA/Silverlight projects 196 | Generated_Code/ 197 | 198 | # Backup & report files from converting an old project file 199 | # to a newer Visual Studio version. Backup files are not needed, 200 | # because we have git ;-) 201 | _UpgradeReport_Files/ 202 | Backup*/ 203 | UpgradeLog*.XML 204 | UpgradeLog*.htm 205 | 206 | # SQL Server files 207 | *.mdf 208 | *.ldf 209 | 210 | # Business Intelligence projects 211 | *.rdl.data 212 | *.bim.layout 213 | *.bim_*.settings 214 | 215 | # Microsoft Fakes 216 | FakesAssemblies/ 217 | 218 | # GhostDoc plugin setting file 219 | *.GhostDoc.xml 220 | 221 | # Node.js Tools for Visual Studio 222 | .ntvs_analysis.dat 223 | 224 | # Visual Studio 6 build log 225 | *.plg 226 | 227 | # Visual Studio 6 workspace options file 228 | *.opt 229 | 230 | # Visual Studio LightSwitch build output 231 | **/*.HTMLClient/GeneratedArtifacts 232 | **/*.DesktopClient/GeneratedArtifacts 233 | **/*.DesktopClient/ModelManifest.xml 234 | **/*.Server/GeneratedArtifacts 235 | **/*.Server/ModelManifest.xml 236 | _Pvt_Extensions 237 | 238 | # LightSwitch generated files 239 | GeneratedArtifacts/ 240 | ModelManifest.xml 241 | 242 | # Paket dependency manager 243 | .paket/paket.exe 244 | 245 | # FAKE - F# Make 246 | .fake/ 247 | -------------------------------------------------------------------------------- /SampleDeskbandLib/BandObject.resx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 60 | 61 | 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 | text/microsoft-resx 89 | 90 | 91 | 1.3 92 | 93 | 94 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 95 | 96 | 97 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 98 | 99 | 100 | ExplorerBarForm 101 | 102 | -------------------------------------------------------------------------------- /SampleDeskband/SampleDeskband.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Local 5 | 7.0.9466 6 | 1.0 7 | {ACCDA683-C6AC-43DD-819F-4C3DE36E6BD7} 8 | Debug 9 | AnyCPU 10 | 11 | 12 | SampleDeskband 13 | 14 | JScript 15 | Grid 16 | IE50 17 | false 18 | Library 19 | SampleDeskband 20 | 21 | 22 | 23 | v4.6.1 24 | 25 | 26 | 0.0 27 | publish\ 28 | true 29 | Disk 30 | false 31 | Foreground 32 | 7 33 | Days 34 | false 35 | false 36 | true 37 | 0 38 | 1.0.0.%2a 39 | false 40 | false 41 | true 42 | 43 | 44 | 45 | bin\Debug\ 46 | false 47 | 285212672 48 | false 49 | 50 | DEBUG;TRACE 51 | 52 | true 53 | 4096 54 | false 55 | false 56 | false 57 | false 58 | 4 59 | full 60 | prompt 61 | false 62 | 63 | 64 | bin\Release\ 65 | false 66 | 285212672 67 | false 68 | 69 | TRACE 70 | 71 | false 72 | 4096 73 | true 74 | false 75 | false 76 | false 77 | 4 78 | none 79 | prompt 80 | false 81 | 82 | 83 | 84 | System 85 | 86 | 87 | System.Data 88 | 89 | 90 | System.Drawing 91 | 92 | 93 | System.Windows.Forms 94 | 95 | 96 | System.XML 97 | 98 | 99 | ..\packages\InputSimulator.1.0.4.0\lib\net20\WindowsInput.dll 100 | 101 | 102 | 103 | 104 | Code 105 | 106 | 107 | UserControl 108 | 109 | 110 | HelloWorldBar.cs 111 | 112 | 113 | 114 | 115 | False 116 | .NET Framework 3.5 SP1 117 | true 118 | 119 | 120 | 121 | 122 | {bdb3b670-a17b-483e-954c-52fc2b6ff9d3} 123 | SampleDeskbandLib 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | -------------------------------------------------------------------------------- /SampleDeskband/HelloWorldBar.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 | -------------------------------------------------------------------------------- /SampleDeskband/HelloWorldBar.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.ComponentModel; 3 | using System.Windows.Forms; 4 | 5 | using BandObjectLib; 6 | using System.Runtime.InteropServices; 7 | using WindowsInput.Native; 8 | using WindowsInput; 9 | using System.Drawing; 10 | 11 | namespace SampleBars 12 | { 13 | [Guid("AE07101B-46D4-4a98-AF68-0333EA26E113")] 14 | [BandObject("Hello World Bar", BandObjectStyle.Horizontal | BandObjectStyle.ExplorerToolbar | BandObjectStyle.TaskbarToolBar, HelpText = "Shows bar that says hello.")] 15 | public class HelloWorldBar : BandObject 16 | { 17 | private System.Windows.Forms.Button button1; 18 | private TableLayoutPanel tableLayoutPanel1; 19 | private Button button2; 20 | private Button button3; 21 | private System.ComponentModel.Container components = null; 22 | 23 | public HelloWorldBar() 24 | { 25 | InitializeComponent(); 26 | } 27 | 28 | protected override void Dispose(bool disposing) 29 | { 30 | if (disposing) 31 | { 32 | if (components != null) 33 | components.Dispose(); 34 | } 35 | base.Dispose(disposing); 36 | } 37 | 38 | #region Component Designer generated code 39 | private void InitializeComponent() 40 | { 41 | this.button1 = new System.Windows.Forms.Button(); 42 | this.tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel(); 43 | this.button3 = new System.Windows.Forms.Button(); 44 | this.button2 = new System.Windows.Forms.Button(); 45 | this.tableLayoutPanel1.SuspendLayout(); 46 | this.SuspendLayout(); 47 | // 48 | // button1 49 | // 50 | this.button1.BackColor = System.Drawing.Color.Black; 51 | this.button1.Dock = System.Windows.Forms.DockStyle.Fill; 52 | this.button1.FlatAppearance.BorderSize = 0; 53 | this.button1.FlatStyle = System.Windows.Forms.FlatStyle.Flat; 54 | this.button1.Font = new System.Drawing.Font("Segoe UI", 10.8F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); 55 | this.button1.ForeColor = System.Drawing.SystemColors.HighlightText; 56 | this.button1.Location = new System.Drawing.Point(0, 0); 57 | this.button1.Margin = new System.Windows.Forms.Padding(0); 58 | this.button1.Name = "button1"; 59 | this.button1.Size = new System.Drawing.Size(30, 30); 60 | this.button1.TabIndex = 0; 61 | this.button1.Text = "⏮"; 62 | this.button1.UseVisualStyleBackColor = false; 63 | this.button1.Click += new System.EventHandler(this.button1_Click); 64 | // 65 | // tableLayoutPanel1 66 | // 67 | this.tableLayoutPanel1.ColumnCount = 3; 68 | this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 33.33333F)); 69 | this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 33.33333F)); 70 | this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 33.33333F)); 71 | this.tableLayoutPanel1.Controls.Add(this.button3, 0, 0); 72 | this.tableLayoutPanel1.Controls.Add(this.button1, 0, 0); 73 | this.tableLayoutPanel1.Controls.Add(this.button2, 2, 0); 74 | this.tableLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Fill; 75 | this.tableLayoutPanel1.Location = new System.Drawing.Point(0, 0); 76 | this.tableLayoutPanel1.Name = "tableLayoutPanel1"; 77 | this.tableLayoutPanel1.RowCount = 1; 78 | this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F)); 79 | this.tableLayoutPanel1.Size = new System.Drawing.Size(92, 30); 80 | this.tableLayoutPanel1.TabIndex = 1; 81 | // 82 | // button3 83 | // 84 | this.button3.BackColor = System.Drawing.Color.Black; 85 | this.button3.Dock = System.Windows.Forms.DockStyle.Fill; 86 | this.button3.FlatAppearance.BorderSize = 0; 87 | this.button3.FlatStyle = System.Windows.Forms.FlatStyle.Flat; 88 | this.button3.Font = new System.Drawing.Font("Arial", 13.8F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); 89 | this.button3.ForeColor = System.Drawing.SystemColors.HighlightText; 90 | this.button3.Location = new System.Drawing.Point(30, 0); 91 | this.button3.Margin = new System.Windows.Forms.Padding(0); 92 | this.button3.Name = "button3"; 93 | this.button3.Size = new System.Drawing.Size(30, 30); 94 | this.button3.TabIndex = 2; 95 | this.button3.Text = "▶"; 96 | this.button3.UseVisualStyleBackColor = false; 97 | this.button3.Click += new System.EventHandler(this.button3_Click); 98 | // 99 | // button2 100 | // 101 | this.button2.BackColor = System.Drawing.Color.Black; 102 | this.button2.Dock = System.Windows.Forms.DockStyle.Fill; 103 | this.button2.FlatAppearance.BorderSize = 0; 104 | this.button2.FlatStyle = System.Windows.Forms.FlatStyle.Flat; 105 | this.button2.Font = new System.Drawing.Font("Segoe UI", 10.8F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); 106 | this.button2.ForeColor = System.Drawing.SystemColors.HighlightText; 107 | this.button2.Location = new System.Drawing.Point(60, 0); 108 | this.button2.Margin = new System.Windows.Forms.Padding(0); 109 | this.button2.Name = "button2"; 110 | this.button2.Size = new System.Drawing.Size(32, 30); 111 | this.button2.TabIndex = 1; 112 | this.button2.Text = "⏭"; 113 | this.button2.UseVisualStyleBackColor = false; 114 | this.button2.Click += new System.EventHandler(this.button2_Click); 115 | // 116 | // HelloWorldBar 117 | // 118 | this.Controls.Add(this.tableLayoutPanel1); 119 | this.MinSize = new System.Drawing.Size(92, 30); 120 | this.Name = "HelloWorldBar"; 121 | this.Size = new System.Drawing.Size(92, 30); 122 | this.Title = "Hello Bar"; 123 | this.tableLayoutPanel1.ResumeLayout(false); 124 | this.ResumeLayout(false); 125 | 126 | } 127 | #endregion 128 | 129 | private void button1_Click(object sender, System.EventArgs e) 130 | { 131 | InputSimulator s = new InputSimulator(); 132 | //s.Keyboard.ModifiedKeyStroke(new [] { VirtualKeyCode.LWIN, VirtualKeyCode.LCONTROL }, VirtualKeyCode.LEFT); 133 | s.Keyboard.KeyPress(VirtualKeyCode.MEDIA_PREV_TRACK); 134 | } 135 | 136 | private void button2_Click(object sender, EventArgs e) 137 | { 138 | InputSimulator s = new InputSimulator(); 139 | //s.Keyboard.ModifiedKeyStroke(new[] { VirtualKeyCode.LWIN, VirtualKeyCode.LCONTROL }, VirtualKeyCode.RIGHT); 140 | s.Keyboard.KeyPress(VirtualKeyCode.MEDIA_NEXT_TRACK); 141 | } 142 | 143 | private void button3_Click(object sender, EventArgs e) 144 | { 145 | InputSimulator s = new InputSimulator(); 146 | //s.Keyboard.ModifiedKeyStroke(new[] { VirtualKeyCode.LWIN, VirtualKeyCode.LCONTROL }, VirtualKeyCode.RIGHT); 147 | s.Keyboard.KeyPress(VirtualKeyCode.MEDIA_PLAY_PAUSE); 148 | } 149 | 150 | } 151 | } 152 | -------------------------------------------------------------------------------- /SampleDeskbandLib/ComInterop.cs: -------------------------------------------------------------------------------- 1 | // This file is a part of the Command Prompt Explorer Bar project. 2 | // 3 | // Copyright Pavel Zolnikov, 2002 4 | // 5 | // declarations of some COM interfaces and structues 6 | 7 | using System; 8 | using System.Drawing; 9 | using System.Runtime.InteropServices; 10 | using System.Windows.Forms; 11 | 12 | namespace BandObjectLib 13 | { 14 | 15 | abstract class ExplorerGUIDs 16 | { 17 | public static readonly Guid IID_IWebBrowserApp = new Guid("{0002DF05-0000-0000-C000-000000000046}"); 18 | public static readonly Guid IID_IUnknown = new Guid("{00000000-0000-0000-C000-000000000046}"); 19 | } 20 | 21 | 22 | 23 | [Flags] 24 | public enum DBIM : uint 25 | { 26 | MINSIZE =0x0001, 27 | MAXSIZE =0x0002, 28 | INTEGRAL =0x0004, 29 | ACTUAL =0x0008, 30 | TITLE =0x0010, 31 | MODEFLAGS =0x0020, 32 | BKCOLOR =0x0040 33 | } 34 | 35 | 36 | [StructLayout(LayoutKind.Sequential,CharSet=CharSet.Unicode)] 37 | public struct DESKBANDINFO 38 | { 39 | public UInt32 dwMask; 40 | public Point ptMinSize; 41 | public Point ptMaxSize; 42 | public Point ptIntegral; 43 | public Point ptActual; 44 | [MarshalAs(UnmanagedType.ByValTStr, SizeConst=255)] 45 | public String wszTitle; 46 | public DBIM dwModeFlags; 47 | public Int32 crBkgnd; 48 | 49 | /// 50 | /// The view mode of the band object. This is one of the following values. 51 | /// 52 | [Flags] 53 | public enum DBIF : uint 54 | { 55 | /// 56 | /// Band object is displayed in a horizontal band. 57 | /// 58 | DBIF_VIEWMODE_NORMAL = 0x0000, 59 | 60 | /// 61 | /// Band object is displayed in a vertical band. 62 | /// 63 | DBIF_VIEWMODE_VERTICAL = 0x0001, 64 | 65 | /// 66 | /// Band object is displayed in a floating band. 67 | /// 68 | DBIF_VIEWMODE_FLOATING = 0x0002, 69 | 70 | /// 71 | /// Band object is displayed in a transparent band. 72 | /// 73 | DBIF_VIEWMODE_TRANSPARENT = 0x0004 74 | } 75 | 76 | }; 77 | 78 | [ComImport] 79 | [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] 80 | [Guid("FC4801A3-2BA9-11CF-A229-00AA003D7352")] 81 | public interface IObjectWithSite 82 | { 83 | void SetSite([In ,MarshalAs(UnmanagedType.IUnknown)] Object pUnkSite); 84 | void GetSite(ref Guid riid, [MarshalAs(UnmanagedType.IUnknown)] out Object ppvSite); 85 | } 86 | 87 | /// 88 | /// 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. 89 | /// 90 | [ComImport] 91 | [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] 92 | [Guid("00000114-0000-0000-C000-000000000046")] 93 | public interface IOleWindow 94 | { 95 | /// 96 | /// Retrieves a handle to one of the windows participating in in-place activation (frame, document, parent, or in-place object window). 97 | /// 98 | /// A pointer to a variable that receives the window handle. 99 | /// This method returns S_OK on success. 100 | [PreserveSig] 101 | int GetWindow(out IntPtr phwnd); 102 | 103 | /// 104 | /// Determines whether context-sensitive help mode should be entered during an in-place activation session. 105 | /// 106 | /// TRUE if help mode should be entered; FALSE if it should be exited. 107 | /// This method returns S_OK if the help mode was entered or exited successfully, depending on the value passed in fEnterMode. 108 | [PreserveSig] 109 | int ContextSensitiveHelp(bool fEnterMode); 110 | }; 111 | 112 | [ComImport] 113 | [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] 114 | [Guid("012dd920-7b26-11d0-8ca9-00a0c92dbfe8")] 115 | public interface IDockingWindow 116 | { 117 | int GetWindow(out System.IntPtr phwnd); 118 | int ContextSensitiveHelp([In] bool fEnterMode); 119 | 120 | int ShowDW([In] bool fShow); 121 | int CloseDW([In] UInt32 dwReserved); 122 | int ResizeBorderDW( 123 | IntPtr prcBorder, 124 | [In, MarshalAs(UnmanagedType.IUnknown)] Object punkToolbarSite, 125 | bool fReserved); 126 | } 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | /// 153 | /// Gets information about a band object. 154 | /// 155 | [ComImport] 156 | [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] 157 | [Guid("EB0FE172-1A3A-11D0-89B3-00A0C90A90AC")] 158 | public interface IDeskBand : IDockingWindow 159 | { 160 | #region IOleWindow Overrides 161 | 162 | [PreserveSig] 163 | new int GetWindow(out IntPtr phwnd); 164 | 165 | [PreserveSig] 166 | new int ContextSensitiveHelp(bool fEnterMode); 167 | 168 | #endregion 169 | 170 | #region Overrides of IDockingWindow 171 | 172 | [PreserveSig] 173 | new int ShowDW(bool bShow); 174 | 175 | [PreserveSig] 176 | new int CloseDW(UInt32 dwReserved); 177 | 178 | [PreserveSig] 179 | new int ResizeBorderDW(RECT rcBorder, IntPtr punkToolbarSite, bool fReserved); 180 | 181 | #endregion 182 | 183 | /// 184 | /// Gets state information for a band object. 185 | /// 186 | /// The identifier of the band, assigned by the container. The band object can retain this value if it is required. 187 | /// The view mode of the band object. One of the following values: DBIF_VIEWMODE_NORMAL, DBIF_VIEWMODE_VERTICAL, DBIF_VIEWMODE_FLOATING, DBIF_VIEWMODE_TRANSPARENT. 188 | /// The pdbi. 189 | /// 190 | [PreserveSig] 191 | int GetBandInfo(UInt32 dwBandID, DESKBANDINFO.DBIF dwViewMode, ref DESKBANDINFO pdbi); 192 | } 193 | 194 | /// 195 | /// Exposes methods to enable and query translucency effects in a deskband object. 196 | /// 197 | [ComImport] 198 | [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] 199 | [Guid("79D16DE4-ABEE-4021-8D9D-9169B261D657")] 200 | public interface IDeskBand2 : IDeskBand 201 | { 202 | #region IOleWindow Overrides 203 | 204 | [PreserveSig] 205 | new int GetWindow(out IntPtr phwnd); 206 | 207 | [PreserveSig] 208 | new int ContextSensitiveHelp(bool fEnterMode); 209 | 210 | #endregion 211 | 212 | #region Overrides of IDockingWindow 213 | 214 | [PreserveSig] 215 | new int ShowDW(bool bShow); 216 | 217 | [PreserveSig] 218 | new int CloseDW(UInt32 dwReserved); 219 | 220 | [PreserveSig] 221 | new int ResizeBorderDW(RECT rcBorder, IntPtr punkToolbarSite, bool fReserved); 222 | 223 | #endregion 224 | 225 | #region IDeskBand Overrides 226 | 227 | [PreserveSig] 228 | new int GetBandInfo(UInt32 dwBandID, DESKBANDINFO.DBIF dwViewMode, ref DESKBANDINFO pdbi); 229 | 230 | #endregion 231 | 232 | /// 233 | /// Indicates the deskband's ability to be displayed as translucent. 234 | /// 235 | /// When this method returns, contains a BOOL indicating ability. 236 | /// If this method succeeds, it returns S_OK. Otherwise, it returns an HRESULT error code. 237 | [PreserveSig] 238 | int CanRenderComposited(out bool pfCanRenderComposited); 239 | 240 | /// 241 | /// Sets the composition state. 242 | /// 243 | /// TRUE to enable the composition state; otherwise, FALSE. 244 | /// If this method succeeds, it returns S_OK. Otherwise, it returns an HRESULT error code. 245 | [PreserveSig] 246 | int SetCompositionState(bool fCompositionEnabled); 247 | 248 | /// 249 | /// Gets the composition state. 250 | /// 251 | /// When this method returns, contains a BOOL that indicates state. 252 | /// If this method succeeds, it returns S_OK. Otherwise, it returns an HRESULT error code. 253 | [PreserveSig] 254 | int GetCompositionState(out bool pfCompositionEnabled); 255 | } 256 | 257 | [ComImport] 258 | [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] 259 | [Guid("0000010c-0000-0000-C000-000000000046")] 260 | public interface IPersist 261 | { 262 | void GetClassID(out Guid pClassID); 263 | } 264 | 265 | 266 | [ComImport] 267 | [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] 268 | [Guid("00000109-0000-0000-C000-000000000046")] 269 | public interface IPersistStream 270 | { 271 | void GetClassID(out Guid pClassID); 272 | 273 | void IsDirty (); 274 | 275 | void Load ([In, MarshalAs(UnmanagedType.Interface)] Object pStm); 276 | 277 | void Save ([In, MarshalAs(UnmanagedType.Interface)] Object pStm, 278 | [In] bool fClearDirty); 279 | 280 | void GetSizeMax ([Out] out UInt64 pcbSize); 281 | } 282 | 283 | 284 | [ComImport] 285 | [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] 286 | [Guid("6d5140c1-7436-11ce-8034-00aa006009fa")] 287 | public interface _IServiceProvider 288 | { 289 | void QueryService( 290 | ref Guid guid, 291 | ref Guid riid, 292 | [MarshalAs(UnmanagedType.Interface)] out Object Obj); 293 | } 294 | 295 | 296 | [ComImport] 297 | [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] 298 | [Guid("68284faa-6a48-11d0-8c78-00c04fd918b4")] 299 | public interface IInputObject 300 | { 301 | void UIActivateIO(Int32 fActivate, ref MSG msg); 302 | 303 | [PreserveSig] 304 | //[return:MarshalAs(UnmanagedType.Error)] 305 | Int32 HasFocusIO(); 306 | 307 | [PreserveSig] 308 | Int32 TranslateAcceleratorIO(ref MSG msg); 309 | } 310 | 311 | [ComImport] 312 | [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] 313 | [Guid("f1db8392-7331-11d0-8c99-00a0c92dbfe8")] 314 | public interface IInputObjectSite 315 | { 316 | [PreserveSig] 317 | Int32 OnFocusChangeIS( [MarshalAs(UnmanagedType.IUnknown)] Object punkObj, Int32 fSetFocus); 318 | } 319 | 320 | public struct POINT 321 | { 322 | public Int32 x; 323 | public Int32 y; 324 | } 325 | 326 | public struct MSG 327 | { 328 | public IntPtr hwnd; 329 | public UInt32 message; 330 | public UInt32 wParam; 331 | public Int32 lParam; 332 | public UInt32 time; 333 | public POINT pt; 334 | } 335 | 336 | [StructLayout(LayoutKind.Sequential)] 337 | public struct RECT 338 | { 339 | public RECT(int left, int top, int right, int bottom) 340 | { 341 | this.left = left; 342 | this.top = top; 343 | this.right = right; 344 | this.bottom = bottom; 345 | } 346 | 347 | 348 | public int left, top, right, bottom; 349 | 350 | public int Width() 351 | { 352 | return right - left; 353 | } 354 | 355 | public int Height() 356 | { 357 | return bottom - top; 358 | } 359 | 360 | public void Offset(int x, int y) 361 | { 362 | left += x; 363 | right += x; 364 | top += y; 365 | bottom += y; 366 | } 367 | 368 | public void Set(int left, int top, int right, int bottom) 369 | { 370 | this.left = left; 371 | this.top = top; 372 | this.right = right; 373 | this.bottom = bottom; 374 | } 375 | 376 | public bool IsEmpty() 377 | { 378 | return Width() == 0 && Height() == 0; 379 | } 380 | } 381 | 382 | } -------------------------------------------------------------------------------- /SampleDeskbandLib/BandObject.cs: -------------------------------------------------------------------------------- 1 | // Copyright Pavel Zolnikov, 2002 2 | // 3 | // BandObject - implements generic Band Object functionality. 4 | 5 | using System; 6 | using System.Windows.Forms; 7 | using System.Runtime.InteropServices; 8 | //using SHDocVw; 9 | using System.Reflection; 10 | using System.Diagnostics; 11 | using System.Drawing; 12 | using System.ComponentModel; 13 | using Microsoft.Win32; 14 | 15 | [assembly: AssemblyVersion("1.0.0.0")] 16 | [assembly: AssemblyKeyFile(@"..\..\..\BandObjects.snk")] 17 | 18 | namespace BandObjectLib 19 | { 20 | /// 21 | /// Implements generic Band Object functionality. 22 | /// 23 | /// 24 | /// [Guid("YOURGUID-GOES-HERE-YOUR-GUIDGOESHERE")] 25 | /// [BandObject("Hello World Bar", BandObjectStyle.Horizontal | BandObjectStyle.ExplorerToolbar , HelpText = "Shows bar that says hello.")] 26 | /// public class HelloWorldBar : BandObject 27 | /// { /*...*/ } 28 | /// 29 | public class BandObject : UserControl, IObjectWithSite, IDeskBand2, IDockingWindow, IOleWindow, IInputObject 30 | { 31 | public const int E_NOTIMPL = unchecked((int)0x80004001); 32 | public const int S_OK = 0; 33 | 34 | 35 | /// 36 | /// Reference to the host explorer. 37 | /// 38 | //protected WebBrowserClass Explorer; 39 | protected IInputObjectSite BandObjectSite; 40 | /// 41 | /// This event is fired after reference to hosting explorer is retreived and stored in Explorer property. 42 | /// 43 | public event EventHandler ExplorerAttached; 44 | 45 | public BandObject() 46 | { 47 | InitializeComponent(); 48 | } 49 | 50 | private void InitializeComponent() 51 | { 52 | // 53 | // ExplorerBar 54 | // 55 | this.Name = "BandObject"; 56 | } 57 | 58 | 59 | /// 60 | /// Title of band object. Displayed at the left or on top of the band object. 61 | /// 62 | [Browsable(true)] 63 | [DefaultValue("")] 64 | public String Title 65 | { 66 | get 67 | { 68 | return _title; 69 | } 70 | set 71 | { 72 | _title = value; 73 | } 74 | }String _title; 75 | 76 | 77 | /// 78 | /// Minimum size of the band object. Default value of -1 sets no minimum constraint. 79 | /// 80 | [Browsable(true)] 81 | [DefaultValue(typeof(Size),"-1,-1")] 82 | public Size MinSize 83 | { 84 | get 85 | { 86 | return _minSize; 87 | } 88 | set 89 | { 90 | _minSize = value; 91 | } 92 | }Size _minSize = new Size(-1,-1); 93 | 94 | /// 95 | /// Maximum size of the band object. Default value of -1 sets no maximum constraint. 96 | /// 97 | [Browsable(true)] 98 | [DefaultValue(typeof(Size),"-1,-1")] 99 | public Size MaxSize 100 | { 101 | get 102 | { 103 | return _maxSize; 104 | } 105 | set 106 | { 107 | _maxSize = value; 108 | } 109 | }Size _maxSize = new Size(-1,-1); 110 | 111 | /// 112 | /// Says that band object's size must be multiple of this size. Defauilt value of -1 does not set this constraint. 113 | /// 114 | [Browsable(true)] 115 | [DefaultValue(typeof(Size),"-1,-1")] 116 | public Size IntegralSize 117 | { 118 | get 119 | { 120 | return _integralSize; 121 | } 122 | set 123 | { 124 | _integralSize = value; 125 | } 126 | }Size _integralSize = new Size(-1,-1); 127 | 128 | 129 | public virtual void GetBandInfo( 130 | UInt32 dwBandID, 131 | UInt32 dwViewMode, 132 | ref DESKBANDINFO dbi) 133 | { 134 | dbi.wszTitle = this.Title; 135 | 136 | dbi.ptActual.X = this.Size.Width; 137 | dbi.ptActual.Y = this.Size.Height; 138 | 139 | dbi.ptMaxSize.X = this.MaxSize.Width; 140 | dbi.ptMaxSize.Y = this.MaxSize.Height; 141 | 142 | dbi.ptMinSize.X = this.MinSize.Width; 143 | dbi.ptMinSize.Y = this.MinSize.Height; 144 | 145 | dbi.ptIntegral.X = this.IntegralSize.Width; 146 | dbi.ptIntegral.Y = this.IntegralSize.Height; 147 | 148 | dbi.dwModeFlags = DBIM.TITLE | DBIM.ACTUAL | DBIM.MAXSIZE | DBIM.MINSIZE | DBIM.INTEGRAL; 149 | } 150 | 151 | 152 | 153 | public virtual int CanRenderComposited(out bool pfCanRenderComposited) 154 | { 155 | pfCanRenderComposited = true; 156 | return S_OK; 157 | 158 | } 159 | 160 | public virtual int GetCompositionState(out bool pfCompositionEnabled) 161 | { 162 | pfCompositionEnabled = false; 163 | return S_OK; 164 | 165 | } 166 | 167 | /// 168 | /// Not used. 169 | /// 170 | public virtual int ResizeBorderDW(IntPtr prcBorder, Object punkToolbarSite, bool fReserved) 171 | { 172 | return E_NOTIMPL; 173 | } 174 | 175 | public virtual void SetSite(Object pUnkSite) 176 | { 177 | if( BandObjectSite != null ) 178 | Marshal.ReleaseComObject( BandObjectSite ); 179 | 180 | //if (Explorer != null) 181 | //{ 182 | // Marshal.ReleaseComObject(Explorer); 183 | // Explorer = null; 184 | //} 185 | 186 | BandObjectSite = (IInputObjectSite)pUnkSite; 187 | if( BandObjectSite != null ) 188 | { 189 | //pUnkSite is a pointer to object that implements IOleWindowSite or something similar 190 | //we need to get access to the top level object - explorer itself 191 | //to allows this explorer objects also implement IServiceProvider interface 192 | //(don't mix it with System.IServiceProvider!) 193 | //we get this interface and ask it to find WebBrowserApp 194 | _IServiceProvider sp = BandObjectSite as _IServiceProvider; 195 | Guid guid = ExplorerGUIDs.IID_IWebBrowserApp; 196 | Guid riid = ExplorerGUIDs.IID_IUnknown; 197 | 198 | try 199 | { 200 | object w; 201 | sp.QueryService( 202 | ref guid, 203 | ref riid, 204 | out w ); 205 | 206 | //once we have interface to the COM object we can create RCW from it 207 | //Explorer = (WebBrowserClass)Marshal.CreateWrapperOfType( 208 | // w as IWebBrowser, 209 | // typeof(WebBrowserClass) 210 | // ); 211 | 212 | OnExplorerAttached(EventArgs.Empty); 213 | } 214 | catch( COMException ) 215 | { 216 | //we anticipate this exception in case our object instantiated 217 | //as a Desk Band. There is no web browser service available. 218 | } 219 | } 220 | 221 | } 222 | 223 | public virtual void GetSite(ref Guid riid, out Object ppvSite) 224 | { 225 | ppvSite = BandObjectSite; 226 | } 227 | 228 | /// 229 | /// Called explorer when focus has to be chenged. 230 | /// 231 | public virtual void UIActivateIO(Int32 fActivate, ref MSG Msg) 232 | { 233 | if( fActivate != 0 ) 234 | { 235 | Control ctrl = GetNextControl(this,true);//first 236 | if( ModifierKeys == Keys.Shift ) 237 | ctrl = GetNextControl(ctrl,false );//last 238 | 239 | if( ctrl != null ) ctrl.Select(); 240 | this.Focus(); 241 | } 242 | } 243 | 244 | public virtual Int32 HasFocusIO() 245 | { 246 | return this.ContainsFocus ? 0 : 1; //S_OK : S_FALSE; 247 | } 248 | 249 | /// 250 | /// Called by explorer to process keyboard events. Undersatands Tab and F6. 251 | /// 252 | /// 253 | /// S_OK if message was processed, S_FALSE otherwise. 254 | public virtual Int32 TranslateAcceleratorIO(ref MSG msg) 255 | { 256 | if( msg.message == 0x100 )//WM_KEYDOWN 257 | if( msg.wParam == (uint)Keys.Tab || msg.wParam == (uint)Keys.F6 )//keys used by explorer to navigate from control to control 258 | if( SelectNextControl( 259 | ActiveControl, 260 | ModifierKeys == Keys.Shift ? false : true, 261 | true, 262 | true, 263 | false ) 264 | ) 265 | return 0;//S_OK 266 | 267 | return 1;//S_FALSE 268 | } 269 | 270 | /// 271 | /// Override this method to handle ExplorerAttached event. 272 | /// 273 | /// 274 | protected virtual void OnExplorerAttached(EventArgs ea) 275 | { 276 | if ( ExplorerAttached != null ) 277 | ExplorerAttached(this, ea); 278 | } 279 | 280 | /// 281 | /// Notifies explorer of focus change. 282 | /// 283 | protected override void OnGotFocus(System.EventArgs e) 284 | { 285 | base.OnGotFocus(e); 286 | BandObjectSite.OnFocusChangeIS(this as IInputObject, 1); 287 | } 288 | /// 289 | /// Notifies explorer of focus change. 290 | /// 291 | protected override void OnLostFocus(System.EventArgs e) 292 | { 293 | base.OnLostFocus(e); 294 | if( ActiveControl == null ) 295 | BandObjectSite.OnFocusChangeIS(this as IInputObject, 0); 296 | } 297 | 298 | 299 | /// 300 | /// Called when derived class is registered as a COM server. 301 | /// 302 | [ComRegisterFunctionAttribute] 303 | public static void Register(Type t) 304 | { 305 | string guid = t.GUID.ToString("B"); 306 | 307 | RegistryKey rkClass = Registry.ClassesRoot.CreateSubKey(@"CLSID\"+guid ); 308 | RegistryKey rkCat = rkClass.CreateSubKey("Implemented Categories"); 309 | 310 | BandObjectAttribute[] boa = (BandObjectAttribute[])t.GetCustomAttributes( 311 | typeof(BandObjectAttribute), 312 | false ); 313 | 314 | string name = t.Name; 315 | string help = t.Name; 316 | BandObjectStyle style = 0; 317 | if( boa.Length == 1 ) 318 | { 319 | if( boa[0].Name != null ) 320 | name = boa[0].Name; 321 | 322 | if( boa[0].HelpText != null ) 323 | help = boa[0].HelpText; 324 | 325 | style = boa[0].Style; 326 | } 327 | 328 | rkClass.SetValue(null, name ); 329 | rkClass.SetValue("MenuText", name ); 330 | rkClass.SetValue("HelpText", help ); 331 | 332 | if( 0 != (style & BandObjectStyle.Vertical) ) 333 | rkCat.CreateSubKey("{00021493-0000-0000-C000-000000000046}"); 334 | 335 | if( 0 != (style & BandObjectStyle.Horizontal) ) 336 | rkCat.CreateSubKey("{00021494-0000-0000-C000-000000000046}"); 337 | 338 | if( 0 != (style & BandObjectStyle.TaskbarToolBar) ) 339 | rkCat.CreateSubKey("{00021492-0000-0000-C000-000000000046}"); 340 | 341 | if( 0 != (style & BandObjectStyle.ExplorerToolbar) ) 342 | Registry.LocalMachine.CreateSubKey(@"SOFTWARE\Microsoft\Internet Explorer\Toolbar").SetValue(guid,name); 343 | 344 | } 345 | 346 | /// 347 | /// Called when derived class is unregistered as a COM server. 348 | /// 349 | [ComUnregisterFunctionAttribute] 350 | public static void Unregister(Type t) 351 | { 352 | string guid = t.GUID.ToString("B"); 353 | BandObjectAttribute[] boa = (BandObjectAttribute[])t.GetCustomAttributes( 354 | typeof(BandObjectAttribute), 355 | false ); 356 | 357 | BandObjectStyle style = 0; 358 | if( boa.Length == 1 ) style = boa[0].Style; 359 | 360 | if( 0 != (style & BandObjectStyle.ExplorerToolbar) ) 361 | Registry.LocalMachine.CreateSubKey(@"SOFTWARE\Microsoft\Internet Explorer\Toolbar").DeleteValue(guid,false); 362 | 363 | Registry.ClassesRoot.CreateSubKey(@"CLSID").DeleteSubKeyTree(guid); 364 | } 365 | 366 | public int GetWindow(out IntPtr phwnd) 367 | { 368 | phwnd = Handle; 369 | return S_OK; 370 | 371 | } 372 | 373 | public int ContextSensitiveHelp(bool fEnterMode) 374 | { 375 | return S_OK; 376 | } 377 | 378 | public int ShowDW(bool bShow) 379 | { 380 | if (bShow) 381 | Show(); 382 | else 383 | Hide(); 384 | 385 | return S_OK; 386 | } 387 | 388 | public int CloseDW(uint dwReserved) 389 | { 390 | Dispose(true); 391 | return S_OK; 392 | } 393 | 394 | public int ResizeBorderDW(RECT rcBorder, IntPtr punkToolbarSite, bool fReserved) 395 | { 396 | return E_NOTIMPL; 397 | } 398 | 399 | public int GetBandInfo(uint dwBandID, DESKBANDINFO.DBIF dwViewMode, ref DESKBANDINFO pdbi) 400 | { 401 | pdbi.wszTitle = this.Title; 402 | 403 | pdbi.ptActual.X = this.Size.Width; 404 | pdbi.ptActual.Y = this.Size.Height; 405 | 406 | pdbi.ptMaxSize.X = this.MaxSize.Width; 407 | pdbi.ptMaxSize.Y = this.MaxSize.Height; 408 | 409 | pdbi.ptMinSize.X = this.MinSize.Width; 410 | pdbi.ptMinSize.Y = this.MinSize.Height; 411 | 412 | pdbi.ptIntegral.X = this.IntegralSize.Width; 413 | pdbi.ptIntegral.Y = this.IntegralSize.Height; 414 | 415 | pdbi.dwModeFlags = DBIM.TITLE | DBIM.ACTUAL | DBIM.MAXSIZE | DBIM.MINSIZE | DBIM.INTEGRAL; 416 | 417 | return S_OK; 418 | } 419 | 420 | public int SetCompositionState(bool fCompositionEnabled) 421 | { 422 | fCompositionEnabled = true; 423 | return S_OK; 424 | } 425 | 426 | } 427 | } --------------------------------------------------------------------------------