ThomThom's Website

MSN scripting in DesktopX with events

26 Aug 07 - 13:00

While I was looking through the Yahoo! Widget manual I came across an interesting piece of code snippet demonstrating how to connect to COM objects. The code snippet showed how to connect to MSN and access methods and events.

I tried the script in DesktopX with some adaptation and managed to get access to the methods. However, there was no way of handling the events from COM objects in DesktopX.

While I was doing this I was rambling about it on #stardock. And fortunately for me, Julien was there. He had the idea of using a Script Component.

The script component was able to connect to the MSN COM object and receive the events. Now I could connect to the script component and make it act as a proxy to the MSN object and receive the events.

I build a little DesktopX package that demonstrate how to interact with the MSN automation object.

Connect to MSN object

To begin a MSN project you need to add the file MSN.wsc as a custom file to one of your objects. Then you can refer to it via the script as such:


var MSN;
MSN = GetObject('script:' + Object.Directory + 'MSN.wsc');

Dim MSN
Set MSN = GetObject("script:" & Object.Directory & "MSN.wsc")

The DesktopX package example I made demonstrate how to get a list the contacts in your contact list in VBScript and JScript.

Events

In order to receive events from the MSN objects you need to register the functions you can't to be executed whenever an event is triggered.


var MSN;
MSN = GetObject('script:' + Object.Directory + 'MSN.wsc');
MSN.OnContactStatusChange = hello_world;

function hello_world(contact, status)
{
  // contact is the contact that changed status
  // status is the new status code of the contact
  Script.MsgBox(contact.FriendlyName);
}

Dim MSN
Set MSN = GetObject("script:" & Object.Directory & "MSN.wsc")
Set MSN.OnContactStatusChange = GetRef("hello_world")

Function hello_world(contact, status)
  ' contact is the contact that changed status
  ' status is the new status code of the contact
  Script.MsgBox(contact.FriendlyName)
End Function

This is a list of the events you can use:

  • OnAppShutdown
  • OnContactAddedToGroup
  • OnContactBlockChange
  • OnContactFriendlyNameChange
  • OnContactListAdd
  • OnContactListRemove
  • OnContactPagerChange
  • OnContactPhoneChange
  • OnContactRemovedFromGroup
  • OnContactStatusChange
  • OnGroupAdded
  • OnGroupNameChanged
  • OnGroupRemoved
  • OnIMWindowContactAdded
  • OnIMWindowContactRemoved
  • OnIMWindowCreated
  • OnIMWindowDestroyed
  • OnMyPropertyChange
  • OnMyStatusChange
  • OnSignin
  • OnSignout
  • OnUnreadEmailChange

Methods

At the moment, the only way to get access to the events and methods is by using the getMSNObject function. This means you'll have two objects related to MSN. I plan to make a new release which merges the two into one object. Check this page for updates.


var MSN, MSNobj;
MSN = GetObject('script:' + Object.Directory + 'MSN.wsc'); // Events
Set MSNobj = MSN.getMSNObject(); // Access to methods via MSNobj

Dim MSN, MSNobj
Set MSN = GetObject("script:" & Object.Directory & "MSN.wsc") ' Events
Set MSNobj = MSN.getMSNObject() ' Access to methods via MSNobj

Bring on the gadgets!

I hope that this will allow people to start making gadgets interacting with MSN. It could be simple contact lists residing on the desktop. Or even on the Vista Sidebar now that DesktopX 3.5 allows you to export to Sidebar gadgets. You could incorporate MSN into an address book. Or make a gadget where each user floats in your desktop like icons, displaying their status.

IE ate my linebreaks!

14 Aug 07 - 14:36

I was working on a syntax highlighter to use on my code elements on my website. The script is quite simple; it finds all <code> elements that is contained inside a <pre> element and uses the class attribute of the <code> element to determine what code language it is. I used innerHTML to extract the content of the <code> element. (Yes, I know, innerHTML shouldn't be used with XHTML as it will break if it's served as XML, but that's a whole other topic, and to my defence I've been contemplating switching back to HTML.)

Everything was fine when I tested it in Firefox, but... (You have heard this so many time...) ...in IE, some of my linebreaks was missing. When I sent the string I got from innerHTML I noticed that some, not all, of the linebreaks was missing. I even ran a loop on the string and printed all the character codes, but there was nothing. IE had simply eaten the linebreaks and partially normalized the text even though it was inside a <pre> element.

