Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Languages / C#

CatchCulator Suite for .NET

4.97/5 (16 votes)
11 Feb 2008CPOL12 min read 1   482  
A new approach on catching and combining values output by different applications and much more
ccn_01.gif

Introduction

A couple of years ago, I came up with CatchCulator, a tool which ran more than one application in parallel on the same machine while watching their numerical outputs and combining the results in order to draw some important conclusion.

Friends of mine around the world, many of whom were involved in cross-boundary development work, were very pleased when using this tool. Being the kind of man that I am, I decided to come back to them with a .NET approach and improved functionality. My efforts ended up with a CatchCulator Suite consisting of CatchCulator 2.0 and Catch2Use add-on.

Compared with its previous version, CatchCulator 2.0 welcomes you with a totally new, HTML-based user interface and offers support for using math functions in combining the numerical outputs of the running applications. Catch2Use supports you in grabbing ideas from all over your computer world and keeping those ideas right at hand, whenever you need them while programming or while working with the CatchCulator.

Working with the CatchCulator Suite

ccn_10.gif Working with CatchCulator 2.0

I wrote two simple form applications to help explain the functionality of the tool. Bring them up onto your screen and choose CatchCulator by clicking its icon on the suite's layout. You will recognize the three result displays introduced by version 1.0.

ccn_02.gif

At the very bottom of CatchCulator's layout, there is a set of icons to allow you navigate to the desired functionality; an information bar is also available. The left-most icon starts the process to "hover-and-catch" the displayed application data you are interested in, while the right-most one brings the Catch2Use tool on. Click on the left icon ccn_03.gif. This brings you to a new layout on which you can see in red the text of the control you are currently hovering over.

Hovering for data

It may happen that you hover over an editor, combobox or other control which usually displays text, but you do not see what you are expecting on CatchCulator's layout. It could be that the control was created on a frame and therefore you capture the text belonging to that frame. Press ccn_04.gif on your keyboard in order to hide the frame (or whatever stops you from reaching the right control). To show back a hidden control you must press ccn_05.gif on your keyboard. Were I you, I would not care too much about trying to view the hidden controls, as they will show up by themselves as soon as you decide to catch some data or you navigate to the next layout. For those who do not know what catching means yet, that is about getting the handle of a control belonging to a given application on your computer screen and displaying a value that you are interested in. When you decide that you are hovering over the control you want to catch, simply press ccn_08.gif on the keyboard.

Note: Make sure that CatchCulator is the active application on the screen while hovering for data. In other words, do not click on the hovered applications.

ccn_07.gif

As soon as you catch some data, CatchCulator creates a default variable name, which you may change in order to reflect the nature of the data. You can change the default variable name right away, by clicking the name on CatchCulator's layout to select it, then right-clicking it, which pops up a dialog to allow you to enter a new name. You will also have the opportunity to rename the caught variables later on, while defining the way the variables are to be combined to display the final result.

Renaming a caught variable

After catching all you need, click the ccn_10.gif icon to navigate to the previous layout, where you click any of the three result displays to define the function used to compute the result and / or change (again) the variable names.

Note: The change of a variable name at this point propagates throughout the definitions of the functions used to compute the results.

ccn_11.gif

When defining a function to compute the result, think JavaScript, as you actually make use of it. Start with the function reserved name, then write down a name for your function. Do not insist in choosing the function name, as it will be automatically refactored anyway to reflect the result the function computes: therefore, fncc_r1 will be generated for Result 1, fncc_r2 for Result 2 and, as you already guessed, fncc_r3 for Result 3. Knowing that, an ' f ' will just be enough for the function name. Should you see an interesting code snippet anywhere, remember you can take advantage of your Catch2Use tool.

