AIM 7.0 Beta 2 Now With AIM Lifestream

July 6th, 2009

AOL released the second beta of AIM 7.0 for Windows today. This build has a lot of changes since the first beta. While some are very noticeable like the new color/theme chooser and the Lifestream and Me tabs, others might not be so noticeable like the total footprint on disk was reduced by 3MB between the two betas. AIM 7 now installs in under under 15MB of disk space. By comparison (chosen totally at random), Digsby takes up 67.7MB on my PC.

Here is my Buddy List using the new “Grass” theme:

AIM Buddy List with Grass theme

There are a lot of cool and very new things to try out in this beta. AOL needs your help. If you find any issues or have some suggestions, be sure to click on the “Beta Feedback” link and leave a comment. The IM window has a handy “Beta Feedback” link at the top as shown here:

AIM Beta Feedback

Clicking on that link will open a browser window where you can leave your comments. Here is a screen shot of me leaving some feedback.

Sample AIM Beta Feedback

Remember, like saved away messages, you have to ask for the features you want in order to give them the attention you believe they deserve. Just make sure you ask for something you really want. Please comment early and often. The more details the better.

If you have not tried the first beta, be sure to try this one today.

Could it be the fastest AIM client yet?

AIM 6.9 for Windows

May 1st, 2009

AIM 6.9 Running Man Buddy IconBy now I am sure you have heard about the new AIM 6.9 client that was announced by AOL this week.

Don’t let the minor version number fool you. These days, any version number higher than the previous one can signify an important update. AIM 6.9 is much improved over AIM 6.8, it is still FREE, and best of all, AOL has officially brought back the Running Man!

You can read more about this client on the AIM website and in some of my fellow teammate’s blog posts. There are also plenty of folks tweeting about it too.

I have been using this client throughout the betas and can confirm that all of my plugins work with AIM 6.9 as long as you update to their latest versions.

Try it today.

As a bonus tip, here is a quick way to switch your current buddy icon to the new Running Man (pictured above):

Click Here to Get the New Running Man Buddy Icon

Enjoy.

CoreWitness 1.3.0

March 9th, 2009

CoreWitness Plug-inI just released an update to my CoreWitness plugin. This minor release adds the showing of the current preference value in the OnPreferenceChanged and OnPreferenceInvalid events. Here is a sample trace I get when I toggle all the check boxes in the privacy tab off, click apply, and then check them again and click save:

01:58.754 [gusblog  ] DAccEvents::OnPreferenceChange - 'aimcc.Privacy.DiscloseTypingStatus'
   new value = No
01:58.755 [gusblog  ] DAccEvents::OnPreferenceChange - 'aimcc.privacy.discloseBuddyFeed'
   new value = No
01:58.764 [gusblog  ] DAccEvents::OnPreferenceChange - 'aimcc.Privacy.DiscloseIdleTime'
   new value = No
01:58.777 [gusblog  ] DAccEvents::OnPreferenceChange - 'aimcc.privacy.disclosePluginsToBuddyFeed'
   new value = No
01:58.777 [gusblog  ] DAccEvents::OnPreferenceChange - 'aimcc.Privacy.DiscloseWireless'
   new value = No
02:03.859 [gusblog  ] DAccEvents::OnPreferenceChange - 'aimcc.Privacy.DiscloseTypingStatus'
   new value = Yes
02:03.860 [gusblog  ] DAccEvents::OnPreferenceChange - 'aimcc.privacy.discloseBuddyFeed'
   new value = Yes
02:03.868 [gusblog  ] DAccEvents::OnPreferenceChange - 'aimcc.Privacy.DiscloseIdleTime'
   new value = Yes
02:03.869 [gusblog  ] DAccEvents::OnPreferenceChange - 'aimcc.Privacy.DiscloseWireless'
   new value = Yes
02:03.869 [gusblog  ] DAccEvents::OnPreferenceChange - 'aimcc.privacy.disclosePluginsToBuddyFeed'
   new value = Yes

You can get the latest version here.

Please note that activation of the CoreWitness plugin is now automatic. No registration is needed.

This is a free plugin for Open AIM developers.

Welcoming Gmadkat to the Blogging World

February 22nd, 2009

Gmadkat's Open AIM BlogOpen AIM developers can now enjoy a new resource and blogger covering the Open AIM SDK. Gowri IMed me over the weekend to let me know that she started her own blog, called Gmadkat’s Open AIM Blog. You can follow her posts at the www.gmadkat.com site.

I have known and worked with Gowri for a number of years now. Unfortunately, I just realized that I have never asked her where “madkat” came from. Be sure to check out her blog and let us know what ideas and issues you want answers on about Open AIM. Gowri is actually on the Open AIM team, so she has first-hand knowledge of all the current issues and questions that developers are stuck on. I look forward to her many great posts to come.

Lets all give Gowri a nice warm welcome to the blogging world.

