Programming in C#, Java, and god knows what not

VB 6.0 in Windows 7

Visual Basic 6.0 will be supported under Windows 7. That means ten more years of runtime being shipped with OS and all applications “just working”. This support is for runtime and supported runtime files (mostly those that came with it). There is no support for controls that were not part of VB 6 delivery (some VB 5 compatibility files).

Development environment (IDE) hasn’t had same fortune. It’s officially supported life already ended but it does work fine on Windows 7 beta 1. I just hope that it will stay like that for final version also.

Edit and Continue

Illustration

Long time ago, I have sinned. Yes, I used Visual Basic 6.0 to make programs. Even worst, I got paid to do so.

My work involved working with medical devices (oh, AxSYM, how I miss you…) there was one killer feature for me. Ability to set breakpoint, change some code and resume from that point was priceless. I would connect to device, when something in communication goes wrong, I would edit code in place, fix a bug and continue onto next packet. I could afford myself to be lazy (ok, there were timeouts to consider) and fix few bugs that occurred in single session. How did I liked it.

When .NET came I was missing that feature. I cannot say I was too sorry for old VB since new VB.NET was so much more powerful, but some things took a little more time and concentration to be done.

For Visual Studio 2005, there was a treat for me. They reintroduced that very same feature as “Edit and Continue”. It wasn’t as good as one in Visual Basic 6.0, even small changes would force you to restart, but smaller adjustments were possible. Life was good.

Recently, I switched to 64-bit system. I figured that since 64-bit systems were gathering momentum, so should I.

Illustration

It was not as smooth transition as I hopped. There were driver problems, non-working 16-bit programs, some API calls that kept failing since I had int instead of IntPtr. All those things are nothing compared to not having “Edit and Continue” again.

Not only that I lost it, there is stupid dialog that reminds me of it every time. You can turn whole feature off in order to prevent that annoying dialog, but then you cannot play with it even on 32-bit applications (yes, feature still works if you compile for x86).

I do not use it often anymore. It is just to annoying to switch between Any CPU and x86 platforms. However, when I have some weird problem at hand, and I see that lot of debugging is involved, switching temporary into 32-bit world is small price to pay.

Small Basic

My first programming steps were done in GW-BASIC but quite soon I switched to QBASIC. Those languages were simple to learn and they gave instant results. Yes, you couldn’t do anything really big (or useful) in them, but they had a power to make your eyes glow when some simple idea became a real program.

When I started programming for money I switched to C/C++ for a while, until I discovered Visual Basic. Although it had lack of C/C++ power and control, no one can deny development speed (faster I create something, more money I earn).

Illustration

It is hard to recommend any high-level language for learning programming to kids. You just need to learn too much of boring stuff in order to do anything that looks even remotely fun.

But now, there is Small Basic. That language doesn’t even try to be serious. Whole point is just to have fun - not productivity. It’s interface is simple and nice. Intelli-sense is not only useful and descriptive (it is more detailed than some help files I saw) but it really gives you that “someone gave this some thought” feeling.

It does borrow some nice ideas from other “kid languages” (turtle from LOGO comes to mind) but there are some ideas that will take a kid instantaneously. For example, there is special class for accessing Desktop (e.g. change wallpaper) and accessing photos on Flickr. If that doesn’t enchant your kid, I don’t know what will.

Illustration

If you, as a big kid with big toys, feel left out in this story - you are wrong. You can extend this gem with your code written in .NET thus giving your kid access to “only sky is a limit” world of ideas. You and your kid can do each its part of code and have fun. I find this precious.

Open Packaging Convention

For it’s XML based file formats (XML Paper Specification and Office Open XML) Microsoft used zip file as storage (not a new thing - lot of manufacturers did use it before). If one is using .NET Framework, support already comes built-in (i think from version 3.0 but I didn’t bother to check - if you have 3.5, you are on safe side).

Since every package file can consist of multiple parts (look on it as files inside of package) it seemed just great for one project of mine.

ZipPackage

Illustration

Class that handles that all is ZipPackage. It uses little bit newer specification of zip format so support for >4GB files is not an issue (try to do that with GZipStream class). Although underlying format is zip, it is rare to see zip extension since almost every application defines it’s own. That makes linking files and program a lot easier.

But there is (in my opinion of course) huge stupidity in way that writing streams is handled. Every stream first goes to Isolated Storage folder which resides on system drive. Why is that problem?

Imagine scenario where your system drive is C: and you want to create file on drive D: (which may as well be over network). First everything is created on drive C: and then copied to drive D:. That means that whatever amount of data you write, this class writes almost twice as much on disk - once uncompressed data goes on C: drive and afterwards gets compressed on drive D:.

That also means that not only you need to watch amount of disk space on your final destination but also your system drive needs to have enough space to hold total uncompressed content.

Even worse, if program crashes during making of package, you will get orphaned file in isolated storage. That may not be an issue at that moment but after a while system may complain about not having enough space on system drive. Deleting orphaned files could also prove to be difficult since it is very hard to distinguish which file belongs to which program (they have some random names).

