May 26, 2009

Skype Automation in Powershell : Don’t have to dial in conference codes anymore

For teams located in different locations conference calling is a must. Most of these calling facilities have toll free 1-800 dial in numbers. Skype lets you dial in to the toll free 1-800 numbers without any cost. One annoying thing with these conference calls is that you have to dial in a pin code to enter. If you are dialing in to one conference only then you memorize it. But if you have to dial in several different conferences calls in a day it becomes a pain. You would probably have to lookup the outlook calendar entry and type it in, which is quite annoying and distracting. Recently I have been trying to do everything with Powershell. As you have guessed … … now we can dial into a Skype meeting with one powershell command.

You can download the powershell script : Download skype.ps1 (5.2K)

I just wrote a function ( just bare minimum, no error handling ) that calls a Skype contact or a phone number waits for certain time then enters the pin as DTMF codes. I have the different meeting and number to different  functions which calls this function. And now I can get into any meeting without hassle.

The function is called Call-SkypeContactSendDTMF. The first parameter can be a skype contact name or a saved phone only contact or a number to dial. The second parameter is the number of seconds to wait after the phone has been picked up by the conference bot. The third parameter is the DTMF codes. You can add pause by putting in “@” to pause for a second. Here is the calling syntax

Call-SkypeContactSendDTMF (ConferenceNo, SecondsTOWait, DTMFCodes)

So I have created different entries from the meetings like this

function call-conf1()
{
   Call-SkypeContactSendDTMF ("ConfNo",10,"7363784394#")
}

All I have to do is type in call-conf1 like this

call-conf1

I love powershell. Hope this helps someone.

btw: When executing this script remember that we want the function to stay in memory so you can either put this in the powershell profile or you can call it in the same context by adding a “. ” to it.

May 23, 2009

Executing Powershell Scripts in the Same Execution Context

Recently I have been trying to do almost everything in Powershell. With the release of Powershell V2 RC and the awesome visual debugger that comes with Powershell called Powershell ISE, I have a Powershell window open at all times. I am getting my google calendar events form command line, doing recursive ftp uploads and download as well. Now I have started to even do outlook automation with PS.

The Problem

Any slightly efficient developer would write functions and reuse them later. So I tended to write functions add kept on adding them to my Powershell profile file. After a while that turned a little messy and hard to manage. So now I thought why don’t write different script files put my functions in there and use them when needed. So I created functions for Google Data API, Outlook functions. Now when I call them from the prompt, after execution of the script the functions are no longer there. It is because the scriptblock runs in a different execution context and after execution the context is removed. So the functions I have put the file no longer exist when I call them.

For example I have written a function in myfunc.ps1 to convert string into base64 string which looks like this

function tobase64 ( $asciistring )
{
  return [Convert]::ToBase64String([System.Text.Encoding]
    ::ASCII.GetBytes($asciistring))
}

Now after running the script .\myfunc.ps1 when I call the function, it no longer works.

Solution

After running around the internet for hours, looking for a solution to run scripts in the same executions context and trying out several different approaches, I was about to give up. Then I found the worlds easiest solution in Donn Felkers blog. All you need to do is to add a simple dot ( “.” ) at the start of the line to make it run the in the same context.

So if you were running the script like this,

.\myfunc.ps1 
or
c:\somefolder\myfunc.ps1

You should run it like this

. .\myfunc.ps1 
or
. ‘c:\somefolder\myfunc.ps1’

See the added dot? That does the trick. I wish this was advertized more, then I wouldn’t have had to search for hours to find a solution.

kick it on DotNetKicks.com

April 14, 2009

InterOp: Using a .NET based component from a non .NET platform by creating Isolated Application

Whenever we try to use a .NET component from VB6 or VC++ applications we tend to expose the .NET classes as COM components and register them and from the VB6 or VC applications so that we can instantiate and use the COM components written in .NET. One downside to doing interOp this way is the use of Registry to store the COM information as COM uses registry to lookup the prog id and clsid. This hassle can be avoided by using xcopy deployment with Registry Free COM.

Isolated Applications and Side by Side Assemblies

.NET is not the sole platform to come up with xcopy deployment and freedom from dll hell. Cpp and Delphie had this for long time. Isolated Applications and Side by side Assemblies  have been invented as a solution to the versioning problem.

