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

ToolStrip as Main Menu

Let’s take small project as an example. You need two or three options and you cram everything as root menu item. Since you like your users and your users like pictures, you additionally create toolbar with same options. Final toolbar has one-to-one mapping with menu. Now question is why do we need menu in first place?

Personally I see only one reason - keyboard accessibility. Toolbar might be nice but it will not allow us to use pure keyboard interface in order to select items. However, solution is simple. First we set KeyPreview=true on form itself and then we just handle Alt key:

private void MainForm_KeyDown(object sender, KeyEventArgs e) {
    switch (e.KeyData) {
        case Keys.Alt | Keys.Menu: {
            menu.Select();
            menuNew.Select();
            e.SuppressKeyPress = true;
            e.Handled = true;
        } break;
    }
}

This code acts upon Alt key press. First we need to select ToolStrip control and then we select first item (New, in this case) within it. If we just use Select on item it will look same, but keyboard arrows will not move selection between items.

Downside to this is handling shortcut keys. While MenuItem will allow us to set Ctrl+N as shortcut key same is not true for ToolStripButton. All shortcuts should be handled explicitly now (within MainForm_KeyDown event):

···
case Keys.Control | Keys.N:
    menuNew_Click(null, null);
    e.SuppressKeyPress = true;
    e.Handled = true;
    break;
···

Full code example is available here.

Not All Files Can Be Embedded

Quite a lot of helper files needed for average applications are best stored as resource. This way separation of data and code is kept on logical level but everything gets stored in one executable so nothing can be lost.

In order to make some file resource only thing needed is selecting “Properties” from context menu and setting “Build Action” to “Embedded Resource”. Reading this from code is equally easy (assuming program is called MyProgram and resource file is called Test.txt):

Stream myStream = Assembly.GetExecutingAssembly().GetManifestResourceStream("MyProgram.Test.txt");

It is easy as it can be and I was very surprised when I could not get this to work. I added file “File.hr.xml” to project and I embedded it correctly but GetManifestResourceStream method returned null for it. Documentation says that this can only happen when resource is not there and this was impossible in my case.

In order to confirm this I looped through all resources I had embedded:

foreach (string name in Assembly.GetExecutingAssembly().GetManifestResourceNames()) {
    Debug.WriteLine(name);
}

To my surprise documentation was correct, my file simply wasn’t there. However, in my bin folder there was subfolder named “hr” with “MyProgram.resources” file inside.

Then it hit me. Problem was in multi-dotted extension with valid language code as first part. These files are understood by Visual Studio as being language specific and reading them from another culture is not possible (ok, it is possible but not easy).

Since I really wanted this resource to be available regardless of localization, solution was simple. I just renamed file to “File-HR.xml” and it magically appeared in resource list.

Mercurial Over Both Http and Https

My last post about Mercurial left us with Mercurial server listening to https-only requests. This is probably best solution security-wise but there might be valid reasons for having it on http also (e.g. performance within local network).

Solution lies in editing “/etc/apache2/sites-available/hg” to have two configurations - one for http and one for https:

NameVirtualHost *:80
NameVirtualHost *:443

<VirtualHost *:80>
    ServerAdmin webmaster@localhost
    DocumentRoot /srv/hg/cgi-bin
    <Directory "/srv/hg/cgi-bin/">
        SetHandler cgi-script
        AllowOverride None
        Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
        Order allow,deny
        Allow from all
    </Directory>
    ErrorLog /var/log/apache2/hg.log
    <Location />
        AuthType Basic
        AuthName "Mercurial"
        AuthUserFile  /srv/hg/.htpasswd
        Require valid-user
    </Location>
    RewriteEngine on
    RewriteRule (.*) /srv/hg/cgi-bin/hgweb.cgi/$1
</VirtualHost>

