I'll start off with a description of what I wanted to do, and what actually happened. I wanted to pick a project that had a bunch of different aspects to it. Something that was pretty trivial to write, was useful, but had its fingers in a lot of different things. So I picked a desktop wallpaper changer. It lives in the tray and changes my wallpaper at user-picked intervals to some random wallpaper. I liked this as a project since it would include image manipulation, basic file i/o, the registry (for saving preferences), tray icon support, standard UI widgets, declares (I think they're called something else in .NET terminology though) as well as a bunch of C# language features. You can download the source and the executable, and feel free to leave comments or suggestions about either. [Source, Binary] [Updated Dec 15, 2004 to include memory leak fix] (Note that to run the binary, you need to have the .NET framework installed on your system. If you don't have it, post here and I'll figure out how you can get it).
Overall, I was very impressed with .NET and C# as far as a toolkit and language are concerned. Microsoft has done a pretty good job with keeping the APIs consistent, which goes a long ways towards making them easier to use. For example, all error checking is done via exceptions. All of it. That means I don't have to remember what returns boolean values, what returns status codes, what has ByRef success parameters, etc. Another thing I was impressed with was the scope of the API. There's a lot of code under the hood that is needed to make this all work, and I can only imagine the engineering power behind the framework.
That being said, I did manage to find two bugs with the runtime toolkit -- one annoying, and the other is rather esoteric. I'll get into those in a later post.
I started the project out in the form editor. This is a fairly easy, though somewhat slow RAD tool. One of the things I like and yet despise about the form editor is the auto-hiding toolbar on the left. This toolbar contains all of the controls that you can add to the window, but it's really unintuitive to use. It's hidden by default, it goes away too quickly after adding a control (which slows down design when adding many controls to a form) and I can never tell where I'm really placing controls. Another thing that bothers me about the form editor is the lack of guidelines. One nifty feature of REALbasic and XCode is that control placement is augmented by giving you guidelines that your controls can snap to. This means that all your controls have the proper spacing between them, as well as around the edges of the window itself, etc. It makes laying controls out a much nicer experience. It's certainly a feature I missed when designing DesktopChanger.
Another few gripes I have about the form editor is the fact that it streamlines things in what seems like an excellent way, but turns out to be not quite as smart as I would like it to be. Here's what I mean: when I double click on a button on the form editor, it causes the event code to be created for me in the code editor. This is an awesome feature since it means I don't have a bunch of event code with nothing in it laying around my source code. But they missed the boat on one important thing. When I accidentally double click and get taken to the code, and decide to delete the code because I don't want that event, it doesn't update based on the fact I just deleted the event code. There's still some hidden code in the form layout event that says "hook this control up to this event" that I always forget to remove. If it's smart enough to put code in there, it should be smart enough to yank unused code out.
Something else that I found bothersome is that there's no easy to way enter ToolTips. You have to make them and set them up in code. All they have to do to make this a little better is add another property (a fake one that only shows up in the form editor's properties viewer) that lets you add the ToolTip text on a per-control basis. They can auto-generate the tooltip code for you under the hood based on that property.
I don't want you to think my first experience with the form editor was an entirely horrible one. There are also a lot of good things about the form editor. I like the concept of a pasteboard on the bottom of the editor for you to place invisible controls. This means that they're not cluttering up my design view with icons that will never actually appear. But there's still a centralized place for me to get access to these items (such as timers, tooltips and other invisible "controls").
Another thing that I like is how easy it is to get tab ordering right. There's no excuse for tab ordering issues with this editor -- everything comes in a sensible order. What's more, you can tell the tab ordering just by tabbing thru the controls in the editor themselves. The tab order is the same in design view as it is in the application itself. A very nifty feature!
Since my UI needs were fairly minimal for this project, I don't have too much else to say about the form editor itself. Overall, I think it's a functional editor that will get the job done given sufficient patience. So long as you don't mind double checking your work (like spacing issues, or making sure mmenonics are all unique), the form editor will get the job done.
That's all for this time. But stay tuned for the next posting when I delve into how I wrote the application itself.
nice writeup! I agree on all points.. but let me lend a hand, as I have with the previous C# posts...
those invisible "controls" .. in a .Net world are called "components" .. just an FYI!
control toolbar hiding, I hate it too, but thats why I also LOVE the pin.. cause it allows me to say.. ok stay up for a while until I unpin you...
i absolutely HATE the event wireup not going away when you delete code, but thats a HUGE inference the IDE has to make... imagine cutting an event wireup and then pasting.. how is the IDE to distinguish? .. easier thing to do... go to your event property and right click and hit Reset... takes care of ALL of it..
tooltips work like the context menu and validation error handler :( static objects for the lifetime of the form.. blah...
there is a grid you can snap to for controls... one nifty thing about controls is Docking and Locking... pick up Chris Sells "Windows Forms Programming in C#" or if you don't want to be outdated in a year... pick up XAML (WinFX) stuff... they are intrigal in making sure you know everything...
another bittersweet point of the visual designer is Visual Inheritence... it works in Visual Studio 2003 but things get hairy.. sometimes your new controls disappear.. sometimes they move.. it gets annoying..
Im almost tempted to move you to Whidbey.. but its in beta bits ... but the UI is FAST as hell and it makes C# development a breeze... i can code 10x faster in Whidbey
remember the shortcuts... (IDE) CTL-Space - autocomplete, CTL-SHFT-B - build, F5 - build/run ... (DEBUGGER)F11 - step into , F10 - step over, F9 - quick breakpoint
Thanks for the tips Jake! Thankfully, I've gotten the keyboard shortcuts down (at least, the most commonly used ones) finally. And I agree, the pin is a handy thing -- but I don't recall seeing it on there (I must have missed it).
As for Docking and Locking, those are pretty standard RAD tools that Microsoft just now picked up on. I already took note of them. My biggest gripe is that they didn't implement visual guidelines for spacing. They're not that tough to put in...
I agree with you on the event removal stuff. But I think it's possible to be sufficiently clever with it. For example, only do the remove of unused hookup code as a preprocessor to building. Neato idea with the Reset though -- I never knew about that.
I would try it, but I don't feel like downloading a 20+ meg framework. :-P
On the other hand, I do want a desktop switcher. ;) Good work!
I am pretty sure (but Jake or someone will correct me if I'm wrong) that XP and 2k come up the framework already installed. You can always download it and try it out. If it works, great, and if it doesn't, then no harm done (it's an 11k download or something).
the .Net framework is an option for Windows 2000
the .Net framework is included with XP SP2, otherwise you have to download it...
Aaron could, if he so chose to.. create an easy installer from Visual Studio that can bootstrap the framework with his setup... ;) but that would put the setup to a larger size
if you dont have the .Net framework , you're missing out ;) 20mb framework .. blah.. Aaron and I downloaded the 2 gig ISO of Visual Studio from MSDN.. its all about getting what you want
Update: Well, it looks like the application comes with a slow memory leak. When I got home from work today, it was sitting around 160 MB of RAM taken up. Looks like it's debugging time for me. If anyone else spots the leak, lemme know!
Well, I found the problem. I wasn't closing the stream or releasing the image when setting the wallpaper. What I find odd is -- isn't this stuff supposed to happen automatically due to garbage collection?
I went through your code.. first pass just to see how you're dealing with the syntax.. A+
I was just now going to go through your code for the no-nos.. but looks like you found one! ;)
w00t! I get an A+ for syntax on my hello world app! :-D See any other no-nos?
[...] ) Filed under: Programming — Aaron @ 7:58 am After coming up with the initial idea for the project, I decided to start simple. I made a form with a single button on [...]
source not found
Sorry Steve -- fixed now. :: sighs :: damn typos.
hmm, had issues adding a directory that was a mapped drive...
one thing i noticed too, and maybe its just your preference, but you have all the Using statement, yet you write out all the System.IO, System.Drawing, etc...if you use the Using , you can omit that, saves alot of extra code per line
I'll look into the mapped drive problem once I get back to Austin (where I have an internal network to test on). And yeah, I was doing the System.Foobar so that I could auto-complete my code since the IDE won't let me autocomplete without it. I'm trying to get away from that though since it is messy.
backgamon rules
The Good of man is the active exercise of his soul's faculties in conformity with excellence or virtue...Moreover this activity must occupy a complete lifetime; for one swallow does not make spring, n