According to MSDN, Isolated Applications are self-describing applications installed with manifests. The benefits of Isolated Applications are that these are more stable and reliable since they are not affected by installation or change in other software, they will always run with the component version they were originally intended for, they can take advantage of Side by Side Assemblies feature, can be installed with xcopy deployment without impacting the registry. A side by side assembly can be a dll, windows class, COM server, type library or interface defined by manifests.

Private and Shared Assembly

There are two types of Side By Side Assemblies. Private Assemblies are those which are for consumption of one single application, usually placed in the application folder or sub folder. But a Shared Assembly can be used by multiple applications. A fully Isolated application uses only side by side assemblies. If you want to find the Shared Assemblies installed in your computer look in \Windows\WinSxS folder. The shared assemblies are installed here.

Manifests

Manifests are xml files that accompany assemblies with extra information like dependency, binding, activation. A manifest can be an external file or can be embedded as a resource within the assembly. In older operating systems like Windows XP, manifests need to be embedded inside the side by side (denoted SxS) assemblies to work properly. Assembly Manifests describe side by side assemblies and thus needs to be embedded to work properly in operating systems like Windows XP. Application Manifests describe isolated applications and do not need to be embedded inside the application.

Normal Registry Based COM Component Load Procedure

If we look up a COM self registering dll we will find that it usually* has four stdcall  calling convention functions. Look at the dependency walker image below of a standard self registering COM server dll.

dependency_walker

When we use regsvr32.exe to register a COM dll, the register server application calls the DllRegisterServer function of the dll and that function call inside the dll takes care of putting information in the windows registry so that it can be used by any user application. Now lets have a look at the registry where all these information is recorded. Let us take a standard windows COM component and see its registry structure. The COM component that we will look up today is FileSystemObject from Micorsoft scripting runtime. The progid of the object is Scripting.FileSystemObject. Lets say we are using script code like this

 Set fso = CreateObject( “Scripting.FileSystemObject” )

So lets try to have an understanding how this object is created from the code above. If we go and try looking up the string “Scripting.FileSystemObject” under the HKEY_CLASSES_ROOT key then we would see this.

registry_1

As you can see there is a node called CLSID and it contains the Class ID ( GUID of the class) inside the node. Now lets go and visit that Class ID node under the HKEY_CLASSES_ROOT\CLSID registry node. See below

registry_2

As we can see that this is how the dll containing the class object is found, COM infrastructure then calls the DllGetClassObject function to retrieve a pointer to the object we are looking for. As like all COM interfaces the object implements IUnknown interface and all scriptable COM objects implement IDispatch interface. However how COM identifies and uses the object beyond the scope of this article. The point that I wanted to make is that the windows registry has a very important function here and to have any COM component usable by other applications we had to register it in windows registry. 

Registry Free COM Access in an Isolated Application

In an Isolated Application we can skip entering all the information in the registry and rather enter them in the manifest. We need to create an application manifest which will have the filename in the format of application.exe.manifest. Then we need to create an assembly manifest and embed that assembly manifest inside the dll. Then we would have created an Isolated Application and would not need to register to windows registry to access the functions of the COM dll.

The side by side assemblies are searched in the following order

1. In the executable folder
2. Subfolder of the executable folder, subfolder must have the same name as the assembly. For example see inside your Windows\WinSxS folder
3. In language specific or culture specific subfolder of the executable

For more information on assembly search order look here in MSDN.

Activation Contexts are data structures that allows the OS to redirect loading. For example it can redirect the loader to load a specific version of a dll, or redirect COM object loading process. We will use the COM object loading redirection to avoid using windows registry. For more information on Activation Contexts read this

Doing it by example

I have setup a sample application with source that will show how we can create a registry free COM component. Please note that there is already a practical example in the following article in MSDN, Registration-Free Activation of .NET-Based Components: A Walkthrough by Steve White and Leslie Muller. You might want to read that article if you find my example not clear enough.

Download Sample Code

Here is what we are going to do in the sample application

1. Create C# based class that serves funny quotes and expose that as a COM component and register it.

2. Create a VB6 executable that uses the COM dll to show quotes

3. Unregister the COM dll to show that without COM registration in windows registry the application is no longer working

4. Create an application manifest, then create an assembly manifest and recompile the C# application with the embedded assembly manifest to create our isolated application.

5. Move the isolated application to a different folder and prove that the application is using COM without registry.

