Next version is done. Well, done except for my old tests that I have to run through. But the new functionality is in there and it works. This also marks the first time I set up anything resembling acceptance tests. Essentially its a list of URLs, both that are designed to pass and designed to fail, that hit every permutation of my test data. That's proper, but it isn't set up using a tool like Fit. I just added the URLS to a "group" in Maxathon which I opened and checked against my testing documentation. This kind of testing would be so sweetly done if I had it set up using FitNesse, but that's a job for the future.
I checked my longest query, and its up to 14 pages from 11, the original length. 99% of the time only a portion of that query will be evaluated, but in the worst case scenario... its the worst case.
In celebration for this milestone (and my ability now to rejoin my work moving development out of the dark ages here), let's groove on some Chocolate Rain!
So, what's the point of this class? If you think about events, you normally think "awesome." Something in your object happens, you inform other objects about what just happened, and they do stuff with this information. Its a sweet wrapper around delegate swapping. But there are some things you have to take into consideration with events. First, they require code. Code you never see. When your event is compiled into IL, it is transformed into a private delegate field, and a property containing add_eventname and remove_eventname methods.
That means that objects that have lots of events, such as System.Windows.Forms.Control and its 69 public events, most of which are never used, waste lots of memory. And since just about everything in the UI of a Windows Form is a Control, you're potentially talking about lots of wasted memory that puts unneeded pressure on the GC.
The EventHandlerList is a way to get around wasting this memory. Event delegates are not created until someone registers interest in them. That's what the EventHandlerList does--it keeps track of event delegates, adding new registrants to existing delegates and creating new ones when needed. But there are two things you must understand about this class.
First, it is implemented as a linked list. So event access is, in a worst case situation O(n), where n is the number of events already registered. If you have a thousand events and expect registrations to come in very quickly, that could show up as a performance hit. Will that ever happen? No. Pretty much no. But why waste time with a slow-ass linked list when the collection could be managed with a hashtable and get O(1) access times?
Second thing to consider, and probably the most important one, is that the EventHandlerList is not thread safe. At all. If you use it, you are responsible for managing how two or more threads access this object at the same time. Sucks to be you.
Jeffrey Richter supposedly has an "EventSet" object that addresses these two issues, however it (and him) are AWOL on the subject. You can go buzz around his blog and website to see if its there.
Anyhow, that's the dope on the EventHandlerList object. Gotta go to another friggen meeting. Bye for now...
Eileen Rumwell (who needs to turn comments on at her blog) recently asked the question, "Where do you get your .NET information?" Its an interesting question; one that applies across just about every profession but is of significant importance for developers. Information changes so quickly that relying on printed material is a liability. So where do good developers go to find the answers to their questions? For me, there's three primary places. Blogs, books and Google.
I consider regularly reading programming blogs to be a class I attend daily. This "class" primarily consists of reading posts from about 50 different feeds that are relevant to my interests. blogs.msdn, CodingHorror and DotNetKicks are among these. Although not a primary resource, I do consider books to be still important in keeping abreast of things in the programming world. Often I use books as a less frequently used resource for research. Often this consists solely of reading books related to work. For example, the last book I read was the Mythical Man-Month; I'll be reading a book on implementing Agile with VSTS next. My third source of information is primarily for quick searches. Often this consists of taking five minutes to search for information on a specific, well defined topic, related to a task I'm currently programming or a subject I'm posting about. These searches take place in three places: VS help, Google web search and Google groups search. Which I do in what order depends on the task and where I am. In VS, the help gets my first attention. When that fails (as it often does), I go to google groups. Almost always someone has had the same question that I have and has posted it on Usenet. Google Groups is the best place to search Usenet to get clues as to possible answers, if not the answer itself. Once I have a better understanding of the problem and its possible solutions, I can refine this knowledge by continuing to search the web. There's a higher percentage of crap in a web search, but I often can refine it by specifying a site (i.e., site:msdn.microsoft.com) or -negating -specific -words -that -indicate -useless -websites.
Anyhow, that's a quick overview of what I do. I'm always open to finding more useful sources of information. Post yours here!
It hasn't been long since I put up 1.0, but I've made some important changes that make the dang thing worth your while. If you run Windows, check it out. If you have Mono, see a doctor, then check it out.
The current release adds an installer, fixes some minor bugs, enforces a single program instance, includes folder browsing (selecting one image essentially selects all in the folder).
Actually, this post is more like: Programming | Political | Bullshit. Today I just learned something about myself. I'm an Omega Geek. Which is definitely cool. And not just because we aren't virgins, like Alpha Geeks. Its because when you think "Omega Geek", you think... Chuck Heston. The original Omega Geek.
Just added another project to my sidebar -- Image.NET. K, sounds a little more amazing than it is. It doesn't do all kinds of wicked image file manipulations or stuff like that. What it does do is show pictures.
I wrote it because I'm sick of all the crappy image file viewers out there. Most of them either flat out suck or are so full of bloat that they... flat out suck. So I wanted something that would do two tings, and two things only:
1) Show images
2) Leave me the fuck alone
So that's what Image.NET does. Right now you have to select the files you want to view. I'm looking to integrate it into the shell better, so you can do stuff like right click on a bunch of image files and view them in Image.NET or just select a bunch of them and hit enter and all that kind of stuff. Anyhow, lightweight, no bloat, view images. Check it out if you're bored.
Most of the time breaking into a program you're debugging is easy. Just load the project in your IDE of choice, set your breakpoint, and run. But what happens when you can't run your program via the IDE? Its sometimes hard to do for things like providers and services that cannot be directly executed by the development environment or that require complex setups or mock frameworks in order to host for debugging. Or something.
Anyhow, there's a simple way to force a program to break, ask to have a debugger attach to the process, and then break for debugging. Here's the code:
The Debugger object has some lovely static methods that allow us to check and see if a debugger is attached, and if not, request one be attached. I could show you what the dialog looks like, but its about 1:30 Saturday morning and I'm 100% sober. Please, let my suffering end a little bit quicker.
Damnit, you friggin bastards. Okay. Here it is:
Right, so just pick the version of your IDE that has your source loaded and you're off and running. The Break() method acts just like a breakpoint. Oh, and wrapping these statements in the #if DEBUG #endif construct ensures that only the debug version will behave in this way. Cool.
Been a bit busy and a lot lazy recently. Time to post!
One of the tools every user has for accessing menu items are mnemonics. Mnemonics, other being one of the freakiest words in the English Language, is a method of accessing menu and toolbar items via the keyboard. Mnemonics in Windows programs are accessed by an alt-[key] combination, similar to the way shortcuts are accessed via ctrl-[key]. An example of a mnemonic you can use right now is alt-f. That opens up the File menu on just about every Windows program. To get a quick idea what mnemonics are available to you in a program, hit the alt key and look at the program's menus and toolbars. See how some of the letters are now underlined? Those are your mnemonics. Use them with the alt key to perform a "click".
Programming in mnemonics is pretty simple in Windows Forms. Everything you see in a program, from the lowly Label to the big daddy Form itself is an extension of the System.Windows.Forms.Control class. From this virtual class they inherit the Text property. The implementation of this property is left for inheritors, but if the control displays text and takes input, your mnemonic will be set by using this property. The standard convention is to, when setting the text of this property, prefix your mnemonic with the "&" symbol. For example, if I was going to name my File menu, I would do the following:
MenuItem _fileMenu = new MenuItem();
_fileMenu.Text = "&File";
By simply placing the "&" before the letter F I designate that alt-f will be the mnemonic for the control. Nice and simple. And that's where it gets you.
You see, every keypress you make must be examined to determine if it is normal input or a mnemonic key combination. If the keypress event (not an actual event name but a group of events; check this blarg post for more detail than you could ever want about the process) is a combination of the alt key and any of the keys a-z and 0-9, that is treated as a mnemonic. And if no control is watching for that mnemonic, you get beeped at.
What this means is that if you have a menu or toolstrip in your program, you cannot use alt-key combinations for anything other than mnemonics, otherwise every time your users... use... that function, your program will ding at them. Extremely annoying. Unfortunately, the standard events for handling key presses can't be used to intercept the key event and prevent it from bubbling to your menus and toolstrips, thus preventing the beep from bugging the crap out of you and your users. Which is why I'm writing this.
I'm working on a dinky little side project right now, and one of the features is the ability to go into fullscreen mode. The standard mnemonic for this is alt-enter. Try it in Windows Media Player. Unfortunately, because mnemotics are designated by placing an "&" in the text of a control before the letter you wish to use... well, you can see the issue here. Besides, I have a Fullscreen button on my toolbar (and no menu--its a very simple program by design), I want to use alt-f as another means to go to fullscreen. I can add a KeyUp event handler in the form and intercept the alt-enter key combination in order to perform a fullscreen, but again I can't prevent that event from bubbling to the toolbar, which will trigger a beep as it doesn't have an alt-enter mnemonic. So, is there a solution?
Well, its a good thing you asked (goddamn, I'm dragging this out). There is. You can override the form's ProcessDialogKey method and intercept that key combination and mark it (by returning true from the method) as not being a mnemonic. The method is as follows:
/// Processes a dialog key.
/// <param name="keyData">One of the <see cref="T:System.Windows.Forms.Keys"></see> values that represents the key to process.</param>
/// true if the keystroke was processed and consumed by the control; otherwise, false to allow further processing.
/// <remarks>The purpose of this override is to prevent alt-enter from being processed as a command, which results in the windows beep being played as it is not a valid mnemonic.</remarks>
protected override bool ProcessDialogKey(Keys keyData)
if (keyData == (Keys.Alt | Keys.Enter))
Of course, you can substitute Keys.Enter for any key you wish to prevent from being identified as a mnemonic. And that's that.
I've been thinking about teaching my cat how to code so I can sleep later. Now I can, with the advent of LOLCODE.
CAN HAS STDIO?
PLZ OPEN FILE "LOLCATS.TXT"?
The program is, as I said, very simple. The program eases the creation of image archives, or in other very similar words, images that contain archives. It isn't slick like steganography. Its pretty much just an image file with an archive stuck to the back of it.
The program does also, optionally, shrink the image and stick a little icon on it to indicate that it contains an archive. Had to have some excuse for its existance.
Why, you may ask, would anyone other than illicit pornographers need such a tool? Well, as I said, its not steganography. Its pretty obvious when your 128x128 pixel image of tacgnol weighs in at 1.2 gigs that you're hiding a porno ISO inside of it. Of course, a stego'd pic would be just as big... I'm getting away from the point.
You may find yourself on an imageboard or other discussion forum that allows its users to upload images but no other type of content. If you have a need to upload other content, ImageRAR is for you. Simply zip up your content, stick it in an image of your choice, and upload it on the server for great lulz.
I shared this before, and got some complaints about it. Having it up on CodePlex will allow users to register feedback, which transforms into work items that I can use to improve the code. It also lets the paranoid see what's in the program so they know I'm not trying to format their hard drive.
Anyhoo, check it out if you're incredibly bored sometime.