Defining the result function You should keep in mind ten more reserved words, apart from those used by JavaScript:
  • acqPeriod - the time interval in milliseconds (100 by default) used to update the data caught from the running applications
  • r1_prefix - the text to be displayed before the computed value in Result 1
  • r1_suffix - the text to be displayed after the computed value in Result 1
  • r1_decs - how many digits are to be used after the decimal point in Result 1
  • r2_prefix - the text to be displayed before the computed value in Result 2
  • r2_suffix - the text to be displayed after the computed value in Result 2
  • r2_decs - how many digits are to be used after the decimal point in Result 2
  • r3_prefix - the text to be displayed before the computed value in Result 3
  • r3_suffix - the text to be displayed after the computed value in Result 3
  • r3_decs - how many digits are to be used after the decimal point in Result 3

The math function support is the one provided by the Math object of JavaScript. You have already access to the list of the available Math.functions through the Catch2Use tool.

Once you defined the result function(s) you want to use, all you have to do is to click the ccn_14.gif icon on the layout to start monitoring the combined results of the caught variables in the running applications. Should the processor load be dramatically affected by CatchCulator, remember to change its update rate by setting a higher value for acqPeriod within the body of any of the three functions used to compute the results.

CatchCulator at work

ccn_15.gif Working with Catch2Use

The other tool from the suite helps you gather useful ideas and pieces of code. Or, you can simply use it to store and retrieve function definitions for your CatchCulator.

ccn_16.gif

Once you navigate to the Catch2Use layout, a list of available topics is displayed on the right side. Through the layout, you have access to:

  • retrieving information ready to use within your projects
  • creating a new entry in the topic repository
  • inspecting a topic
  • removing a topic from the repository

Let us use Catch2Use to retrieve the function definition used to compute and display the power rate in our CatchCulator example. Select the topic in the displayed list and click the ccn_17.gif link on the layout. The topic content goes directly to the clipboard allowing you to simply paste the information into your project.

To catch some information while browsing a document, select the text you are interested in and copy it to the clipboard. Then click the catching link on the Catch2Use layout, popping up a dialog interface where you are asked to provide a short description for the new topic. Finally, add the caught topic to the repository by clicking the ccn_19.gif button.

Catching useful information

Valuable ideas will mostly come from the web. Therefore, Catch2Use offers the possibility to extend the context menu of your IE browser, so that you can directly catch ideas from a web site without starting the CatchCulator suite. Click the ccn_25.gif link on the Catch2Use layout to set the extension. From now on, whenever you select some text within a page and then right-click on it, you will be provided with the 'Catch selection' command:

Catching web selection

A dialog form pops up so that you can see the caught text, give it a topic name and store it to the repository.

Store to the repository

Inspecting and removing a topic is very straightforward. Just click the corresponding link on the layout.

The Code Behind the CatchCulator Suite

ccn_10.gif The Code Behind CatchCulator 2.0

CatchCulator assumes the existance of two working folders:
  • one reserved to HTML layouts
  • and one reserved to java script files
The file structure

The user interface is based on the navigation within an HTML document, specific to a bunch of activities to be carried out. The tool incorporates a WebBrowser control displaying the currently navigated section.

The weorking schema

The user chooses either to navigate to another section or selects one of the commands displayed by the layout. Such a selection leads to calling a method of the main form class implementation, which, in turn,

  • calls other computational methods or
  • consumes Win32 API functions and/or
  • invokes JavaScript to do the math and to update the layout for a customized result displaying.

Consuming Win32 API functions is accomplished through the Messenger class which is responsible for calling the following unmanaged functions in user32.dll:

C#
[DllImport("user32.dll", EntryPoint = "SendMessageA")]
  private static extern int SendMessageToNativeWindow
               (IntPtr hwnd, int wMsg, int wParam, IntPtr lParam);
               
[DllImport("user32.dll")]
public static extern IntPtr WindowFromPoint(Point Point);
  
[DllImport("user32.dll", EntryPoint = "ShowWindow")]
public static extern bool ShowWindow(IntPtr hWnd, bool bShow);

The first step in combining values displayed by different running applications is to catch the handles of the controls involved in the combination. Prior to deciding what handles must be caught, you should be able to see what you catch. For that purpose, CatchCulator uses a 100 ms timer. Within the tick event handler, the Messenger.WindowFromPoint() method is used to get the handle of the control currently under the mouse pointer, and the Messenger.SendMessageToNativeWindow() method is used to send WM_GETTEXT and EM_GETLINE messages to the control previously identified through its handle. The control responds with its text, which CatchCulator displays in red on its layout.

