Three more code samples

clock February 28, 2008 09:46

We just posted three new apps in our Code Samples section:

A complete Web Browser is what its name implies. This sample uses the WebBrowser control to implement a full-featured web browser, which supports URL auto-completion, printing, HTML source window, favorite window, and progress bar. VB Migration Partner can migrate it without adding any pragma!

ezDatabase is a demostration of virtually all ADODB features. VB Migration Partner convert this sample correctly at the first attempt, therefore it is also a great demo of VBMP's converting features. Unfortunately, the original VB6 code has a few bugs and they are migrated as well. (In other words, if you see any malfunctioning in VB.NET code, check the original VB6 code before putting the blame on VB Migration Partner )Wink

LCD Clock is a simple digital clock with many options. You can move on top of other window and move with the mouse. It has other intriguing features, all of which are correctly migrated to VB.NET. We needed just one WriteProperty pragma to beautify the user interface.

Note for Beta testers: current version 0.94 can't correctly migrate the WebBrowser sample, due to a number of bugs for the WebBrowser control that we've fixed after the 0.94 release. The support library that comes with these samples doesn't suffer from these bugs.


Version 0.94 is out!

clock February 26, 2008 04:15

Another little step towards the official 1.0 release...

 Version 0.94 adds many important features, including:

  • the ability to clear the typelib cache when the program starts (in Options-General)
    The typelib cache is an area of your hard disk where VB Migration Partner stores the .NET assemblies resulting from the conversion of COM type libraries, and is useful to speed up execution. We now provide the option to clear this cache when the program starts because it might solve a few issues that might occur when your VB6 app references a .NET DLL via interop and you've recompiled the .NET DLL. Also, disabling this option allows to run multiple instances of VB Migration Partner (which might raise problems if automatic typelib cache clearing is enabled)
  • a new setting to decide how many migration errors and warnigns are displayed in the bottom pane and the initial status of Errors/Warnings/Infos/ToDos switches (in Options-Results)
    Many beta testers asked for this feature, which is essential when migrating very large applications. When you have thousands of messages in the bottom pane, switching between windows is painfully slow. This new option greatly reduces this problem. (Incidentally, this is the very reasons why Visual Studio has an upper limit to the number of compiler messages that can be displayed in its Error List pane.)
  • A new command allows you to quickly edit the master VBMigrationPartner.pragmas file, located in VB Migration Partner's install folder. By putting pragmas in this file you can control the default behavior used when migrating several VB6 statements, for example how arrays with nonzero LBound are migrated, or whether the support for default members is enabled by default. Of course you can always override such settings with pragmas inside individual projects.
  • The AxWrapperGen utility has been greatly improved, which means that it is now easier to create wrappers for 3rd party ActiveX controls.
  • A warning is emitted if the VB6 project contains a pragma that should be located in a *.pragmas file, for example an AddLibraryPath or ProProcess pragma.

We also fixed nearly 50 bugs, so the program is better and more stable than before. As usually, you can learn more by browsing the VERSION HISTORY.TXT file, in VB Migration Partner's install folder.

Comparing the & operator, the String.Concat method and the String.Format method

clock February 20, 2008 12:16

You might be aware that VB.NET supports at least 4 techniques to append strings:

    1) the & operator (or the + operator)

    2) the String.Concat static method

    3) the String.Format static method

    4) the StringBuilder object and its Append and Insert methods

By peeking at the code that the VB.NET compiler generates for the & (or +) operator, you can quickly realize that this operator is rendered as a call to the String.Concat method, thus using either technique #1 or #2 has no impact on performance and is just a matter of coding style. I usually prefer the & operator over String.Concat for readibility's sake, and I guess most VBers do the same, but it should be clear that the two are perfectly equivalent if you are concerned only about speed. (NOTE: when working with values other than strings, you might find String.Concat more readable, because it doesn't force you to explicitly invoke the ToString() method of each operand.)

When working with long strings that undergo many concatenations, the StringBuilder object is the fastest technique, period. Too much digital ink has been spilled on this topic, and I won't repeat those well-known concepts here. (BTW, if you're looking for a smart way to replace the & operator with the StringBuilder object without messing up your existing code, read here.)

However, when you have to perform a few concatenations on many short strings, the overhead needed to setup the StringBuilder object often shadows the benefits of its Append method. In these scenarios, the choice is among techniques #1 (or #2, which is equivalent) and technique #3. Today I decided to take some time to compare their performance. I run 100,000 concatenations over two or more 10-char strings. Here are the results on my on a 2.20 GHz Core Duo, 2G RAM Dell notebook running Vista (timings are in milliseconds and are averaged over several runs):

# of operands   Concat    Format
2                  12         60
3                  22         95
4                  28        150
5                 125        160
6                 185        192
7                 210        215
8                 235        239
9                 270        272

To summarise, the Concat method runs 4-5 times faster than Format with 4 operands of fewer, but there is no significant difference with 6 or more operands. It is interesting to notice the steep increase (from 28 to 125 milliseconds) for the Concat method when passing fro 4 to 5 arguments. The reason: there is no String.Concat overload that takes 4 arguments, therefore the VB.NET (and C#) compiler has to build a temporary array with 5 elements and pass it to the String.Concat overload that takes a ParamArray. The same thing happens with the String.Format method when you pass from 3 to 4 arguments.

In general, I prefer to use the String.Format method when appending 3 or more strings, except inside time-critical code. For example, I use it for building error messages and other UI elements; in this case the loss of speed rarely (or never) affects the overall execution speed. Another advantage of String.Format is that you can easily create a table of messages and store them on a database, an XML file, or just a plain text file (possibly stored as a resource). For example, all VB Migration Partner error and warning messages are stored in a format like this:

        Using the '{0}' Windows API method as an argument to the '{1}' function might result in an string filled with spaces. Please split the next line in two statements.

This approach makes the code more readable and maintenable. Plus, localizing the code for a language other than English will be a breeze, if I ever need to.


Speaking ofconcatenations, the fact that Concat, Format and other static methods of the System.String class have an overload that takes a ParamArray (and therefore a standard array) makes it possible to implement a few nice tricks. For example, you can quickly concatenate all the elements in an array using this code:

    Dim arr() As String = {"one", "two", "three", "four"}
    Dim res As String = String.Concat(arr)    ' => onetwothreefour

If you need to use a delimiter between each element or concatenate onlya subset of the array, use the String.Join method:

    res = String.Join(" ", arr)         ' => one two three four
    res = String.Join(" ", arr, 1, 2)   ' => two three

When working with arrays of 10 elements or fewer, or you are interested in just the first 10 elements, you can use the Format method in creative ways, as in this code:

    ' display elements in random order
    res = String.Format("{3} {1} {0} {2}", arr)    ' => four two one three