<VirtualHost *:443>
    ServerAdmin webmaster@localhost
    DocumentRoot /srv/hg/cgi-bin
    <Directory "/srv/hg/cgi-bin/">
        SetHandler cgi-script
        AllowOverride None
        Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
        Order allow,deny
        Allow from all
    </Directory>
    ErrorLog /var/log/apache2/hg.log
    <Location />
        AuthType Basic
        AuthName "Mercurial"
        AuthUserFile  /srv/hg/.htpasswd
        Require valid-user
    </Location>
    RewriteEngine on
    RewriteRule (.*) /srv/hg/cgi-bin/hgweb.cgi/$1
    SSLEngine on
    SSLOptions +StrictRequire
    SSLCertificateFile /srv/hg/https.crt
    SSLCertificateKeyFile /srv/hg/https.key
</VirtualHost>

After quick Apache restart your Mercurial will answer both http and https requests.

Mercurial Over Https

My guide on making Mercurial server left us with http as a protocol of choice. This might be ok in local network but https would be more comfortable choice. This post starts with already running Mercurial server on Ubuntu.

Apache does come with https module which has to be enabled:

sudo a2enmod ssl
 Enabling module ssl.
 See /usr/share/doc/apache2.2-common/README.Debian.gz on how to configure SSL and create self-signed certificates.
 Run '/etc/init.d/apache2 restart' to activate new configuration!

Before restarting Apache we need to create few things (key, certificate signing request, certificate) and easiest way is to create it ourself (write whatever you want for organization details):

openssl genrsa -out https.key 1024
 Generating RSA private key, 1024 bit long modulus
 ..........++++++
 ......++++++
 e is 65537 (0x10001)

openssl req -new -key https.key -out https.csr
 You are about to be asked to enter information that will be incorporated
 into your certificate request.
 What you are about to enter is what is called a Distinguished Name or a DN.
 There are quite a few fields but you can leave some blank
 For some fields there will be a default value,
 If you enter '.', the field will be left blank.
 -----
 Country Name (2 letter code) [AU]:
 State or Province Name (full name) [Some-State]:
 Locality Name (eg, city) []:
 Organization Name (eg, company) [Internet Widgits Pty Ltd]:
 Organizational Unit Name (eg, section) []:
 Common Name (eg, YOUR name) []:
 Email Address []:

 Please enter the following 'extra' attributes
 to be sent with your certificate request
 A challenge password []:
 An optional company name []:

openssl x509 -req -days 36500 -in https.csr -signkey https.key -out https.crt
 Signature ok
 subject=...
 Getting Private key

Once keys are created we must enter following lines in “/etc/apache2/sites-available/hg” (I left other stuff for clarity):

NameVirtualHost *
<VirtualHost *>
    ServerAdmin webmaster@localhost
    DocumentRoot /srv/hg/cgi-bin
    <Directory "/srv/hg/cgi-bin/">
        SetHandler cgi-script
        AllowOverride None
        Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
        Order allow,deny
        Allow from all
    </Directory>
    ErrorLog /var/log/apache2/hg.log
    <Location />
        AuthType Basic
        AuthName "Mercurial"
        AuthUserFile  /srv/hg/.htpasswd
        Require valid-user
    </Location>
    RewriteEngine on
    RewriteRule (.*) /srv/hg/cgi-bin/hgweb.cgi/$1
    SSLEngine on
    SSLOptions +StrictRequire
    SSLCertificateFile /srv/hg/https.crt
    SSLCertificateKeyFile /srv/hg/https.key
</VirtualHost>

With this we are ready for restart:

/etc/init.d/apache2 restart
 * Restarting web server apache2
     [warn] NameVirtualHost *:80 has no VirtualHosts
 ... waiting [warn] NameVirtualHost *:80 has no VirtualHosts

After these changes Mercurial is listening ONLY on https. Since we made self-signed certificate, browser will complain about verification, but that is quite normal.

P.S. To use both http and https, read some more.

From SVN to Mercurial

