Since I graduated and actually started working in my field, I've been working almost exclusively on Windows, which is a large part of the reason, I believe, that lately I've been focusing more and more on getting involved in Open Source and GNOME development. Now, while I do prefer Linux and non-Microsoft software, I've long since gotten over the whole blaming Microsoft for being an Evil Mega-corporation. Actually, their recent technologies, such as Silverlight and .NET, really interest me. C# is one of my favorite languages. Yes I'd probably have never given them another look had Miguel de Icaza not started the Moonlight and Mono projects, respectively. But since I have an option to play with the technology, I've come to really like it. I just wish the .NET API was a little more stable.
Still, as much as I like .NET, I don't feel that Windows.Forms did enough to correct what I feel is wrong with Windows GUI development. First, when they shipped .NET, the environment would create the GUI as code in whatever language you were working in. This is just stupid. Having to recompile your application in order to make a small tweak to the UI is just ridiculous. I know they've since corrected this with an XML-schema, but what I've read about it suggests it still isn't as flexible as what Glade can do for GTK+, not that information about it is easy to find. Most searches for Windows.Forms and XML just want to tell you about the DataGirdView class.
Plus, Windows.Forms applications are still hard to design such that the GUI handles resizing and the like cleanly. While it's an improvement over straight Win32, I found that I had a hell of a time getting an window to properly resize, particularly shrink. Plus, if I increased the size of the Window, I may not have been able to get it to reduce again. Sure, this may just be my lack of intimate familiarity with Windows.Forms, something that I am working to rectify, but when I design a GUI in GTK+, it just works. I pack the widgets into the containers I want them in, set some settings, and it works for me. It does what I want, and I don't have to write a ton of code to ensure my widgets behave as I expect when I resize the window. I was also disappointed that while the idea of "container" objects really took hold on this version of the API, I feel Microsoft really messed up in not making everything a container. That, in my opinion, is what makes GTK+ so easy to use. All widgets are packed in containers, and while it takes some work to get used to it, I feel that it goes a long way to ensuring that programs written in the toolkit will be more uniform in their behavior.
I already sort of mentioned it, but the documentation on MSDN is really, really hard to use. For instance, go to the MSDN, and enter the term "ADODB" into the search box, I would expect to get the API documentation for the ADODB COM Object first. Instead, I get an enormous amount of articles, forum posts, blog entries, and links that aren't even on MSDN. Even if I filter my search by the MSDN Library, I still don't get the result that I'm looking for. If the COM object I need to use in order to use the ActiveX Data Object (ADO) is ADODB, why doesn't that search get me to the ADO portion of the Library? This is really, really bizarre to me, because in general Microsoft's Live Search does a really good job of returning relevant results. So what's wrong with the MSDN search?
Finally, lately I've been working in VBScript and ASP. I was never much of a fan of VB or VBScript, I always felt they were a little too verbose. Having done mosto f my programming in C/C++/Java/C#/Perl and now Python, BASIC is a bit of a culture shock. However, this would probably be more tolerable if the language would be
more internally consistent. For instance, why do Do and For Loops have different termination keywords? Why not just use LOOP for marking the end of both a For/For Each or Do loop? Even Next would be acceptable, as long as it was consistent. Of course, there really isn't a good reason I can find that End isn't used to mark the End of a For block or Do Block, especially since the Exit keyword is used to denote premature ending of a loop. The End keyword should be a generic method to End the current code block, kind of like the function that curly brackets serve in C-based syntaxes, or the indention level does in Python. Maybe it's just culture shock, but the Loop and Next keywords just seem like unnecessary cruft to me.
Error handling could be a lot more robust as well. I should be able to tell the runtime which errors it's allowed to ignore and continue on. Instead, all I can do is tell the software to Goto a certain line, or just keep executing on an error. If I'm writing a library call, and an error occurs, I can't just let the runtime propagate that error up the caller for me, which requires I either handle the error (not the best idea for libraries), or issue a specific call to raise the same error again. Plus, errors aren't named, and are harder to identify. I shouldn't have to guess at the contents of the Error Description to determine what actually went wrong in my program. Especially when the error messages are usually pretty cryptic.
Of course, keyword cruft and poor error handling is nothing compared to the use of " as both the only way to denote the beginning and end of strings and as an escape character. If you thought counting parentheses is a LISP-like language was annoying, just wait until you have to count double quotes. I mean, who thought this:
"""He's dead Jim,"" Bones said with a hushed voice."Was possibly a good idea?