Scaling Textile Image Links
This is something that has been driving me crazy; plenty of sites (including Basecamp) use Textile still, and I often want to link an image in without formally downloading it, resizing it and re-uploading it.
All the Textile examples I found all show how to display an image inline via a URL, but none of them show how to resize the image, at least not in a fashion I could make work. Some digging finally turned this up, and I figured I’d post this here for when I forget next time, and in case it’s useful for someone else.
A plain image is linked in as follows:
!http://farm6.static.flickr.com/5306/5627310027_eb64230826_t.jpg!
Resulting in: 
To force a specific size:
!{width: 50px; height: 33px;}http://farm6.static.flickr.com/5306/5627310027_eb64230826_t.jpg!
Resulting in: ![]()
Whoosh!
Feet wet with the Arduino: Debouncing
My lovely family got me for Xmas this year an Arduino Uno, and some associated bits like a breadboard. I’ve always been interested in how things work, but intimidated by component-level electronics, so I figured this would be a good place to get over it and learn something at the same time.
I’d already done a bunch of reading, including the Getting Started guide (thanks, Douggie, Hannah!), so next came a quick trip to RadioShack, where I rifled through their parts bins looking for anything interesting to hook up. Maybe not the cheapest solution, but it was a neat experience to be able to dig through and find stuff that might be fun to hook up, but not be sure what it’s useful for yet. In a world where everything you buy has an exact purpose, and generally only one way of hooking it up, it was an eyeopener!

