Hello There, Guest! (LoginRegister)

Skinning Documentation

Introduction to Skinning
Getting Started
What's a Skin in Messenger Plus! ?
How Does it Work?
Integration with Messenger
Your First Skin
Skins Essentials
Windows Definitions and Styles
The Trace File
Using Pictures
Packaging Your Skin
Specialized Subjects
Restrictions: How and Why?
Reshaping Your Windows
User Modifiable Options
Options for Advanced Users
Skinning Plus! Itself
XML Schemas Reference
SkinInfo Files
SkinInfo Information
SkinInfo Diagram
Schema Documentation
Messenger Plus! Interfaces
Interfaces Information
Schema Documentation

Windows Definitions and Styles

To create and display its window, Messenger uses two different kind of files: definition files and style sheet files. Although each file is used for its own specific reasons, some of the properties of a window can be defined in both files by using a different syntax. Here is a quick description of the purpose of each file.

  • Definition File. This is the main file defining a window, it describes how the window is created and what elements/controls it contains. It is formatted like an XML file (although it will not validate against strict XML syntax) with element tags and attributes. Many elements include sub-elements to create more complex layouts. An id/class is attached to most elements to be used in the style file.
  • Style Sheet File. This file needs to be paired with a definition file to be meaningful. When an element is declared in the definition file, many of its attributes can be placed in the style sheet file. This creates a separation between the bones of the window and its actual look. Style files work and look like CSS files for web pages.

Note that this section of the documentation is only meant to introduce you to the windowing system of Messenger. It is not meant to completely document the way definition and style files are created for Messenger. Microsoft uses an internal library called DirectUI for its windows. This library is several years old and has never been documented for public use by Microsoft so you'll need patience and determination to make the best out of what you have. Once you get used to the basics of the system, you'll see that it's not that difficult to make Messenger display what you want: you don't need to understand everything, just look at the windows displayed by Messenger, look at their definition files and figure out how to make changes by trial and error.

Elements Definition

Let's start with how attributes are defined for the various elements of a window. Elements are often simply named element but can be called anything else such as button, urlelem, etc... character case does not matter as long as you close the element with the exact same name. Example:

  • <element></element> is valid,
  • <Element></Element> is also valid but
  • <element></Element> is not.

The syntax for sub-elements is identical to XML: each element needs a matching closing element but can also be closed with an ending slash if no sub-elements are needed. To demonstrate this, here are two identical examples:

  • <element id=atom(ai1)></element> allows to include sub-elements
  • <element id=atom(ai1) /> is closed and cannot contain sub-elements.

In the example above, id is an attribute and atom(ai1) is the value of the attribute. Once again, this works like in XML except that values are not enclosed in quotes if they don't refer to strings. The list of attributes available for each element depends on the element's kind, however, you'll find two attributes with a basic general use: id and class. Case does not matter here either so id can also be written Id or ID. These two attributes are used to match elements with their respective styles and to help Messenger identify which is which. The value of these attributes will often be a strong hint of what the element is about. Examples:

<element class="WindowLogo" ID=Atom(ai198)/>
<element id=atom(idSearchTextBackground) padding=rect(4,0,3,0) Height=0/>

In the first element, both a class and an ID are specified. Hopefully in this case, the class name is enough to understand that the element is about displaying the logo of the window. However, many other elements use numeric ids that are meaningless on their own. In such a case, you'll need to check the style file to find more information about the element.

Elements Styles

Style sheet files are organized with simple structures: for each element listed in the file, one or more attribute is specified. Attributes generally apply to specific elements based on their id and/or class and can also depend on some other attributes or internal states. Let's take a look at this example:

button[id=atom(accountStatusbtn)]
{
    AccDefAction:"Press";
    ShortcutString:"Account &information";
}

Each block of style is defined the same way: the first line identifies the condition for the style to be applied and the following attributes are placed between { } brackets. The first word of the first line is the element's name. In this case, the element's name is button meaning that this style will apply to elements defined as <button> in the definition file. Following the element's name is 0, 1 or more condition, each one specified between [ ]. The conditions can be two things:

  • An attribute value. This is what you'll see the most in style sheet files. Attributes specified as condition will often be id or class but can also be anything else recognized by the element. Attribute conditions are written using the [name=value] syntax.
  • An internal state. Internal states give real purpose to the style sheet files by allowing attributes to vary depending on the state of an element. States are indicated on their own without an attached value and their meaning is often straightforward. For example, [pressed] specifies that the attributes should be applied when the element is pressed (generally by clicking on it).

