Monday, February 22, 2010

Simulating Keyboard Input with C#

I visited a potential client who is using a barcode reader-based timekeeping system. Well, actually, the barcode reader is just configured as a keyboard wedge. So from the application's point of view, it just looks like a the user is typing his ID number on the keyboard. This prospect is interested in shifting into a fingerprint-based biometric timekeeping system. But because of their complex business rules, we looked at ways to implement the biometric identification as an adjunct to the existing system.

So the challenge is -- how do I capture a fingerprint; determine its associated ID; then simulate a keyboard input to their existing keyboard-based 3rd application so that no changes need to be made on their end. The same business rules would apply. Since their program is keyboard-based instead of serial or USB, that greatly simplified matters. I recall reading of a Windows API to send characters to the 'keyboard' device to make it appear as if somebody inputed something on the keyboard. But the extra challenge here is to be able to send those virtual keypresses into another running application.

A little Google search for examples in C# yielded some answers. The SendKeys class in .NET Framework already encapsulated the Windows API calls to do this. I just need to first invoke SetForegroundWindow() to transfer control to the application that I want to send the keys to, then SendKeys does the rest. There is no existing encapsulation of the SetForegroundWindow() API call in .NET so I had to use the platform invoke (pinvoke) method. This is easily done with the ff. declaration:

[return: MarshalAs(UnmanagedType.Bool)]
static extern bool SetForegroundWindow(IntPtr hWnd);

As can be seen from the declaration, SetForegroundWindow() requires a native Window handle as a parameter. One way of getting a window handle is by enumerating the processes running in a system. The process object's MainWindowHandle property is what we need to pass to the API.

Process[] processes = Process.GetProcessesByName("notepad");
foreach (Process p in processes)
IntPtr pFoundWindow = p.MainWindowHandle;

System.Windows.Forms.SendKeys.SendWait("Hello world");

The above example assumes there's a Notepad running on the system. This program sends the text "Hello world" to the notepad's window. Based on my tests, the Sleep call is important as it takes a split second for SetForegroundWindow() to switch windows. Without the needed pause, the first few characters of the keys to send are missed.

Friday, February 19, 2010

Reclaiming Hard Disk Space on my Windows PC

For the past several months, I've been struggling with my Drive C because it has been running out of space. My System Tray would keep popping warnings that the space left is critically low. I would then clear my IE cache and temporary files just to free up some teeny-weeny space. It has become an almost daily routine.

I decided to spend some time this morning tinkering with Free Disk Analyzer from Extensoft. It gives you a graphical overview of your storage allocation down to the drives/folders/files. It can sort files or folders by space used and you can quickly isolate the space-hoggers.

It seems that a large chunk of space is eaten up by temporary files in my c:\Documents and Settings\[username]\Local Settings\temp folder. It looks like its acting as the general dumping ground of several applications for their temporary scratch area. And several files there look like they were already abandoned by their application and left to just gather dust.

Sorting them by space used and by date allowed me to determine which temporary files are most likely abandoned already and deleted them. After the 2 minute exercise, I was able to reclaim a whopping 11.3 GB of space on my Drive C! Yey!

I will try the other free tools at Extensoft. Their version of the Windows Explorer / File Manager looks very interesting.

Thursday, February 18, 2010

Converting DVD into AVI for YouTube Upload

I recorded our appearance on Kabuhayang Swak na Swak the other day. Hey, its not everyday that one gets featured in a major TV channel. Ok, ok, so it was on a Sunday morning at 7am. But quite surprisingly, a few people whom I know saw it, and several interested prospects txt-ed us to know more about the product.

I used my old Philips DVD Recorder to save the show for posterity. The Philips recorder saves its recordings onto its internal hard drive. It does allow you to burn it into removable media as a regular DVD using its burn capability. Since my objective is to upload the video to YouTube, that got me thinking -- how do I convert DVD to a format supported by YouTube?

YouTube supports the major formats like MPEG, Quicktive (.mov), AVI, and Windows Media Video. Unfortunately, the only DVD converter I know is the DivX Converter. And YouTube does not support .divx. I've previously relied on my tech guys to convert DVD music video to WMV for Fliptunes. But now, it looks like I have to figure out how to do this on my own. As usual, first stop is Google!

My search led me to a free software called bitRipper. My search highlighted the word FREE when I searched for a converter, and bitRipper appeared at the top of the list. The installer file is small enough and the website looks very professional. So I installed it on my home PC and ripped the DVD that my Philips recorder burned.

