RTL problem

Thu, March 17, 2005, 11:38 AM under MobileAndEmbedded
In some places in the world they read and write from right to left (RTL). Prime examples of such languages are hebrew and arabic. As a software developer, if your market extends to such users, you should support RTL in your application. Unlike support for a LTR language, there are additional things your windows app must do. For .NET apps this includes using the Control.RightToLeft property.

For the Compact Framework the story is less straightforward. You see, the CF is a subset of the .NET Framework that runs on Windows CE based devices. Windows CE 4.x and previous versions do not support RTL (since all current Pocket PC devices are based on the CE 3.x/4.2 operating system, by definition they do not support RTL either). There may be 3rd party solutions available, but I am not aware of any. It would be a nice touch if the CF implemented RTL support without support from the OS (i.e. it could simulate it) however that would probably mean that the windows controls would not be just thin wrappers of the OS equivalent and hence performance would suffer - not to mention framework size.

The OS story becomes much better with the next version of Windows CE. In a sentence, CE 5.0 supports RTL :-)

For devs with their own platform this means migrating from 4.2 to 5.0. (for devs of PPCs [Windows Mobile for Pocket PC] or SPs [Windows Mobile for SmartPhone], my *guess* is you have to wait for a next version of Windows Mobile which if based on CE 5.0 could expose the underlying OS support).

Since CE 5.0 supports RTL and since Compact Framework 2.0 *only* runs on CE 5.0 (and WM2003 for PPC), I'd forgive you for making the logical jump that CF 2.0 exposes Control.RightToLeft - think again. That's right, the infamous "postponed"!

Before we go off in a sulk, it is worth capturing what we mean by RTL support:

1. CheckBoxes (the square bit) and RadioButtons (the circle bit) should appear on the left [there is no CheckAlign property on CF]
2. UpDown buttons (e.g. NumericUpDown and DomainUpDown) should appear on left
3. Controls with vertical scrollbar (e.g. TreeView, ListView, ListBox, multiline TextBox etc) should render the scrollbar on the left
4. Wherever there is text that is naturally left-aligned, it should be right-aligned (e.g. *any* control with .Text property such as Form or .Items such as ListView)
5. Menus, ToolBar buttons and form buttons (i.e. max/min/close buttons, control box) must be mirrored (right aligned)
6. ProgressBar, TrackBar and HScrollBar should start from right.
and a more subtle one
7. Shadows of controls should appear on the left. If you haven't noticed this before, have a closer look at button/scrollbar/trackbar etc: they have a white border top & left and dark border bottom & right. The left & right shades must be switched when RTL applies.

Next time we'll see what we can do with CF 2.0 to support RTL on CE 5.0. I'll include screenshots and details of which controls (based on the November CTP) pose insurmountable problems!

Polymorphism is not coupled to implementation inheritance

Wed, March 16, 2005, 03:32 PM under dotNET
On his blog, as part of a useful OOP series, Raymond Lewallen defines polymorphism. He merges 3 concepts in one post. We've had the discussion on the topic previously, but I don't think we reached total agreement. In my opinion, to say that there is such a thing as "true" polymorphism and to claim that it applies only when inheritance is involved, is plain wrong.

If you are reading that blog entry to understand polymorphism, please read my (complementary) take on the topic below.

First I would ignore overloading. This has nothing to do with polymorphism and I would not bring it up in any discussions on the topic. Just for info, overloading is the ability to define two or more methods on the same class with the same name but different argument lists. Nothing more, nothing less.

Second, do not directly associate polymorphism with inheritance (as you can probably tell this is my pet peeve :-). Polymorphism directly depends on subtyping. Unfortunately, many people confuse subtyping with implementation inheritance. Inheritance is *a* way to achieve subtyping, but not the only one (another is interface implementation). If you ask the question in reverse: Is inheritance the same as polymorphism? The answer is no. Inheritance offers a way to achieve subtyping *and* a way to reuse code.

So if someone asks you to explain polymorphism with a VB.NET example using inheritance, you can do something simple like this:
Public Class EntryPoint
Shared Sub Main()
Dim m As New Mouse
Dim s As New Shark
DoSomethingWith(m)
DoSomethingWith(s)
End Sub

' Client code
Public Shared Sub DoSomethingWith(ByVal a As Animal)
a.Bite()
End Sub
End Class

Public MustInherit Class Animal
Public MustOverride Sub Bite()
End Class

Public Class Mouse
Inherits Animal

Public Overrides Sub Bite()
MsgBox("Disease")
End Sub
End Class

Public Class Shark
Inherits Animal

Public Overrides Sub Bite()
MsgBox("ouch!")
End Sub
End Class
The client code uses the type Animal. It does not know what objects it will be given (i.e. instances of what class) but the fact that they support the programmatic interface of the Animal type is enough for it to use them: polymorphism in action.