1. C# COM Dll

We are going to create a dll called QuoteSource and a class that serves Quotes called QuoteProvider and it is going to implement the IQuoteProvider interface. The methods in the interface will be exposed.

Here is how the interface looks like.

 interface_1

Here is the class that serves quotes and implements the interface above

class_1  ‘

The assembly info contains the assembly guid

assembly_info

We need to make sure that a tlb file is generated and the assembly we created is registered. We will select “Register for COM interop” option from the build properties screen. See below …

build

2. VB6 Client Executable that uses the C# Library

We have created a simple VB6 application that refers and calls the C# assembly dll. See below:

VB6Client

Let compile the executable and it becomes VB6Client.exe

3. Unregister the C# COM dll to make sure that we a re not using the reference

We will use the following command line in the folder where the dll resides

regasm /u QuoteSource.dll

Lets run our VB6Client.exe and press the Get Quote button… walla! It does not work anymore. The executable exits with automation error since we unregistered it from windows registry.

4. Create the Application and Assembly Manifest and embed Assembly Manifest inside the QuoteSource.dll

First we are going to create an application manifest. The application manifest has to have the name in the format of exetutable full name + .manifest. Since our executable is called VB6Client.exe our application manifest will be called VB6Client.exe.manifest. Here are the contents of the manifest.

asm_manifest

Now lets create the assembly manifest and embed it inside out QuoteSource.dll. First we will create an xml file called QuoteSource.manifest. Please observe that we have put in the progid and clsid of the COM exposed class.

asm_manifest2

Now we need to convert this assembly into a resource file. We will use rc.exe that comes with windows SDK, or VC++ or VB6 installation.

We will create a text file called QuoteSource.rc  will put in the following line here.

1 24 QuoteSource.manifest

Here 1 is the manifest resource id and 24 means that it is a type of manifest resource. We will now invoke the Windows SDK resouce compiler from the command line. Check where in you computer you have the resource compiler installed. Here is the command line

rc.exe QuoteSource.rc 

After invoking this it will create a file called QuoteSource.res. This is a windows resource file.

Now we will use a custom build command to create the dll. Observe the command line below

csc /t:library /out:QuoteSource.dll /win32res:QuoteSource.res 

IQuoteProvider.cs QuoteProvider.cs Properties\AssemblyInfo.cs

See the win32res switch, it tells the compiler that it is a win32 resource.

Now copy the dll to the same folder as the exe, also copy the application manifest. There is no need to copy the assembly manifest as we have already embedded it inside the dll.

Run the the application and press the Get Quote button, it works!

5. XCopy Deployment

Copy or move the folder elsewhere, even to another computer. It will still work without any need to register the .NET COM dll. This is because we have created the application and assembly manifest and windows is treating our application as a Isolated application.

Last Words

This way you can create XCopy deployment for even COM based applications and avoid storing information in registry. Even a multi dll VB6 or VC++ application can be made Isolated Application.

kick it on DotNetKicks.com

March 28, 2009

Converting Typepad Exported Blog format to BlogML

My blog is hosted at Typepad, which in my personal opinion takes the least time to manage than any other blog hosting service. The payment option from typepad has no Paypal support as of the time of my writing and I did not want to spend from my card. So I planned to move from typepad to self hosting. However that situation was resolved with help of typepad and I am still in Typepad,the best managed blog service.

I was planning to use BlogEngine.NET, a .NET based blogging platform to host and it supports importing from BlogML. Typepad is a blog hosting service that is based on MovableType blogging platform. MovableType exports blog contents into a plain text based format. I searched around the internet for a tool that converts typepad format to BlogML. Unfortunately there was none. So I had to write a converter to convert the typepad format.

Gotcha!

After converting the the blog content to BlogML I just found out that there is a click once installer that comes with BlogEngine.NET 1.4.5 and the application do not start. After a little investigation I had figured that the location of the installer is no longer valid. I then had to add support to directly import into BlogEngine by calling their webservice. So if you are converting the typepad blog exported please use the code below.

Download, Source and Usage

Download Typepad2BlogMLBinary
Download Typepad2BlogML

Usage: Typepad2BlogML.exe -i:[input file] -mode:[blogml|service] -o:[output file] -s:[service address] -u:[username] -p:[password]

There are 2 application modes, one for converting into BlogML and another for uploading to BlogEngine via a webservice.