While hovering with your mouse over the computer's screen, you may want to hide a control in order to let other controls reveal their text. Hiding and showing back controls are made possible by the Messenger.ShowWindow() method. When deciding on catching a control, you instruct CatchCulator to store the value of that control's handle.

For all those operations to be performed, the CatchCulator main form class implemets an IMessageFilter interface in order to capture the keyboard events before they are dispatched to its controls. Keeping CatchCulator active, i.e. hovering the mouse all over the screen and not clicking other running applications, any "key down" activity is monitored through the PreFilterMessage() implemetation of the interface, active only in "catching" mode:

C#
public bool PreFilterMessage(ref Message m)
{
    if (m.Msg == 0x100) /* key down */
    {
        switch (m.WParam.ToInt32())
        {
            case (int)'C':
                // Get the handle of the window 
                //   currently under the mouse pointer
                // 
                // Build the name for the newly caught variable
                //   (if not already caught) and add it to the list
                //   of caught variables
                break;
            case (int)'H':
                // Hide the control currently under the mouse pointer
                break;
            case (int)'S':
                // Show all the hidden controls (if any)
                break;
        }
    }
}

Each of the caught control handles is assigned to an instance of the CaughtAppVar class called caught application variable, and exposing the following properties:

CaughtAppVar properties

After all the desired application variables have been caught, you put CatchCulator in acquisition mode, in which it uses a customizable timer to read the text currently displayed by each caught control.

C#
private void timerAcq_Tick(object sender, EventArgs e)
{
    AcquireAndDisplay();
}

Within the AcquireAndDisplay() method, the text -- caught again with the help of the Messenger class -- is translated into double values, qualifying also for translation a text consisting from numbers followed by non-digit characters. In general, throughout the entire code, text interpretation is accomplished with regular expresions.

Finally, the caught values are combined and displayed by invoking a javascript function for each of the three result displays on CatchCulator's layout:

C#
InvokeScript(fncc_r1, ... parameters ...);
InvokeScript(fncc_r2, ... parameters ...);
InvokeScript(fncc_r3, ... parameters ...);

ccn_15.gif The Code Behind Catch2Use

Catch2Use assumes the existance of following working folder:
  • the topic repository (ideas) folder
The file structure

As already seen, the incorporated WebBrowser control provides the user interface. You click one of four links on the layout, which in turn, calls one of the four dedicated methods of the CatchCulatorNET class implementation.

Catch2use working schema

The data all those methods deal with is stored within a text file, in blocks of lines delimited by $%$-BEGIN and $%$-END markers. The starting marker is also used to store a short topic description listed by Catch2Use:

$%$-BEGIN:Short topic description
    ... some text here ...
    ...
$%$-END

In order to support direct catch of ideas from a web site without starting the CatchCulator suite, the tool makes use of its ExtendIEContextMenuToCatch() function to extend the context menu of the IE browser:

string keyName = "HKEY_CURRENT_USER\\Software\\Microsoft\\
    Internet Explorer\\MenuExt\\&Catch selection";
/* HKEY_LOCAL_MACHINE can also be used if desired
In that case, the key must also be changed within the Script\iecatch.htm file */
// Get extension's script path
string extensionPath = GetScriptPath("iecatch.htm");
// Set the registry key values to support text catching in IE browser
Registry.SetValue(keyName, "", extensionPath, RegistryValueKind.String);
Registry.SetValue(keyName, "Contexts", 0x10, RegistryValueKind.DWord);
Registry.SetValue(keyName, "ccn", Application.ExecutablePath, RegistryValueKind.String);

It creates a new registry key, which is responsible for adding an entry called Catch selection into the standard context menus in Internet Explorer.

