Monthly Archives: June 2012

Just Upgraded to SyntaxHighlighter 3.0.83

0
Filed under Blogging, WordPress

I had to use the shLegacy.js option since I’ve got tons of <PRE> tags all over this site using the older version. Not great bbecause the “Autoload” function for syntax brushes doesn’t seem to work in conjunction with shLegacy.js, but I suppose that’s to be expected.

If you notice any “unhighlighted” code, just let me know.

KnockOut 2.1.0, the SELECT Binding, and No Initial Value Displayed

0
Filed under Javascript, KnockOut, Web

Fair warning; this post doesn’t have a lot to do with the Feng Shui of VB, or does it…. <g>

I’ve been recently playing quite a lot with Javascript, and various frameworks and libraries that really turn the browser into a client development platform in its own right.

To me, that combination just rings truer than the use of server-side html-generating frameworks like ASP.net, etc. But that’s philosophy for another discussion.

In this case, I’m using JQuery, JQueryMobile, and Knockout to build a mobile capable app that can run on various devices via single source, and hopefully be deployed via PhoneGap, but still look relatively native on each device.

If you’re not already aware of these libraries/frameworks (it can be difficult to tell exactly where each of these fits in the grand spectrum of browser client side development):

  • JQuery : the granddaddy of client side browser libraries. Even Microsoft is supporting this one out of the box now. This thing really makes working with the DOM and client side development a joy.
  • JQueryMobile : A UI kit running on top of JQuery that renders almost native looking UI across a broad spectrum of mobile devices (think one source set running on everything from iPhones, to Kindles, to Android phones, to Win7 Phones).
  • KnockOut : a framework for doing client-side data binding between DOM elements (text boxes, select lists, spans, etc), and Javascript JSON objects.

I wanted to bind a SELECT list to the equivalent of  a .net ENUM in Javascript (which doesn’t technically have ENUMs, so I had to create a class to support something similar).

Here’s the KnockOut View Model:

var userProfileViewModel = {
    timeToTrack : ko.observable(SecondsEnum.secs15),
    secondsEnum : ko.observableArray(SecondsEnum.toArray())
}

The toArray function is just a convenience function to convert my ENUM class into a typical Javascript array that KnockOut can work with. Eventually my plan is to construct a KnockOut Custom Binding that would do all this automatically . But that’s for another post…

The HTML to actually view and bind to that model looks like this:

<span data-bind='text: timeToTrack'></span>
<select name="selTimeToTrack" id="selTimeToTrack" data-mini="true" data-bind="
        options: secondsEnum, 
        optionsText: 'desc',
        optionsValue: 'value',
        value: timeToTrack">
</select>

Everything worked great, except for one nasty bit. When the displayed page first comes up, the select lists are empty. You can see the effect here.

image

Notice how the 15 that’s highlighted DOES populate properly (the value of the bound property is 15 in the view model), but the dropdown list value is empty.

Interestingly, if I click the dropdown, the resulting list does show the proper initial value (15 seconds):

image

After days of Google searching for answers, I finally got a few hours of free time and decided to just roll up my sleeves and start tracing through the KnockOut unminified debug version.

Eventually, I fell into this function (in KnockOut.2.1.0.js):

function ensureDropdownSelectionIsConsistentWithModelValue(element, modelValue, preferModelValue) {
    if (preferModelValue) {
        if (modelValue !== ko.selectExtensions.readValue(element))
            ko.selectExtensions.writeValue(element, modelValue);
            
    }

    // No matter which direction we're syncing in, we want the end result to be equality between dropdown value and model value.
    // If they aren't equal, either we prefer the dropdown value, or the model value couldn't be represented, so either way,
    // change the model value to match the dropdown.
    if (modelValue !== ko.selectExtensions.readValue(element))
        ko.utils.triggerEvent(element, "change");
};

Something didn’t quite look right about this.

If the first block of IF’s ends up true, the modelValue (the value of the property from view model) is going to be set as the initial value of the select DOM element, which is what we want.

BUT, if that happens, the next IF will ALWAYS be false (because the code just set the two value equal), so the “change” event will not be triggered in this case. The problem is, if it’s not triggered, the select DOM element won’t get updated to reflect that value that just got written.

My suspicion is that this was an attempt to circumvent having two lines of code to trigger then change element, but the logic just doesn’t seem to work.

So, I made a subtle change:

function ensureDropdownSelectionIsConsistentWithModelValue(element, modelValue, preferModelValue) {
    if (preferModelValue) {
        if (modelValue !== ko.selectExtensions.readValue(element))
            ko.selectExtensions.writeValue(element, modelValue);
            // DWH added this to correct problem with the change not firing on initial population
            ko.utils.triggerEvent(element, "change");
            
    } else {
        // No matter which direction we're syncing in, we want the end result to be equality between dropdown value and model value.
        // If they aren't equal, either we prefer the dropdown value, or the model value couldn't be represented, so either way,
        // change the model value to match the dropdown.
        if (modelValue !== ko.selectExtensions.readValue(element))
            ko.utils.triggerEvent(element, "change");
    }
};

