Monday, December 10, 2007

"Newer Version" of GMail does not like Firefox

It is hard to believe, but our old faithful Google is producing a newer version which is badder than the older version.

I am generally happy with Firefox. But after the "newer" version of GMail is out, I am forced to use IE more, because Firefox will crash on GMail before I can do anything. These are frequent places of crash:

- send a new email;
- browse trash or spam folder;
- close a tab with GMail;

After switch to the "older" version of GMail, the crash problem goes away immediately. Hopefully the next "newer" version of GMail will be a better one.

Friday, December 07, 2007

Embedding Chart in Web Pages Made Easy

This week, embedding charts in your web page (either dynamic or static) is made extremely easy by the release of two new tools by Yahoo and Google. Both released free tools to help create chart online.

I am not sure if this is competition between Yahoo and Google or just coincidence. The two tools are released within the same week (this week):
YUI 2.4.0 released on 12/04/2007
Google Chart API released on 12/06/2007

The two tools actually complement each other.

Google Chart API:

Nothing can describe it better than the following text on their web site:
The Google Chart API lets you dynamically generate charts. To see the Chart API in action, open up a browser window and copy the following URL into it:|World

Press the Enter or Return key ...
- absolutely the simplest and the easiest chart tool I have ever seen;
- there is no CPU overhead on your web server and client's computer;
- may have problem serving chart over SSL (at least IE will complain about secure and non-secure content on the same page);
- chart is static, no user interaction;
- very limited control over chart's look and feel;
- can only show limited data range;
- can only show limited number of data points;
- your data has to be sent to a Google server, it may be a security concert;

Below is a sample chart serve by Google Chart API. It is the real thing! Served dynamically from Google's server farms! It takes me only 20 seconds to embed it into this blog.

Yahoo! User Interface Library (YUI):

YUI implementation is based on a Flash component. You will need to write JavaScript to control the data and look&feel on the Flash chart.
- Rich user interaction (there is potential to allow user zoom, pan, or edit charts);
- More control over look and feel;
- Can show more data;
- Can be hosted on your own server (no worry about Google being BIG BROTHER or going BANKRUPT);
- Less Internet traffic is required (only need to download data, not PNG or any other image files);
- Can serve live data (again, only data download is needed, we can afford to update the chart frequently);
- substantial JavaScipt programming and HTML editing is required;
- end user need to have Flash Player 9.0.45 or higher (not many people have that as on December 2007);
- end user's computer must have some spare CPU power, especially when multiple charts are embedded on the web page;