Moving from SVN to Mercurial is obvious if you don’t want history. Folder copy/paste action is more than enough. If we want to get whole history, that is where things get more involved. This guide is written with assumption of Ubuntu installation of Mercurial. If you are using something other, do adjust a little (yes, it also works on Windows).

First thing that we need is “python-subversion” package installed. For some reason I could not find this through Ubuntu Software Center. It worked from Synaptic Package Manager without issues. Afterward we need to enable Mercurial’s convert extension. Just edit “/home/josip/.hgrc” (do change folder if your name is not Josip) and add these lines to it:

[extensions]
hgext.convert=

Last thing to do is actual conversion:

mkdir TestRepo

hg convert svn://192.168.0.3/TestRepo TestRepo
 initializing destination TestRepo repository
 scanning source...
 sorting...
 converting...
 32 
 31
 ...
 1 
 0

cd TestRepo

hg update
 49 files updated, 0 files merged, 0 files removed, 0 files unresolved

Your Mercurial repository awaits. :)

P.S. If folder with Mercurial repository is empty, you probably forgot to do “hg update”.

How Hard Can It Be to Create ListView

Illustration

In WPF data binding is fairly consistent, I would even dare to say best that I ever saw. It is easy to do fairly complex things at some cost to way how simpler things are done. Internet is full of examples how to do simple WPF data binding but it surprisingly lacks examples for doing background updates. I tried here to make simplest example that will work with dynamic updates.

Everything revolves around ObservableCollection. In my example this class is inherited within ItemViewCollection class and all “filling” should be done to Items property. I opted to do so with hard-coded data but you can imagine it being done with data from database or any other source.

...
this.Items.Clear();
this.Items.Add(new ItemViewData("Primary weapons", 1000));
this.Items.Add(new ItemViewData("Secondary weapons", 1000));
this.Items.Add(new ItemViewData("Shields", 1000));
this.Items.Add(new ItemViewData("Torpedos", 1000));
this.Items.Add(new ItemViewData("Item " + DateTime.Now.ToLongTimeString(), 1000));
this.OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
...

Once data is shown, it will not be refreshed unless OnCollectionChanged method gets called. Only then update will propagate around. Above we can see how whole collection should be refreshed once Items get cleared and filled again. If you see that ListView does not respond to your changes (e.g. you added some items) there is chance you forgot to call it.

Data itself is stored within ItemViewData class. That class implements INotifyPropertyChanged interface and thus it enables update notifications for selected properties (e.g. Energy and ImageIndex). You could update all properties but updating only those that you actually changed will improve performance. Again, if you changed property and your ListView does not reflect it, you forgot to do notification.

public void SetEnergy(decimal newEnergy) {
    if (newEnergy < this.Energy) {
        this.ImageIndex = 1; //down
    } else if (newEnergy > this.Energy) {
        this.ImageIndex = 2; //up
    } else {
        this.ImageIndex = 0; //same
    }
    this.Energy = newEnergy;
    this.OnPropertyChanged(new PropertyChangedEventArgs("Energy"));
    this.OnPropertyChanged(new PropertyChangedEventArgs("ImageIndex"));
}

Code that handles data binding is in following (abreviated) XAML:

...
    <Window.Resources>
        <ObjectDataProvider x:Key="parts" ObjectType="{x:Type local:ItemViewCollection}" MethodName="GetInstance" />
    </Window.Resources>

    <ListView Name="List" ItemsSource="{Binding}" DataContext="{Binding Source={StaticResource parts}}">
    ...
    </ListView>
...

What really happens here?

ListView uses binding to “parts” data provider in order to call GetInstance method within item collection (ItemViewCollection). Whatever this method returns get’s treated as rows for ListView control. Our code is responsible for putting right stuff inside (in FillItems method) and for doing it in correct thread (thus Invoke code there). This is all there is to it.