Here, you can see the “change” event is triggered in both situations (whether the ModelValue is preferred or not).

Once I made the change, I run the page and now I get the much more reasonable:

image

Notice how each dropdown list is initially populated with the current value from the view model.

The Take Away

Javascript (and dynamic languages in general) are a huge departure from static languages like VB ( and all the .net languages). Whether that’s a good thing or not is debatable, but the fact is, there is a tremendous amount of flexibility available because of the dynamic nature of Javascript. And frameworks like JQuery and KnockOut really bring some fantastically clean functionality to client-side browser development.

But, as with most code, these frameworks aren’t bug free. I’m not saying that this is definitively a bug in the KnockOut code, yet, though. I’ve posted to the KnockOut forums and am awaiting a reply.

In the meantime, though, this is a quick and easy fix to a vexing problem.

So if you’ve run into similar problems with KnockOut, it might be worth investigating.

How to Force a Single Instance of FireFox

0
Filed under Firefox, Troubleshooting, Utilities

We have a multiple computer household, but for some reason, my workstation seems to be the one everyone wants to use to check for directions, their email or whatnot. Unfortunately, as I research issues online, I often leave multiple tabs open as quick and dirty bookmarks till I’ve finished whatever work I was doing.

I happen to use the excellent TabMixPlus plugin for Firefox to manage this, and generally, it works great.

But, from time to time, I’ll sit down to continue work, open Firefox and all my tabs will be gone! Even LOCKED tabs! Ugh.

So a few days ago, I decided to try and track down why.

Turns out it’s pretty easy to accidentally do just that.

All it takes is a few simple (and easy to accidentally perform) steps:

  1. Have an instance of Firefox with tab you care about open.
  2. Under Win7, right click on a pinned Firefox icon and select New Firefox Window.
  3. A completely fresh, empty window opens, but the already loaded window is not “in the background”
  4. Click the already loaded window, and close it.
  5. Now, click the newly loaded empty Firefox window and close it.

At this point, if you reload Firefox, all your tabs will be gone!

It turns out that TabMixPlus, as good as it is, doesn’t quite handle this situation properly. If you close the window with all your wanted tabs FIRST, they will be saved properly. But then, when you close the second window with some other (not your) tabs, when that window closes, those tabs will wipe out the previously saved list!

Yikes!

Now, I can’t really call this a bug on Firefox’s or TabMixPlus’s side. It’s a pretty good example of an odd edge case.

Still, that’s not the way I want it to behave.

The Simple Fix

After some digging around, I’d turned up a number of suggestions, including changing the FireFox shortcut link, adding command line options like “about:Blank”, and others.

However, it turns out that the best solution was in TabMixPlus the whole time, just not quite as I would have thought.

On the LINKS tab of the TabMixPlus config options is the “Enable Single Window Mode.”

image

Just make sure that option is CHECKED.

If you do that, anytime a new, EMPTY Firefox window would have opened, instead, a new tab will open in the existing window.

This still means other users could close your tabs, etc, but they’d have to do it intentionally. It can’t happen by accident.

And… all your locked/protected tabs will stay in place, locked and protected. Those would have to intentionally be unlocked/unprotected to be closed out.

So far, I haven’t run into any issues as a result of enabling this mode, but, obviously YMMV.

Uniquely Identifying RawInput Devices in AutoHotKey

18
Filed under AutoHotKey, Hardware, MP3s

NOTE: My take on this has changed slightly, as a result of some feedback. See the end of this post and the "Better Alternate Solution” for details.

I recently completed restoration of an old 1930’s era console radio into a fully modern touch-screen mp3-playing networked jukebox, and have been putting the finishing touches on the loaded software configuration for a few weeks.

Jukebox Original CL Photo

WP_000576

Radio as we found it, stuffed at the back of a barn/storage area

After the conversion, that touchscreen you see automatically folds and the top lowers back down to it’s original position when not in use

There were 3 knobs on the original unit. The actual knobs were long gone, but the holes were still there and I wanted some old-school tactile controls for this thing, as well as the touchscreen.

A few ebay searches and junk drawers scavanges later, and I had 3 very serviceable knobs for the front. You can see them in the photo, the two large dial knobs and the one small brass knob on the center plate.

WP_000498

Now that that was taken care of, I had to determine

  1. What I wanted them to do
  2. How to make them actually do that

Believe it or not, the “what” has actually turned out to be harder than the “how”

All About the “How”

Realistically, the what doesn’t much matter from a technical standpoint. Controlling volume, track playback etc is pretty trivial stuff with most software these days. So I’ll focus on the “how”.

I’d used a macro application called AutoHotKey on several occasions, and, while it’s programming language is quirky to put it mildly, it does get the job done, particularly when the job consists of converting one type of computer input into another.