In the example above, one attribute value condition is specified as id=atom(accountStatusbtn). This means that the attributes specified between brackets will be applied to any element defined as <button id=atom(accountStatusbtn) ...>. Because this is the most important part of style files to understand, let's analyze two other examples:

button[class="WebcamStatusBtn"][enabled=false]
{
    alpha:128;
}
wledit[id=atom(WindowEmail)][keyfocused]
{
    contentalign:middleleft;
}

Can you guess what elements are touched by these styles before reading the answer? :-)

The first example has two conditions based on an attribute value. This simply means that for the style to be applied, a button element must be defined with class="WebcamStatusBtn" and be disabled. Note that attributes such as enabled can be changed at runtime by Messenger. This means that any element defined as <button class="WebcamStatusBtn" ...> can be touched by this style if Messenger disables the element after its creation. Of course, any element defined as <button class="WebcamStatusBtn" enabled=false ...> would use this style by default. Also, remember that attributes can be specified in any order so <button ... enabled=false ... class="WebcamStatusBtn"> would also receive this style.

The second example uses an internal state condition. This means that any <wledit id=atom(WindowEmail)> element that's considered being keyfocused will use this style. This kind of condition is useful to allow elements to change on their own following an action from the user. For example, buttons often use the pressed condition to look different when pressed or keyfocused to display a hint indicating that a control is currently active (if a keyboard is used instead of a mouse to select the control).

Styles in Definition Files

Because styles are just groups of attributes, every attribute that's specified in a style sheet file can also be specified directly in the definition file. Let's consider the following example of a style block and a matching definition:

button[id=atom(accountStatusbtn)]
{
    AccDefAction:"Press";
    ShortcutString:"Account information";
}
<button class="HIGToolbarButton" id=atom(accountStatusbtn) cmdid=692>

The style can be merged in the definition file simply by replacing : with = to create compatible attribute syntax.

<button class="HIGToolbarButton" id=atom(accountStatusbtn) cmdid=692
 AccDefAction="Press" ShortcutString="Account information">

If this line was used in the definition file and the style was removed from the style sheet file, the end result would still be the same. Styles are just that: extra attributes added to each element. One of the main reasons why you can't simply get rid of style files altogether is the use of internal state conditions. These conditions cannot be expressed in a definition file. This means that you need a style file to declare different attributes for different states as mentioned above with the wledit example. Also, because styles can be combined, it is sometimes practical to set some general conditions in the style sheet file. For instance:

button[enabled=false]
{
    foreground:rgb(193,193,193);
}

This would be useful to specify that any button (no id or class was specified) that's disabled uses a different foreground color defined as foreground=rgb(193,193,193). To specify a color that's based on the user's chosen color (which is blue by default), you'll need to check out the <Colors> elements in SkinInfo as colorized colors cannot be specified as data in Style Sheet files (these colors use a single Intensity attribute which modifies the brightness of the original RGB).

What's next?

To practice is to learn so if modifying the heart of Messenger windows is a subject that interests you, practice, practice, and practice again. The contact list's logon frame is a good starting point to experiment. Edit its files to reorganize elements and change some of the styles it uses. This window is not that complicated to decipher and it's the first one you see when starting Messenger (testing requires a lot of restarting so you won't want to spend too much time signing back-in if all you want to do is test some general ideas). Also, before jumping to any other section of this documentation, make sure to read about the trace file, it will save you a lot of time when things don't go as planned after editing one of Messenger's files.

Remember that when modifying definition files, it is always better not to remove whole elements from the original file. If you want to visually remove an element from a window, add a "visible=false" or "height=0" attribute. This way, Messenger will still be able to locate the element but it won't appear on screen. This is important to prevent internal problems and crashes. In cases where removing an element is inevitable, make sure to double your tests.

Replacing definition files and style files in your skininfo file is achieved by adding <Definition> and <Style> elements. Text files must be encoded in ANSI as Messenger does not support Unicode in this case. Also, instead of using text files, definition and style data can be embedded directly into skininfo by using the <Data> element (this not recommended if you want to keep things easy to maintain). Here is an example showing how to replace the files of the contact picker window (ids taken from Messenger 8.5) :

<Resources><Replace>
    <Windows>
        <Definitions>
            <Definition Id="45703">
                <File>contactpicker_newdef.txt</File>
            </Definition>
        </Definitions>

        <Styles>
            <Style Id="45703">
                <File>contactpicker_newstyle.txt</File>
            </Style>
        </Styles>
    </Windows>
</Replace></Resources>

One thing you'll need to learn to create good looking windows is the way to manipulate pictures in your files. This big subject is waiting for you in Using Pictures but remember to practice what you learnt here first!

See Also

Skins Essentials, The Trace File, Using Pictures.