Weird defaults

There is also issue that when you first create a part, it’s compression option is set to not compressed. That did surprised me since one of advantages of zip packaging is small size. Since every disk access slows things down, having file compressed is advantage.

Since every part is can have separate compression option, I tend to set them to Normal for most of it. Only if I know that something is very random (encrypted or sound), I set it to no compression. Speed is little bit slower when reading compressed data but I am still to find computer so slow that I have issue with uncompressing data.

To use it or not

I do hope that next version of framework will optimize some things (e.g. just get rid of temporary files). However, I will use it nevertheless since it does make transfer of related files a lot easier. Just be careful that there is enough space on system drive and everything should be fine.

If you want to check it, there is simple sample code available.

Microsoft Access X64

As many of you, I am a sinner. I have been using .mdb as database of my choice for small projects. I knew even then that there are better choices out there but .mdb was easy accessible over OLEDB, in need you could use Microsoft Access to edit database (yes, I did ugly “just this time” fixes on data), it didn’t kill machines with small amounts of RAM and its network model was sufficiently fast on local networks (although someone may argue whether it had any network model at all).

Story of one bug

As I sometimes do, I got bug report for one of old programs. Since I like to confirm things first, I opened project in Visual Studio 2008 (of course, conversion was needed since that was 2005’s project) and started it. There was a strange error: “The ‘Microsoft.Jet.OLEDB.4.0’ provider is not registered on the local machine.”. Of course, reading is not necessary for my level of experience so instead of analyzing what was said to me, I decided to install Visual Studio 2005 and run the program without conversion. Same error.

Google

My blind faith in google forced me to try bunch of stuff. One wise guy said that Vista comes without MDAC so I tried to install it. Other one said that you need to manually register MDAC files. I did that also. After installing all possible updates (did you know that Jet 4.0 is at SP8?) I decided to search Microsoft’s support. First page offered was one with my problem. There is no 64-bit version of Jet. OLEDB provider. At that minute I remembered that I do run 64-bit Windows…

Solution

Once I finally knew what exactly is problem here, solution was easy. We just need to go back to 32-bit world in order for things to work.

Illustration

Illustration

In C# that is done in Project Properties, Build page. Just select x86 as platform target and everything will start working as it was before. In case you have some dlls that access database, you will need to convert them also.

In case you are working in VB, path is little different since you need to go to My Project then Compile tab and on Advanced Compile Options button you will find target CPU setting.

After that small change, your program is 32-bit citizen and loading 32-bit OLEDB is easy as it once was.

OIB

Today my government (Croatian) started with distribution of our personal identification number (SSN as Americans know it). It is greatest invention since sliced bread or so they tell us. One could even be puzzled on how we managed to live without it for all these years. But wait, we had that number before.

JMBG

From ex-Yugoslavian time we inherited our personal number. It was 13 digits, 12 were data and 1 was checksum. When I say data, I mean real data - you could find person’s date of birth, gender and region of birth. This came in really handy with medical software. Just take JMBG as unique identifier and extract date from it to get persons age (something that doctors like to know).

Although that was very handy, it was doom of it. Some people here don’t like others to know their age and since split of Yugoslavia, ex-republic of their birth became a no-no subject. There was even law passed that removed it from every ID. That was not a smart move.

OIB

Our new identification number consists of 11 purely random digits - that means harder to remember of course. It should replace JMBG and since verification algorithm is different that also means update of every application that uses it. But there are good things to it also.

European union uses up to 12 digits so we are compatible with them if we ever enter. Here I need to say that I am sorry it is not 12 digits - plenty of barcode symbologies encode even number of digits more easily. It also uses standard ISO 7064 (aka as modulo 11,10) encoding of check digit which is always good.

Conclusion

There is not even an intent of it.

I do think that they could have done better job at defining that number (e.g. making it even number of digits and/or encoding date of birth inside of it) but we need to learn how to live with it as good as we did with JMBG.

My first step to it was to write some C# code to validate it.

Case of Missing Font

Once upon a time I was Visual Basic 6 programmer. These days one of those applications needed small update. I did change within five minutes, compiled it (in P-code because it doesn’t work when compiled as Native - but that is another story) and deployed it on network. Of course next day I got a call about a bug.

Barcode fonts

In those days it was hard to put barcode (Code 128 to be exact) on Data Report. Easiest path you could take was to use barcode font (or create it as I did) and store some textual representation of that code in database. When report is created, it would use that font to display text and by accident it would printout barcode. It wasn’t elegant solution but it worked.

The Bug

Since I don’t use same “barcode style” these days I hadn’t had that font installed on my system. For one reason or another something happened during compile that caused application to forget about my barcode font defined in Data Report. It just used same font as for rest of page which caused big numbers (my encoding of barcode used quite few of them) to appear where barcode should be.

Solution was quite simple. I installed that font on my Vista (yes I know, bug may as well be because VB6 is not supported on Vista officially) and recompiled application. Everything was ok this time.