The default value of the newly created key is set to the URL of the page that contains the script to be executed by the menu entry, i.e. Script\iecatch.htm. For the script to be executed only on selected text within a web page, the additional binary value, named Contexts, is created and its value is set to 0x10. As the script will actually deal with a form implemented by the CatchCulator suite, another registry value is necessary to store the full path to it. I named it ccn, according to the tool name.

The 'Catch selection' is linked to the following script:

C#
var parentWnd = external.menuArguments;
var theDoc = parentWnd.document;
var crtSelection = theDoc.selection;
var selectionRange = crtSelection.createRange();
var strText = new String(selectionRange.text);

if(0 < strText.length)
{
   if (window.clipboardData)
   {
     // Put the selected text onto the clipboard
     window.clipboardData.setData("Text", selectionRange.text);
     // Get the full path cu ccn
     var WshShell = new ActiveXObject("WScript.Shell");
     var ccn = WshShell.RegRead("HKEY_CURRENT_USER\\
                  Software\\Microsoft\\Internet Explorer\\
                  MenuExt\\&Catch selection\\ccn");
     // Run ccn with option /c to catch the selected text as a topic
     WshShell.Run("\"" + ccn + "\" /c");
     WshShell.Quit;
   }
}

If there is a text selection and a clipboardData object is available, then the selected text is passed to the clipboard and the full path to CatchCulator is retrieved from the system's registry. The ActiveX object assigned to the WScript.Shell provides the means for the registry access, as well as for running the NewTopicForm form implemented by the CatchCulator suite. The trick here is to actually run CatchCulator with the '/c' option as parameter. This is the deciding factor in running the NewTopicForm form instead of the CatchCulatorNET one:

C#
namespace CatchCulatorNET
{
    static class Program
    {
        [STAThread]
        static void Main(string[] args)
        {
            ....
            bool justCatch = false;
            if (args.Length > 0)
            {
                if (args[0].ToLower() == "/c")
                {
                    justCatch = true;
                }
            }
            if (!justCatch)
            {
                // Run the CatchCulator suite
                Application.Run(new CatchCulatorNET());
            }
            else
            {
                // Build the list of available topics from the repository
                .... and pass it to a NewTopicForm from ....
                NewTopicForm ntf = new NewTopicForm();
                ntf.Topics = ... // the reference to the topic list;
                // Catch what's on the clipboard using the NewTopicForm
                Application.Run(ntf);
            }
        }
    }
}

The NewTopicForm displays the caught text, asks the user for a topic name as it normally does from within CatchCulator and then quietly closes.

A final word: Catch2Use comes with the following topics which you may use with the CatchCulator tool or anywhere else within your projects:

  • Avoiding multiple clicks on buttons (web - IE, aspx.cs)
  • Background worker: cross-thread operation
  • CatchCulator: power computation
  • CatchCulator: power factor computation
  • Compiling the web site
  • JavaScript Math functions
  • Text action in behalf of a hidden button (aspx)
  • Text action in behalf of a hidden button (aspx.cs)

Hints

  • CatchCulator incorporates a WebBrowser control. Therefore, all your mouse gestures will be recognized and interpreted as they usually are when using the IE. That may lead to page scroll, intentionally or not -- especially when using a laptop's touchpad. To retrieve the currently navigated layout section, click the information bar at the bottom of CatchCulator
  • The way CatchCulator's layout looks like is a result of the HTML code written in the ccsuite.htm, cc.htm, catch.htm and c2u.htm files. Feel free to redesign the layout to suite your taste.
  • The global variable names acqPeriod, r<sup>i</sup>_prefix, r<sup>i</sup>_suffix and r<sup>i</sup>_decs (i = 1 to 3) can be used wherever you want within the function definitions. Keep in mind that the result functions are called in this order: fncc_r1, fncc_r2 and fncc_r3. Therefore, the values of those variables will be overwritten if set in more than one place.

History

Jan 11, 2008 : Created
Jan 25, 2008 : Context menu support for catching the selected text in IE browser's window
Feb 11, 2008 : Bug fix for navigation to an internal anchor related to some OS / service pack combination; function FileUrlPatch() added
(see also the discussion on the MSDN forum)

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)