If someone asks you to explain polymorphism with a VB6 example, you can do something like this:
In a Standard EXE project, change the startup Object in project properties to Sub Main.

Add a module1 with this code:
Sub Main()
Dim m As New Mouse
Dim s As New Shark
DoSomethingWith m
DoSomethingWith s
End Sub

' Client code
Sub DoSomethingWith(ByVal a As Animal)
a.Bite
End Sub
Add a Animal class module:

Public Sub Bite()
End Sub
Add a Mouse class module:
Implements Animal
Private Sub Animal_Bite()
MsgBox "Disease"
End Sub
Add a Shark class module:
Implements Animal
Private Sub Animal_Bite()
MsgBox "ouch!"
End Sub

That's it. Polymorphism in VB6: nothing fake or incomplete about it.

Naturally you can mix many concepts in your designs including polymorphism, inheritance and overloading etc. If you want to see a design combining these topics, then Raymond's post has a nice VB.NET example.

Customer visits round 2

Tue, March 15, 2005, 04:36 PM under SoftwareProcess
I have returned from another round of customer visits (in the Midlands this time). Lots of positive feedback on IQView and great ideas contributing to our current plans for a new product (can't say much more on that, apart from that it is also on WinCE with CF). In terms of generic shareable takeaways, everything I said last time was re-enforced on this visit too. A couple more:

7. You can learn as much by listening to your client talk about competitive products as you can from when they talk about yours; encourage it!

8. If you are already the UK's market leader, maybe you should try to obtain feedback from other countries [OK, so this is more of a hint to my manager to send me to our customers abroad :-]

Now back to catching up with my spam... later...

Blog link of the week 10

Sun, March 13, 2005, 03:57 PM under Links
+ Declarative validation with attributes and Java annotations by ex-Avanade Steve Maine.

+ Assuming this has no irony/sarcasm and without belittling anybody, with a dead-straight face I wholeheartedly agree with this (the alternative is to steer VB.NET to cater for this overlooked group; as a .NET dev do you want that?)

+ Never realised comment spam has good side :-)

Please read before posting to the ng

Sat, March 12, 2005, 08:20 AM under Communication
Helping out in the newsgroups but also as someone that got a lot of support from them in my earlier days, I thought it would be interesting to classify the "types" of posts in a newsgroup (ng) that may rub some people the wrong way (myself included). Note that in the past, I have broken many of these rules myself :-)

So here are my suggestions (in random order):

1. ALL CAPITALS
Capitals are interpreted as shouting so post in capitals if you want to start an argument rather than get help.

2. WRONG NG
Before posting to an ng, it makes sense to check if your question applies to it - otherwise you are just wasting bandwidth.

3. GENERIC QUESTIONS DON'T BELONG TO SPECIFIC NGs
Just because you are hanging out in the aspnet newsgroup doesn't mean you should start asking about the difference between value types and reference types. It is a .NET question but it is not specific to the technology ng. Same goes e.g. into asking about differences between C# and VB in the winforms ng: both are dotnet languages but that doesn't mean you can post them anywhere.

4. READ THE FAQ
So obvious, but so rarely adhered to. I think there is a problem with the technology we are using. There should be a method to detect when a new user posts to an ng and send them the FAQ with a 30 minute delay before they can actually post a question. BTW, for CF look here.

5. AT LEAST READ THE DAY'S POSTS
Follows on from “Read the FAQ”, but guess what you look like when your exact question was asked and answered a few hours ago.

6. BASHING MSFT BEFORE ASKING THE QUESTION DOESN'T HELP
Opening your post with insults to Microsoft and the way they support developers (e.g. documentation) is not helping your cause (to get support). The experts helping out are obviously happy with the platform, so you are insulting their choice. Even when you are right with your accusations, do you think that others are not aware of them? That is why the ng is there: Ask your question without the rant.

7. IF YOU ARE GOING TO POST, HAVE A QUESTION
Describing a problem is fine, but do try to end your post by formulating some kind of question.

8. YOU DON'T KNOW IF YOU FOUND A BUG
Just stating that you found a bug will not get you many replies. Do you really think you are the first one to report the bug? If yes then fine, you have reported it and don't expect any replies. If on the other hand you would like some help to work around it or validate that it is a bug, state your problem with repro steps and ask for help (note how that does not include proclaiming that you found a bug).

9. SHOW ME THE CODE
This is probably the number one omission. Imagine if I send you an email telling you I have a problem when e.g. calling a WS but don't show you any code; kind of daft, right? Show me the code so I can repro your problem and show you what is wrong or how to change it to make it right.

10. TELL ME SOMETHING ABOUT YOUR ENVIRONMENT
Which version are you running (SP1, SP2 etc)? E.g. you have a problem running some code on your device but not the emulator. What device/emulator (PPC 2000/2002/2003, WinCE 4.1/4.2/5.0 etc)? E.g. you'd like a code sample that does xyz. What language are you using (VB/C#/C etc)?