Small beginnings
Among other things I ended up with a couple of plain old green LEDs, and a momentary switch (275-646). I had to crimp the switch’s legs with a pair of pliers to get them to fit into my breadboard, since in my RadioShack fugue I wasn’t savvy enough to imagine this might be something I’d want to do.
I’ve done some programming, and am comfortable digging and researching until I understand something, so I was happy enough with the coding side of it – which in fact is very similar to c#, given its c / c++ heritage. Something that fascinates me is that in coding, everything is very deterministic most of the time, but in hardware, there was a whole side I’d never guessed at; contacts can ‘bounce‘, or a potentiometer can flick back and forth between two values, or any number of other mysterious and distressing behaviours can manifest. I decided to combine the LEDs and a button, and explore the whole thing to get a better handle on it.
Every Arduino LED tutorial starts off with a LED (or two), and indicates you needed a resistor in line with each LED. A bit of digging turned up the underlying reason: the LEDs just don’t handle the current that results from a 5V source. That’s probably not exactly worded correctly, and of course there’s more to it than that, but the end result is that I needed 100 ohm resistors in series with each LED. The resistance calculation was pretty straightforward using a handy online calculator; doing it manually is a bit more work, but definitely useful. It took me a while to find a site that actually explains the calculation, which works out as follows:
The Arduino’s digital pins provide 5V, and my LEDs have a forward voltage (voltage level needed to make them light) of 2.1 volts. So we need to reduce the 5V DOWN to 2.1V, i.e. reduce it by 2.9V – this is the amount the resistor has to drop the voltage by. The LEDs have a forward current (how much current we want to drive through the LED) of 30 mA.
So for the resistor, since V=IR, i.e. 2.9 = (0.030 * R), then R = 2.9 ÷ 0.030 = 96.6667. The next ‘size up’ for resistors is 100Ω, so we select that. Whew!
The only other thing that I found non-intuitive is that I needed a resistor between the switch and ground. After some research to understand it, I found it helps to think of it this way: When the switch is open, the digital pin ‘sees’ the ground normally, through the resistor. In this case, the resistor is redundant; there’s only one path, so the digital pin is ‘low’. When the switch is closed, however, the pin can see two paths; one to ground, and one to the 5V source. The fact that one path (the ground path) has a resistor causes the pin to have a ‘preferred path’ the other way, through to the 5V source – i.e. the resistor on the ‘ground path’ makes it a less ‘desirable’ path. I’m sure that’s not technically accurate, but it makes it easier for me to remember!
So, the circuit looks like this in Fritzing:
And less attractive, but keepin’ it real:
The Arduino code to control all this is as follows:
const int led0Pin = 11; // LED1 is connected to pin 11
const int led1Pin = 12; // LED2 is connected to pin 12
const int btnPin = 2; // Momentary button is connected to pin 2
const int minTime = 30; // The minimum time the button must be pressed (in ms) before we consider it a valid press
int lastReadBtnState; // Used to store the last state that we read from the button (this could flop all over the place)
int acceptedBtnState; // Used to store the last ACCEPTED state that we read from the button (this should be very stable)
int ledLit = 0; // Which LED is lit; 0 = led0, 1 = led1
unsigned long lastChangeTime; // Used to store the last time that we observed a change in the button's state
boolean inTransition = false; // If this is true, we've observed a button change, and are waiting to see if it is stable
void setup()
{
Serial.begin(9600); // Initialise the serial output so that we can write out debug messages
pinMode(led0Pin, OUTPUT); // Set the LED0 pin as output
pinMode(led1Pin, OUTPUT); // Set the LED1 pin as output
pinMode(btnPin, INPUT); // Set the button pin as input
acceptedBtnState = digitalRead(btnPin); // Initialise the stable button state to whatever state it actually is
lastReadBtnState = acceptedBtnState; // Indicate that we're in a stable state
}
void loop()
{
lastReadBtnState = digitalRead(btnPin);
if (!inTransition && (lastReadBtnState != acceptedBtnState))
// Bam, we registered a button state change
{
lastChangeTime = millis(); // Mark the time we observed the change
inTransition = true; // Note that we're now in a transition state
Serial.println("Button state changed from " + StateToStr(acceptedBtnState) + " to " + StateToStr(lastReadBtnState) + ". Going into transition");
}
else if (inTransition && ((millis() - lastChangeTime) > minTime))
// The button state hasn't changed for at least minTime milliseconds, so assume we're stable now
{
Serial.println("Met minimum time requirement: going from " + StateToStr(acceptedBtnState) + " to " + StateToStr(lastReadBtnState));
if (lastReadBtnState == LOW)
// Only toggle the LED if the button is in a LOW state
{
Serial.println("New state is LOW; toggling LED");
ledLit = 1 - ledLit;
}
// Move the last-read value into the accepted state variable
acceptedBtnState = lastReadBtnState;
// Note that we're no longer in transition
inTransition = false;
}
// Turn on the appropriate LED
if (ledLit == 0)
{
digitalWrite(led0Pin, HIGH);
digitalWrite(led1Pin, LOW);
}
else
{
digitalWrite(led0Pin, LOW);
digitalWrite(led1Pin, HIGH);
}
}
String StateToStr(int AState)
// Given a pin state variable, returns a text equivalent of its value
{
return (AState == HIGH ? "HIGH" : "LOW");
}
The LEDs alternate smoothly when the button is pressed, so mission accomplished. Back to the sack of goodies to see what’s next!
VBA Date Picker
I often work within the suffocating constraints of VBA (in my case, a derivative called WinWrap), and the control set is fairly limited.
I often poke around in the Windows API looking for better ways to do things, and today I put together some old code and set up a routine to display a date picker control on a dialog – and was almost surprised when it worked.
The trick is to use CreateWindowEx to create the date control, and SendMessage to set and read the value, with the rest just being VBA/API plumbing.
Note that the code below expects pixel coordinates for the control position instead of the funky values used by WinWrap.
Here’s the complete source:
Option Explicit
Private Type SYSTEMTIME
wYear As Integer
wMonth As Integer
wDayOfWeek As Integer
wDay As Integer
wHour As Integer
wMinute As Integer
wSecond As Integer
wMilliseconds As Integer
End Type
Declare Function CreateWindowEx Lib "user32" Alias "CreateWindowExA" ( _
ByVal dwExStyle As Long, _
ByVal lpClassName As String, _
ByVal lpWindowName As String, _
ByVal dwStyle As Long, _
ByVal x As Long, _
ByVal y As Long, _
ByVal nWidth As Long, _
ByVal nHeight As Long, _
ByVal hWndParent As Long, _
ByVal hMenu As Long, _
ByVal hInstance As Long, _
lpParam As Any) As Long
Private Declare Function DestroyWindow Lib "user32" (ByVal hwnd As Long) As Long
Private Declare Function SendMessage Lib "user32.dll" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByRef lParam As SYSTEMTIME) As Long
Private Const DTM_GETSYSTEMTIME As Long = &H1001
Private Const DTM_SETSYSTEMTIME As Long = &H1002
Private Const DATETIMEPICK_CLASS = "SysDateTimePick32"
Private Const WS_BORDER As Long = &H800000
Private Const WS_CHILD As Long = 1073741824
Private Const WS_VISIBLE As Long = 268435456
Private hWndDatePicker As Long
Sub Main
Begin Dialog UserDialog 160,77,.evMain ' %GRID:10,7,1,1
OKButton 40,42,90,21
End Dialog
Dim dlg As UserDialog
Dialog dlg
End Sub
Rem See DialogFunc help topic for more information.
Private Function evMain(DlgItem$, Action%, SuppValue?) As Boolean
Select Case Action%
Case 1 ' Dialog box initialization
hWndDatePicker = CreateDateControl SuppValue&, 10, 10, 100, 25
SetDateControl hWndDatePicker, #12/25/2012#
Case 2 ' Value changing or button pressed
Dim pickedDate As Date
pickedDate = ReadDateControl(hWndDatePicker)
MsgBox "You selected: " + CStr(pickedDate)
DestroyWindow hWndDatePicker
Rem evMain = True ' Prevent button press from closing the dialog box
Case 3 ' TextBox or ComboBox text changed
Case 4 ' Focus changed
Case 5 ' Idle
Rem Wait .1 : evMain = True ' Continue getting idle actions
Case 6 ' Function key
End Select
End Function
Sub SetDateControl(ControlHWnd As Long, AValue As Date)
Dim wMsg As Long
Dim wParam As Long
Dim lParam As SYSTEMTIME
Dim result As Long
wMsg = DTM_SETSYSTEMTIME
wParam = 0
With lParam
.wYear = Year(AValue)
.wMonth = Month(AValue)
.wDay = Day(AValue)
.wHour = Hour(AValue)
.wMinute = Minute(AValue)
.wSecond = Second(AValue)
.wMilliseconds = 0 'not supported in Date type
End With
SendMessage(hWndDatePicker, wMsg, wParam, lParam)
End Sub
Function ReadDateControl(ControlHWnd As Long) As Date
Dim wMsg As Long
Dim wParam As Long
Dim lParam As SYSTEMTIME
Dim result As Long
wMsg = DTM_GETSYSTEMTIME
wParam = 0
SendMessage(hWndDatePicker, wMsg, wParam, lParam)
With lParam
result = CDate(CStr(.wMonth) + "/" + CStr(.wDay) + "/" + CStr(.wYear))
End With
ReadDateControl = result
End Function
Function CreateDateControl(DlgHWnd As Long, AX As Long, AY As Long, ADX As Long, ADY As Long) As Long
Dim dwExStyle As Long
Dim lpClassName As String
Dim lpWindowName As String
Dim dwStyle As Long
Dim x As Long
Dim y As Long
Dim nWidth As Long
Dim nHeight As Long
Dim hWndParent As Long
Dim hMenu As Long
Dim hInstance As Long
Dim lpParam As Long
dwExStyle = 0
lpClassName = DATETIMEPICK_CLASS
lpWindowName = ""
dwStyle = WS_BORDER Or WS_CHILD Or WS_VISIBLE
hWndParent = DlgHWnd
hMenu = vbNull
hInstance = MainFormHandle
lpParam = vbNull
CreateDateControl = CreateWindowEx(dwExStyle, lpClassName, lpWindowName, dwStyle, AX, AY, ADX, ADY, hWndParent, hMenu, hInstance, lpParam)
End Function
Private Type SYSTEMTIME
wYear As Integer
wMonth As Integer
wDayOfWeek As Integer
wDay As Integer
wHour As Integer
wMinute As Integer
wSecond As Integer
wMilliseconds As Integer
End Type
Declare Function CreateWindowEx Lib “user32″ Alias “CreateWindowExA” ( _
ByVal dwExStyle As Long, _
ByVal lpClassName As String, _
ByVal lpWindowName As String, _
ByVal dwStyle As Long, _
ByVal x As Long, _
ByVal y As Long, _
ByVal nWidth As Long, _
ByVal nHeight As Long, _
ByVal hWndParent As Long, _
ByVal hMenu As Long, _
ByVal hInstance As Long, _
lpParam As Any) As Long
Private Declare Function DestroyWindow Lib “user32″ (ByVal hwnd As Long) As Long
‘Private Declare Function DateTime_GetSystemtime Lib “Comctl32″ (ByVal hwndDP As Long, ByRef lpSysTime As SYSTEMTIME) As Long
Private Declare Function SendMessage Lib “user32.dll” (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByRef lParam As SYSTEMTIME) As Long
Private Const DTM_GETSYSTEMTIME As Long = &H1001
Private Const DTM_SETSYSTEMTIME As Long = &H1002
Private Const DATETIMEPICK_CLASS = “SysDateTimePick32″
Private Const WS_BORDER As Long = &H800000
Private Const WS_CHILD As Long = 1073741824
Private Const WS_VISIBLE As Long = 268435456
Private hWndDatePicker As Long
Sub Main
Dim userChoice As Integer
Begin Dialog UserDialog 160,77,.evMain ‘ %GRID:10,7,1,1
OKButton 40,42,90,21
End Dialog
Dim dlg As UserDialog
Dialog dlg
End Sub
Rem See DialogFunc help topic for more information.
Private Function evMain(DlgItem$, Action%, SuppValue?) As Boolean
Select Case Action%
Case 1 ‘ Dialog box initialization
hWndDatePicker = CreateDateControl SuppValue&, 10, 10, 100, 25
SetDateControl hWndDatePicker, #12/25/2012#
Case 2 ‘ Value changing or button pressed
‘DateTime_GetSystemtime hWndDatePicker, pickedDate
Dim pickedDate As Date
pickedDate = ReadDateControl(hWndDatePicker)
MsgBox “You selected: ” + CStr(pickedDate)
DestroyWindow hWndDatePicker
Rem evMain = True ‘ Prevent button press from closing the dialog box
Case 3 ‘ TextBox or ComboBox text changed
Case 4 ‘ Focus changed
Case 5 ‘ Idle
Rem Wait .1 : evMain = True ‘ Continue getting idle actions
Case 6 ‘ Function key
End Select
End Function
Sub SetDateControl(ControlHWnd As Long, AValue As Date)
Dim wMsg As Long
Dim wParam As Long
Dim lParam As SYSTEMTIME
Dim result As Long
wMsg = DTM_SETSYSTEMTIME
wParam = 0
With lParam
.wYear = Year(AValue)
.wMonth = Month(AValue)
.wDay = Day(AValue)
.wHour = Hour(AValue)
.wMinute = Minute(AValue)
.wSecond = Second(AValue)
.wMilliseconds = 0 ‘not supported in Date type
End With
SendMessage(hWndDatePicker, wMsg, wParam, lParam)
End Sub
Function ReadDateControl(ControlHWnd As Long) As Date
Dim wMsg As Long
Dim wParam As Long
Dim lParam As SYSTEMTIME
Dim result As Long
wMsg = DTM_GETSYSTEMTIME
wParam = 0
SendMessage(hWndDatePicker, wMsg, wParam, lParam)
With lParam
result = CDate(CStr(.wMonth) + “/” + CStr(.wDay) + “/” + CStr(.wYear))
End With
ReadDateControl = result
End Function
Function CreateDateControl(DlgHWnd As Long, AX As Long, AY As Long, ADX As Long, ADY As Long) As Long
Dim dwExStyle As Long
Dim lpClassName As String
Dim lpWindowName As String
Dim dwStyle As Long
Dim x As Long
Dim y As Long
Dim nWidth As Long
Dim nHeight As Long
Dim hWndParent As Long
Dim hMenu As Long
Dim hInstance As Long
Dim lpParam As Long
dwExStyle = 0
lpClassName = DATETIMEPICK_CLASS
lpWindowName = “”
dwStyle = WS_BORDER Or WS_CHILD Or WS_VISIBLE
hWndParent = DlgHWnd
hMenu = vbNull
hInstance = MainFormHandle
lpParam = vbNull
CreateDateControl = CreateWindowEx(dwExStyle, lpClassName, lpWindowName, dwStyle, AX, AY, ADX, ADY, hWndParent, hMenu, hInstance, lpParam)
End Function
Word 2007 Document Language Change
I frequently have to switch between working on documents for a UK/NZ/US audience, and often want to change the document’s language to match.
Spelling has never been an issue for me, but there’s something just wrong with having the document set to a language different to what you’re writing. Words like ‘colour’ and ‘neighbour’ get the annoying red squiggle, and it’s irritating that real typos get mixed in with the (ahem) original English spellings of words. Every now and then I have to work out how to beat this, and I always forget, so think of this as a note-to-self that may be useful to others too.
Some googling will tell you that the most common solution is to do a select-all (ctrl-A), then use the language selector in the status bar (or in the Review ribbon). This only sets the selected text, though, and you’ll have to re-do it every time you add new text. How could that ever be good enough?
Another solution you’ll see is to change the default language for the Normal template by clicking the ‘Default…’ button in the language dialog. As far as I know, this will affect all new documents from that point on – obviously crazy talk.
Fortunately, there’s a way that feels a lot more right, in that it changes the entire document (but just the current document), and any new text that you add. It’s easy to do at any time during the document editing process, and you don’t have to keep reapplying it.
It just boils down to changing the Normal style for the current document. Not for the next document, or all future documents, or all the documents in your housing subdivision… just for this one. Steps are easy:
1. From the ‘Home’ ribbon, open the style editor:

