March 2006 - Posts

Budgeting for marketing

I just loved this Dilbert comic yesterday:

 
Of course the inverse is true. Get the product right in the first place and you have a lot more money to pour into the product itself rather than on marketing.
 
 
 
Posted by bill | with no comments
Filed under: ,

Yet another reason why C# is LAME

From an email list, a poster finally got some code to show an excel dialog to work. This is their code:
 
if(xlApp.Dialogs[Excel.XlBuiltInDialog.xlDialogOpen].Show(sTextName, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing)
 
In VB, that code is:

If xlApp.Dialogs(Excel.XlBuiltInDialog.xlDialogOpen).Show(sTextName) Then
 
C# sure does suck when it comes to working with Office or COM.
 
 
Posted by bill | 2 comment(s)
Filed under: ,

Atlas And Administrator Approved ActiveX

A couple of weeks ago I was chatting with Nigel about the security permissions needed client side for Atlas//Ajax.  Typically you will find it uses XML, so IE needs permissions to use MSXML.  Rather than allow all ActiveX, I add MSXML to my administrator approved controls.  See my earlier post for details…
Posted by bill | with no comments
Filed under:

IE Administrator Approved ActiveX

I like to run IE with ActiveX for the internet set to administrator approved.  This allows me to run things such as windows update, media player, macromedia flash, without all the other activex possibilities to worry about ;)  This is the reg file I use to set the administrator approved controls
 
Windows Registry Editor Version 5.00
 
[HKEY_CURRENT_USER\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\AllowedControls]
;
; ShockWave flash
"{D27CDB6E-AE6D-11CF-96B8-444553540000}"=dword:00000000
;
; MediaPlayer  ( old verion, hence commented out)
;"{22D6F312-B0F6-11D0-94AB-0080C74C7E95}"=dword:00000000  
;
; Media Player 10
"{6BF52A52-394A-11d3-B153-00C04F79FAA6}"=dword:00000000
;
; Microsoft Update
"{6E32070A-766D-4EE6-879C-DC1FA91D2FC3}"=dword:00000000
;
; Microsoft Tranfer Manager
"{82774781-8F4E-11D1-AB1C-0000F8773BF0}"=dword:00000000
;
; ("W3C-DOM XML Document 6.0 (Apartment)")
"{88D96A05-F192-11D4-A65F-0040963251E5}"=dword:00000000
 
 
 

 
Posted by bill | 3 comment(s)
Filed under: ,

Keyboard mapping on the Toshiba M200

I was reading Richard Tallent's blog entry about a CAPS lock problem which turned out to be a keyboard scan mapping problem, and it reminded me of one of those things that's always been on my virtual TODO list to fix in regard to the Toshiba M200.
 
The problem with the M200 is there is no left windows key, instead it's up the top right of the keyboard.  They also have moved the ` ~ key to the bottom of the keyboard where the windows key would normally go. 
 
So I decided to put a windows key back on the left of the space bar.  but that meant I'd have to remove the right windows key or something else would have to go.  Well I decided that the Insert key was the most useless key on my keyboard, so that could be the windows key, but it was on the wrong side of the space bar.   ah ha !!  The ` ~ key is really a pain where toshiba put it.  I can never find it (well I can but I really do have to search). 
 
