Congrats on the nice article and the efforts you have put in it (you've got my 5). I have one comment on the model you have chosen - you assume that as far as the Tooltip is Alive, it is associated with a Win32 Handle (a simple property set like Active uses the SendMessage API). However, you may want to use it in certain cases (like Design-time) where Handle is not needed. Or you may want to instanciate it and display it later on. I think it is a good practise to create (and destroy) its Handle on demand (like System.Windows.Forms.Control does).
I could move the createwindow call out of the constructor and allow it to be created manually, and I did consider this. The only problem is that I would have to test the handle for validity in every property/method, because developer may be attempting to set properties before creating the tooltip window with the creation method. Most implementations that I have seen (in C), create the tooltip as a standing member of the application, that is, it is alive and waiting from the point when the application is first initialized. The ToolTip class itself does not have a very large footprint, (basically a static window with timers and drawing functionality), so I think this is a reasonable way to implement the class.
It has nothing to do with the footprint - it is just a semantic used through all Windows Forms - there is a distinct separation between a Control and its Handle. The Control, as an object, may exists without a Handle created. Its Handle is created whenever needed, however you may alter its properties even if its Handle is NOT created (managed vs unmanaged resources). This gives you the ability to have a Design-Time support - as seen from 2 comments below, you will have troubles with instanciating your Tooltip at Design-Time. The Control class itself has CreateHandle and DestroyHandle methods which reallocate system resources and destroy them respectively.
So when are you gonna do a custom TabControl for us?
"Why don't you tie a kerosene-soaked rag around your ankles so the ants won't climb up and eat your candy ass..." - Dale Earnhardt, 1997 ----- "...the staggering layers of obscenity in your statement make it a work of art on so many levels." - Jason Jystad, 10/26/2001
Grid is a listview hybrid, based on a control I wrote in vb6 some years back. Original (vhGrid on psc), was 27k lines of code, and very fast and featured. This iteration will hopefully outshine the other by quite a margin, and should be worth the wait..
I mean the same way the standard .NET tooltip can be used. So, add the tooltip to the VS toolbox and drag the tooltip on to the form. Now the properties of the tooltip can be set by VS instead of having to do this from within the code.
Don't think that will work. It derives from NativeWindow. The VS designer needs classes derives from Control or at least Component afaik. Some attributes and additional coding would be the least to achive this imo.
But honestly, even adding the standard .NET tool tips directly in the code is twice as fast as using the designer. Create instance, eventually change a property and call SetToolTip and you're done. With intellisense that take only 5 seconds.
I see.. you would have to drop this into a usercontrol, then add a subclasser class, hook up the subclass eventhandler and compile. Why bother though, the class is easy to wire up, create an instance and call SetToolTip for each control and your done.
I agree it can easily be done in the way you describe. But if it comes to localization it's much more work. Then you have to write all the plumbing code to obtain the resource value from the resource file and assign it to the tooltip. If it is all done from within VS, you just have to enter the text and it is automagically placed in a resource file.
"In my own implementation, I'll use SafeHandle rather than IntPtr for the window handle (why didn't they just fix the garbage collector?), but in an attempt to keep this available to pre 2.0 versions of C#, I am using IntPtr here."
You can not open a new tooltip in example until the last tip has closed. This is a limitation set in the example only. I used IsVisible to check if the tip had closed before allowing a new one to open, because the same tip is demonstrating many different styles, and so has to flip property settings before reappearing. Also. VS 2.0 users should change window from IntPtr to SafeHandle as described in the article.