Open the Style Editor
2. Modify the Normal style:

Modify the Normal Style
3. Change the language:

Change the language
Select the language you need, and you’ll notice that it appears in the description of the style (see the screenshot above). A nice side affect is that most (all?) of the other styles are based on Normal, so they get the change too.
Finally, just OK your way back out to the document.
Calculated Outlook Column: Lag

Lag Field
We recently started getting a slowdown in our mail at work, and didn’t spot it until people started calling (and even sending other emails) to ask the singularly most overused question of all time: “Did you get my email?”
I figured it must be easy enough to display the message lag in Outlook somehow, so that performance problems become more apparent. It turns out to be even easier than you’d expect; all you need is a calculated field to display the difference between the Sent and Received fields:
Note:
- ‘Sent’ means the time that the sender’s client (e.g. Outlook) sent the message, and it is displayed in your local time zone. Technical description here.
- ‘Received’ means the time that the message hit your mail server (in our case this is Exchange), and is also displayed in your local time zone. Technical description here.
I’m working in Outlook 2007, so the screens below may look slightly different at your end.
I set the field to show as ‘h:mm:ss’, but of course this could be shown in any number of ways.
Step 1: Create a new user-defined field. Right-click anywhere in the header bar and select “Field Chooser”:

Step 1
Step 2: In the Field Chooser, select ” User-defined fields in folder” (or “…in Inbox” if you’re working in the inbox):

