|
Windows for your Script
Depending on what your script is doing, user input may be
required at some point. For that reason, a very special feature was
added to the Messenger Plus! Live scripting system called Interface
Windows. If you take a look at the various windows of Messenger
Plus! Live itself, you'll notice that they tend to blend nicely
into Windows Live Messenger, have similar looking controls, use the
same background color etc... a brand new User Interface system was
created during the conception of Messenger Plus! Live to achieve
what you can see in the software, one that's not based on resource
files but specially crafted XML files.
The user interface system mentioned above can be accessed
through scripting so your scripts can painlessly benefit from the
whole interface engine. However, to use the system, you will need
to get used to the way XML interface files are constructed and this
may require a little bit of time. Interface files are not
particularly complicated to understand, however, they contain a lot
of different kinds of elements and attributes, some of them may not
even be of any use to your scripts. The end result will be worth
the trouble though as you won't need to create external DLLs to
display your windows and you'll benefit from the current look of
Windows Live Messenger as well as possible future updates. Your
script will be guaranteed to appear just like any other Messenger
Plus! window.
Interface Windows are created and displayed with a single call
to MsgPlus.CreateWnd. The
only parameters required for this function to succeed are the name
of your XML interface file and the identifier of the window you
want to create (each interface file can define more than one
window). To demonstrate the feature, here is the XML definition of
a simple window displaying "Hello World!". For now, don't try to
understand the content of the text, just copy paste it to a plain
text file called "InterfaceTest.xml" and save it in your script's
directory.
<Interfaces xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<Window Id="WndTest" Version="1">
<Attributes>
<Caption>Test Window</Caption>
</Attributes>
<TitleBar>
<Title><Text>Hello!</Text></Title>
</TitleBar>
<Position ClientWidth="170" ClientHeight="45"/>
<DialogTmpl/>
<Controls>
<Control xsi:type="StaticControl" Id="LblTop">
<Position Left="10" Top="10" Width="150"/>
<Caption>Hello world!</Caption>
</Control>
<Control xsi:type="ButtonControl" Id="BtnClose">
<Position Left="115" Top="25" Width="50"/>
<Caption>Close</Caption>
</Control>
</Controls>
</Window>
</Interfaces>
Now, create a new script called "Window Test" and replace the
Initialize event by the following code:
function OnEvent_Initialize(MessengerStart)
{
var Wnd = MsgPlus.CreateWnd("InterfaceTest.xml", "WndTest");
}
Save the script. If you did alright, you'll see a window titled
"Test Window" in your task bar (it may have been displayed below
the script editor). This window's title show "Window Test -
Hello!", with a "Hello world!" message and a "Close" button. Note
that because every window created by Messenger Plus! is modeless,
your script continues to run as soon as the window gets created.
Now let's take a closer look to the XML file.
First, a <Window> element is
declared with two attributes: Id (used
in your call to MsgPlus.CreateWnd to identify which window
to show) and Version (just set it to
"1" for now, this parameter will be used by future versions of
Messenger Plus!). Inside the <Window> element are a couple of interesting
sub elements:
- <Attributes>. You'll often
see this element in various other places. In a <Window> element it is used to define
optional attributes for the window such as <Caption> (which is the caption of the
window displayed in the task bar), <TopMost> (to make the window appear above
every other), ...
- <TitleBar>. Most Messenger
Plus! windows display a title bar baring a Messenger Plus! logo,
the name of the window and system buttons to minimize, maximum or
close the window. Everything related to the title bar is defined in
this element. If not specified otherwise, the name of the script
will automatically be inserted in the title.
- <Position>. Used to define
the default width and height of the client area, this element can
also be used to specify that the window can be resized. You may
want to notice that the size is specified in Dialog Units, not
Pixels. Every positions and sizes defined in interface files uses
Dialog Units by default which allows the windows to adapt on
various dpi settings (if this does not make any sense to you,
forget about it).
- <DialogTmpl>. This empty
element is very important as it defines one of possible three
choices for each window: dialog, window or child window. Most of
your windows will probably be based on the dialog template which
defines a double border and allows different kinds of extra
settings such as a bottom bar.
- <Controls>. This is where
you'll define all the controls displayed in the window like static
controls (text labels), buttons, checkboxes, lists, ...
Let's take a look at the controls defined in this window:
- Each control has the same basic structure. A control is always
defined with a <Control> element
and two mandatory attributes: xsi:type
and Id. xsi::type specifies the kind of control that's
being defined, like a a static control or a button. Id is the unique identifier of the control in the
window. No control can have the same Id in a given window or the creation of the window
will fail (remember that as it can easily be the cause of
copy/paste frustrations). The Id can
be anything you want but cannot contain any space character.
Although it is considered to be a good practice to prefix your
identifiers with the kind of control you're defining (like "Btn"
for buttons), it is not mandatory.
- Next comes <Position>. This
element is required for any kind of control. The Left and Top
attributes are always mandatory, Width
is generally required too, however, Height can be optional for controls that don't
need it. For example, in the case of a single line static control
and a button, the Height parameter is
automatically computed by Messenger Plus! to prevent
inconsistencies through out the windows. You can always specify
your own value though.
- Elements that come after <Position> are generally type dependant,
meaning that each kind of control has its own set of possible
elements and attributes. Here, we see <Caption> being used in both controls,
however, we could also have used <BackgroundColor> for the static control and
<Image> for the button which are
elements reserved for each type of control respectively.
Now, you may be wondering "how am I supposed to know and
remember all these elements and attributes names?"... the good news
is that you don't have to, as long as you're using a good XML
editor such as XMLSpy from
Altova. Every XML file can be paired with its corresponding
schema file which defines every possible element and attribute that
can be inserted in the XML. Schema files also come with various
comments to help you understand the purpose of some elements and
attributes, when deemed necessary. In the case of XMLSpy, the
editor also provides contextual help so you'll get lists of choices
while you type your XML. These are all good reasons NOT to code
your windows inside notepad so please, do yourself a favor and use
a specialized XML editor to do the job :). The Interface Windows
schema file and its documentation can be found in the schema reference section of this
documentation.
Of course, the windows would be useless if you had no way to
hear back from them. A special set of events was created for that
occasion prefixed "OnWindowidEvent_". Notice how "WindowId"
is written in italic: to avoid mixing the events coming from
different windows, Messenger Plus! fires events named after the
corresponding window's Id. In the case of our test window, all
events will be prefixed "OnWndTestEvent_". A list of available
events can be found in the events'
reference but let's test this simply with a common purpose
event: "CtrlClicked". This event is fired every time a control such
as a button is clicked. You may already have noticed that clicking
on "Close" in the test window currently does nothing, that's
because the current code does not catch the "clicked" event for the
button. Let's fix this by adding the following function at the end
of the script:
function OnWndTestEvent_CtrlClicked(Wnd, ControlId)
{
if(ControlId == "BtnClose")
Wnd.Close(1);
}
The first parameter of the event is a PlusWnd object (the object representing your
window) and the second one is the Id of the control that fired the
clicked event. The function above checks if the event comes from
the "Close" button (which has an Id equal to "BtnClose") and if so,
calls the Close function of the
PlusWnd object. The numeric parameter sent in Close
is of no consequence and is just passed to the Destroyed event in case you would
want to handle different types of close scenarios.
You can now experiment working with different kinds of controls
and calling various functions from the PlusWnd object. A lot
of possibilities are offered by this system and it is now up to you
to discover them. Because this subject is an important and complex
one, you should not hesitate to seek help in the official
Messenger Plus!
forum. Remember to spend time in the Interface Windows Reference too and
practice! And finally, a special tool is also available to help you
test your windows out of the Messenger environment, for more
information, check out Testing your
Windows.
See Also
Testing your Windows,
Interface Windows Reference,
PlusWnd Object, Interface Windows Events Reference.
|