The hero of the day was the almighty DOM which even IE didn't dare stealing from. When I accessed the text node inside the <code> element I got all the linebreaks. So instead of .innerHTML I used .childNodes[0].nodeValue. It should be noted that this isn't an ideal substitute, as it will not return all the text if it's split up into several text nodes, caused by elements of other DOM nodes. But it's not hard writing a little function to extract all the text nodes and compile them into one string. The important bit is that IE doesn't normalize the string returned and returns all the whitespace as it should.

.split() misbehaviour

Another part of the code I ran into trouble with was when I was splitting each line into an array of strings, which I then used to parse through each item in the array and compile a numbered list so I would get line numbers next to each line of the codeblock.

I had used .split(/\n\r|\r\n|\r|\n/g); to return an array of each line of code, which again worked fine in Firefox and Opera, but not in IE. If there was an empty line IE would simply eat it. So a codeblock of 5 lines, whereas 1 was an empty line, IE would return and array of four.

The solution was to normalize all linebreaks into \n and then split the text. For one reason or another, IE then returned all the lines, even the empty ones.


// === THIS DOES NOT WORK AS EXPECTED IN IE === //
// Split each line into an array;
this.lines = this.codeText.split(/\n\r|\r\n|\r\n/g);

// === THIS WORKS IN IE === //
// Convert all linebreaks to \n
this.codeText = this.codeText.replace(/\n\r|\r\n|\r/g, '\n');
// Split each line into an array;
this.lines = this.codeText.split('\n');

So finally I had a syntax highlighter that works in Firefox 2, IE7 and Opera 9. I've yet to test it in other browers as I'm still working on it. The script is located here. It's still a bit rough and needs some work and commenting.

Hopefully this will be useful to someone. I didn't find much information myself when I had a look on Google.

DesktopX - Bugs, issues and feature requests

06 Aug 07 - 09:17

I've compiled a list of bugs and issues I've come across with DesktopX. Additionally I've added a list of features I'd like to see. I'll be updating this list as I discover new bugs or issues, or they get fixed.

Apparently there will be a wiki section up at the Wincustomize Wiki soon. I'll contribute to the list once it comes online.

Last updated: 16 September 2007

Index

Bugs

  1. NULL character in Object_OnDropFiles
  2. Missing events in javascript
  3. Object Lister Columns
  4. MsgBox arguments
  5. Code insight misplaces on second monitor
  6. Can not set forms' button caption

Issues

  1. Cloning related objects with Widget property
  2. Linebreaks in Edit Controls
  3. Javascript Syntax Highlighting
  4. Old File Dialog
  5. It's Script.MsgBox, not DesktopX.MsgBox
  6. System.SimpleRead returns junk on error
  7. Undocumented Script namespace
  8. Opacity doesn't affect child objects
  9. Can not set filedialog filter in forms.

Feature Requests

  1. HTTP Headers
  2. Quick Code Insert
  3. Function List
  4. Treeview Object List
  5. Get Text Size
  6. GIF support
  7. Default Scripting Language
  8. Colour Picker Dialog
  9. Debug Console
  10. HSL Colour Control
  11. Disable Objects
  12. Quickfind Objects

Bugs

NULL character in Object_OnDropFiles
Fixed in 3.49e[b].014. The Object_OnDropFiles function will return a string with a NULL character at the end of the list of strings. If you try to output this string to a DX text object any text after the NULL character will not be rendered. Example, if you drop some files (for instance foo.file and bar.file) onto an object with the following script:

function Object_OnDropFiles(files)
{
  DesktopX.Object('lblStatus').Text = files.charCodeAt(files.length-1) + ' start ' + files + ' end';
}
This will return: start + foo.file|bar.file as oppose to the expected start + foo.file|bar.file end. Until a fix for this is made it's recommended that in your code you check for the NULL character at the end of the string is trim it if it should be present.
Missing events in javascript
When you use Javascript the Object_OnSetFocus() and Object_OnKillFocus() events does not trigger. It works fine when using VBScript.
Object Lister Columns
Fixed in 3.49e[b].014. In DesktopX 3.5 beta the columns in the Object Lister doesn't save the order of the columns.
MsgBox arguments
MsgBox is suppose to be able to take up to four arguments, letting you define the icon, buttons and title. However, if you use more than one argument the function throws an error.

// This works - Simple message box text
Script.MsgBox('message');

// This throws an error - Messagebox with stop icon and title text
Script.MsgBox('message', 16 'title');
Code insight misplaces on second monitor
When the script editor is used on a monitor other than the primary, the code insigh drop down list appears on the edge on the primary monitor.
Can not set forms' button caption
DesktopX throws an error when you try to set the caption of forms' Ok and Cancel button using Form.OkButton and Form.CancelButton.