As an obvious proof of the difficulty to start using YUI, I am not willing to try to embed a sample chart here in my blog! :-(

The Verdict:
If you want a simple chart embedded on a static page or your blog, use Google Chart API.
If you have total control of your web server, and want to create powerful dynamic charts, use YUI 2.4.0's experimental chart component.

Last Words:
Of course, if you have enough server side CPU power and deep programming knowledge, server side chart rendering always give you ultimate control over the look and feel of your charts. On this end, you have these great open source libraries to help you: ZedGrap (C#), JFreeChart (Java), ASTRA (Flash).

Thursday, November 08, 2007

Error Installing ActiveX in IE

If an ActiveX component fails to install in IE, to find out the source of the problem, you just need to select IE menu: Tools > Internet Options, click "Settings" button in the "Browsing history" group, then click the "View files" button. There should be a file named like this: "?CodeDownloadErrorLog!name={XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}". This is the error log that contains a bit more information to help find the source of installation failure. The above description is based on IE 7, you should be able to find similar options in other IE versions.

In my specific case, the error log looks like this:

*** Code Download Log entry (07 Nov 2007 @ 10:01:26) ***
Code Download Error: (hr = 800c0300) Unknown Error!!
Operation failed. Detailed Information:

LOG: Item mfc42.dll being processed.
ERR: INF Processing: Failed (800c0300) processing: mfc42.dll
. Cannot get primary/default language!LOG: URL Download Complete: hrStatus:0, hrOSB:800c0300, hrResponseHdr:0, URL:(*****.CAB)
LOG: Reporting Code Download Completion: (hr:800c0300 (FAILED), CLASSID: e45975a1..., szCODE:(*****.cab), MainType:(null), MainExt:(null))

Below is the related section in the .inf file:

file=http://[Web Server]/

After I commented out the "FileVersion" parameter, the ActiveX component is installed successfully.

file=http://[Web Server]/

Since the problem only happens on Windows 2000 computers, and my development environment in Windows XP Pro. I suspect that the MFC42 library provided by me may not be compatible with Win2000. Or the MFC42 is already in use by Win2000, and Win2000 have difficulty upgrading to the newer version provided by me.

Wednesday, November 07, 2007

Reboot Remote Computer

"Remote Desktop" makes it easy to manage Windows computers remotely.

But, if you want to reboot the remote computer, you will be frustrated. Because there is no "Shut Down" button on the start menu. The trick is to click on the "Windows Security" menu which will bring up the "Windows Security" dialog which gives you the options to "Shut Down..." computer. You can also use the shortcut: Ctrl+Del+End to access the "Windows Security" dialog.

Friday, November 02, 2007

Aptana Out of Beta: 1.0 Released

Just noticed that Aptana has been out of beta. In the 2.0 era when everything stays "BETA" forever, this is a rare achievement.

In version 1.0, an open-source Community edition and a commercial Professional edition are available at the same time. The professional edition definitely deserves the nominal price it asked for. But as its name suggests, only professionals really have an urge for that edition. The free Community edition has enough features for 90 percent of its potential users.

My main IDE is still Visual Studio 2005. But the Javascript editor in Aptana is the best I ever seen. Its auto-complete is way better than even the latest Visual Studio 2008 Beta2.

Thursday, October 18, 2007

JSLint with ANT

"This is a java wrapper around the fabulous tool by Douglas Crockford, jslint. It provides a simple interface for detecting potential problems in JavaScript code."

With this tool, batch scan JavaScript files with JSLint is a piece of cake. Here is a sample ANT target:

<target name="jslint.src.js" depends="init">
<description>scan javascript files using jslint</description>
<apply executable="java" parallel="false" failonerror="false">
<arg value="-jar" />
<arg file="${tools.dir}/${jslint}" />
<arg value="--bitwise" />
<arg value="--browser" />
<arg value="--undef" />
<arg value="--widget" />
<srcfile />
<sort xmlns:rcmp="">
<rcmp:name />
<fileset dir="${web.js.dir}">
<include name="**/*.js" />
<exclude name="**/YUI/**" />
<exclude name="**/*-min.js" />
<exclude name="**/*-debug.js" />

For ease of future reference, JSLint output can be redirected to a text file:
ANT jslint.src.js > jslintreport.txt

YUI Compressor in ANT

Here is a sample ANT target to batch minify all JavaScript files using YUI Compressor:

<target name="js.minify" depends="init">
<description>minify js files</description>
<apply executable="java" parallel="false" failonerror="true">
<arg value="-jar" />
<arg file="${tools.dir}/${yuicompressor}" />
<arg value="--nomunge" />
<!-- line break set at 20 characters, so that we can get many line breaks, this
is good for debugging in IE-->
<arg value="--line-break" />
<arg value="20" />
<arg value="--preserve-strings" />
<arg value="--preserve-semi" />
<arg value="--charset" />
<arg value="ISO-8859-1" />
<arg value="-o" />
<targetfile />
<srcfile />
<!-- files are processed in alpha-order so that we can know the progress,
and easily identify the file that is failed.-->
<sort xmlns:rcmp="">
<rcmp:name />
<fileset dir="${src.dir}">
<include name="**/*.js" />
<exclude name="**/YUI/**" />
<!-- avoid cycling -->
<exclude name="**/*-min.js" />
<!-- define output file name -->
<mapper type="glob" from="*.js" to="*-min.js" />

About YUI Compressor: it is a tool to minimize JavaScript and CSS files. I have used it for more 6 months on a public web site without any problem.

About ANT:
I have been using APACHE ANT for 7 years, since 2001. To me, an ANT build file structure is more intuitive and scalable than MAKE files.
Apache Ant is a Java-based build tool. In theory, it is kind of like Make, but without Make's wrinkles.

This is the post that gets me started on this direction:
Building Web Applications With Apache Ant

Friday, September 28, 2007

Open Source File in Visual Studio 2005 with Auto-Complete

Just discovered this convenient feature of Visual Studio. It is not well publicized by Microsoft, but I believe it is one of those hidden gems of VS2005.

If you type ">open" followed with the file name in the "Command Windows" or "Find/Command Box", Visual Studio will search the whole solution and try to auto-complete the file name for you (see screenshot below).

There are 2 other approaches to open a source file in VS2005: 1. use the open file dialog; 2. expand the solution tree and double click on the file of interest.

This feature is very useful when you have solution with many projects. If you can remember the file's name, this feature allow you to open a file in under 10 seconds. With the other 2 approaches, you will have to browse up and down the project trees to find the file.

100,000 + 100 = 65635? Excel 2007 bug

100,000 + 100 = 65635?

The math is not right, but apprently Microsoft Excel 2007 wants you to believe that. See the screenshot below:

Ok, this is a recently published bug: when you ask Excel to multiply 77.1 by 850, it will show you 100,000, although it knows the correct answer. It messes up when formatting the answer on the screen. In cell A1, I actually have formular: "=77.1*850". :-)

Friday, August 31, 2007

YUI widget "Dialog" now depends on "Button Control"

Environment: YUI 2.3, IE 7.0

This is another problem I discovered during update from YUI 0.12 to YUI 2.3. As always, when updating library, there are many surprises that you have to run into.

Problem: Error message: "Error: Function expected" appears when I call the "render" method of YUI "Dialog" control a second time on the web page. Turn out the offending line is here: container.js, line: 6373,
if (oButton instanceof YAHOO.widget.Button) {

Why: The new "Dialog" implementation depends on the "Button" control now. Due to the above offending line, the dependency is not "optional" as stated in the documentation even if you don't use the new button control. If you don't include "button.js", you program will break at the above point.

Fix: If you are willing to change the source code, we can change the offending line to something like this:
if (YAHOO.widget.Button && oButton instanceof YAHOO.widget.Button) {
BUT, I am 80% sure, at another line, or in another control, I may run into the same problem again.
So, the best bet is to include "Button.js" to my web page.

Friday, August 24, 2007

ASTRA -- Open Source ActionScript 3.0 Library From Yahoo

Here is a first look of ASTRA: ActionScript Toolkit for Rich Applications.
ASTRA, the ActionScript Toolkit for Rich Applications, is Yahoo!’s collection of Flash and Flex components, libraries, toolkits and advanced applications. These libraries are open-source and available under the BSD license.

The "Flash Componet Library" is the library that really draws my interest. I only looked at this library. I guess, however, the "Web APIs Library" is the one YAHOO really want people getting attached too. :-)

The download is a complete package that starts to be useful within seconds
The download (9.6 MB) contains complete documentation, source code with detailed comments, examples, and binaries that can be installed into Flash CS3 directly. If you are only interested in using the components, you only need to double click the file "astra.mxp", the components will automatically installed and you can start to use it in Flash CS3. You will find the new components under "yahoo" folder. (Notice: if double click "astra.mxp" does not lead you to anything, please check you have installed "Adobe Extension Manager", a separate installation that can be downloaded here: It is not installed when you first install Flash CS3.)

Small Footprint
All the .swf files in example directory are no more than 50 KB (even chart samples).

Excellent learning tool
If you have reservation on using "Beta" libraries in your product, there may still be reason to have a look at this library. It's source code is fully commented, and neatly organized. This make it a great tool for beginners who are learning to use ActionScript 3.0 and trying to understand object-oriented programming.

As I said, being a "beta" library, we should expect a lot of bugs. After about 10 minutes playing with chart. I already found a few things worth mentioning. The Flash I created is here:
1. Rotated chart cannot be shown properly (although preview on the design surface seems to be ok);
2. Error handling of chart data is weak. It do not show any error message if "dataProvider" has string values. I also managed to make X axis shift to the right by 1 unit, which I don't know why it happens;

Thursday, August 23, 2007

Error: "YAHOO.util.CustomEvent is not a constructor"

The Problem: This error message ("YAHOO.util.CustomEvent is not a constructor") appears after I update my YUI library from 0.12 to the latest release (2.3). There was no such error before the update.

The Why: The new Container in YUI implementation fires CutomEvent at various stage, thus is dependent on the event utility. In my old web pages, the .js files happened to be included in the wrong orders (container.js was included before event.js) and caused this error message.

The Fix: include "event.js" before "container.js". Better yet, try the new YUILoader utility which claims to be able to load the correct libraries automatically.

The Lesson: Whenever you see an error like "[XYZ] is not a contructor", try to check for typo then file dependence.

Link: Also see this thread on YUI discussion group:

Thursday, August 09, 2007

Using SyntaxHighlighter on BLOGGER

SyntaxHighlighter is a
Free syntax highlighter written in JavaScript
It can insert colored code snippets on a web page using client-side javascript only. It is ideal tool for users of BLOGGER because we do not have server side resource to parse and highlight the code. And we are lazy, we do not want to write a lot of CSS to just post a code snippet. :-).

However it takes a little twisting to make it work properly.

Below are the steps to setup:
1. Download and find a place to host the library files for SyntaxHighlighter. A free choice is, of course, Google Page Creator;
2. Login to BLOGGER, go to: "Settings > Template > Edit HTML", make the following changes (credit goes to yehyeh's blog):

</div></div> <!-- end outer-wrapper -->
<link href='http://[YOUR HOST]/SyntaxHighlighter.css' rel='stylesheet' type='text/css'/>
<script src='http://[YOUR HOST]/shCore.js' type='text/javascript'/>

<script src='http://[YOUR HOST]/shBrushCpp.js' type='text/javascript'/>
<script src='http://[YOUR HOST]/shBrushCSharp.js' type='text/javascript'/>
<script src='http://[YOUR HOST]/shBrushCss.js' type='text/javascript'/>
<script src='http://[YOUR HOST]/shBrushJava.js' type='text/javascript'/>
<script src='http://[YOUR HOST]/shBrushJScript.js' type='text/javascript'/>
<script src='http://[YOUR HOST]/shBrushSql.js' type='text/javascript'/>
<script src='http://[YOUR HOST]/shBrushXml.js' type='text/javascript'/>

<script class='javascript'>
function FindTagsByName(container, name, Tag)
var elements = document.getElementsByTagName(Tag);
for (var i = 0; i < elements.length; i++)
if (elements[i].getAttribute("name") == name)
var elements = [];
FindTagsByName(elements, "code", "pre");
FindTagsByName(elements, "code", "textarea");

for(var i=0; i < elements.length; i++) {
if(elements[i].nodeName.toUpperCase() == "TEXTAREA") {
var childNode = elements[i].childNodes[0];
var newNode = document.createTextNode(childNode.nodeValue.replace(/<br\s*\/?>/gi,'\n'));
elements[i].replaceChild(newNode, childNode);

else if(elements[i].nodeName.toUpperCase() == "PRE") {
brs = elements[i].getElementsByTagName("br");
for(var j = 0, brLength = brs.length; j < brLength; j++) {
var newNode = document.createTextNode("\n");
elements[i].replaceChild(newNode, brs[0]);
//clipboard does not work well, no line breaks
// dp.SyntaxHighlighter.ClipboardSwf =
//"http://[YOUR HOST]/clipboard.swf";


3. Now you can post code snippet on BLOGGER using either "pre" or "textarea" tag.

  1. The solution above is found here: That blog was written in Chinese. I made some minor changes and posted here. The reason for the Javascript code to remove <br/> tags is because BLOGGER has a setting to automatically add <br/> where there is line break. It is very convenient feature for blog posters, but somehow syntax highlighter will display the <br/> tag in plain text;
  2. Clipboard for the SyntaxHighlither does not work well here. It tends to give you the text without line breaks, so I commented out the Javascript that setup the clipboard function;
  3. When posting HTML code, remember to replace < with &lt;, and replace > with &gt;;
Now you've got beautiful code in your blog, next step might be some nice charts for your blog. You will find a way to embed a chart with one line HTML code here: Embedding Chart in Web Pages Made Easy
And, here is a post to show you how to Embed Silverlight video on Blogger:Embed Silverlight Streaming in Blogger

Update 11/11/2008
There are a few questions and comments regarding script hosting. .NET Dev posted an interesting idea here:

Basically, he setup the links directly to the trunk location of SyntaxHighlighter project.

Update 07/07/2010
I found using is way easier to paste syntax highlighted code in blogger. Here is my post showing you how to use it:

Syntax Highlighting on Blogger - Gist

Tuesday, August 07, 2007

Free Screen Capture Tools for Windows

Here are two free screen capture tools that work decently well for small tasks:

1. CamStudio 2.0: Open Source software that comes with Visual Studio solution, and Win32 installation package. It works very well. Can capture to .AVI, and has a tool to convert AVI file to .SWF file and a HTML template to embed the Flash file. The captured file size is big. 40 seconds capture generated 20MByte AVI file and 1.5MByte SWF file.
SourceForge Host:
CamStudio - Free Streaming Video Desktop Recording Software
: read the "Issues" section on this page. You will need to manually edit the generated HTML template in order for it to play in Firefox or Netscape.

2. Windows Media Encoder: Free Microsoft tool for video capture and editing. Capture result is WMV file format. File size is very small. But I recommend to use at least medium quality option which will generate a 500 KByte WMV file for 40 seconds capture.

My environment: Windows XP Professional, Dual Monitor

Thursday, July 19, 2007

Javascript "Empty Statement"

Spot anything wrong in the Javascript below?
var a=[];
//initialize array
for(int i = 0; i < 10; i++);
a[i] = 100;

Values in array a will be:
[undefined, undefined, 100]

The semicolon at the end of the for loop forms an "Empty Statement". So a[i]=100; is actually outside of the for loop!

Wednesday, July 18, 2007

Reload Magellan MobileMapper CE OS Firmware

Where to download MobileMapper CE OS Firmware Image

Some Magellan official documentations have this out-dated information about location of MobileMapper CE OS firmware download location:
"The current version of MobileMapper CE Operating System (OS) firmware can be downloaded from in the /Mobile Mapping/MM CE/Firmware/OS Firmware/ folder."
This turned out to be out-dated information. The above directory does not exist on the FTP server. After some digging, I found the OS firmware in this zip file:
Notice: the above FTP location is accurate as 7/18/2007, may be changed by Magellan.

What Happened

I saw low battery warning on the device. Naturally, I select "Full Shut Down" to allow the system do a proper backup. This turned out to be a mistake. Apparently, battery was out before the device can fully shut-down, and the OS firmware image is corrupted. After this, upon each reboot, I am asked to calibrate stylus, then there are 2 dialogs:
Dialog 1: dialog title: "Warning", Text: "This is a Rescue Image! The
Main Image failed to start. Press "Cancel" to Retry Main Image. Press
"OK" to continue with Rescue Image."
After I press "OK" which is the only button on the dialog, I am lead to
the second dialog:
Dialog 2: dialog title "OS Loader", Text: "Please choose a new image
file. The image file cannot be in the MyDevice directory."
After I press "OK", an "Open File" dialog appears with option to load a
file type: Image Files (*.nbx).

Following the instruction in "Getting Started Guide", page 61 "Updating MobileMapper CE OS Firmware", I was able to load the OS image I downloaded from Magellan. The system seems to be back to proper working order afterwards.

Lesson Learned

When you have low battery warning, rather than to risk corrupt the OS firmware image, it is probably better to wait for the battery to die out or, if possible, recharge the battery immediately.

Friday, July 13, 2007

Invoke CTRL-ALT-DELETE on Remote Desktop

When you are connected to other Windows computer using Remote Desktop Connection, the combination CTRL-ALT-DELETE will invoke the local computer's logon screen or task manager. Use CTRL-ALT-END to invoke it on the remote computer.

Thursday, July 12, 2007

Delay Load DLL and __HrLoadAllImportsForDll

Here are a few tips for delay loaded DLLs based on my experience with Visual Studio 2003 (Visual C++ 7.1)

  1. Delay load can be easily setup using the Visual Studio IDE by the following steps:
    • Open project property page: Linker > Input
    • In Additional Dependencies, add library: delayimp.lib;
    • In Delay Loaded DLLs, add all the DLLs you want to delay load.
      TIP #1: if you have more than one DLLs, the file names must be separated by ";", e.g.: rapi.dll;ceutil.dll. If you forget this, and try something like: rapi.dll ceutil.dll, then the linker will treat the whole string as the file name of a single file and fail to find a file with that name. There will be a subtle warning during build: LINK : warning LNK4199: /DELAYLOAD:rapi.dll ceutil.dll ignored; no imports found from rapi.dll ceutil.dll, which most likely will be ignored.
  2. Detect if the delay loaded DLLs exists on the host computer:
    The whole purpose of delay loaded DLLs is to allow our program to be more flexible. It can be loaded on computers that do not have certain DLLs, and it can choose to use those DLLs when they are present. So, there is always a need to know if we can load the delay loaded DLLs on the host computer. __HrLoadAllImportsForDll is the recommended function by MSDN documentation to do the job.
    TIP #2:Do not use __HrLoadAllImportsForDll because it use memcmp to compare DLL file names byte by byte which is too strict. File names in Windows system is not case sensitive, so the file names can be the same even if memcmp fails. This function will return module not found error code even when the DLL files are installed on host computer. I end up lift the implementation from delayhlp.cpp, and replace memcmp with _tcsicoll which is case insensitive.

Friday, July 06, 2007

Regular Expression Designer

Writing regular expression is always tough for me, not to mention trying to read regular expressions written by other programmers. I found this excellent FREE tool: Regular Expression Designer provided by a Sydney based company.

As you can see from the screen-shot below, it makes it very easy to experiment and visually inspect output of regular expression applied against various text input. You can try MATCH, SEARCH or REPLACE with one click. Match results are displayed in a tree format, so that you can instantly see all the matches and captured groups. An online help of regular expression language elements is provided as a quick reference.

This application only runs on Windows computer with .NET Framework 1.1 or 2.0.

Thursday, July 05, 2007

Boost.Regex with MFC/ATL in Visual Studio 2003 or Above

Searching, parsing, and validating text input is always a big part of contemporary programming. Regular expression is a powerful tool that is available to C#, Java, Perl, ... Unfortunately, it does not come with C++ or MFC library. One of the best regular expression library in C++ is Boost.Regex, which is accepted as part of C++ standard library in the next release of C++ standard. Boost.Regex library provides direct support for MFC/ATL string types, so that integration with MFC/ATL project is very straightforward. However, integrating BOOST library into Visual Studio 6.0 or older is very hard, due to their lack of standard C++ support.

To use Boost.Regex in a MFC/ATL project in Visual Studio 2003 or above is very easy. Just follow these steps:
  1. Download installation package created by Boost Consulting, following the links: Products > Free Downloads, you will find installer for latest BOOST library distribution. Just run the installer, it will automatically download the selected BOOST library source code from a and pre-compiled binaries from a mirror site;
  2. Setup VC++ include and library directories for BOOST libraries, detailed instructions can be found here: BOOST--Getting Started on Windows;
  3. If you are like me, getting very comfortable using MFC/ATL string types like CString, CStringW, TCHAR, _T, ... Please notice BOOST libraries normally only support standard string type. Please read this before you start to write code: Boost.Regex--Working with MFC/ATL String Types. Boost.Regex does provide a set of overloaded functions that use MFC/ATL types, you will need to include a header file: <boost\regex\mfc.hpp> which defines all the overloaded Boost.Regex APIs as shown in the document;
A sample code:
   1://boost regular expression library
2:#include <boost/regex.hpp>
3://support for MFC string types in boost Regular Expression library
4:#include <boost/regex/mfc.hpp>
6://extract string value from XML by given key
7://Example: given the string below, and key="LogFile"
8://<add key="LogFile" value="c:\temp\error.txt" />
9://return will be: c:\temp\error.txt
10:CString GetXMLValue(LPCTSTR xmlContent, LPCTSTR key)
12: CString strRegEx;
13: strRegEx.Format("<add\\s+key\\s*=\\s*\"%s\"\\s+value\\s*=\\s*\"([^\"]*)\"\\s*/>", key);
14: tregex re(strRegEx);
15: tmatch matches;
17: //we are expecting no more than 1 match in the file
18: if(regex_search(xmlContent, matches, re))
19: {
20: //extract the value from sub-expression
21: return CString(matches[1].first, matches[1].length());
22: }
23: else
24: {
25: return "";
26: }

Static link to Boost.Regex library for the above sample code, adds about 80K to the compiled binary output.
Official documentation of Boost.Regex library:

Tuesday, July 03, 2007

CeCopyFile (RAPI) Requires Both Files on Remote Device

There is no mention of this restriction in MSDN documentation, but be aware that CeCopyFile requires both lpExistingFileName and lpNewFileName refer to files on remote device. If you want to copy files from PC to remote device or from remote device to PC, you can refer to samples: Pget, and Pput provided in Windows Mobile SDK (in Mobile 5.0 SDK, the samples are under: Samples\CPP\Win32\Rapi).

Definition of CeCopyFile:
BOOL CeCopyFile(
LPCWSTR lpExistingFileName,
LPCWSTR lpNewFileName,
BOOL bFailIfExists

Monday, July 02, 2007

C++ Primer (Recommended Book)

Title: C++ Primer (I own the 3rd Edition)
Authors: Stanley B. Lippman, Josée Lajoie

Bottom Line: A keeper. Highly recommended. With its accurate and complete coverage, concise text and short code samples, this book serves as a good C++ reference book for intermediate or advanced C++ programmers. But definitely not a book for beginners.

This is the 1st and the only C++ book I have. The books has been on my shelf for 6 years. I was already familiar with C++ when I bought this book, and I find this book very useful through out the years. It covers EVERY fine details of standard C++, and the information is ACCURATE and CLEAR.

At first, I spent a few weeks browse through it. I found it has tremendous amount of new information for me -- an self-taught intermediate level C++ programmer.

But, if you are beginner trying to learn C++ and Object-Oriented programmer, I would recommend you to find another book.For one thing, in many places, there are terms referencing concepts in future chapter that make you having to read the book in two passes to understand it. Then there are too much fine details about C++, and too little practical guides. Even if you manage to read the book, it could easily take you a full year to finish this book and emerge in all the intricacy about C++, then come out not able to write a single program. There is NO full-blown sample program, nor step by step guide to setup development environment.

Due to its sheer volume and broad coverage, I didn't read the book cover to cover. Instead, I kept this book as a C++ standard reference. Whenever I have doubt, I lookup the index and read the related chapters. The books is written in concise and clear language, and has coverage of many minor details that cannot be easily find elsewhere. Having to juggle between C, C++, C#, Javascript, and SQL, I constantly need to refresh my memory about subtle C++ issues. To be honest, even if I work with C++ every day, I do not think I can master the full-depth of C++ language. C++ is a powerful language that provides many opportunities for programmers to express their ideas. This books is the perfect reference tool for me, it provides all the details about a language feature with enough details (but not too long to read) to remind me of the key points very quickly and precisely.

If this book is not a keeper that I feel deeply indebted to, I would not have the urge to write about it. :)

Thursday, March 29, 2007

Escape CSV string in XSLT

To output CSV format, we will need to escape a field if it has quote, or comma or line feed. To escape a CSV string in XSLT is not a straight forward task. After a little search I found the following solution which passed my test. The code is from a thread I found here:

 48:  <!-- Sample of calling the escape template -->
49: <xsl:template match="*">
50: <xsl:call-template name="display_csv_field">
51: <xsl:with-param name="field" select="myFieldToEscape"/>
52: </xsl:call-template>
53: </xsl:template>
55: <!-- Template to escape csv field -->
56: <xsl:template name="display_csv_field">
57: <xsl:param name="field"/>
59: <xsl:variable name="linefeed">
60: <xsl:text>&#10;</xsl:text>
61: </xsl:variable>
63: <xsl:choose>
65: <xsl:when test="contains( $field, '&quot;' )">
66: <!-- Field contains a quote. We must enclose this field in quotes,
67: and we must escape each of the quotes in the field value.
68: -->
69: <xsl:text>"</xsl:text>
71: <xsl:call-template name="escape_quotes">
72: <xsl:with-param name="string" select="$field" />
73: </xsl:call-template>
75: <xsl:text>"</xsl:text>
76: </xsl:when>
78: <xsl:when test="contains( $field, ',' ) or contains( $field, $linefeed )">
79: <!-- Field contains a comma and/or a linefeed.
80: We must enclose this field in quotes.
81: -->
82: <xsl:text>"</xsl:text>
83: <xsl:value-of select="$field" />
84: <xsl:text>"</xsl:text>
85: </xsl:when>
87: <xsl:otherwise>
88: <!-- No need to enclose this field in quotes.
89: -->
90: <xsl:value-of select="$field" />
91: </xsl:otherwise>
93: </xsl:choose>
94: </xsl:template>
96: <!-- Helper for escaping CSV field -->
97: <xsl:template name="escape_quotes">
98: <xsl:param name="string" />
100: <xsl:value-of select="substring-before( $string, '&quot;' )" />
101: <xsl:text>""</xsl:text>
103: <xsl:variable name="substring_after_first_quote"
104: select="substring-after( $string, '&quot;' )" />
106: <xsl:choose>
108: <xsl:when test="not( contains( $substring_after_first_quote, '&quot;' ) )">
109: <xsl:value-of select="$substring_after_first_quote" />
110: </xsl:when>
112: <xsl:otherwise>
113: <!-- The substring after the first quote contains a quote.
114: So, we call ourself recursively to escape the quotes
115: in the substring after the first quote.
116: -->
118: <xsl:call-template name="escape_quotes">
119: <xsl:with-param name="string" select="$substring_after_first_quote"/>
120: </xsl:call-template>
121: </xsl:otherwise>
123: </xsl:choose>
125: </xsl:template>

By the way, remember to set the XSLT's output like this:

<xsl:output method="text" encoding="iso-8859-1">


Wednesday, March 28, 2007

Serialization of UTC DateTime from SQL database is still awkward

Although treatment of UTC DateTime in .NET 2.0 is significantly improved, handling data selected from SQL database is still awkward.

If you try to serialize a DataSet selected freshly from SQL database, value of a DateTime column will look like this:


While, I really want to see something like this:

This behavior is to keep compatibility with .NET 1.1. However, trying to change this default behavior is awkward. The best I can find is to change DataSet schema before rows are added (after rows are added, you can only change between "Unspecified" and "UnspecifiedLocal"). Anyway, here are a couple of lines of code that eventually helped me to get the desired output:
   1:        /// <summary>
2: /// fills the dataset using the select command.
3: /// In this function, we assume all DateTime in database is UTC, and fixed
4: /// types here.
5: /// </summary>
6: public int FillDataSet(DataSet dataSet)
7: {
8: int numRowAffected = 0;
9: SqlConnection connection;
10: SqlCommand command;
11: //code to initiate connection, command
13: connection.Open();
14: SqlDataAdapter sqlDA = new SqlDataAdapter();
15: sqlDA.SelectCommand = command;
16: sqlDA.MissingSchemaAction = MissingSchemaAction.AddWithKey;
18: //a detour:
19: //it is still awkward to serialize UTC DateTime from database.
20: //fix DateTime type, assuming all are saved in UTC time
21: //we cannot change type after rows are added, so
22: sqlDA.FillSchema(dataSet, SchemaType.Source);
23: Utilities.SetDateTimeMode(dataSet, DataSetDateTime.Utc);
25: numRowAffected = sqlDA.Fill(dataSet);
26: connection.Close();
27: return numRowAffected;
28: }
30: /// <summary>
31: /// Set all the data columns to speicified mode.
32: /// (only Unspecified or UnspecifiedLocal can be set after rows are added.)
33: /// </summary>
34: /// <param name="data"></param>
35: /// <param name="dtMode"></param>
36: public static void SetDateTimeMode(DataSet data, DataSetDateTime dtMode)
37: {
38: foreach (DataTable dt in data.Tables)
39: {
40: SetDateTimeMode(dt, dtMode);
41: }
42: }
44: /// <summary>
45: /// Set all the data columns to speicified mode.
46: /// (only Unspecified or UnspecifiedLocal can be set after rows are added.)
47: /// </summary>
48: /// <param name="dt"></param>
49: /// <param name="dtMode"></param>
50: public static void SetDateTimeMode(DataTable dt, DataSetDateTime dtMode)
51: {
52: foreach (DataColumn col in dt.Columns)
53: {
54: if (col.DataType == typeof(DateTime))
55: {
56: col.DateTimeMode = dtMode;
57: }
58: }
59: }

This newsgroup thread has help me develop the above strategy: How do I set the DateTimeMode property when filling a DataTable. It is posted on microsoft.public.dotnet.framework.adonet

Friday, March 09, 2007

Aptana Perspective Bug

I am now officially a fan of Aptana. With Visual Studio like auto-complete and helpful compatibility information popup, Aptana proved to be a powerful Javascript editor. I even tried to use Aptana HTML editor to edit Javascript embedded in .aspx files with great success.

Here is a bug (or maybe I expected too much?) that caught me off-guard when I am trying to customize Eclipse perspective:

After opening "Aptana" perspective, I selected menu "Window"->"Save Perspective As", and saved perspective as "My Workspace" so that I can make changes without ruining the original Aptana perspective. Then I noticed that after I restart Eclipse "Code Assist Profiles", "Outline" and "Actions" no longer work. It took me a while to figure out the root reason is that I am not using THE "Aptana" perspective. After I select back to "Aptana" perspective, everything works again. In my opinion, this is not how perspective supposed to work. I should be able to make a copy of their perspective and add my own customizations.

I have reported the bug to Aptana:

Thursday, March 08, 2007

View Generated Source in IE

I have "Web Developer" add-on for Firefox installed for a while. I love the "View Generated Source" function. Recently, I discovered an excellent way to add this functionality to IE by Favelet or Bookmarklet. This approach is inspired by the reference links below. I tried 2 variations of the Favelet, and end up using the first one.

javascript:void("javascript:'<xmp>' +
opener.window.document.documentElement.outerHTML + '</xmp>'"));

Good: HTML source is shown in new window.
Bad: Only works for pages served from localhost, due to IE's policy against cross domain access. However, this is not a concern for me, because the main reason I want to see "generated source" is for web development on local computer.


To make this function easily accessible, I added it to IE bookmark "Link" folder (see screenshot below). Now, I can see the generated source (including generated HTML and Javascript) with just one click on the link named "source".

Related Links:

Monday, March 05, 2007

JSON.JS and ASP.NET AJAX Extension

JSON.JS was always an important part of my JavaScript library. But, after I start using ASP.NET AJAX extension, I found out that there is a conflict between JSON.JS and AJAX extension.

What is wrong:
On one web page with both AJAX extension control "Accordion" and JSON.JS. I get these error message during page load:
  • Sys.Res has no properties
  • Sys.Application has no properties
  • Sys.UI.DomEvent has no properties

If I edit web.config, change debug="true" to debug="false", these loading errors disappear. But, I found Accordion's performance is very bad. The whole page is held up for at least 10 seconds after each click.

Now "Firebug" comes for the rescue. The "profile" tool in Firebug is very easy to use. It only took me 2 minutes to find out the offender. Just switch to "Console" tab, and click on "Profile", then start clicking on the page. After I am done, I click on "Profile" button again to stop profiling and see the report of activities. Not surprisingly, "toJSONString" is number 1 CPU consumer (see screen shot below). So, the conclusion is obvious, JSON.JS cannot live in the same space as AJAX extension.

Work around:
Now that AJAX extension does not like JSON.JS, and they DO have an alternative to JSON.JS. A reasonable work around is to stop using JSON.JS, and start use the functions provided in Microsoft AJAX library. So here are the alternatives: Sys.Serialization.JavaScriptSerializer.serialize

By doing this, did I fell into one of Microsoft's secret agenda?