For converting to blog ML you should use something like this:

Typepad2BlogML.exe -i:mytypepadfile.txt -m:blogml -o:out.blogml

For importing into BlogEngine 1.4.5 use command line code like this:

Typepad2BlogML.exe -i:mytypepadfile.txt -m:service -s:http://www.myblog.com/api/BlogImporter.asmx -u:username -p:password

February 16, 2009

Preparing to move to BlogEngine.NET from Typepad

I have been blogging for over a year now and have been using www.typepad.com as my hosting provider. Typepad is a wonderful host but it does not accept payments via paypal and accepts only credit/debit card which I do not want to use at the moment. Also it is written in perl/cgi probably. The MovableTypes framework is a awesome but it requires perl/cgi. Since I work on the .NET platform mostly I wanted to add some functionality to the blog which I cannot do with typepad or MT. So I have selected BlogEngine.NET as the blogging framework and preparing to move there.

The site will look the same as I will use the same design as it is now. I am also writing a converter that exports from typepad export format to BlogML which the BlogEngine accepts. Typepad has been a superb blog host until recently. The ticket that I opened a few days ago is still unresolved without a reply. Sad!

January 02, 2009

WPF Kid Stuff: Extracting a Control Template

One of the design principles for WPF was to enable the developer decide the look and feel of the control and that resulted in the most versatile UI framework that can be customized in any way the developer wants. Previously there were many widgets for different languages and frameworks because their look could not be customized beyond the method the control builder provided. With the help of templates in WPF that has changed and that is why there are a lot less custom controls in WPF than the previous technologies. In order to customize something the end developer has to only modify the templates.

If we want to modify a the default look of a controls that is not controllable by the properties, the best way to do that is to extract the existing template of the control and change that. Manually we could open up Expression Blend and right click on a control end edit a copy of the template. See image below.

extract

This would actually reveal the control template that builds control and we can modify it and use as we please.

Another procedure is the extract the template from code is to get the template from the control itself. We can write c# code to extract the template like this …

// Get the template from the control ControlTemplate template = ctl.Template;
// We want our xaml of be properly indented, ohterwise
// we would not be able to indent them.
XmlWriterSettings xmlSettings = new XmlWriterSettings();
xmlSettings.Indent = true;
// Make the string builder
StringBuilder sb = new StringBuilder();
XmlWriter writer = XmlWriter.Create(sb, xmlSettings);
XamlWriter.Save(template, writer);

// Now the sb.ToString() should give us the template

Note: There will be more controls in the xaml template output. Their templates can be extracted further.

October 07, 2008

Comparison of Different Open Source Licenses -“With Comparison Chart!”

I was a little confused with which license to use for an open source initiative and the benefits and limitations of difference licenses, so I dug a little and here is what I have found. I hope this helps you with your selection of a license for your open source initiative.

Pretext

Previously I had my open source projects listed in SourceForge.net, and the last one I worked on was pretty long ago. Recently I took on a few more initiatives to release some of the libraries that I developed as open source projects and a new open source project for file synchronization. As a .NET person my first choice was CodePlex.com which is a great site with TFS and subversion and issue tracking support.

I am used to write the license myself for the software. However the codeplex site comes with a bunch of pre defined standard licenses and no option to write your own custom open source license. In order select a license I had to read all of these licenses and also read this cool book on licenses - Open Source and Free Software Licensing By Andrew M. St. Laurent from O’Reilly press (ISBN: 0-596-00581-4).

The Licenses In Discussion

I am going to discuss the following licenses:

1. The MIT License
2. New BSD License
3. Apache License
4. Microsoft Public License (Ms-PL)
5. Microsoft Reciprocal License (Ms-RL)
6. GNU General Public License (GPL)
7. GNU Library General Public License (LGPL)
8. Common Development and Distribution License
9. Mozilla Public License 1.1 (MPL)

The Basis of Open Source Licensing

Open source does not mean free software, but often is associated with it. Some licenses makes the software free for use, some licenses are to make sure that source is always distributed with the binaries. There are 2 items common among all of these licenses. Firstly the license must be distributed with the software usually with both binary and source code form. Secondly, the licenses have a warranty disclaimer. Having a warranty disclaimer is very important when you are making a free software. Since software creator is not making money out of a software it does not make sense to be liable for implied warranty. The warranty disclaimer releases the creator of the software from the liability of implied warranty.

