DZone Snippets is a public source code repository. Easily build up your personal collection of code snippets, categorize them with tags / keywords, and share them with the world

Boon has posted 2 posts at DZone. View Full User Profile

May Fortune Be My IM Status.

01.29.2008
| 2720 views |
  • submit to reddit
        // Tired of having others have cooler status on their IM clients,
// I decided that I shall put an end to that.
// Yet, I am no factory of coolness, but I figured my favorite buddy,
// "fortune" will help me out a little.

// By the way, this tool can definitely be done much better with regard
// to the way it updates the MSN, but hey, I just wanted to play with
// C#. My first time :P

// BTW, the MSN thing works only if you have your MSN not minimized PLUS
// the toolbar showing. (LAME! I know.)

// If you really want to do it right, use http://www.xihsolutions.net/dotmsn/
// and send me the code ;) bhtek@yahoo.com

using Microsoft.Win32;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Automation;
using System.Runtime.InteropServices;


namespace ZenStatusUpdater
{
    class Program 
    {
        [DllImport("USER32.DLL", EntryPoint = "FindWindowA", CallingConvention = CallingConvention.StdCall)]
        private static extern IntPtr FindWindow(string sClassName, string sWindowName);

        [DllImport("USER32.DLL", EntryPoint = "PostMessageA", CallingConvention = CallingConvention.StdCall)]
        private static extern bool PostMessage(IntPtr hWnd, uint iMsg, long wParam, long lParam); 

        static void exploreElement(AutomationElement sub)
        {
            foreach (AutomationProperty prop in sub.GetSupportedProperties())
            {
                Console.WriteLine("\tProp[" + prop.ProgrammaticName + "]: " + sub.GetCurrentPropertyValue(prop));
            }

            foreach (AutomationPattern pat in sub.GetSupportedPatterns())
            {
                Console.WriteLine("\tPat[" + pat.ProgrammaticName + "]");
            }
        }

        static void explore(AutomationElement el)
        {
            Console.WriteLine("Self...");
            exploreElement(el);


            foreach (AutomationElement sub in el.FindAll(TreeScope.Descendants, Condition.TrueCondition))
            {
                Console.WriteLine("Sub...");
                exploreElement(sub);
            }
        }

        static void Main(string[] args)
        {
            String fortune = null;
            int tries = 0;

            do
            {
                fortune = GetFortune();
                tries++;
            } while (fortune.Length > 130);

            Console.WriteLine("Try #" + tries + ": " + fortune);

            updateMsnStatus(fortune);
            updateYahooStatus(fortune);

            System.Threading.Thread.Sleep(5000);
        }

        protected static void updateYahooStatus(String fortune)
        {
            // Get the current signed in user
            //
            string sUserName = "bhtek";
            Console.WriteLine("The currently logged in user is " + sUserName);

            // Now open the current user's profile and set the current status message, pass true to
            // OpenSubKey to request write access

            RegistryKey keyYahooCustomMessages = Registry.CurrentUser.OpenSubKey("Software\\Yahoo\\Pager\\profiles\\"
            + sUserName + "\\Custom Msgs", true);

            // Set the 5th message, seems like yahoo messenger has the functionality to move the newly set
            // message up as the first one.
            String status = fortune;
            keyYahooCustomMessages.SetValue("5", status);
            byte[] statusBin = (new ASCIIEncoding()).GetBytes(status);
            keyYahooCustomMessages.SetValue("5_bin", (byte[])statusBin); 
            keyYahooCustomMessages.Close();
                
            // We are done setting the value in the registry. We now need to notify y! of this change
            //

            // Find the yahoo messenger window and sent it the notification
            // 0x111: WM_COMMAND
            // 0x188: Code 392

            IntPtr hWndY = FindWindow("YahooBuddyMain", null);
            System.Diagnostics.Debug.WriteLine("Find window got: " + hWndY.ToString());
            PostMessage(hWndY, 0x111, 0x188, 0);
        }

        protected static void updateMsnStatus(String fortune)
        {
            AutomationElementCollection msnWindows = AutomationElement.RootElement.FindAll(TreeScope.Children, new PropertyCondition(AutomationElement.ClassNameProperty, "MSBLWindowClass"));
            if (msnWindows.Count > 1)
            {
                foreach (AutomationElement potentialMsn in msnWindows)
                {
                    exploreElement(potentialMsn);
                }

                return;
            }

            AutomationElement msn = msnWindows[0];
            msn.SetFocus();

            AutomationElement tools = msn.FindFirst(TreeScope.Descendants, new PropertyCondition(AutomationElement.AccessKeyProperty, "Alt+T"));
            ExpandCollapsePattern toolsPat = (ExpandCollapsePattern)tools.GetCurrentPattern(ExpandCollapsePattern.Pattern);
            toolsPat.Expand();

            AutomationElement options = tools.FindFirst(TreeScope.Descendants, new PropertyCondition(AutomationElement.NameProperty, "Options..."));
            InvokePattern optionsPat = (InvokePattern)options.GetCurrentPattern(InvokePattern.Pattern);
            optionsPat.Invoke();

            AutomationElement optionsWindow = AutomationElement.RootElement.FindFirst(TreeScope.Descendants, new PropertyCondition(AutomationElement.NameProperty, "Options"));

            AutomationElement personalMessage = optionsWindow.FindFirst(TreeScope.Descendants,
                new AndCondition(
                    new PropertyCondition(AutomationElement.ClassNameProperty, "RichEdit20W"),
                    new PropertyCondition(AutomationElement.NameProperty, "Type a personal message for your contacts to see:")
                    )
            );
            ValuePattern personalMessagePat = (ValuePattern)personalMessage.GetCurrentPattern(ValuePattern.Pattern);
            personalMessagePat.SetValue(fortune);

            AutomationElement ok = optionsWindow.FindFirst(TreeScope.Descendants, new PropertyCondition(AutomationElement.NameProperty, "OK"));
            InvokePattern okPat = (InvokePattern)ok.GetCurrentPattern(InvokePattern.Pattern);
            okPat.Invoke();
        }

        private static String GetFortune()
        {
            System.Diagnostics.Process process = new System.Diagnostics.Process();
            process.StartInfo.FileName = "c:\\cygwin\\bin\\fortune.exe";
            process.StartInfo.RedirectStandardOutput = true;
            process.StartInfo.UseShellExecute = false;
            process.Start();
            String fortune = process.StandardOutput.ReadToEnd();

            fortune = System.Text.RegularExpressions.Regex.Replace(fortune, "\\s+", " ");
            return fortune;
        }

       
    }
}