To make things more interesting I added small method (BackUpdate within App.xaml.cs) that updates some values every two seconds (INotifyPropertyChanged.OnPropertyChanged gets triggered here) and every 20 seconds everything gets reloaded from start (thus need for ObservableCollection.OnCollectionChanged).

It might seem complicated when you look at it for first time but once you see full example code these code fragments should make some sense. :)

Nicer Mercurial URL

I already went through motions of installing Mercurial server on Ubuntu. However, that left us with nasty looking URL with hgweb.cgi in it (e.g. http://192.168.0.2/hgweb.cgi/TestRepo). Can we make it nicer?

We need to edit “/etc/apache2/sites-available/hg” in order to add two highlighted lines (I kept all other lines for clarity):

NameVirtualHost *
<VirtualHost *>
    ServerAdmin webmaster@localhost
    DocumentRoot /srv/hg/cgi-bin
    <Directory "/srv/hg/cgi-bin/">
        SetHandler cgi-script
        AllowOverride None
        Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
        Order allow,deny
        Allow from all
    </Directory>
    ErrorLog /var/log/apache2/hg.log
    <Location />
        AuthType Basic
        AuthName "Mercurial"
        AuthUserFile  /srv/hg/.htpasswd
        Require valid-user
    </Location>
    RewriteEngine on
    RewriteRule (.*) /srv/hg/cgi-bin/hgweb.cgi/$1
</VirtualHost>

Next thing to do is enabling Apache’s mod_rewrite module and restarting apache:

sudo a2enmod rewrite
 Enabling module rewrite.
 Run '/etc/init.d/apache2 restart' to activate new configuration!

sudo /etc/init.d/apache2 restart
  * Restarting web server apache2                                                                                                                              apache2: Could not reliably determine the server's fully qualified domain name, using 192.168.0.2 for ServerName
 [Tue Feb 01 09:42:15 2011] [warn] NameVirtualHost *:80 has no VirtualHosts
  ... waiting apache2: Could not reliably determine the server's fully qualified domain name, using 192.168.0.2 for ServerName
 [Tue Feb 01 09:42:16 2011] [warn] NameVirtualHost *:80 has no VirtualHosts

If everything went fine you should be access your repositories without hgweb.cgi, e.g. http://192.168.0.2/TestRepo/. Not a big change but it does look much better.

Gone

On 23rd August, 2008 Lutz Roeder gave .NET Reflector development to Red Gate Software. At that time Red Gate agreed to provide free community version and everything seemed same. There was paid version available with Visual Studio integration but for occasional need you could always count on free one. This is bound to change with 1st March. Red Gate Software decided to require $35 for what was once known as freeware.

I remember .NET Reflector as a great tool for debugging assemblies that you have no source for. It helped me more than once to navigate my way around some obscure bug that would trigger in other people’s library. I will not even mention how much I learned by viewing other people’s code. :)

I will not go into blaming anyone for killing free version of this tool. Lutz was quite in his rights to give it to Red Gate and I assume that Red Gate is allowed to ask money for it. I also think that most of attacks on Red Gate’s forum are unfounded and uncalled for. Reality sucks, learn to live with it. I am just sad that this beautiful tool will leave my toolbox for now.

Will I buy a licence? Maybe some time, but not right now.

[2012-11-07: Licence for .NET Reflector is $95 these days but there is freeware alternative from JetBrains: dotPeek]

Legacy

When I did redesign of site into blog format some things got lost. I was quite surprised that those files, not linked from my site, were still getting bunch of hits, especially legacy VB 6.0 code. It seems that there are still some people using it.

By popular demand, here is all that code in single archive. Do note that even most youngest code is from 2004 with most of code being even older. I bring you also original descriptions, nothing is modified in any way.

Download is here.

VB.NET 2.0

  • DnDTabControl How to reorder TabPages inside TabControl.
  • Highlander Detecting already running program and letting first instance know that.