Comparison Summary

The chart below shows a basic comparison of explicitly stated items among different open source licenses (click to enlarge)

OpenSourceLicenseComparison

Hope this helps to have an overview of the licenses

Simple Licenses

The MIT License

The MIT License is the simplest non restrictive open source license. It has only two parts, at the first part lets anyone use the software for free even it lets anyone publish, distribute, sublicense or even sell copies of the software. The second part is the disclaimer for warranty.

New BSD License

The new BSD license is as unrestrictive as the MIT license except for the fact, it does not allow the name of the contributors to be used to endorse any derivative software.

Microsoft Public License (Ms-PL)

The Microsoft Public License is similarly non restrictive as the previous two with the following explicit notations. Firstly, the license does not grant permission to the contributor’s name, logo or trademark. Secondly this license lets you royality free use of contributor’s patents that are used in the software but if you make any patent claim against any part of the software your license to the use of contributor’s parent is revoked.

Microsoft Reciprocal License (Ms-RL)

This license exactly as same as the previous one except that if you use any file from software then you must provide source for those files and the copy of the license and the other files in the end result software can be licensed under any term you want.

Common Development and Distribution License (CDDL)

CDDL is also a non restrictive type of open source license, but it has a lot of items explicitly described. See license details

Apache 2.0 License

Apache license makes sure that the software is free, the name of apache foundation cannot be used to endorse the product, any change to the software needs to be distributed in source form and it lets you provide warranty if you want to.

So read the licenses now and select the one that you like.

Complex Licenses

GNU General Public License (GPL) 

This is a highly restrictive license and any software that uses this license must also be distributed under GPL which makes GPL quite infamous and at the same time favorite to a breed of developers. There are several gotcha clauses in GPL. I am not going to describe it as there are many points to discuss. Please read it carefully.

GNU Library General Public License (LGPL)

This is a better version of the GPL license aimed more at the software components. It lets you have LGPL license for the component to be used in software while other components can have different licenses.  Both the GPL and LGPL allows the open source software to be sold as long as the source code is provided. Please read the license carefully before selecting it.

Disclaimer

Firstly I am not a lawyer, and this is my understanding from what I have read in the licenses and there is no guarantee that what I am writing here is correct since this is my personal interpretation. I would advice you to read the  licenses before you apply them and I do not take any responsibility of my interpretation.

kick it on DotNetKicks.com

October 01, 2008

A very simple C# interview question that most developer fails

We interview a lot of people and usually go through at least 3 interviews to select someone for the organization I work in. A recent trend of new developers is baffling me. The newcomer to development do not seem to know any of the basics. These newcomers might know some Linq, Ajax and famous frameworks but they fail at very simple OOP questions and fairly have very little or no idea about the CLR.

Anyway that is not the topic that I was going to write today, I have seen good candidates fail at a this question, which is basic knowledge. I don’t know why but this simple question baffles a lot of people. So I have decided to ask the readers this question.

Question:

How do you define a property read only for the outside world and writable for the same assembly classes?

For example I have a class named User where everyone outside the assembly can read the string ‘Name’ property but cannot set it. However the classes inside the assembly is able to set the property.  I am further detailing the exlanation.

User myUser = SomeClass.GetUser();

// OK for all classes since all can read it
string name = myUser.Name;    

// This line does not compile if this code is 
// written in a class that is not in the same 
// assembly as the type User. But it compiles
// if the code is written in the same assembly
// that contains the type user.
myUser.Name = "C# Developer"; 

Answer:

Now all I want is the c# code declaration for the property name that matches my requirement of being read only for the outside world. Write it in the comments section. I will answer the question 24 hours from now.

kick it on DotNetKicks.com

September 19, 2008

Extend WPF: Add your own keywords and functionality to XAML with Custom Markup Extensions

WPF is highly customizable and flexible. Also what makes WPF even better is XAML, the markup based declaration language, which is often associated to WPF but not limited to it. I am pretty sure whoever is reading this post have already wrote few XAML based UI and many of the readers have created a full blown WPF application. We use many XAML extensions in our day to day applications. All of these extensions derive from the System.Windows.Markup.MarkupExtension class. We use extensions like StaticResource, DynamicResource etc in everyday Xaml.