bitRipper worked quickly on the DVD. Its a no fuss, no nonsense program. I did not really tinker with the settings options anymore and just used the default. In a few minutes, I got a 180mb AVI version of the 1-hour DVD content.

Now, obviously, I can't upload the entire show since a large part of it is irrelevant and it contains several commercials. So I needed another program to cut it down to just the portion that I needed (our segment!). I used another free video editing program called Avidemux. Just like bitRipper, its a no-frills program which does what its supposed to do very well. In a matter of minutes, I chopped down the file to just 20MB and just contains our segment. Then off it goes to YouTube!

A strange note -- the day after I did this, my monitor resolution went haywire. The usual 1440x900 widescreen format disappeared. In place are the usual resolutions which are meant more for 4:3 monitors. I tried reinstalling the video drivers to no avail. Finally in desperation, I uninstalled bitRipper. After a reboot, my screen was back to 1440x900. I'm not really sure what happened. I won't categorically say that it was bitRipper that caused the problem as it was working fine after my ripping session. The problem only cropped up after the reboot.

Wednesday, February 17, 2010

A Barcoded Taxi?

I saw this taxi while driving along C5 the other day. It looks like an ordinary and unassuming white Toyota Vios except for the barcode printed on its bumper.

The barcode is actually the telephone number of the operator (or is it the LTFRB's).

I really just wonder though if it can actually be read by a regular barcode reader. Or even if it was a really huge reader, can it read it like a regular barcode? I would assume that the spaces between the bars have a maximum distance before a reader would assume that nothing follows anymore. So with such a large barcode, that limit must be exceeded. So it must be printed on the bumper just for aesthetic design purposes.

It would be interesting nonetheless if its possible to have the license plate printed in barcode form on the card so that it can easily be tagged when entering carparks, etc.

Sunday, February 14, 2010

TV Interview of ThePictureShop for ABS-CBN

We were interviewed this past Feb 10 by the Bayan Productions team for their weekend show Kabuhayang Swak na Swak. The show focuses on entrepreneurs (generally small-scale) and unique business ideas. For this Valentine's Day, their team went out looking for couples (married or not) who have ventured into business together. Their researcher bumped into the 2006 article at Inquirer which featured ThePictureShop. They contacted us through Cols' cellphone which is listed at site, and in a matter of 2 days, they were here at our house for a live shoot!

The crew arrived around 10am. The 'director' started off with some basic Q&A's while the cameraman proceeded with setting up the location for the shoot. The shoot was done at our main garden. They positioned 2 seats with the pond as the background. The 'director', hidden from the camera's view, fielded the questions which Cols and I answered alternately.

From the garden, we proceeded to the den where we were asked to do mock photobook editing. Cols was seated while I was asked to stand beside her and comment on her work as if we were working. Of course, all the audio were edited out so we just mouthed whatever we wanted to say to make it appear like we're discussing something about the project on the screen.

We were wrapping up around 11am and Caitlin had to go to school. But since Ethan was around, we included him in some more shots to be used as background material. Here's the finished product which aired Feb 14, 2010 at 7:00am (our 3 minutes of fame!):

Wednesday, February 10, 2010

The End of Time for Doctor Who

I stayed up past midnight last night watching Part 2 of The End of Time -- the finale for David Tennant's stint as as the tenth Doctor Who in the popular BBC sci-fi series. After 3 full seasons plus several Christmas specials, I guess David Tennant finally wanted to move on and called it quits. That's too bad since I think he was one of the best Doctors ever. The eleventh Doctor, Matt Smith, has big shoes to fill.

I downloaded both Parts 1 & 2 in Quicktime's .mov format. The Part 2, however, was recorded from an HD source. My HP Mini's Intel Atom processor and graphics card couldn't keep up with the high definition video demand. It would skip/freeze the video often, with the audio just streaming normally. I guess this HP Mini is just good for watching standard definition movies.

The 2-part ending was a good farewell for David. It included cameo appearances of the major characters that were part of his series. As his way of "collecting his reward", he got a chance to bid farewell to Martha Jones (who is already married to Mickey Smith, former boyfriend of Rose Tyler, in the alternate universe he's trapped in -- how did she end up there?); to Rose Tyler (at Christmas Eve 2005 before she met him); to Captain Jack Harkness (that bar pick-up scene was great); and to Donna Noble's family. It was sad that they did not let Donna recover her memory of the Doctor -- at least, to properly say goodbye to him.

The Time Lords coming out of their imprisonment (I thought they were dead) with Timothy Dalton as their leader also provided a respite from the usual major baddie like the Daleks or the Master to end a season. Well, actually, the Master was part of the story line but he redeemed himself at the end when he realized he was just a pawn of the Time Lords.

The Doctor is supposed to have like 13 lives. With Matt Smith now playing the 11th "regeneration", I wonder if they will really kill the character off after 2 more future versions. Hopefully by that time, the writers would have figured out a loophole from this storyline. Incidentally, I heard The End of Time is also Russel T. Davis' last Dr. Who episode. He has been one of the prolific writer of the screenplays and would be missed by this blogger.

Monday, February 8, 2010

Disabling USB AutoRun on Windows XP Home

I don't know about other people, but I really find it very annoying that when you plug in a flash drive in Windows, it opens that dialog box and asks you whether you want to open the content as a folder, load images, execute the autorun, etc. I prefer that it does nothing while I open the Windows Explorer and access it myself.

For regular Windows XP/Vista users, this functionality can be easily disabled using the Local Policy Manager as described in the following url:

For users of Windows XP Home, however, you will realize that there is no gpedit.msc. Since I'm trying to disable the autorun of my HP Mini (which has XP Home installed), I had to use another method using the Registry directly as described here:

You have to set the bitmask for the drives that you want to disable this behavior from. In my case, I wanted to disable autorun on all unrecognized drives (0x81) and the USB drive (0x10). So the masked I used was 0x91. Worked like a charm.

Friday, February 5, 2010

Brother HL-2040 Laser Printer

I bought a Brother HL-2040 laser printer about 5 years ago when they had this trade-in promo at Megamall. It seemed like a good deal (I think around P5k for the laser printer) and it came with a 3-year warranty.

My only issue with it then was there are not a lot of ink-refilling stations who are capable of refilling Brother cartridges unlike the more common HP's. The usual Ink-for-Less do not support Brother. We were eventually able to find one Inkman outlet at Tomas Morato who does.

In the past year or 2, the unit has been having chronic problems with paper jams. It has gotten to the point that its really annoying already and I'm considering junking it and buying a new printer altogether. I think the design of how the paper flows from the tray to the toner and out the printer is more complex as compared to how HP designed their printers. Our HP laser printer at the store is also 5 years old already and its working pretty well (and no problem with ink refills).

I'm now deciding whether I should get an HP entry-level laser printer (about P6k+) or an entry-level Samsung laser for almost half the price (about P3.2k). Or will I end up paying more in the future since there will not likely be a lot of refilling stations supporting Samsung cartridges. :)

Wednesday, February 3, 2010

Getting Foreign Exchange Currency with C#

Since our online payment service PayEasy works with 24 countries for direct bank debit, we have to perform currency conversion as necessary. For the longest time, I have been using the free currency converter Web Service at -- com.webservicex.www.CurrencyConvertor().

But lately, I don't find it very reliable. I would often get time-outs or errors. Also, I'm not really sure as to where it gets its exchange rates. For manual currency conversion, I prefer to use the service of XE ( However, XE does not provide an API for getting rates. So I decided to just implement my own API by retrieving the output of and parsing it.

Luckily, its fairly simple as they display the rate right at the page's title bar. So its a simple matter of crafting the necessary HTTP GET request given the source and destination currency. Then read the page header of the response and extract the rate from the title.

Below is a snippet of my C# code:

string xeString = String.Format("{0}&To={1}", srcCurrency, dstCurrency);

System.Net.WebRequest wreq = System.Net.WebRequest.Create(new Uri(xeString));
System.Net.WebResponse wresp = wreq.GetResponse();
Stream respstr = wresp.GetResponseStream();

int read = respstr.Read(buf, 0, BUFFER_SIZE);
result = Encoding.ASCII.GetString(buf, 0, read);

At this point, the string result already contains the title which can look something like USD to EUR rate: 1.00 USD = 0.716372 EUR. As can be clearly seen, its a simple matter of parsing the title in order to get the rate.

Monday, February 1, 2010

Of Pins and Pigeons

I met up with Cols at Serendra for lunch break. She's been complaining of migraine and her friend recommended she see the acupuncturist at The Spa. I'm not much on "alternative medicine". To me, acupuncture is a bit on the hocus-pocus side. But Cols' friends swear by it so she wanted to give it a try.

Unlike the usual acupuncturist from China who are typically old people, this guy is a Filipino-Chinese about my age. And he's actually a trained. licensed, and formerly, practicing neuro-surgeon. During one of his trips to China, he got curious about the Chinese alternative form of treatment and has since become a convert; preferring the less-invasive Eastern style of medicine over Western.

The session started with him putting his two thumbs on Cols' wrists with her palms facing up. Using his "powers", he seem to have correctly deduced several things. He said that Cols blood is "thick" making it hard to circulate. Because its getting stuck in certain sections of her veins, oxygenated blood is finding it hard to get to her brain -- causing the "migraine" and pain in her "batok".

Cols' blood really IS thick. In fact, her obstetrician made her take blood thinners during her pregnancy with both kids. As to how the acupuncturist was able to figure that out by just touching her veins was impressive. He went on to explain that she does not have enough water content in her blood making it thick also. If he starts telling me what Cols had for lunch by just touching her wrist, I would have fallen backward from my chair.

As Cols went to her cubicle for her session, the doctor chatted with me at the holding area. He explained to me the principles behind acupuncture. All bodies basically have the ability to heal itself. However, we fall out-of-tune with the natural rhythm of things every now and then. What the acupuncture needles do is re-orient or tune you back to the correct "station". And if you have to much heat, it adds cold, and vice versa. Its all about balancing the yin with the yang.

I've been experiencing pain with the sole of my foot so I asked him what he thought about it. He said that its not really my sole but more of the arch. I have to admit -- he's correct there too. He said the problem is my kidneys are weak. He explained that with Western medicine, the most important organ inside the body is the heart. But with Eastern medicine, its the kidneys. The heart does not except pump blood. But the kidney has a lot more function -- from cleaning our blood, to taking away the toxins and flushing them out through urine.

I also told him I've tried acupuncture once before because my palms are always sweaty and so are the soles of my feet. He said, again, its related to my kidneys. The explanation is that the kidneys are like reservoirs. If there's too much water, it "overflows". The overflowing liquid manifests through sweat on my palms and sole. This part takes a bit imagination to accept.

He could tell I was a bit skeptic so he gave several case studies where Eastern medicine supposedly triumphed over traditional Western forms of treatment. One other fact I learned is that a normal person's heart beat about 3 to 4 times within a single breathing cycle. If your heart beats faster than that, you're in trouble!

Cols' treatment lasted about half an hour. Then I got back to work for my next meeting at Mandaluyong. This meeting turned out to be also interesting and informative. It seems that there are these groups of pigeon enthusiasts all over the Philippines. These guys would conduct pigeon races every week. The mechanics is simple. They would all converge in an agreed place. Release their pigeons. Then determine which pigeon flew fastest.

The obvious question is -- how do you determine pigeon flight speed? Well, when you join a pigeon club (of which there are 70+ clubs all over the country), someone from the club will go to your house, which presumably is where you keep the pigeons, and take a GPS reading of your exact coordinates. Then whenever they have a race, they would also take the GPS reading of the place-of-release. Speed is determined by simply getting the distance from the place-of-release and its home (based on GPS readings) and dividing it by the time it took the pigeon to reach home.

The next obvious question is -- how do you then determine the time it took the pigeon to reach home. At the point of release, they would put a tag on the pigeon's foot. The tag has an outer code, and a "scratch-off" area which contains an inner code. At the time of release, the organizer sends an SMS to a particular number which acts as the time server. When the pigeon reaches home, the pigeon owner scratches off the inner code and txt-es it to the time server. The time server verifies the code and determines the time by simply subtracting arrival time from departure time.

What I can't figure out is -- does the owner actually sit out all night at home waiting for the pigeon to arrive? So that they can quickly get the tag; scratch off the code; and SMS it? I mean, what if the pigeon arrives in the middle of the night? Does that mean the owner does not get to SMS the code until the next day?

There is big money involved here. A race can fetch P500k up to P1M if there are several participants. It is not regulated by PAGCOR, even though I think its a form of gambling. The argument is that its treated more as a hobby and that only the owners can participate. This is unlike horse racing or cock-fighting where the audience (who neither own the horse nor the cock) can join and bet.

In any case, the only reason for the meeting is the organizers were looking at alternatives to the SMS-based time server and to discuss whether its something that we can develop for them.