VB.NET 1.1 DLLs

  • Medo This DLL is compiled version of classes given on these pages and some classes without source code. There is Profile class that lets you save Form position, ListView Columns witdh and more. OleDb class lets you to easily perform one line queries. There are few more CRC algorithms including CRC8. There is also many more classes that can prove to be useful. There are not too many samples now but more of them will come.

VB.NET 1.1 Classes

  • BigOFD OpenFileDialog class implemented in .NET has small problem. Buffer size is too small to handle more than few hundred files or even less. This replacement was designed to give you direct access to Windows API and to allow custom buffer sizes. It is mostly compatible with .NET OpenFileDialog so no porting problems should occur.
  • Bitwise This class gives you ability to perform unsigned Shift left, Shift right, Rotate left and Rotate right bitwise operations over Integer and Short (aka Int16 and Int32) data types. This is very usefull in some algorithms that must be implemented in unsigned logic that is currently unupported by Visual Basic.
  • COM This class can be used to perform read and write operations on serial communication ports (COM). It has basic example until I gather some time to make better one.
  • CRC-16 This class gives you ability to check data integrity with CRC16 algorithm.
  • CRC-32 This class gives you ability to check data integrity with CRC32 algorithm.
  • RC4 This class enables you to crypt your data using fast RC4 algorithm.
  • Registry VB.NET includes its own vision of registry access. This vision makes everything possible but its drawback is in number of code lines for most simple things. By using this class you can write/read REG_DWORD and REG_SZ data types in one line.
  • TagItem First ListBox control use in .NET was very confusing for me. Like, I am sure many of you, I used ItemData to fill in ID of somekind. But there is no ItemData in Kansas anymore so “Dorothy” had to find another solution. It took some time to see that new “Items.Add” formula takes Object as argument. From there, everything was downhill. By using Text and ID as an argument, this class can be successfully used to retrieve same information later. One Object argument is added for “just in case” situations.

VB.NET 1.1 Macros

  • VB6ver Enables you to use VB6 style versioning in .NET enviroment.

Java

  • DateTime 1.10 When I started to learn Java, its date management model drove me crazy. It was too much complicated for simple calculations. Here is class that enables date/time management in simple .NET alike class.
  • Road to Java This script is diary of differences I notice while learning Java. It is not complete nor it will ever be but I will work on it.

VB 6.0 Classes

  • APIFile This class was developed to open files via API which has advantage of being able to trim them by using Length property.
  • CRC32 This class gives you ability to check data integrity with standard CRC32 algorithm.
  • SHA-1 This class enables you to encrypt your passwords with SHA-1 hash (one-way) algorithm.
  • Window You can enumerate open windows by using this class.
  • XY This class enables you to draw in X-Y coordinate system. Usefull for drawing mathematical functions graphs.

VB 6.0 Controls

  • CmnDlg Complete substitude for CommonDialog control. No .ocx needed.
  • Contain This control can be used as container for other controls.
  • Progress Complete substitude for ProgressBar control. No .ocx needed.
  • TextComplete This control gives you AutoComplete ability.
  • TrayIcon This control gives you option to show icons in Tray notification area.

VB 6.0 Modules

  • Browse This module enables you to show Browse dialog.
  • CRC16 This module gives you ability to check data integrity with standard CRC16 algorithm.
  • CRC32 This module gives you ability to check data integrity with standard CRC32 algorithm.
  • Date This module enables you to find out when is Easter.
  • HrBox This module enables you to show Croatian MsgBox and InputBox.
  • RC4 This module enables you to crypt your data using fast RC4 algorithm.
  • Registry This module enables you to access Windows registy.
  • SHA-1 This module enables you to encrypt your passwords with SHA-1 hash (one-way) algorithm.
  • Shuffle This module contains functions for shuffling elements of zero-based arrays (for playlists, cards, etc.).
  • ShutDown This module enables you to shut down your computer or put it in sleep mode from your program.
  • Swap This module enables you to Swap variables in single instruction.