The curly braces “{ }” notation tells the XAML processor that it has encountered an extension and the Xaml processor responds accordingly by evaluating the text inside the curly braces. Here is an example on how extensions are used.

<Window.Resources>
  <SolidColorBrush x:Key="mybackground" Color="#FF8080C8"/>
</Window.Resources>    
<Rectangle Height="84" Name="rect1" Width="162" 
Fill="{DynamicResource mybackground}" />

In the above sample we have declared a rectangle element and we taking the fill color dynamically from the ‘mybackgorund’ solid color brush which is defined within the windows resources. By taking approach this we can also use the same brush in other WPF elements.

Markup Extensions

MarkupExtension is the base class for any Xaml extension. Just like .NET attributes which ends the name with the word ‘Attribute’, the markup extensions end the class name with the word ‘Extension’. They should be used in Xaml syntax without the appended word ‘Extension’ just like attributes.

Extensions
The above diagram shows how extensions are inherited and how those classes are used with curly brace (“{ }” ) markups.

Custom Markup Extensions

XAML cannot do everything, and in any good application we need to write code. However if there are some code that are repetitive and we want to declare those code in XAML markup we can write our own markup extensions.  In order to do so we need to inherit from the abstract class System.Windows.Markup.MarkupExtension and implement the abstract method ‘ProvideValue’. See the signature of the provide value method below ...

public object ProvideValue(IServiceProvider serviceProvider)

Then we need to reference our namespace in Xaml and use the extension.

Relative Color Markup Extension : A Custom Extension example

There are many cares where we need to have a relatively lighter or darker color of a certain color. For example if we are designing a button and when the mouse moves over the button we want a lighter shade of the normal color of the button and when mouse is down we want a darker color. In order to do these things in XAML we would have to write triggers and 3 different colors. Lets assume we start with color blue and define blue, a lighter shade of blue and a darker shade of blue, then we would be in trouble if we decide to make our button green and have a light green, green and dark green color. We would have to change all 3 colors. Now wouldn’t it be nice if we could define one color and then have darker and lighter shade of it? If we decide to change color then we would have to change the base color only. See the example below

Colro Example

Writing the custom markup extension

Lets name the custom markup extension that we are writing as RelativeColor, so the class name has to be ‘RelativeColorExtension’.

[MarkupExtensionReturnType(typeof(Brush))]
public class RelativeColorExtension : MarkupExtension

Here our class inherits from MarkupExtension and we are explicitly declaring that the return value is a brush. The MarkupExtensionReturnType attribute lets you specify the return type. However this is optional. You might not want to declare that, specially where the return type determined at runtime and can vary.

Before we proceed further lets see and example of just how this extension will be written in Xaml so that we can better explain how we will write the extension.

XamlUser

The Styles

In our custom markup extension we have 3 styles, Lighten, Normal and Darken. We will specify the base color and which style to apply in the Xaml markup. So we define an enum in the custom extension class like this.

public enum MorphStyle
{
    Lighten, Normal, Darken
}

We need to define a property that will store this style

private MorphStyle _style = MorphStyle.Normal;
/// <summary>
/// Which style to render 
/// </summary>
public MorphStyle Style
{
    set { _style = value; }
}

The Reference Color

Since we need to refer to a color in the resource dictionary, we need to have a property for that as well.

private string _baseColorKey = null;
/// <summary>
/// This is the key of the reference color. This should be defined in a
/// dictionary 
/// </summary>
public string BaseColorKey
{
    set { _baseColorKey = value; }
}

In this variable the key (x:key attribute) of the reference color will be stored.

Overriding the ProvideValue

We simply have to override the ProvideValue method first like this.

/// <summary>
/// Overridden method returns the brush based on style and base color reference
/// </summary>
/// <param name="serviceProvider"></param>
/// <returns></returns>
public override object ProvideValue(IServiceProvider serviceProvider)

By the time this method is called the Xaml Processor have already set the two properties from our Xaml declaration ( we will see the Xaml declaration a little later in the post). So we have the resource key of the base color and how to render it. We are going to keep our resources in the Application resource file and load from there.

