A while ago I switched from Virtual Server 2005 R2 to VMware Server and so far I think it was a good switch. Unfortunately it wasn't without some consequences -- mainly that I should have read the procedure prior to converting my VM image. I had the Virtual Server extensions installed on my image and I forgot to remove them and then I seemed to be unable to remove them without doing extensive damage to the image. Now I am not able to install the VMware Tools as it causes the mouse to freak out and navigating through the keyboard is increasingly challenging these days, not to mention a pain.

I even went through the trouble of searching through the registry to find the Microsoft extensions and remove them. I also removed the C:\Program Files\Virtual Machine Additions folder and used Autoruns to remove the additions driver. The bottom line is -- don't bother -- it broke and wasn't worth fixing. Alas, I will have to put up with the annoyances (having to use Ctrl-Alt to release the cursor, finding out the system time is inaccurate after suspending the image, not being able to use the clipboard across the host and VM, etc.).

Since then I created a new image from scratch (for a different purpose so I still occasionally use the older image) and it is working great. Oh well, I'll get around to recreating the old image sometime soon.


Comment Section

Comments are closed.


I really like Subtext, but unfortunately I haven't had too much time to try to configure my blog. I've looked through the wiki, but haven't seen enough information to emulate the configuration of Subtext founder Phil Haack. For example, the FeedBurner plugin which lists the number of subscribers and links to get the RSS and even email feeds -- how exactly is that configured? I suppose I should RTFM but I'm having trouble finding it at the moment (not to mention I have way too much to do right now with work!). It seems the Subtext Wiki is describing plug-in features in Subtext 2.0 (I'm running 1.9.x currently -- 2.0 is not released yet) so that doesn't help.

Sooner or later I will install Phalanger and test out DokuWiki. I also want to install umbraco and possibly Rainbow portal while I'm at it. I'd love to have GNU Mailman installed to manage mailing lists, but there are too many issues related its dependence on UNIX-style usernames and groups and I would probably need to user IronPython for the Python functionality. I guess it is just too much work right now, especially as I am utterly swamped at work. Unfortunately at work I am stuck working on a design portion of a project and I don't even get to do "real" programming that much -- sometimes you long to launch Visual Studio or work on source code. Oh well, hopefully this phase will end soon.


Comment Section

Comments are closed.


A while back I needed to disable fields on a web page during submit and I found a utility written by Nancy Michell for MSDN Magazine. The utility covered the basic cases, but I found that I needed to use it for AJAX style calls as well as standard submits. So I modified the code to include an enable function as well. Finally I added exception handling around the disable and enable code to avoid pesky Javascript errors. The only thing I might change is to capture an array of the controls that were successfully disabled and then process only those controls on enable.

To use the disable utility, do the following:

// Method 1: Using the param string[] for controls
DisableHelper.DisableCtrlOnSubmit(this,
    "ServerForm.btnCancel",
    "ServerForm.btnSave");

// Method 2: Using the ArrayList of controls
aryDisableControls = new ArrayList();
aryDisableControls.Add("ConfigLoopForm.btnCancel");
aryDisableControls.Add("ConfigLoopForm.btnSave");
DisableHelper.DisableCtrlOnSubmit(this, aryDisableControls);

Here is the utility source:

using System;
using System.Collections;
using System.Text;

namespace Utility.Web.UI
{
    public class DisableHelper
    {
        /// 
        /// Adds client-side javascript code to disable controls on a submit.
        /// 
        /// Reference to the current page
        /// String array of client-side control names.
        public static void DisableCtrlOnSubmit(
            System.Web.UI.Page Page,
            params string[] strControls)
        {
            StringBuilder sbJS = new StringBuilder(200);
            sbJS.Append(@"

"
                );

            if (!Page.IsClientScriptBlockRegistered("MSDisableImpl"))
            {
                Page.RegisterClientScriptBlock(
                    "MSDisableImpl",
                    sbJS.ToString());
            }

            Page.RegisterOnSubmitStatement("MSDisable", "MSDisable(false);");
        }

        /// 
        /// Adds client-side javascript code to disable controls on a submit.
        /// 
        /// Reference to the current page
        /// ArrayList with the client-side control names
        public static void DisableCtrlOnSubmit(
            System.Web.UI.Page Page,
            ArrayList aryClientControlNames)
        {
            if (aryClientControlNames != null)
            {
                string[] strControls = (string[]) aryClientControlNames.ToArray(typeof(string));
                DisableCtrlOnSubmit(Page, strControls);
            }
        }

        private static void DiableCtrlOnSubmit(
            System.Web.UI.Page Page,
            ArrayList aryClientControlNames)
        {
            DisableCtrlOnSubmit(Page, aryClientControlNames);
        }
    }
}

Comment Section

Comments are closed.


I vastly prefer Javascript over VBScript for many of the reasons describe by Joel On Software and by this MSDN article. Many projects that I work on use Excel for simple data relationships. Most of the data is so simple that it does not warrant a full SQL database, but a single table (spreadsheet) will suffice. I use the spreadsheets to generate files for multiple systems in some cases. For example, in an embedded turbine governor project I used a spreadsheet to map the tagnames to the communication details (rSpeed1 = 32025). The spreadsheet generated a C source file for the embedded controller, an XML file for the configuration software, and a mapping file for the help documentation. Using the spreadsheet helped keep three distinct systems synchronized.

I still receive a lot of Excel files from customers and I usually need to process and filter the spreadsheets. I receive files with DCS tag names and I often need to filter the list. The auto-filter in Excel is fine for two or three types, but I usually need to filter based on more than ten regular expression filters. The following is an example of a Javascript file I used to filter the spreadsheet:

// Constants
var INITIAL_ROW = 3;                    // Two rows of header
var DELETED_COLUMN_NAME = "DELETED";
var FILTER_COLUMN_NAME = "INST_NO";
var INCLUDE_COLUMN = [
     "INST_NO"
    ,"PID_SHT"
    ,"INTOOLS__Loop_No"
    ,"INST"
    ,"DESCRP1"
    ,"DESCRP2"
    ,"HI_SCALE"
    ,"ENG_UNITS"
    ,"ALMLL"
    ,"ALML"
    ,"ALMH"
    ,"ALMHH"
    ,"SET_POINT"
];
var INCLUDE_TAGPREFIX = [
    // Analog Inputs
     "AI"
    ,"FI"
    ,"LI"
    ,"PI"
    ,"TI"

    // DCS Calculations
   
    // Controllers
    ,"AC"
    ,"FC"
    ,"LC"
    ,"PC"
    ,"TC"
    ,"AIC"
    ,"FIC"
    ,"LIC"
    ,"PIC"
    ,"TIC"
   
    // Hand Switch PV Flag
    ,"HS"
    ,"PVFL"
];


// Basic Excel object
var Excel = {
    _App : null
    ,_created : false
    ,Constants : {
         pause : 0
        //Excel.XlDeleteShiftDirection
        ,xlShiftToLeft    : 0xFFFFEFC1
        ,xlShiftUp        : 0xFFFFEFBE
    }

    ,newApp : function() {
        this._App = new ActiveXObject("Excel.Application");
        this._created = true;
        return this._App;
    }

    ,getApp : function() {
        this._App = GetObject("","Excel.Application");
        return this._App;
    }

    ,_quit : function() {
        if (this._App)
        {
            this._App.Quit();
            this._created = false;
            this._App = null;
        }
        return;
    }

    ,bye : function() {
        if (this._created)
            this._quit();
        this._App = null;
    }
};


// Load the header row
function getHeaderRow(sheet, table)
{
    if (sheet)
    {
        var row = 1;
        var lastCol = sheet.UsedRange.Columns.Count;

        for (var col = 1; col <= lastCol; ++col)
        {
            var title = "" + sheet.Cells(row, col).Text;
            table[title] = col;
            table["_" + col] = title;
        }
    }
}

function ProcessWorksheet(sheet, rowFunction, map)
{
    if (sheet)
    {
        var lastRow = sheet.UsedRange.Rows.Count;
        var row = INITIAL_ROW;
        while (row <= lastRow)
        {
            // If the row does not match, it is deleted and
            // do not move to the next row as the rows are shifted up.
               if ( rowFunction(sheet, row, map) )
                   ++row;
               else
                   --lastRow;
           }
    }
}

function matchTagPrefixSetup(prefixArray)
{
    var result;
    if (prefixArray)
    {
        result = new Array(prefixArray.length);
        for (var i = 0; i < prefixArray.length; ++i)
        {
            result[i] = new RegExp("^" + prefixArray[i] + "[0-9]");
        }
    }
    return result;
}

// Hide row if it does not match any filter prefix
function processRowFunction(sheet, row, data)
{
    var match = false;
    data.rowsProcessed += 1;
    var text = sheet.Cells(row, data.deleteCol).Value;
    if (!text)
    {
        text = sheet.Cells(row, data.matchCol).Value;
        for (var i = 0; i < data.prefixes.length; ++i)
        {
            var a = data.prefixes[i].exec(text);
            if (a != null)
            {
                match = true;
                break;
            }
        }
    }

    if (!match)
    {
        sheet.Cells(row, data.matchCol).EntireRow.Delete(Excel.Constants.xlShiftUp);
        data.rowsDeleted += 1;
    }
   
    return match;
}

function main(args)
{
    // Attempt to get an open instance of Excel
    var app = Excel.getApp();
    if (app)
        var sheet = app.ActiveSheet;

    if (sheet)
    {
        // Get an array of RegExp for the matching prefixes
        var prefixes = matchTagPrefixSetup(INCLUDE_TAGPREFIX);

        // Get the header row
        var table = new Object();
        getHeaderRow(sheet, table);
        var matchCol = table[FILTER_COLUMN_NAME];
        var deleteCol = table[DELETED_COLUMN_NAME];

        // Build the row process function
        var map =
        {
             "prefixes"        : prefixes
            ,"matchCol"        : matchCol
            ,"deleteCol"       : deleteCol
            ,"rowsProcessed"   : 0
            ,"rowsDeleted"     : 0
            ,"startTime"       : null
            ,"finishTime"      : null
            ,"elapsedTime"     : null
        };

        map.startTime = new Date();

        // Process the worksheet
        app.ScreenUpdating = false;
        ProcessWorksheet(sheet, processRowFunction, map);
        app.ScreenUpdating = true;

        map.finishTime = new Date();
        map.elapsedTime = map.finishTime - map.startTime;
       
        // Statistics
        WScript.Echo("Rows Processed: " + map.rowsProcessed);
        WScript.Echo("Rows Deleted: " + map.rowsDeleted);
        WScript.Echo("Elapsed Time: " + map.elapsedTime / 1000 + " seconds");
    }

    // Cleanup
    sheet = null;
    myApp = null;
    Excel.bye();
}

// Program entry point
main(WScript.Arguments);

Comment Section

Comments are closed.


Command Line Clipboard

Comments [0]

I just needed to copy the output of the DOS command dir to another file. The usual mechanism is to send the output to a file, open the file, then copy the contents to the actual destination file. I was sure there must be an utility that would copy output in the command line to the clipboard and indeed I found such an utility. Kudos to Steve Kemp and his clipboard utility. I was able to do what I needed very easily:

C:\>dir /s /b *.txt | clipboard -

Then just paste into Notepad++ or other application!


Comment Section

Comments are closed.


<< Older Posts | Newer Posts >>