P.S. Thanks for the kudos on my CoreWitness plugin — I enjoy developing it just as much as I enjoy using it. ;)

Checking AIM Capabilities Via JavaScript

February 12th, 2009

Open AIMWith so many different AIM clients out there, how can we tell if a client supports a particular feature? The answer is capabilities. Each screen name has a list of capabilities (GUIDs) that are asserted by the client and plugins.

How can I read these capabilities in the AIM SDK, you might ask? You can see what a user supports via the AccUserProp_Capabilities property and what the client asserts via the AccSessionProp_Capabilities property.

Here is a dump of the capabilities property for one of my screen names as seen by my CoreWitness plugin:

  AccUserProp_Capabilities = Array { ...GUIDs removed from trace here... } 
      {09461345-4C7F-11D1-8222-444553540000} = Direct IM
      {748F2420-6287-11D1-8222-444553540000} = Chat
      {09461343-4C7F-11D1-8222-444553540000} = File Transfer
      {67753137-6A38-6C77-4672-762D49755071} = UUID of a plugin: 'Gus Verdun's Core Test Plug-in (Dev)'
      {09461346-4C7F-11D1-8222-444553540000} = Buddy Icon
      {9FD3969B-84CB-45C1-B5DF-72DF5FAAB98E} = RX-Plugin

The AIM SDK returns an array of GUIDs in string form for those two properties. The CoreWitness plugin will automatically map the GUIDs to friendly names. When it encounters a GUID it does not recognize, it scans to see if the GUID matches that of any plugin you have installed. Yes, you can assert your plugin’s key as a capability if you want too. However, this is not required even thought your plugin’s key is reserved for you. I chose long ago to assert a different GUID as a capability for my RX-Plugin as you can see above. The capability is used to change the behavior of the IMpulse feature when both users have the RX-Plugin installed.

The AIM SDK always returns VB arrays in JavaScript so you must convert them to a JS array by using the toArray() method. Here is one way you can test to see if a buddy supports a particular capability:

// Test to see if buddy (IAccUser) has the RX-Plugin capability asserted
function HasRXPlugin(buddy)
{
    if ( SafeHasCapability(buddy, '{9FD3969B-84CB-45C1-B5DF-72DF5FAAB98E}') )
        alert('yes');
    else
        alert('no');
}
 
// cap must be in upper case.
function SafeHasCapability(user, cap)
{
    try {
        return  user.capabilities.toArray().join('').indexOf(cap) >= 0;
    } catch ( e ) {
        return false;
    }
}

The first function calls the more general function to test if the buddy has the capability asserted by my RX-Plugin.

You can use capabilities in your plugins for anything. They can be used to indicate that something is “on”, “selected”, etc. You can even have more than one—within reason. The AIM Vote ‘08 plugin uses capabilities to indicate your vote for McCain or Obama and then tallies up the number of buddies with either of those capabilities.

AccEx C++ Library R3

February 8th, 2009

AccEx Library for Open AIM DevelopersA new release of the AccEx library is now available. This is a library of functions and classes for C++ based Open AIM clients and plugins using the AIM SDK.

This release adds three new classes.

AccEx::CAccExPluginPreferences

This class wraps an AccEx::CAccExPreferences object to help you manage the reserved name space for preferences in a plugin. Open AIM Plugins can keep any number of preferences under the “aimcc.plugin.__GUID__.prefs.__PREF__” key specifier where __GUID__ is your plugin key and __PREF__ is any alphanumeric name for your preference.

The class is initialized with a pointer to the session and the plugin’s CLSID. It builds the base preference specifier for the plugin and gives you easy access to the preferences under it. The class also has methods to let you test if a given specifier is in the plugin’s name space and is of a particular preference. The GetPref() and SetPref() methods are identical to that of AccEx::CAccExPreferences with the only exception that you use the __PREF__ suffix rather than the full specifier.

AccEx::CAccExDAccEventSink

This class helps you implement your own DAccEvents handler. It differs from a the CAccEventSink supplied by the Open AIM SDK in a number of ways.

  1. Supports ATL
  2. Adds an OnPreEventMapFilter() function that you can use to filter out events
  3. Adds an OnUnknownDispId() function that you can use to catch unhandled events
  4. Wraps all calls to your handler functions in an exception handler
  5. Adds an OnException() function that is called when an exception occurs
  6. Event handlers are not virtual functions
  7. Does not implement the IAccSession manager (See: AccEx::CAccExIAccSessionArray)

AccEx::CAccExIAccSessionArray

This class helps you keep track of up to 10 IAccSession objects. The purpose of this class is to encapsulate the management of these interfaces in an array along with their connection point cookie. You can add, remove, and find sessions. There are handy methods to get the first session, also known as the primary session, check if the array is empty, and check if a session is already registered.

You can download the latest release and get more information at the AccEx page.