var frm = DesktopX.CreateForm;
frm.Caption = 'Choose a Colour';
frm.OkButton = 'foo';     // <-- this throws an error
frm.CancelButton = 'bar'; // <-- as do this

Issues

Cloning related objects with Widget property
When an object, which has a widget name defined, is cloned; and you choose to clone its child and group objects, all the objects with the same widget name is cloned. Though the same widget group might be considered being related its something that can cause problems if you have imported a widget into your existing project as the widget name is then generally applied to all the newly imported objects. Maybe it's a feature and the widget group is regarded as being related, but I'd prefer if it didn't.
Linebreaks in Edit Controls
To add linebreaks in the DX edit control when using Javascript you have to use nr. Any other combination of the line break characters does not result in anything. The standard DX text object however accepts nr, rn, n and n as linebreaks.
Javascript Syntax Highlighting
The syntax highlighting in the script editor when using Javascript does not highlight many important keywords rendering the code harder to read. The syntax highlighting doesn't seem to account for regular expressions. For instance the following code example will mess up the highlighting: var regex = /<link rel="pingback" href="([^"]+)" ?/?>/g;
Old File Dialog
When selecting custom files to be added to an object you're presented with an old style file dialog which doesn't cope well with files that's not following the 8-3 naming scheme.
It's Script.MsgBox, not DesktopX.MsgBox
The DX manual states that you use DesktopX.MsgBox to call the prompt dialog, but that's incorrect. It's Script.MsgBox.
System.SimpleRead returns junk on error
If System.SimpleRead is told to read a non existing file it will not return an error, but instead random characters of junk. Be adviced to check manually for the existance of files for error recovery.
Undocumented Script namespace
When you use the DesktopX script editor and type Script. the code insight pops up a menu displaying the following commands; InputBox, InputBoxEx, MsgBox, MsgBoxEx, MsgDbg. None of these commands are explained anywhere in the documentation.
Opacity doesn't affect child objects
Setting the opacity doesn't affect child objects, they retain they full opacity. I had expected it to apply the same opacity to all child objects at's set to be tru children. If an object only has the parent attribute set, but child attribute to false, I wouldn't expect it to inherit the opacity.
Can not set filedialog filter in forms.
There's not way to spesify the file dialog's filter when using forms or widget preferences.

Feature Requests

HTTP Headers
Being able to set headers for the System.SendRequest function. In order to for instance set the user-agent header as certain sites will return 403 unless you provide an acceptible user-agent string. Something many sites use to fight spambots.
Quick Code Insert
A dropdownbox in the script editor that contains a list of availible functions for the Object, DesktopX, Widget and System namespace. The user can then choose a function from the list and the editor will then insert necessary framework for that function. This list being saved in a textfile would be nice so it could be customized.
Function List
A dropdownbox in the script editor that contains a list of all the functions in the script. This would make navigation easier when scripts begin to grow in length.
Treeview Object List
Have a treeview in the Object List so that you can contract/expand the tree of objects. Useful when the list of objects grow. Then it's nice to be able to hide the children of objects you are not working on.
Get Text Size
Be able to retrieve the width and height of a string based on the font settings of the current object. For instance: Object.TextWidth("fooBar"). Example usage: be able to create a pure DX textbox object that uses variable width font.
GIF support
Being able to load GIF files. (being able to load animated GIFs would be a plus)
Default Scripting Language
As people might prefer Javascript as oppose to VBScript it'd be nice to set the default language for when you create new scripts.
Colour Picker Dialog
In addition to the file dialog it'd be nice to have access to the colour picker dialog.
Debug Console
A debug console where you could print debug data into would be of great help. I.e.: Console.Print(foo, bar); Allows the developer to use MsgBoxes and custom text objects as debug output.
HSL Colour Control
Being able to set all respective HSL values would be nice. Currently Hue and Lightness is supported, but not Saturation.
Disable Objects
Being able to disable object preventing events to do not trigger.
Quickfind Objects
It'd be nice if there was a textbox where you could enter parts of an object name and it'd filter out the objects listed to only those that match. It'd make it alot easier to manage many objects.

New Host

04 Aug 07 - 02:41

I've just switched to a new host. One that supports PHP5 and goes by the amount of bandwidth used, not pagehits.

I was closing in on my limit of pagehits due to my gadgets I made that checks in with a file on my server to check for software updates. This caused many pagehits without using hardly any bandwidth.

I also wanted to migrate to PHP5 as PHP4 has reached its end of life. Hopefully everything is back online.