Step 2
Step 3: Name the new field “Lag” (or whatever you prefer), and select a type of ‘Formula’:

Step 3
Step 4: Paste in the following formula:
format(Hour([Received]-[Sent]),"0") & ":" & Format(Minute([Received]-[Sent]),"00") & ":" & format(Second([Received]-[Sent]),"00")

Step 4
Step 5: Drop the new field into your header bar, wherever you want it to display:

Step 5
From there, you should be able to see the new ‘Lag’ column.
Registering DLLs in Vista x64
I recently migrated from 32-bit XP to 64-bit Vista. It was a bit of a shock, and I’m still trying to find my way around some of the differences; One of the more problematic issues I found is setting up legacy 32-bit apps, since these have DLLs that need to go into the appropriate System folder. The app that prompted this post uses a batch file to copy DLL and OCX files into C:\Windows\System32, then uses the system reg tool to register the files.
In 32-bit XP, you have:
C:\Windows\System - contains 16-bit system files
C:\Windows\System32 - contains 32-bit system files
In 64-bit Vista, you have:
C:\Windows\System32 - contains 64-bit system files
C:\Windows\SysWOW64 - contains 32-bit system files
Niiiice.
First thing was getting an easy way to run the RegSvr32.exe elevated, easily.
I ended up copying the entire file from
C:\Windows\System32\regsvr32.exe
to
C:\Users\\AppData\Roaming\Microsoft\Windows\SendTo\regsvr32.exe
I then edited the properties (of the copy in SendTo) to ‘Run as Administrator’.
Then, to register anything, just select the DLL or OCX file, right-click, Send To, regsvr32.exe. You can even select more than one file at a time, and you only get the one UAC prompt.
Next issue was the location for files. The app I installed copied all its DLLs and OCXs into System32, and then promptly failed when it tried to register them, with:
LoadLibrary failed : 0x8007007E (The specified module could not be found. )
I found the solution to this was to move the files from System32 into SysWOW64. Then, the register action magically worked.
Moving to Origin in AutoCAD
This is something that drives me nuts every time I try to do it. Our AutoCAD guy is kind enough to show me the solution every time I hit it (because my memory is so fantastic), but I figured that THIS time I’ll blog it so I can look it up next time I forget.
If you have something that you are trying to move to (0,0), you would THINK you just have to select it, type ‘M’ for move, hit space, and enter ’0′, comma, ’0′, enter.
Bizarrely enough, it doesn’t, and I’ve even seen experienced AutoCAD dudes stumped by it. The answer is simple: turn off Dynamic Input, either by clicking on the ‘DYN’ slot in the status bar, or in the drafting options.
Alternatively, change the dynamic input options for coordinates: in AutoCAD LT 2007, this is in
Tools | Drafting Settings | Dynamic Input | Pointer Input Settings | Format: Absolute coordinates.
Whoosh!
Reading SQL Server’s IMAGE Data Type
For the “something I always forget and have to search for” bucket: if you have an IMAGE data type in a table, and you want a quick-n-nasty way to read the contents, AND if it’s not more than 8000 characters:
select cast(cast(fieldName as varbinary(8000)) as varchar(8000)) FROM tablename
Told you it was quick, and told you it was nasty
Liz’s Birthday: Triathlon Cake
Liz’s birthday was this week, and she said she wanted the chocolate cake from the Joy of Vegan Baking. It’s amazingly easy to make, we’ve used it for a few occasions, and always comes out really well.
I really wanted to decorate it in a way that means something to her, and at the same time was worried, because I don’t have much of a steady hand when it comes to icing a cake. A quick Google image search for ‘bicycle cake’ confirmed my fears – unless you’re a pastry chef, there’s precious little chance of making something that looks like a bike!
I had been thinking about other ways of decorating it, and then Liz’s coworker made her a beautiful fondant covered cake, which got me to thinking that maybe I could use fondant to achieve what I wanted, since it would let me cut stuff and arrange it before I put it on the cake (the finality of icing bags makes me nervous! One twitch, and your cake changes from a picture of a bike into something postmodern and vaguely frightening). A bit of looking around confirmed that you either make fondant from gelatin and sugar, or cooked marshmallows (aka, gelatin and sugar). There are some vegan recipes out there, but they all looked either tricky or unreliable, and I didn’t find many people saying that fondant was actually delicious regardless of how you make it.
So, the logical conclusion was marzipan, which has always seemed entirely delicious to me, and is something that I know Liz likes. Luckily, based on the numbers coming to the party, we needed three cakes (I can’t imagine the cosmic connection between the number of people at a party and the number of events in a triathlon, but I’m sure it’s there!). And, not only that – I had a mix of cake pan sizes (two eight-inch, one nine-inch) , and Liz’s favourite thing ever is the bike event, which falls in the middle of the famous ‘swim, bike, run’, so that got the larger cake and saved the symmetry.
Anyway, the result came out just how I wanted it – and Liz seemed happy too, which is of course the whole point. Happy birthday baby!
Scroll-Lock on the XPS M1340
Looking for the archaic old scroll-lock on the Studio XPS 13? It’s not labeled on the keyboard, but you can use Fn-F5.
I use it as an Outlook macro ‘modifier’; I use a macro to delay all my messages by two minutes, unless the scroll-lock is on when I send the message (at which point I allow the message to be sent immediately, and turn off the scroll-lock).