In my case, each of those knobs it connected, via a typical encoder wheel, to the inputs of a standard 3 button optical mouse with middle wheel. Yes, you heard that right, there are three mice lurking in that cabinet (a forth if you count the real mouse that I use when working on it).

The Three Blind Mice

If you’ve ever hooked up 2 or more mice to a Windows PC, you know that they all control the single cursor. There’s no clear way to tell one mouse’s input from the other. Windows does that intentionally because it generally makes sense.

However, underneath the covers, there’s an API that exposes all input devices uniquely, meaning you CAN actually tell whether one mouse or another is being moved, clicked, scrolled or what not. It’s called the “RawInput” API, and it’s been there ever since Windows XP (and possibly even earlier, though I’m not sure of that).

Unfortunately, the RawInput functions are not the easiest functions to deal with in the world. Lots of C-style structure parsing and pointer juggling.

AHKHID to the Rescue

Fortunately though, for AutoHotKey users, a user named “theGood” posted AHKHID.ahk, an AutoHotKey script of functions to make working with HID devices (Human Interface Devices) at the RawInput level relatively straightforward.

I’d been able to craft up a script to detect which of my mice were been wheeled and clicked and react accordingly, so things were good.

Until I unplugged the mouse I used for working on the jukebox, and the keyboard.

When I booted it back up, boom, nothing worked right.

An ID isn’t an ID

I had been using the function AHKHID_GetDevIndex, as in:

id := AHKHID_GetDevIndex(h)

in order to retrieve a device ID and I’d assumed that ID would consistently identify a device. And I’d assumed wrong. Unplugging my actual mouse and keyboard had caused the devices to get renumbered on reboot, a common issue with Windows applications.

A Nasty Solution

The AHKHID script includes a function called AHKHID_GetDevName() that retrieves a unique “device name”, but that “name” is huge, consisting of a number of segments of hex number, plus an additional entire GUID, something along these lines:

USB\VID_045E&PID_00DD&REV_0173&MI_00{745a17a0-74d3-11d0-b6fe-00a0c90f57da}

Obviously, this could be used for a key, but it’s a bit unwieldy.

So, to shorten the key name a bit and make it easier to work with, I came up with AHKHID_GetDevKey()

AHKHID_GetDevKey(i, IsHandle = false) {
    ;generate a unique name from the DevName (which is huge, and usually includes a useless GUID)
    devname := AHKHID_GetDevName(i, IsHandle)
    StringReplace, devname, devname, Hid#Vid_, , All
    StringReplace, devname, devname, USBVid_, , All
    StringReplace, devname, devname, KODAK, , All
    StringReplace, devname, devname, &Pid_, , All
    StringReplace, devname, devname, &MI_, , All
    StringReplace, devname, devname, #7&, , All
    StringReplace, devname, devname, #, , All
    StringReplace, devname, devname, &, , All
    StringReplace, devname, devname, \, , All
    StringReplace, devname, devname, ?, , All
    p := Instr(devname, "{")
    if p > 0
    {
        p := p - 1
        StringLeft, devname, devname, p
    }
    ;remove last 5 0's if that's what's there
    if SubStr(devname, -4) = "00000"
    {
        p := StrLen(devname) - 5
        StringLeft, devname, devname, p
    }
    StringUpper, devname, devname
    Return devname
}

The idea here is to essentially strip out all the characters that wouldn’t help to make the string any more unique anyway. It’s a tad brute-force, but it’s easy to understand and it works.

So that insane name could end up a relatively benign:

045E00DD017300

Which is a perfectly reasonable unique key in my book.

An Alternate Solution

After I’d put this together and gotten it in use, I realized a potentially even better solution: just calculate a CRC-32 for the full Device Name. It turns out another user has already built a CRC-32 algorithm in AHK script, so doing so would be trivial. Granted, you might still get collisions with a CRC, but it’s reasonably unlikely.

A Better Alternate Solution

Well, after posting this, I got a comment on the AutoHotKey forums that, essentially, was pointing out that the “VID_” and “PID_” strings that my routine removes, actually can have an impact on the uniqueness of the name. The poster also indicated that the GUID at the end of the name also aided in the uniqueness.

While neither of those two claims held true in my specific case (on the 3 machines I tested on), I don’t doubt them in the list.

Which got me to thinking if there’s a better solution.

And there is. Our old friend, the hash function.

In reality, the CRC-32 approach that I suggest above can certainly be considered a form of hash function, and a pretty good one at that.

But, if you’re really gunning for just about ironclad uniqueness, at 64 or 128 bit hash is what you need, and there’s a couple of implementations that already exist for AutoHotKey.

Grab one of those, run it against the GetDevName value, and convert to a string value and you have a relatively short and manageable, unique and consistent HID device ID.

Wrap Up

I love Visual Basic, and VB.net in particular, but AutoHotKey makes many tasks concerned with translating one type of input into another (converted joystick input to mouse input, or keyboard keystrokes, for instance) so easy, it just often doesn’t make sense to build a dedicated app for the purpose.

It’s definitely an application to key handy in your toolbox.