How to add content to windows taskbar - c#

I have been trying to figure out, for some time, how to add content to the taskbar next to the clock. You can see examples of this in NetSpeedMonitor or NetWorx. I am a noob to taskbar but I cannot find anything no matter how hard I look. I am not interested in ThumbButtonInfo or NotifyIcon. Here are a a couple examples of content in the taskbar(incase I'm not saying this right). I would like so be able to do something similar to the first one:
Thank you,
Rymn

There's an example in codeproject showing Extending Explorer with Band Objects using .NET and Windows Forms
Build a Release version of BandObjectLib and register it in the Global
Assembly Cache. The easiest way to do this is to open
BandObjectLib.sln in Visual Studio, set the active configuration to
Release and select 'Rebuild Solution' from the 'Build' menu. The
second project in the solution - RegisterLib - is a C++ utility
project that performs the 'gacutil /if BandObjectLib.dll' command that
puts assembly into GAC.
As you probably already know, Band Objects are COM components. And for
the .NET framework to find an assembly that implements a COM component
it must be either be registered in the GAC or located in the directory
of the client application. There are two possible client applications
for Band Objects - explorer.exe and iexplorer.exe. Explorer is located
in the windows directory and IE somewhere inside 'Program Files'. So
GAC is actually the only one option in this case. Thus .NET assemblies
that implement Band Objects should be registered in GAC and all
libraries they depend on - like BandObjectLib.dll - should also be
there.
Assemblies in the GAC must have strong names and thus key pairs are
required. I have provided the BandObjects.snk file with a key pair but
I encourage you to replace it with your own. See the sn.exe tool for
more details.
Create a new Windows Control Library project and call it SampleBars.
We are going to rely on the base functionality of BandObjectLib so we
have to add a reference to BandObjectLib\Relase\bin\BandObjectLib.dll.
As we are developing a 'Hello World Bar', rename UserControl1.cs and
the UserControl1 class inside it appropriately - into HelloWolrdBar.cs
and HelloWorldBar. Also put the following lines at the beginning of
HelloWorldBar.cs:
using BandObjectLib;
using System.Runtime.InteropServices;
Make HelloWorldBar class inherit BandObject instead of
System.Windows.Forms.UserControl. As I mentioned earlier, Band Objects
are COM components so we should use the Guid attribute. Use
guidgen.exe to generate your unique GUID or you can use the one I have
generated for you:
[Guid("AE07101B-46D4-4a98-AF68-0333EA26E113")]
We also have to sign our assembly with a strong name. You can do this
by putting the following line into AssemblyInfo.cs file:
[assembly: AssemblyKeyFile(#"..\..\..\BandObjects.snk")]
Now its time to decide what kind of Band Object we want to develop.
Lets make it an Explorer Toolbar as well as a Horizontal Explorer Bar
(also known as a Browser Communication Band). All we need to do to
implement this decision is to add custom BandObject attribute to our
HelloWorldBar class:
[Guid("AE07101B-46D4-4a98-AF68-0333EA26E113")]
[BandObject("Hello World Bar",
BandObjectStyle.Horizontal | BandObjectStyle.ExplorerToolbar,
HelpText = "Shows bar that says hello.")]
public class HelloWorldBar : BandObject
{ ...
That's enough to make our control available through 'View->Explorer
Bars' and 'View->Toolbars' explorer menus. It also takes care of menu
item text - "Hello World Bar", and hen the menu item is highlighted
status bar displays "Shows bar that says hello.". Don't you like
declarative programming and custom attributes?
Now it is time to open HelloWorldBar.cs in the Visual Studio Designer
and put some controls on it. Although in my version of HelloWorldBar I
decided to put a single button with 'Say Hello' caption on it you are
free to do something more personalized. I made the size of the button
equal to the size of the control's client area and also set its Anchor
property to the combination of all possible styles - 'Top, Bottom,
Left, Right'. The background color is 'HotTrack' and ForeColor is
'Info'.
The BandObject control has several properties specific to the Band
Objects (and so classes derived from it) - Title , MinSize, MaxSize
and IntegralSize. I set Title for HelloWorldBar to "Hello Bar" and
both MinSize and Size to '150, 24'. Oh, and in button's On Click event
handler I put code that displays a message box. This is what my final
code looks like (and most of it was generated by VS.Net):
using System;
using System.ComponentModel;
using System.Windows.Forms;
using BandObjectLib;
using System.Runtime.InteropServices;
namespace SampleBars
{
[Guid("AE07101B-46D4-4a98-AF68-0333EA26E113")]
[BandObject("Hello World Bar", BandObjectStyle.Horizontal
| BandObjectStyle.ExplorerToolbar, HelpText = "Shows bar that says hello.")]
public class HelloWorldBar : BandObject
{
private System.Windows.Forms.Button button1;
private System.ComponentModel.Container components = null;
public HelloWorldBar()
{
InitializeComponent();
}
protected override void Dispose( bool disposing )
{
if( disposing )
{
if( components != null )
components.Dispose();
}
base.Dispose( disposing );
}
#region Component Designer generated code
private void InitializeComponent()
{
this.button1 = new System.Windows.Forms.Button();
this.SuspendLayout();
//
// button1
//
this.button1.Anchor = (((System.Windows.Forms.AnchorStyles.Top
| System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right);
this.button1.BackColor = System.Drawing.SystemColors.HotTrack;
this.button1.ForeColor = System.Drawing.SystemColors.Info;
this.button1.Name = "button1";
this.button1.Size = new System.Drawing.Size(150, 24);
this.button1.TabIndex = 0;
this.button1.Text = "Say Hello";
this.button1.Click += new System.EventHandler(this.button1_Click);
//
// HelloWorldBar
//
this.Controls.AddRange(new System.Windows.Forms.Control[] { this.button1 });
this.MinSize = new System.Drawing.Size(150, 24);
this.Name = "HelloWorldBar";
this.Size = new System.Drawing.Size(150, 24);
this.Title = "Hello Bar";
this.ResumeLayout(false);
}
#endregion
private void button1_Click(object sender, System.EventArgs e)
{
MessageBox.Show("Hello, World!");
}
}
}
Ok, now we are ready to build SampleBars.dll but its not enough to see
it in explorer yet. We have to put our assembly into the GAC as well
as register it as a COM server. There are tools - gacutil.exe and
regasm.exe that do just this. The C++ utility project named Register
in my version of the SampleBars solution liberates me from using these
tools manually. It has no files in it, just the following post-build
command (debug version):
cd $(ProjectDir)..\bin\Debug
gacutil /if SampleBars.dll
regasm SampleBars.dll
Of cause you have to make sure that Register project is the last one
to be built in the solution using Project Dependencies / Build Order.
After building the solution, and executing the gacutil and regasm
commands, we are finally ready to start Explorer and see our toolbar
and explorer bar. And if you did everything right you should be able
to see something like the picture at the top of the article. On this
picture you can also see how HelloWorldBar looks in the Windows
Taskbar. To achieve this all you need to do is to modify BandObject
attribute adding the BandObjectStyle.TaskbarToolBar flag.
Also you might want to look at this answer
According to Microsoft, Deskbands are not recommended for Windows
7, although they still work. Also keep in mind that Microsoft
requires that Deskbands support Aero on Windows 7 via IDeskband2
Interface, rather than IDeskband. Also, Micorosft has officially said
that IDeskBand2 may be altered or unavailable in subsequent versions
of the operating system or product.
Finally, be very careful about creating shell extensions in managed
code.

Related

CSS styling in GTKSharp

I'm converting a C/GTK+ GUI application to C# using GTKSharp in VS2017. I've installed this package https://www.nuget.org/packages/GtkSharp/3.1.3 via NuGet.
Here's how I load up the CSS (the application uses a Glade file to define the interface):
static void Main(string[] args)
{
new Program(args);
}
public Program(string[] args)
{
Application.Init();
builder = new Builder();
Gtk.CssProvider provider = new CssProvider();
builder.AddFromFile("interface.glade");
provider.LoadFromPath("style.css");
builder.Autoconnect(this);
Gtk.Window window = (Gtk.Window)builder.GetObject("start");
Gtk.StyleContext.AddProviderForScreen(Gdk.Screen.Default, provider, 800); // couldn't find the equivalent to GTK_STYLE_PROVIDER_PRIORITY_USER so I set the priority to a random number
window.Show();
Application.Run();
}
The selector names seem to be different from GTK+. For example,
window {
...
}
works in C/GTK+ but not in C#, whereas
GtkWindow {
...
}
works in C# but not in C/GTK+. Then there are a few widgets I can't seem to style at all. For example,
button {
...
}
works in GTK+ but
GtkButton {
...
}
does not work in C#. I couldn't find any documentation regarding how GTK# handles CSS styling so I thought it'd be the same as GTK+. Any pointers?
The GTKSharp seems more like an expected GTK3 behavior.
Here is the reference manual from developer.gnome.org
Espcially useful should be the Table 1. Selector syntax section.
In short the elements are named after the GTK class name: GtkButton, GtkLabel and so on.
For a class list of default GTK3 wigets check out the docs talbe of content..
The GTK button is a container wiget that doesn't render background so without seeing the actual CSS properties you try to apply using that selector I can't tell you why it doesn't work but so you might need to style it content separately. Eg.
GtkButton GtkLabel {
color: lime;
}
The selector itself GtkButton should be correct.
It was a version issue.
Version 3.22 of GTK# detects the GtkButton selector correctly. I was using GTK 3.14's native libraries. There is one unlisted NuGet package that provides win32 libraries for the 3.22 version. Strangely enough, that version detects the old "button", "window"... instead of the "GtkButton", "GtkWindow"... tags.

Reference to the right "System" in c# project

I am new to c# and visual studio and have run into some trouble.
I have created a project with references to "Windows" and ".Net" in visual studio because I want to test a little with smart cards.
The code:
using System;
using Windows.Devices.Enumeration;
using Windows.Devices.SmartCards;
class HandleSmartCard
{
public async void checkNumberOfSmartCards()
{
string selector = SmartCardReader.GetDeviceSelector();
DeviceInformationCollection devices = await DeviceInformation.FindAllAsync(selector);
// return "2";
}
}
So far it looks fine. However I also want the project to be able to use
System.Windows.Forms; which I have used in a previos test.
I add reference to System.Windows.Forms; and try to create a form. However in that form when I try this:
Form prompt = new Form();
System.Windows.Forms.Button confirmation = new System.Windows.Forms.Button() { Dock = DockStyle.Bottom };
confirmation.Click += (sender, e) => { prompt.Close(); };
I get a red line under "Close" with the message:
Reference to type component claims it is defined in system but could
not be found.
System is referenced at top of file, but I am guessing it is the wrong type of system right?
Can I somehow use "both Systems" in one project so to speak?
I hope someone understands what I mean and can help me understand this.
You're most likely working on a UWP app. The API for UWP apps is a very small subset of the full .NET framework. You can find more information here
https://msdn.microsoft.com/en-us/library/windows/apps/mt185501.aspx
You're attempting to reference System.Windows.Forms which is not allowed in UWP applications.
Looks like you're trying to create a popup to ask the user something. For this, use the MessageDialog class.
https://msdn.microsoft.com/en-us/library/windows/apps/windows.ui.popups.messagedialog.aspx

Create a Shell ContextMenu by right clicking on Desktop or Directory Background

The .NET Shell extension framework called SharpShell is great; I've developed a right-click file Shell ContextMenu "quite easily" that works selecting both files and directories.
Now I would like to develop a Shell ContextMenu by righ-clicking on an empty space (that is, on the Desktop or on a white spot while I'm inside a folder).
Is it possible do that still using SharpShell? Or do I need to move to a different solution?... and in 2nd case... what do you suggest?
Thanks
The two solutions presented below work, but in the meantime I have found that there is an easier solution that is actually already used in the samples that come with SharpShell.
See the CopyDirectoryLocationHandler class as an example of a context menu handler that is registered for the directory background (and the desktop):
[ComVisible(true)]
[COMServerAssociation(AssociationType.Class, #"Directory\Background")]
public class CopyDirectoryLocationHandler : SharpContextMenu
{
// ...
}
If you want the handler to only handle clicks on the desktop background, use this code instead:
[ComVisible(true)]
[COMServerAssociation(AssociationType.Class, #"DesktopBackground")]
public class CopyDirectoryLocationHandler : SharpContextMenu
{
// ...
}
Old obsolete answer:
You can use SharpShell for this purpose without problem. There are two possible approaches:
Register the Shell Extension to handle the folder background
yourself
or
Modify SharpShell to handle the registration of the
extension for the folder background for you.
Register the Shell Extension to handle the folder background yourself
Your shell extension is a COM server and as such is identified to the system via a GUID. This GUID is then used at places in the registry to register the COM extension for different purposes. When we manually want to register the extension for a purpose such as extending the context menu for folder backgrounds, it is best when our extension has a fixed GUID.
Currently your class looks like this:
[ComVisible(true)]
[COMServerAssociation(AssociationType.Directory)]
public class MyContextMenuExtension : SharpContextMenu
{
When compiling, the compiler will automatically generate a GUID to use for that class. But we can specify a specific one to use like this:
[Guid("A75AFD0D-4A63-41E3-AAAA-AD08A574B8B0")]
[ComVisible(true)]
[COMServerAssociation(AssociationType.Directory)]
public class MyContextMenuExtension : SharpContextMenu
{
Do not use the same GUID as shown here but create your own unique one in Visual Studio via Menu Tools > Create GUID. Use a different GUID for every shell extension you write.
Then recompile the dll and install and register it again (using regasm or the SharpShell Server Manager tool.
Then create a text file named "registry.reg" with the following content (use your own specific GUID). Instead of "MyContextMenuExtension" specify the name of your extension.
Windows Registry Editor Version 5.00
[HKEY_CLASSES_ROOT\Directory\Background\shellex\ContextMenuHandlers\MyContextMenuExtension]
#="{A75AFD0D-4A63-41E3-AAAA-AD08A574B8B0}"
Install the "registry.reg" file by double clicking. Your extension should now be active when you open the context menu for a folder background or the Desktop.
Instead of using the *.reg file, you can also make the changes manually using registry editor or if you have an installer instruct the installer to make those registry changes.
Modify SharpShell to handle the registration of the extension for the folder background for you
Make the following changes to the SharpShell source code:
In the file AssociationType.cs add a new enum value to the AssociationType enumeration:
/// <summary>
/// Create an association to the unknown files class.
/// </summary>
UnknownFiles,
/// <summary>
/// Create an association to the background of folders and the desktop
/// </summary>
DirectoryBackground
In the file ServerRegistrationManager.cs add a new private string constant:
/// <summary>
/// The 'directory' special class.
/// </summary>
private const string SpecialClass_Directory = #"Directory";
/// <summary>
/// The 'directory background' special class.
/// </summary>
private const string SpecialClass_DirectoryBackground = #"Directory\Background";
Also in the file ServerRegistrationManager.cs in the method CreateClassNamesForAssociations in the big switch statement add a new case like this:
case AssociationType.Directory:
// Return the directory class.
return new[] { SpecialClass_Directory };
case AssociationType.DirectoryBackground:
// Return the directory background class.
return new[] { SpecialClass_DirectoryBackground };
Finally you only have to tell your own extension class to use this new enumeration value:
[Guid("A75AFD0D-4A63-41E3-AAAA-AD08A574B8B0")]
[ComVisible(true)]
[COMServerAssociation(AssociationType.Directory)]
[COMServerAssociation(AssociationType.DirectoryBackground)]
public class MyContextMenuExtension : SharpContextMenu
{
I have used SharpShell some time ago, forgotten it since then (because it works flawlessly). I have used it on files and folders, so your question intrigued me. A little research on the tool led me to the answer No(unfortunately).
The binding is done through the com server associations on SharpShell. And by looking at the documentation of the com server associations I am not seeing the way to your desired functionality.
PS: I encourage you to leave a comment on the documentation page, or contact directly with the author of the library. He seems to be really helpful(I've contacted him before).

ILNumerics and Visual Studio Tools for Office (VSTO)

I've been experiemnting with the community version of ILNumerics 3.2.1.0 with .Net 4.0 in Visual Studio 2010 pro on Windows 7, and going through the documentation I succesfully get a windows form project to display a chart, using the code below.
public partial class Form2 : Form
{
public Form2()
{
InitializeComponent();
}
private void ilPanel1_Load(object sender, EventArgs e)
{
ILSurface mySurface = new ILSurface(ILSpecialData.sincf(100, 200));
ILPlotCube myCube = new ILPlotCube(twoDMode: false);
myCube.Add(mySurface);
ilPanel1.Scene.Add(myCube);
}
}
If I try exactly the same code but from inside a VSTO Excel 2010 application all that is displayed in the form is the designer view of the ILPanel, blue circle on white background. I don't get any error messages. Am I missing something obvious? or does anyone have a solution of how to get the chart to display in VSTO?
Update
Thanks to Philliproso for pointing out the IsDesignMode() method. As pointed out in various places, including this question, Detecting design mode from a Control's constructor , the following method is not ideal, but for me is has provided a quick fix to allow me to evaluate ILNumerics.
public static bool IsDesignMode() {
if (System.Windows.Forms.Application.ExecutablePath.IndexOf("devenv.exe", StringComparison.OrdinalIgnoreCase) > -1)
{
return true;
}
return false;
}
This is the same issue as here:
Ilnumerics Ilpanel not activating when compiled in a winform into a dll when loaded into matlab
in-a-winform-into-a-dll-when-loa
Using VSTO as host for ILNumerics lets the panels assume, it was loaded in a designer. We are currently collecting possible workarounds and solutions. One solution might be to introduce a flag in the Settings of ILNumerics:
Hosted [default: false]
Your situation would require the flag to be enabled. In hosted mode, a blacklist of common designers could be checked at runtime and compared to the current entry assembly. Any other suggestions?

"Could not find type" error loading a form in the Windows Forms Designer

I have a .NET 2.0 windows forms app, which makes heavy use of the ListView control.
I've subclassed the ListView class into a templated SortableListView<T> class, so it can be a bit smarter about how it displays things, and sort itself.
Unfortunately this seems to break the Visual Studio Forms Designer, in both VS2005 and 2008.
The program compiles and runs fine, but when I try view the owning form in the designer, I get these Errors:
Could not find type 'MyApp.Controls.SortableListView'. Please make sure that the assembly that contains this type is referenced. If this type is a part of your development project, make sure that the project has been successfully built.
There is no stack trace or error line information available for this error
The variable 'listViewImages' is either undeclared or was never assigned.
At MyApp.Main.Designer.cs Line:XYZ Column:1
Call stack:
at System.ComponentModel.Design.Serialization.CodeDomSerializerBase.Error(IDesignerSerializationManager manager, String exceptionText, String helpLink)
at System.ComponentModel.Design.Serialization.CodeDomSerializerBase.DeserializeExpression(IDesignerSerializationManager manager, String name, CodeExpression expression)
at System.ComponentModel.Design.Serialization.CodeDomSerializerBase.DeserializeExpression(IDesignerSerializationManager manager, String name, CodeExpression expression)
at System.ComponentModel.Design.Serialization.CodeDomSerializerBase.DeserializeStatement(IDesignerSerializationManager manager, CodeStatement statement)
The line of code in question is where it is actually added to the form, and is
this.imagesTab.Controls.Add( this.listViewImages );
listViewImages is declared as
private MyApp.Controls.SortableListView<Image> listViewImages;
and is instantiated in the InitializeComponent method as follows:
this.listViewImages = new MyApp.Controls.SortableListView<Image>();
As mentioned earlier, the program compiles and runs perfectly, and I've tried shifting the SortableListView class out to a seperate assembly so it can be compiled seperately, but this makes no difference.
I have no idea where to go from here. Any help would be appreciated!
It happened to me because of x86 / x64 architecture.
Since Visual Studio (the development tool itself) has no x64 version, it's not possible to load x64 control into GUI designer.
The best approach for this might be tuning GUI under x86, and compile it for x64 when necessary.
when you added the listview, did you add it to the toolbox and then add it to the form?
No, I just edited Main.Designer.cs and changed it from System.Windows.Forms.ListView to MyApp.Controls.SortableListView<Image>
Suspecting it might have been due to the generics led me to actually finding a solution.
For each class that I need to make a SortableListView for, I defined a 'stub class' like this
class ImagesListView : SortableListView<Image> { }
Then made the Main.Designer.cs file refer to these stub classes instead of the SortableListView.
It now works, hooray!
Thankfully I am able to do this because all my types are known up front, and I'm only using the SortableListView as a method of reducing duplicate code.
I had this problem too, related to merging massive SVN changes (with conflicts) in the *.Designer.cs file. The solution was to just open up the design view graphically, edit a control (move it to the left then right) and resave the design. The *.Designer.cs file magically changed, and the warning went away on the next compilation.
To be clear, you need to fix all of the code merge problems first. This is just a work around to force VS to reload them.
I've had a problem like this (tho not the same) in the past where my control was in a different namespace to my form even tho it was in the same project. To fix it I had to add a
using My.Other.Namespace;
to the top of the designer generated code file. The annoying thing was it kept getting blown away when the designer regenerated the page.
The assembly that contains MyApp.Controls.SortableListView isn't installed in the GAC by any chance is it?
when you added the listview, did you add it to the toolbox and then add it to the form?
Perhaps you forgot to add that:
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Release all resources used.
/// </summary>
/// <param name="disposing">true if managed resources should be removed otherwise; false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
private void InitializeComponent()
{
// ...
this.components = new System.ComponentModel.Container(); // Not necessarily, if You do not use
// ...
}
I have had the same problem. After removing some of my own controls of the *.Designer.cs-File the problem was solved. After going back to the original code the problem still was solved. So it seems to be a problem with the Visual Sudio cache. At the moment I cannot reproduce this problem.
If you have the problem try to emtpy the folder
C:\Users\YOURNAME\AppData\Local\Microsoft\VisualStudio\VERSION\Designer\ShadowCache
Did it work?
I had something similar - a user control was referring to a remote serice (which I couldn't guarantee being available at design time).
This post on MSDN suggested that I add
if (this.DesignMode) return;
to the Load function of the control, or in my case to the point before the WCF client was initialised. That did the trick.
So
private readonly Client _client = new Client();
becomes
private Client _client;
public new void Load()
{
if(DesignMode) return;
_client = new Client();
}
I had the same issue. In my case this issue was due to resource initialization. I moved the following code from InitializeComponent method to ctor(After calling InitializeComponent). After that this issue was resolved:
this->resources = (gcnew System::ComponentModel::ComponentResourceManager(XXX::typeid));
In my case the problem was the folder's name of my project! Why I think this:
I use SVN and in the 'trunk\SGIMovel' works perfectly. But in a branch folder named as 'OS#125\SGIMovel' I can't open the designer for a form that uses a custom control and works in the trunk folder.
Just get off the # and works nice.

Categories