Plenty of times we've seen the little status notifications at the bottom of the Home Server Console telling us who is logged in through the remote access web site or the status of the storage balancing:
How would you like to put your own information there? With ITabExtender it is possible.
A word of warning
Before digging into how this can be done it needs to be made very clear that unlike all of the other features of ITabExtender that I've discussed so far this week, having a third-party add-in expose status information using ITabExtender is dangerous as the Home Server Console only has a few places to display such information, places that are normally used by the Microsoft tabs... potentially leading to a third-party add-in visually overwriting important information.
Ideally if a third-party does implement ITabExtender and does make use of the status functionality they don't distribute the add-in and instead just use it for in house functionality and testing... and should later they decide to share it, they disable the status functionality.
Status
An ITabExtender exposes the read only Status property which returns an object that implements the ITabStatus interface which defines the following:
- OnClick()
- StatusEvents()
- StatusImage
- StatusNext
- StatusOrdinal
- StatusText
Right off the bat we can create a custom class that implements this interface:
public class TabStatus : ITabStatus
{
public void OnClick()
{
}
public void StatusEvents(System.Diagnostics.EventLog whsEvents)
{
}
public Bitmap StatusImage
{
get
{
return Properties.Resources.DefaultToolBarIcon16;
}
}
public ITabStatus StatusNext
{
get { return null; }
}
public int StatusOrdinal
{
get { return 0; }
}
public string StatusText
{
get { return "Some Status: " + DateTime.Now.ToString(); }
}
}
An alternative to implementing a stand alone class is to have our implementer of ITabExtender also implement ITabStatus to allow for easier setting and monitoring of status values.
For simplicity this post and the later example add-in build them as two separate classes.
StatusImage & StatusText
Similar to IConsoleTab, ITabStatus expose a pair of properties that define the image and text that should be associated with.
A quick note is that while TabImage is expected to return a Bitmap that is 32x32 pixels in size, StatusImage is expected to return a bitmap that is 16x16 pixels in size.
StatusOrdinal
The status bar along the bottom of the Home Server Console is an instance of the custom StatusBarStrip control which contains 3 separate StatusBarButton instances; the first for Remote login notification, the second for storage balancing status and the third for backup/restore progress.
The StatusOrdinal property of an ITabStatus implementer specifies which StatusBarButton that the status will be displayed on (0-2).
StatusEvents()
Rather than setting up some messaging system using named pipes, remoting or other a simple option is used with ITabStatus... the event log.
StatusEvents is called once, not long after a the Status property is first read, passing in a reference to the HomeServer event log... enabling the receiver to parse the log looking for specific events as well as use the EntryWritten event to be informed with a new log entry is written.
OnClick()
OnClick() is an interesting case... and one that I do not believe was implemented in any of the Microsoft tabs, despite it's existence (or at least support of it) causing a visual bug, it still sorta works and will still be discussed here.
OnClick() is treated like an event handler that is raised when a user clicks the StatusBarButton that is being used by an ITabExtender... only simply clicking the mouse on it isn't enough, instead you have to press the space bar to cause the click to actually occur.
StatusNext
Likely intended to be similar in functionality to ITabExtender.Next for ITabStatus instances... this work appears to be only half complete as nothing I have done has been able to use this to display multiple ITabStatus instances without employing multiple tabs.
Updating
Like many of the other undocumented features of the Home Server Console, changing the visual look of the ITabStatus implementer isn't as simple as just updating the applicable property, instead we need to request that the StatusBarStrip update the status for us.
In order to accomplish this the static CommonState class (Microsoft.HomeServer.Controls, HomeServerControls.dll) exposes a property named MainStatusBar which references the StatusBarStrip at the bottom of the main form... giving us access to a SetStatus() method that requests that this be done.
So from our Home Server Console tab (ideally) we need to call SetStatus and pass in a reference to the tab whose status we want to update:
CommonState.MainStatusBar.SetStatus(this);
After that the Console takes care of the update for us.
Remember though that any update will overwrite any existing updates to the same StatusOrdinal, potentially throwing out important information... just as the information placed there by us can be overwritten by a call to SetStatus() from another add-in.
Another potential issue that can be encountered with updating is removing the status information once it's no longer relevant (ie a user is no longer logged into the system via the web page). One possible option is to remove the existing ITabStatus instance and have ITabExtender.Status return null/Nothing and then call CommonState.MainStatusBar.SetStatus(this). This method will not cause a visual change, instead a more workable option is to change the StatusText and StatusImage properties of the ITabExtender to return and empty string and null/Nothing respectively for the update to actually occur.
Settings
Because the Settings form does not have a StatusBarStrip on it, the ISettingsExtender.Status property is largely worthless for tabs on the Settings side of things.
Sample
At long last... a pair of demo applications that demonstrate the functionality that's been discussed this week.
In each project are six tabs for the main console window that implement the ITabExtender interface that also display the time the last time Refresh() and Prepare() methods are called on it.
Similar functionality exists (sans Refresh() and Prepare() functionality in the settings window with three tabs that implement the ISettingsExtender interface.
On the first tab there are three buttons that allow enable the tab to output a status message, refresh that message and disable that message (which requires one last refresh).
All the while all tabs specify a unique TabOrdinal to ensure that they are displayed in order one after another.
Downloads:
Conclusion
ITabExtender through ITabStatus provides a relatively easy to use mechanism for a tab to display additional information to the user. Unfortunately because ITabExtender and ITabStatus were never intended for end user use, conflicts can easily exist between existing status messages either overwriting or being overwritten by status messages from third-party add-ins.
Next Time
Replacing the Home Server Console with our own application to give us just a little more control over our system when working remotely.
As always though, I'd love to hear your ideas of what you'd like to see in future.
Note: The information in this post is based on undocumented and at times deduced information on Windows Home Server and is not officially supported or endorsed by Microsoft and could very easily be wrong or subject to change in future, so please take it and everything else said on this blog with a grain of salt and use with caution.