It left me wondering however. Are there any other bugs that I introduced by simple fact of recompiling application?

Living in High DPI

What’s the problem?

Most of applications are pretty ignorant regarding DPI settings (including here a majority of mine applications also). Developers tend to optimize for 96 dpi and leave it at that. With more and more high DPI LCDs it is very hard for users to stay at that setting so lot of them are working on 120%.

On Windows XP this would look very bad if application is not high DPI aware but on Vista they decided to stretch client area of those misbehaving applications to match user selected dpi settings. Form is little bit blurry but it is better than element misplacement and text clippings. Old misbehaving applications look almost decent there.

Problem is that on Vista even applications that took effort to look good on higher DPI settings are affected with that scaling. All that work was done for nothing since Vista makes your application think it is working at 96 dpi.

Telling Vista that I am smart guy

There is a way to let Vista know that we took that additional effort. One just needs to call SetProcessDPIAware API (Vista only!) and Windows will leave us alone to manage our own interface. Since P/Invoke is not my favorite way of doing things from .NET I am happy that there is possibility of embedding it in manifest also.

If you have Visual Studio 2008 embedding this manifest is easy as creating new file but in older versions you will have some more work to do.

Some time later I will lead you through actual creation of well behaving application.

Default System Font

.NET Framework 1.0 and above

By Microsoft’s design guidelines you should be using system defined font for displaying user interface elements in your program. Of course, Microsoft found it very helpful to ignore that and assign Microsoft Sans Serif at 8.25 points as default font for all new .NET applications. Since both XP and Vista brought us new font (Tahoma at 8.25 points and Segoe UI at 9 points, respectively) most of .NET applications are just looking slightly out of place.

Solution is quite simple - you should only manually assign new font to form and all elements will pick up that setting (if you left them at default). Only problem is retrieving a font to use.

Proper way

Microsoft states that we should use GetThemeFont API to get this information. Problem is that this function does not exist in managed world and you don’t always have option to make P/Invoke calls (i.e. because of security settings) and portability also comes into question (Windows older than XP and mono).

SystemFonts.???

One would think that SystemFonts.DefaultFont would return what we need but for some reason known only to guy who made that function it returns Microsoft Sans Serif in almost all cases. Why does it ignore real windows default font is unknown to me. Some reflecting is probably needed but I tend to be on lazy side when there is no actual possibility to change anything.

Good choice is strangely SystemFonts.MessageBoxFont since this return proper font on all platforms I have used it. It is not official source for that information but should be good enough if you really want (or need) to stay in managed world.

If one wants to see example of it, I am happy to provide.

How to Choose Barcode Symbology

For one project I needed to select proper barcode symbology (way of encoding). Requirements were clear: variable length (that excludes EAN/UPC subset), some form of check-sum and it needs to work with standard (aka cheap) equipment. That left me with few candidates which I will try to describe.

2 of 5

This symbology is well supported since it is quite old (circa 1960) and it is used within industry. It is numeric only code and there is optional support for check-sum (modulo 10) digit, but that digit needs to be encoded and decoded by software (this may be a problem if you have some devices which are not under your control). Problem is also in width of code since this one encodes data only in bars which makes for a lot of wasted space. It’s low density could be a problem if you are “space challenged”.

To overcome excessive width of standard 2 of 5, somebody though of encoding data in both bars and spaces. That effectively made code twice as dense as standard one (or twice as short) for same amount of data but support is only available for even number of digits. Everything else said for standard version is same for this one.

Codabar (NW-7)

Illustration

Used mostly within blood banks this symbology allows for numbers with limited number of symbols (- $ : / . +). Since it is self-checking there is no additional check-sum needed but one can always use a software one. Code can start and end in four different ways (usually called A B C D) so there is possibility of differentiating code on that base also (but be aware of lock-in since no other code has that option). Since characters are separated with space code is not among shortest.

Code 3 of 9 (Code 39)

This is alphanumeric code and enables encoding numbers, characters (big case only) and some symbols (space - . $ / + % *). It is self checking so check-sum is not necessary but there is defined way of doing it if more security is needed. There is also possibility of concatenating multiple barcodes together but that possibility is rarely used (just don’t start your code with space). There is also extended variant that can encode whole ASCII (0-127) range.

Code 128

Illustration

This symbology is three in one deal. Three different encodings not only allow for full ASCII (0-127) to be encoded but there is also special double density mode which allows it to encode numeric only data in half the width. Check-sum (modulo 103) is mandatory part of encoding so no additional support is needed within software. Since symbols are also self-checking this gives very high confidence in reading. There were small problems with reading Code 128 with old barcode readers but everything that is recent on market supports it. Since there are three different ways of encoding data (and switching between them within) writing optimal encoder is not an easy task.

Conclusion

At the end, I selected Code 128. Not only that it gives highest possible level of security but it also has shortest code (with numeric data at double density). Slightly complex encoding was just another challenge that needed overcoming. C# source code is available.

Useful pages

Here are few pages where you can find more information - enough to write your own encoder.