11. DOT NET IS A MULTI-LANGUAGE PLATFORM. DEAL WITH IT.
Do not finish off your post with "code in VB only". If the help is given in C#, translate it with one of the many online converters or use it in a class library. If you are having trouble translating it, post back including the specific line you are having trouble with. If you prefer to see it in VB, state at the beginning what language you are using (it will be used as a hint but not as a constraint).

12. WHEN YOU POST CODE, INCLUDE THE EFFECT YOU ARE SEEING
"Here is my code. It doesn't work". What doesn't work? Does it not compile (what is the compilation error on what line?), does it throw an exception at runtime (what exception on what line)? Learn to at least use breakpoints and step into to locate the offending line!

13. "URGENT, URGENT, PLEASE HELP" or "REPLY SOON, I AM WAITING"
Everybody that posts to the ng requires help urgently. Marking your message as such will only piss off some experts, thus you get less attention. Don't do it. Don't cry for help; the fact that you posted a question is a big clue that you are after help.

14. DO NOT MULTI-POST
Posting the same question separately to every ng you think it applies to, is real bad manners. Most experts hung out in more than one ng, so they have to read your post multiple times. Imagine if you posted the same question to one ng multiple times; isn't that stupid? That is exactly what multi-posting does. If you think that you *must* target multiple ngs, please cross-post (include the ngs in the “to” field - if your newsreader doesn't support that then change newsreaders).

15. DON'T ASK ME TO DO YOUR PROJECT
"How do I pass parameters from one thread to another" is OK. "Post a sample that animates a little person on the screen collecting coins while avoiding aliens" is not OK.

16. DO NOT ASK UNRELATED QUESTIONS IN ONE GO
Do not gather up your questions in one post. You may have encountered these 5 problems in the last hour, but posting them in one message will not get them answered. Think about it: Unless someone has the best answer to all of them, they are not going to help (had you split them into many posts, some would get answered). Worst, someone replies with answers to some questions (but not all). Given that the post has had a reply, others may not look at the thread so your unanswered questions get ignored. Also, posting many unrelated questions invariably breaks the following rule.

17. CHOOSE A GOOD SUBJECT
Not everybody reads all the posts in the ng. Besides, an expert may get a couple of minutes at lunchtime to scan the group for a few easy questions to address. Guess what they are scanning. You got it: the subject. Subjects such as ".NET" or "TabControl" or "Exception" or "[no subject]" are ignored.

18. THE SUBJECT IS NOT A SUBSTITUTE FOR THE BODY
Sticking your question in the subject and leaving the body empty is not clever. Not repeating any info of the subject (or referring to it) is not clever either. Choose an appropriate subject and then, when you write the actual message, forget what you wrote in the subject: (re)describe the full problem.

19. DO NOT CHANGE THE SUBJECT FIELD
You are participating in a thread of discussion and mid way through you change the subject - please don't! If you want to say "thank you" or "solved" say it in the body; don't change the subject text. Without going into details, this causes problems to some newsreaders (when they are used in a certain way).

20. NEW QUESTIONS GO INTO THEIR OWN NEW THREADS
This is a bit like the multiple unrelated questions in one post. You've started a thread, you got your problem solved and now you have a new problem. Don't insist that the kind person that just helped you should now address your new issue! Start a new thread.

21. EXCLAMATION MARKS
Exclamation marks, smileys etc have their place in newsgroups. I have no problems with them and use them myself but please don't end *every* single sentence that you *ever* wrote on *every* post with 3 exclamation marks!!! [ true story]

22. Last but by no means least: DON’T REPLY TO ME
Replying in the ng is fine. Replying to me personally is not – please don’t. (Comments on my blog entries are always welcome of course)

For more… just search!

The Importance of Customer Interaction

Thu, March 10, 2005, 12:24 PM under SoftwareProcess
Over the last two days we spent time visiting client sites around the country and obtaining feedback on our current products & future thoughts. As much as I was not ecstatic to be offline for two days, I can't stress how important these kinds of events are to a developer. If you have the opportunity to go meet the end users of your magnificent creations, then go do it now. It is invaluable!

I could bore you stiff with the specifics discussed, but I won't. Instead, here are some general thoughts which I think apply to most products.

1. How do you please both the savvy and the newbie? The one that explicitly asks for XML export and the one that says this is the first touch screen device they ever came across!

2. It is hard to draw a line of where the features of one product end and another's begin. What's the point of offering features that drive sales up on this but cut sales from that - dropping the overall profit!

3. Should we abandon PCs and do everything in embedded devices (WinCE, not XPe) or should we dumb them down and have them slaves to PC applications? Everybody can be persuaded one way or the other; the devil's advocate always wins!

