Thursday, June 28, 2007

Beware of "==" in VC++

"==" operator of String class may not return desired result. For example, when checking the equality of two Strings:

if (cmbBx_Pos->Text == S"BOL")

Even if the two Strings are the same, it may have a "false" result. To make sure it return the correct result, use this instead:

if (cmbBx_Pos->Text->Equals(S"BOL"))

It doesn't make much sense why the "==" operator failed. Perhaps it was the operator of Object class, so it was comparing two references instead of two Strings.

Updated: when using a .net string literal in VC, always write as: S"hello". "==" operator will return false when comparing "hello" and S"hello". If a project has only .net strings as S"xxx", using "==" operator probably has no problem. If a project deals with different kinds of string, we better off use String::Equals to check string equality.

Thursday, June 21, 2007

Rules That Make Your Programming Life Easier

Rule 1: Life is like an onion: you peel it one layer at a time, and sometimes you weep. So is programming.

Rule 2: Internet is one of your most reliable friends.

Rule 3: Whenever encounter a problem, search on Internet, refer to books and think. Until you know exactly what the problem is, don't ask for help.

Rule 4: Don't bother (ask tech questions etc.) colleagues too often. People are all busy!

Rule 5: Taking notes is very very important. If you have a doubt, read Rule 1 five times.

Tuesday, June 12, 2007

Access form controls freely

Sometimes we want to access form controls outside the normal scope. For example, a callback function in another file need to notify some control so it can update its display. Simply change the control from private to public is not enough, we also need to get the current form instance. According to the article How to get current ApplicationContext instance at run time, we can create a new class MyForm which inherits Form class and set a similar static field _myForm. The static field will always store the first instance of that class, even if that class is initialized multiple times later.

We then use this new class to run the application:

Application::Run(new MyForm());

Later on, whenever we want to get the instance of MyForm, we can do this:

MyForm* myForm = (new MyForm())->_myForm;

Although this method may not deserve the word "pattern", it is interesting to compare it to the Singleton Pattern. Different from Singleton Pattern, we can have more than one instance in this case, but we can freely get the first instance.

Convert String* to char* and backwards

To convert String* to char*, use the following:

using namespace System::Runtime::InteropServices;
char* temp;
temp = (char*)(void*)Marshal::StringToHGlobalAnsi(txtBx_MgmtName->Text);

To convert char* to String*, just use the constructor of System::String.

BTW, most data types in .NET has the ToString method.