// Check if the key is valid
if (!string.IsNullOrEmpty(_baseColorKey))
{
    object obj = Application.Current.FindResource (_baseColorKey);
    if (obj != null)
    {
        coreColor = (Color)obj;
    }

Deciding based on the style

Since we have found the referenced color, we can create a lighter or a darker version of it. (Disclaimer: The code we used to get darker or lighter version of a color in the static methods DarkenColor and BrightenColor are very simple and basic and may be a very simple and lame implementation. This was done in order to keep the irrelevant code simple so that we can easily transfer the idea of custom markup extension to the reader). Since the style property of the extension was filled by the Xaml Processor we can act on their values. See code

// Lets return a solid color brush 
if (this._style == MorphStyle.Lighten )
{
    return new SolidColorBrush(BrightenColor(coreColor));
}
else if (this._style == MorphStyle.Normal)
{
    return new SolidColorBrush ( CopyColor (coreColor));
}
else
{
    return new SolidColorBrush(DarkenColor(coreColor));
}

Using our extension in Xaml code

Xaml is not a WPF specific markup language, but it is most widely used in WPF and silverlight. In WFP Xaml files start element you will find code that look like this ...

xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

Then we use x:Key and other “x” based namespaces because the it is generally imported under ‘x’ namespace . We have build our custom extension in a dll and we need to import that as a name space to our code.

Custom Namespaces in Xaml

In order to use classes from another dll in Xaml we will need to introduce a custom namespace. The format for defining a custom namespace looks like this

xmlns:namespace="clr-namespace:namespace;assembly=assemblyname"

In our case both the assembly name and the namespace is ‘MyXamlExtensions’ and the namespace that we will use is ‘ce’ which is a short for custom extension. So the entry for our custom extension will look like this in the root element of the Xaml document.

xmlns:ce="clr-namespace:MyXamlExtensions;assmebly=MyXamlExtensions"

We are going to import the namespace in the application resource file and define a style for a rectangle object

<Color x:Key="MyBackColor" R="#80" G="#80" B="#C8" A="#FF" />
<Style x:Key="ActiveRectangle" TargetType="{x:Type Rectangle}" >
  <Style.Triggers>
    <Trigger Property="IsMouseOver" Value="True">
      <Setter Property="Fill" 
         Value="{ce:RelativeColor BaseColorKey=MyBackColor,Style=Lighten}"/>
    </Trigger>
    <Trigger Property="IsMouseOver" Value="False">
      <Setter Property="Fill" 
         Value="{ce:RelativeColor BaseColorKey=MyBackColor,Style=Normal}"/>
    </Trigger>
  </Style.Triggers>
</Style>

You can see in the above example that  we are referencing the ‘MyBackColor’ as a reference and using our markup extension without the word ‘Extension’ at the end and we are also setting the BaseColorKey and Style property. We have defined the style in a way so that a lighter shade of the color is assigned to the rectangle when mouse is over the rectangle at other time the normal shade is used. Also please notice that the properties are defined in the extension with comma separation. Now we will set the style to rectangle like this.

<Rectangle Height="93" Name="rectangle1" Stroke="Black" 
    Width="243" Style="{DynamicResource ActiveRectangle}" >

If we want to change the mouse over and normal colors we could just change the base color defined at ‘MyBackColor’.

Now that we have created an extension we can use it anywhere. We can write our common tasks in code and make them into extensions and re-use them in different Xaml markups.

Sample source code

You can download the custom markup extension code from from here. Have fun and let me know what extension did you make.

kick it on DotNetKicks.com

September 07, 2008

Make Google Chrome Take Less Memory

Earlier I wrote how chrome is taking huge amount of memory because it is running one process for each tab (http://www.shafqatahmed.com/2008/09/google-chrome-i.html). It seems that Chrome supports other process models as well. Here are the process models for Chrome browser

1. Process Per Tab (default model)

2. Process Per Site: One process per website. For example a user with two tabs opened at Gmail and another opened at facebook will have the two google tabs running in the same process. (default model)

3. Single Process ( walla! this is what I was looking for)

All this was cleared by blogger Marc Chung at his post Chrome's Process Model Explained. Right now I am running Chrome in a single process.

At the chrome shortcut pass the appropriate command like option to control Chrome’s behavior.

--process-per-site
--process-per-tab
--single-process

Here is how you edit the shortcut to run with different process model. Open up the properties tab of the Chrome browser short cut and edit it like the image below

single

So here I have 3 shortcuts to Chrome in my desktop. See the picture below

2008-09-07_1920

So now I can run chrome anyway I want. Chrome has become my second browser of choice after Opera. Chrome will occupy less memory now.

Feeds

Pages