4. When you replace an older product, you better make sure *all* features of the original are carried over. There is no feature that "nobody ever used that, it was just there"!

5. Do users understand that this response is bad for my job security: "I love it; it does everything I want; don't change it".

6. Are shortcuts (i.e. having more than one way to do a task) good or bad?

While I ponder on the above (along with 4 A4 pages of notes), please bear with me for any unanswered emails; I will slowly catch up with 5 email accounts and hundreds of blogs, not to mention the newsgroups... hopefully before the next round of customer visits next week.

Blog link of the week 09

Sun, March 6, 2005, 03:34 PM under Links
- My favorite blog entries are those that cover a topic from A to Z. Another attribute I look for is content that has not been published before. Naturally, stuff like that comes once in a blue moon; on Wednesday the moon must have been blue on Peter Foot's blog.

- Layout in WinForms.

- Windows CE History (via droppings)

Back to basics 1

Fri, March 4, 2005, 03:33 PM under dotNET
Here is another question that appears in various guises.
"Event X from control Y gets fired twice" or "I want to stop this event from firing while I am waiting for Z"

For example assume that you do stuff in the event handler of the selectedindexchanged event of a list; you now need to select an item in a list programmatically but do not want to run your event handling in that case (only when it is done by the user). Here is a simple example:

Given a form with a listbox and a button let's assume your event handler looks something like this:
Private Sub ListBox1_SelectedIndexChanged(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles ListBox1.SelectedIndexChanged
MessageBox.Show(ListBox1.SelectedItem.ToString())
End Sub
And let's assume as part of a button click you are doing something like this:
Private Sub Button1_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles Button1.Click
ListBox1.SelectedIndex = 0
End Sub
When you click the button you don't want to see a messagebox.

As you'd expect the solution is simple:
1) Use a boolean flag and check it in your event before processing
or
2) Dynamically remove the event handler

1) Define a boolean in your form code like this:
Private mDontRun As Boolean
Change your button click event handler body to be like this:
mDontRun = True
ListBox1.SelectedIndex = 0
mDontRun = False
And add to the selectedindexchanged event handler the following as the first line:
If mDontRun = True Then Return
2) The alternative is not to declare a boolean, not to change the selectedindexchanged event handler and simply change the button click method body like this:
RemoveHandler ListBox1.SelectedIndexChanged, _
AddressOf ListBox1_SelectedIndexChanged
ListBox1.SelectedIndex = 0
AddHandler ListBox1.SelectedIndexChanged, _
AddressOf ListBox1_SelectedIndexChanged
Simple really... and one more entry I can point to from the ng...

Using C# from VB - Level 000

Mon, February 28, 2005, 04:04 PM under dotNET
It is amazing how many requests in the newsgroups are something like
"...I have this C# code I need to translate to VB..."
Occasionally we get requests for translating VB to C# and the same principle applies.

If you really need to translate the code, *please* learn how to at least read the other language: it will make you a better .NET developer, guaranteed. There are many sites that list the differences and there are many converters for VB-to-C# or for C#-to-VB or both.

However, if you just picked up a C# file and you need to use it from your VB project you can do just that by adding it to a dll first. Given that the advice leads to more "how to" questions (believe me it does!), here are the steps needed to achieve just that:

1. Create New C# Smart Device project (not for Full Fx)
2. From the wizard select the target and then Class Library. Choose a suitable name and location.
3. Delete the default file Class1.cs
4. Project->Add Existing Item (from the menu)
5. Navigate to the folder where you have saved/downloaded your C# file. Open the file (which makes a copy to the project's directory) or Link to it (which allows you to use it in the project but only keeps one copy on disc)
6. Double-click in solution explorer to view the file. Note the namespace declaration at the top (e.g. namespace OpenNETCF.IO). Optionally change it to the name of your project.
7. Repeat steps 5-6 for any other files
8. Build->Rebuild Solution
9. You now have a dll in the bin\Debug directory under the project you just created

From your exe/application project select from the menu Project->Add Reference and browse to the dll; Select it and OK.

Blog link of the week 08

Sun, February 27, 2005, 03:33 PM under Links
- After last week's BLOTW, it is only fair that I point to an MSFT response. There have been many more replies (I count at least 10 in my aggregator) so I will point you to one more, where you should read the comments in addition to the post.

- I was fairly confident I had nailed most of the differences between C# and VB in my head and then I came across a post on value type initialization. Another difference that is widely known is regarding interface implementation. It has been discussed before and is raised again here; if you think you can defend C#, please go comment (I am genuinely interested).

- Not sure if everybody is familiar with the versioning advice found here, but I am looking forward to "The Build Master".

- Some add-in is required to automatically create a BLOTW entry whenever Rico writes something new :-) Check out his latest, where he nails the differences between managed and unmanaged runtime performance.