Blog link of the week 44

Sun, October 31, 2004, 03:26 PM under Links
David Notario (x86 JIT developer) kicks off his blog with two great posts.

Welcome

Sun, October 31, 2004, 07:26 AM under Blogging
This blog has moved to this new home (http://www.danielmoth.com/Blog/) from its previous place (zen13120.zen.co.uk).

If you are reading this in your browser, welcome!

If you are reading this in your newsreader, welcome and thanks for updating your subscription (or for having subscribed to feed://feeds.feedburner.com/DanielMoth)

The end of comments

Sat, October 30, 2004, 03:58 AM under Blogging
1. You will have noticed that blog spam is on the increase. Unfortunately, blogger doesn't offer any protection (e.g. can't preview comments, can't really delete a comment once it is posted, etc) [point A]

2. My less-than-ideal approach was to leave comments open for a week after which I would choose "Hide comments" (as well as forbid new comments) on selected past posts. Sadly, this changes the feed in such a way that some tools pick them up as new posts (which is irritating) [point B]

3. In syndication tools/newsreaders there is no "Comments" link for blogger-generated feeds. [point C]

4. Conceptually I don't separate comments from trackbacks and blogger doesn't support trackbacks [point D]

So, the aggregation of the above points has led me to turn off comments for new posts. At the same time I enabled the "Email Post" feature. As always, should you have a comment or anything else to say to me, you can email me using the link on the left.

Sorry :-(

HideSelection

Wed, October 27, 2004, 10:40 AM under MobileAndEmbedded
"[HideSelection] controls whether the current sub-selection is visibly hidden when the control loses focus. Most controls highlight the currently selected contained item and make its background color the selection color. If this property were set to True, then the background color would revert to normal when the control loses focus."

Some Windows Forms controls of the .NET Framework offer the HideSelection property (e.g. TextBox, ListView and TreeView). So, if for example you have a form with the 3 aforementioned controls on it and you clicked on each one of them, you would be able to see which TreeNode is selected, which ListViewItem is selected and what text is selected without further interaction (presuming you set their HideSelection property to false, which is not the default by the way). So the highlighting is preserved after the control loses focus.

Unfortunately, the Compact Framework does not offer the HideSelection property. Furthermore, the default is not consistent: it is true for TreeView but false for ListView!

You would have thought that with CF 2.0 they would offer us the HideSelection property or change the defaults to be consistent, but my suggestion was postponed.

So this entry serves as a container for the code that I use to simulate the HideSelection property (based on SetWindowLong). The sample should work for CF 2.0 as is and if you wish you can access the TreeView handle without resorting to any tricks (Control.Handle is available in CF 2.0). Place the code on a form that also contains a TreeView. It simulates TreeView.HideSelection = false.

' VB
Protected Overrides Sub OnGotFocus(ByVal e As System.EventArgs)
MyBase.OnGotFocus(e)
Static doneOnce As Boolean
If Not TreeView1 Is Nothing Then
TreeView1.Focus()
If doneOnce = False Then
doneOnce = True
Dim hWnd As IntPtr = Win32Api.GetFocus()
Dim lS As Int32 = Win32Api.GetWindowLong(hWnd, -16)
lS = lS Or &H20
Win32Api.SetWindowLong(hWnd, -16, lS)
End If
End If
End Sub

// C#
private bool doneOnce;
protected override void OnGotFocus(System.EventArgs e) {
base.OnGotFocus(e);
if (TreeView1 != null){
TreeView1.Focus();
if (doneOnce == false){
doneOnce = true;
IntPtr hWnd= Win32Api.GetFocus();
Int32 lS = Win32Api.GetWindowLong(hWnd, -16);
lS = lS | 0x20;
Win32Api.SetWindowLong(hWnd, -16, lS);
}
}
}

Blog link of the week 43

Sun, October 24, 2004, 03:26 PM under Links
Alex Feinman does non-rectangular windows on CE with CF. Cool!

Now that C# gets EnC, if you don't want to use it, there will be a menu item option to turn it off. Early Adopter leaks a Whidbey screenshot of the context menu :-))

I am back

Sun, October 24, 2004, 02:40 PM under Personal
After too many flights/hotels, I have returned to Blighty. We visited a few cities staying between 2-5 nights at each; starting at Hong Kong (Manhattan of the East in my book), then Melbourne (justified its title as 3rd largest Greek population), then Sydney (most beautiful harbour of the world indeed), Uluru (they weren't lying, it is a big red rock), Cairns (if you are a diver don't go - the great barrier reef is addictive, I want to live there!) and finally Singapore (live to eat). Photos are at the usual place on my Home Page.

While off topic (no technical content in this post), let us congratulate Manchester United for a well deserved victory earlier today :-)


[again] Out of Office

Sat, October 2, 2004, 02:51 AM under Personal
Bracing myself for the longest offline period I've ever had in this country: 3-4 weeks!

My offline period includes not updating this blog of course. I guess the greatest miss will be the "Blog link of the week" feature, or am I wrong? So while I am absent, may I interest you in revisiting some previous BLOTW [40,39,38,37,36,35,34,33,32].

Normal service will resume on Sunday 31 October 2004.

Stay subscribed and have fun... Australia here I come! :D

[again] Blog link of the week 40

Sat, October 2, 2004, 02:43 AM under Links
As you know I usually do the BLOTW feature at the end of the week but I will not be online this Sunday so here it is...

This week I recommend All About Handles in Windows Forms; the title says it all.

If you can't stomach the full thing you must at least go through the Design Guidelines Digest

Invoke with Whidbey

Fri, October 1, 2004, 05:30 AM under Whidbey | VisualStudio
Last time we looked at Control.Invoke on both CF and full framework. Assuming you have read it, let’s look at VS2005.

On the desktop, if you forget to use Control.Invoke, you now get an InvalidOperationException with the Message: "Illegal cross-thread operation: Control 'SomeControlName' accessed from a thread other than the thread it was created on." That is cool, and the stack trace will of course point you to the culprit. Note this only works when debugging in the IDE, and is not available to CF projects. Instead, with Smart Device projects, you get the (catchable) System.NotSupportedException (with the Beta 1 bits).

CF 2.0 brings parity with the desktop; all 3 limitations are removed, so you don't need the ThreadPool or the Queue or the need to cast:


// ...or any other type/params you want
delegate void SomeCustomDelegate(object o);

// This method runs on a non-GUI thread e.g. Threading.Timer
internal void OnNonGuiThread(Object o){
// if you have more than one argument just add it to the array
object[] arr = {o};

// assuming all this code is in a form
this.BeginInvoke(new SomeCustomDelegate(UpdateBox), arr);
}

// This method runs on GUI thread
private void UpdateBox(Object o
/*other arguments as defined by SomeCustomDelegate*/){

// TODO use o and other arguments
this.Text = o.ToString();
}


Invoke CF and Full Fx

Fri, October 1, 2004, 05:24 AM under dotNET
It should be a well known fact by now that, when in need to updade controls created on the GUI thread, you must use Control.Invoke (call the thread-safe static Invoke method on any control, e.g. the Form). It should be but, judging at how often this comes up in the newsgroups, it's not.

The issue and solution are the same for both full and compact frameworks; the difference is that, although the desktop seems to be forgiving (sometimes updating from non-GUI thread works), the CF certainly isn't: every time you try it, the result is an application that is hung/frozen/locked up. If you see this on your device, start looking for the said problem.

Of course, like almost every other area of the CF, Control.Invoke support is limited. It is limited in 3 areas:

1. You cannot pass any delegate you want to Invoke; rather, you can only use the EventHandler. So, if you were hoping on using the efficient MethodInvoker or one of your own, forget about it.

2. Invoke cannot be used to pass arguments. So, you can marshal control from a thread to the GUI thread, but you cannot pass any parameters in the same call.

3. BeginInvoke is not supported. So, you can only do it synchronously (your non-GUI thread does not return until the Invoked method itself completes).

A solution to the 2nd limitation is to write code like this:

Private mDataQue As New Queue
Private mUpdateDel As New EventHandler(AddressOf UpdateBox)

' This method runs on a non-GUI thread e.g. Threading.Timer
Friend Sub OnNonGuiThread(ByVal o As Object)
' if you have more than one argument
' create an object or structure
' that holds the data you want to pass to the GUI thread
SyncLock mDataQue.SyncRoot
mDataQue.Enqueue(o)
End SyncLock

' assuming all this code is in a form
Me.Invoke(mUpdateDel)
End Sub

' This method runs on GUI thread
Private Sub UpdateBox(ByVal sender As Object, ByVal e As EventArgs)
Dim o As Object
SyncLock mDataQue.SyncRoot
If mDataQue.Count > 0 Then
o = mDataQue.Dequeue()
End If
End SyncLock

' TODO use o
' cast o to your object/structure and
' use it to update the GUI
End Sub


The 3rd limitation can be overome simply by using the threadpool. Extend the previous solution with:

' NOW, *this* is the method that runs on non-GUI thread
' e.g. Threading.Timer
' The original method is now just a helper
Public Sub OnNonGuiThread2(ByVal o As Object)
ThreadPool.QueueUserWorkItem(AddressOf OnNonGuiThread,o)
End Sub


We look at what Whidbey brings to the table next time.