Centering an AIM Module Plugin Window

February 4th, 2009

The window.external.window.center() is a handy function in the AIM Modules API that you can use when all you want to do is center a window without regard for the buddy list. If you want to center a plugin window in a way that accounts for the buddy list, then you will need to write your own function. A solution I actually needed in one of my plugins.

In order to center a window, we need to know what monitor it’s in. Here is a function that returns the monitor for a given window:

function findMonitorForWindow(tWnd)
{
    // loop over all monitors until we find the one where
    // the top left corner of the target window is in
    for (var i=0; true; i++) 
    {
        var m = client.findWindow('_monitor'+i);
        if (m.exists)
        {
            if ( tWnd.x >= m.x && tWnd.x < (m.x + m.width) &&
                 tWnd.y >= m.y && tWnd.y < (m.y + m.height) ) 
                return m;
        }
        else
            break;
    }
    // default to first monitor
    return client.findWindow('_monitor0');
}

NOTE: ‘client’ above is the window.external.client object that has been assigned to a global variable.

Now that we can find the monitor for a given window, we can center the window any way we want in this monitor. Here is a function that centers the window over the region not occupied by a docked buddy list.

function BuddyListAwareCenterWindow(tWnd)
{
    // The standard center function:
    var center = function(o,w,n) { return (o + ((w-n)/2) ); }
 
    var tWndMonitor = findMonitorForWindow(tWnd);
    var blWnd = client.findWindow('_buddylist');
    var blWndMonitor = findMonitorForWindow(blWnd);
    var blWidth = 0, blOffset = 0;
 
    // are both windows in the same monitor?
    if (tWndMonitor.monitorIndex == blWndMonitor.monitorIndex)
    {
        // adjust centering width if bl is docked on either left or right
        if (blWnd.x == 0 || (blWndMonitor.width - blWnd.width) == blWnd.x )
            blWidth = blWnd.width;
        // adjust centering offset if docked on left.
        if (blWnd.x == 0)
            blOffset = blWnd.width;
    }
 
    tWnd.move( 
        center(tWndMonitor.x +  blOffset, tWndMonitor.width - blWidth, tWnd.width),
        center(tWndMonitor.y, tWndMonitor.height, tWnd.height) );
}

There are some edge cases like when a window is bigger than the space it’s centered on, but this solution should help you get started.

AccEx C++ Library R2

January 31st, 2009

AccEx Library for Open AIM DevelopersA new release of the AccEx library is now available. This is a library of functions and classes for C++ based Open AIM clients and plugins using the AIM SDK.

This release adds some handy helper functions ported over from some of my previous posts. One makes it easier to register plugin commands and the other makes it easy to register an active modeless window in your plugin so that dialog navigation keys are functional. These versions are public domain.

As a follow-on to my post on pushing data to the user’s Buddy Updates feed, I added a new function that can be called to push a plugin installed or updated item to the feed.

I am now including a Visual Studio 2005 build project.

AccEx Solution Explorer

See the AccEx page for more details.

How to Debug a C++ AIM Plugin

January 30th, 2009

Here are some tips on how you can debug your own C++ plugins for AIM.

First, I suggest you get about three or four screen names. Developing C++ plugins requires a lot of client re-starts which can get you log-in rate-limited very fast. Also don’t forget to take advantage of the edit and continue feature in Visual Studio while debugging since this will save you a login cycle.

Debugging a plugin is a little bit different than an entire application. I typically compile my plugin in Visual Studio. Then launch AIM using my IM control panel program. Incidentally, this app also lets me kill AIM completely which I need to do when I crash or want to force a restart. When I see the login window, I attach the debugger via the attach to process dialog (CTRL+ALT+P). Look for the aim6.exe process and attach to it. I then set my breakpoints and log in.

NB: There are two things you should note with the debugger. First is to make sure you are debugging native code and not script; very easy to miss. Second, is that your breakpoints will appear as inactive at this time since the plugin is not loaded yet. As long as you make sure you are debugging native code you should not have to worry too much about the breakpoints being disabled. They should light up once you are online.

AIM has its own crash handler that collects stack trace and other information to send along. Since I am developing my own plugin, it makes no sense to report these crashes to AOL. You can temporarily disable it by renaming the C:\Program Files\Common Files\AOL\AOLDiag\tbdiag.dll file to something else. Without it, all crashes get handled by Windows which lets you attach the debugger at the crash point.

With just these few tips you should be able to get started on debugging your own plugins easily.

This Blog Turns 3

January 28th, 2009

Happy Birthday Blog! Is it me or does time seems to go faster when blogging?

I have a long list of posts to write this year and even more software ideas than ever. This year is already off to a great start.

Let me know if there are any topics you would like me to cover on Open AIM, Plugins, AIM Modules, AIM 6.x, etc.

I hope you find the content informative and interesting. Thank you for reading and trying out my plugins.