So my solution was to physically swap the `~ key with the Ins key. You just pry the keys up from the back and they snap off, and just press them back in place and they snap back on (BTW: nice to see Toshiba uses metal brackets unlike some cheaper keyboards on laptops these days)   Now the Insert key is on the left of the spacebar.
 
The final part is to swap the mappings, making the Insert key, which is really the old `~ key the windows key, and the fixing the new `~ key mapping.  This reg file will do that trick:
 
Windows Registry Editor Version 5.00
 
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Keyboard Layout]
"Scancode Map"=hex:00,00,00,00,00,00,00,00,03,00,00,00,29,00,52,E0,5B,E0,29,00,00,00,00,00
 
 
For more information on the keyboard scan mappings, see the article at :http://www.usnetizen.com/fix_capslock.html
 
Posted by bill | with no comments
Filed under:

MSDN subscription annoyances continue

Last month when I went to update my MSDN DVD collection, I faced the rude awakening that the "New and Removed Products" page was seriously broken.  The search doesn't go past October 2005.
I asked in the private forums, no response. I asked MSDN online concierge.. they couldn't tell me.  I even asked our own Frank Arrigo, and yet still no response.
 
<black helicopters>
Is this some kind of perverted conspiracy ?  Is it so MS can remove products hoping you won't realize until it is too late ?
</>
 
What ever the reason, it's a real pain in the you know where.  It would be nice to know which DVD's have products on them you might want to or actually NEED to archive.
 
 
 
Posted by bill | 8 comment(s)
Filed under:

Loose coupling with Intra-Class events

 
In Visual Studio 2005, we typically have a lot of generated code per application. Strongly typed datasets are a classic example of this. One difficulty of having generated code parts of a class alongside manually written parts has been removed due to the use of partial classes and physical separation of these parts into different files.  The challenge now lays in how do you have these two parts interoperate with each other. How does code in the generated part call into code in the human written part ?  VB solves this with the use of intra-class event coupling.
 
 
The problem :
 
Let's take an example of a Customer class with an Name property As String, and this code is generated for you.  Now assume you want to intercept the property Set and do some complex validation of the value.  
 
'generated code
Partial Class Customer

   Private m_Name As String

   Public Property Name() As String
      Get
         Return m_Name
      End Get
      Set(ByVal value As String)
         'TODO: notify any custom code
         m_Name = value
      End Set
   End Property

End Class
 
' human written code
Partial Class Customer
 
   'TODO add code to intercept the Name being set
 
End Class
 
 
Solutions to the problem :
 
Some approaches taken to this kind of issue is to always provide stubs and use attributes etc to mark those stubs.  this removes the separation of generated code by file, rather the generated code is interweaved with your own code and placeholders are inserted for you to work with. This approach works well except that clean separation is lost, and it requires more work on the code generation tools to parse your code.  Another approach that can be taken is to have conditionally compiled code that checks to see if a function exists and compiled accordingly.  And yet another approach that can be taken is to use inheritance and overridable methods.
 
The inheritance approach falls down very quickly when you have complex object models and factory methods. Admittedly this could be less fragile today due to the use of generics, but still it brings with it an un-due amount of complexity. Conditionally compiled code on the other hand falls down around inheritance, especially when we have separation of code into different assemblies. So of those three approaches I've mentioned, today in Visual studio, the method stubs approach is the preferable one.  But there is one more to consider …
 
The approach you can take in VB is to use intra class events. I'll drill into how these actually work under the covers in a minute, but for now it's easiest to picture them as method stubs that are linked by the compiler. So these in fact work basically the same as using the method stub/placeholder approach, but also provide clean separation of generated code and user code on a per file basis.
 
And the nice thing is in VB they work today, straight out of the box in Visual studio 2005. 
 
 
How intra class events work :
 
Intra class events are the same as any event in VB. The "magic" part is how the compiler injects code to wire these up. Via declarative programming, the VB compiler will inject the code necessary to wire up the generated code and the human written code.  You can see this today in the Strongly Typed Datasets. In VB you can handle the CustomerRowChanging event inside the partial class for the CustomerTable. (note: today in C# you cannot)
 
Let's expand the example we had from above:
 
'generated code
Partial Class Customer
' add an event for the name changing.
' The ValidationEventHandler is just an example of the type of event we could use here
' It passes in old value, new value, property name, and a Cancel argument.
' the NewValue and OldValue are as type T, which in this case is String.
   Private Event NameChanging As ValidationEventHandler(Of String)
  
   Private m_Name As String
 
   Public Property Name() As String
      Get
         Return m_Name
      End Get
      Set(ByVal value As String)
          Dim evArgs as New ValidationEventArgs("Name", Me.m_Name, value, False)
          RaiseEvent NameChanging( Me, evArgs)
          If not evArgs.Cancel Then
             m_Name = evArgs.Value
          End If
       End Set
   End Property

End Class
 
' human written code
Partial Class Customer
 
  
   Public Sub Me_NameChanging(sender As Object, ev As ValidationEventArgs) Handles Me.NameChanging
       'TODO validate the values via the ev parameter's NewValue and OldValue properties
       '         and set ev.Cancel = True to cancel the property set.
   End sub
    
End Class

 
The above example is a simplified use of  events to validate the setting of the Name property. How this actually works is the VB compiler recognizes the Handles declarative syntax and wires the event handler into the object constructors  If you wanted to try to achieve the same in C# you could manually wire up the event handlers in your own constructor, however that approach requires that the generated code does not have any constructors, which is why you can't really do this in c# with strongly typed datasets as the generated code there does provide constructors and needs to.  With VB however, because the declarative syntax tells the compiler to do this wiring, the compiler gets to act as the glue between the generated code and your custom code.
 
The cost
 
The old saying there's no such thing as a free lunch tends to hold true here. the cost however is very minimal.  You may for example want the NameChanging event to be public in your object model, so really there is not overhead.  In other cases, the cost basically is an IntPtr slot for each declared Event, although you can minimize that via collection for all the events. should you actually choose to wire up the event then that IntPtr will point to a multicast delegate which will store a function pointer and a pointer to self. The invocation is also minimal overhead, as it is basically calling delegates in a list. So memory or preformance issues are pretty insignificant, and can actually be favorable compared to inheritance or method stub approaches.
 
One concern you might "one day" need to be aware of is that event invocation does not guarantee the order the listeners will be invoked in the cases where there are more than one listener to the same event.  That being said, the behavior is FIFO (first in first out), and as your intra class events are wired in at the start of the constructor, they are always first in, hence are today first to be notified.
Should that ever change, or should you require further control on the order of the events invocation, you can in VB.NET use the Custom Event syntax which let's you write the Raise method as well as modify the Add and Remove methods,
 
   Public Custom Event SomeEvent As EventHandler
      AddHandler(ByVal value As EventHandler)
          'TODO
      End AddHandler

      RemoveHandler(ByVal value As EventHandler)
          'TODO 
      End RemoveHandler

      RaiseEvent(ByVal sender As Object, ByVal e As System.EventArgs)
          ' ensure events are raised the way you want them to be in here
      End RaiseEvent
   End Event
The VB syntax shown here is as per the MSIL specification, and corresponds to the MSIL of .addon, .removeon, and .fire. 
In C# however they only support the .addon and .remove on, so you have to write a separate method to try to simulate the .fire. Typically the OnXXX pattern is used for this, although great care and code analysis really needs to be run to ensure all event invocation then goes via the OnXXX method.  The .fire method provides an nicer encapsulation of this.
 
Conclusion
 
Hopefully you can now see, or will after a bit of experimentation with the above concepts, that intra class events provide a flexible and powerful way of wiring up generated code with manually written code.  And here once again we have VB leading the way with modern concepts such as declarative programming, and also with full specification implementation of things such as custom Events.  Clearly C# has much catching up to do in these areas. 
 
So next time you start to build your business object layers, or any code that may center around code generation, then think about your choice of language.  It obviously makes a lot of sense to use VB for these kinds of applications as only VB today provides such great coupling via intra class event handling.
 
 
Posted by bill | 2 comment(s)
Filed under: , ,

Some links for VDNUG

For those at the VDNUG meeting last night  and for those who couldn't make it, here are some links for further information.

LINQ:

DSL tools:

 

Posted by bill | with no comments
Filed under: ,