Showing posts with label WTF. Show all posts
Showing posts with label WTF. Show all posts

Monday, November 24, 2008

Sending WM_WININICHANGE message on device with HTC TouchFlo 3D will crash the device

Today I finally solved a very strange bug in a Windows Mobile project Im currently working on. The bug would only show up on HTC devices, and not our HTC devices we had at our location. After the application was installed and the user started it, the whole device would freeze and reboot itself after a minute or so.

After some digging around, rebuilding, re-installing for way too many times; we found out that if the HTC TouchFlo 3D today plugin was enabled the device would crash. With that knowledge I was able to pin point the location of the failure which was that the installation DLL sends a
WM_WININICHANGE message to refresh the PocketPc Today plugins.

As many
sites and forum posts states, this is the only way to refresh the Today plugins.

::SendMessage(HWND_BROADCAST, WM_WININICHANGE, 0xF2, 0);

Of course, this is not documented anywhere within MS documentation; and the
documentation that exists states that the wParam isnt used at all (which in fact it is).

It seems that the HTC TouchFlo 3D isnt capable of handling the
WM_WININICHANGE properly, and even just opening the calendar application after that sending that message will crash the device. So if your WindowsMobile application sends that message, I would advise you to look into this. Using the replacement message WM_SETTINGCHANGE does not change anything, the device will still crash.


One solution is to check if the HTC TouchFlo Today plugin is enabled, which can easily be retrived through the regkey
"HKLM\Software\Microsoft\Today\Items\TouchFLO 3D\Enabled". If it is enabled, then do not send the WM_WININICHANGE message.

Thursday, November 23, 2006

Why no Equals() and GetHashCode() in System.Collection?

Today I had another brain freeze when I was trying to understand why two array lists would generate two different hash codes even if they contained the same data. But when I started my investigation in MSDN, I see that the ArrayList does not override the GetHashCode() nor the Equals() method. Ehhhhh?

So my question is how can I check if two lists are equal? NO, I don't want to go through all items. This should be handled by the framework classes and I don't want to do any unnecessary implementation.

If I look in Java, the ArrayList implements equals(), hashCode() as all good objects should. They have also a good explanation on how it is done here.

If I look through the other classes in System.Collection I see that no implements GetHashCode() or Equals(). If none of them do, then it must be a design choice. But what design choice would that be? If anyone have any explanation, please make a comment to this blog. I really want to know.

There is an interface in System.Collections.Generic that is named IEqualityComparer, which has two methods, Equals() and GetHashCode(). Why make an interface when every class implements those methods? And why doesn't the default list/collection classes implement this interface?

I did a little test application to test this out, because I can not believe it. Full listing here.
Pseudo code:

string a = "A";
string b = "B";
ArrayList list1 = new ArrayList();
list1.Add(a);
list1.Add(b);
ArrayList list2 = new ArrayList();
list2.Add(a);
list2.Add(b);

Console.WriteLine("list1.equals(list2) ? " + (list1.Equals(list2)));
Console.WriteLine("list1.equals(list1.clone) ? " + (list1.Equals(list1.Clone())));
Console.WriteLine("list1.hash == list2.hash ? " + (list1.GetHashCode() == list2.GetHashCode()));

This program would show:
list1.Equals(list2) ? False
list1.Equals(list1.Clone()) ? False
list1.hash == list2.hash ? False


If I create two array lists that contains the same items, the Equals() method will return FALSE. If I clone an array list and checks if they are equal the Equals() method returns FALSE. How can a CLONE not be an exact copy of the object, or how can two exact copies not be equal to each other?

The best part is that Hashtable doesn't implement GetHashCode() either. And that class require all other objects to implement that method in order to be used, but they refuse to do it themselves. "Do what I tell you, not what I do."

Is it because they know people will not implement those methods since developers are lazy? But why have they put them into the Object class if they can't be trusted? Or was it a copy-paste mistake from Java?
To me this is so wrong.