My other blog is now private, until further notice

My programming blog is now private, and will remain as such until I can review its content.

This is due to a new confidentiality agreement sent to everyone by my employer. The terms used to describe intellectual property are ambiguous, and while its concept of proprietary information does exclude “generic knowledge that I would have learned in the course of similar employment elsewhere”, the clauses about source code are ambiguous enough to warrant a concern.

While I feel that the source code and programming examples I shared were generic, and were written at home to describe solutions for programming problems I solved at work, coded into examples that referred to no proprietary information from my employer, I can’t be certain that the content doesn’t contravene their definition of intellectual property.

My apologies to anyone who found this looking for the other blog, and to my followers of the other blog.

Advertisements

It’s too easy to judge addicts, but we shouldn’t.

Every so often I’m reminded how we judge addicts. We all do it – look down on them because it makes us feel a little better. Even I did it last week; shared a meme with an image that was trending on Facebook, of a girl with a trolley more or less attached to her, and some condescending text about meth. Now I’m sorry I shared it.

People used to judge me too, and write me off, but last night I was reminded of some stuff I achieved on meth. I was looking around on my hard drive because it’s getting full and I need to delete some old files, when I found a backup directory, a backup of my old drive from a few years ago, because I gave the drive to my ex…

It contained a lot of evidence, not of my drug use, but of the results of my tweaking on the computer. Besides the movies and downloads, there was also some source code I’d forgotten about.

I’ll try to make this as simple as possible, but that isn’t easy. I’d written my own video player, in c# using DirectShow. It’s not great, but it works, and it works pretty well. But it only plays video files directly. At some point, I was interested in playing DVDs too. So I found source code that I could use, a tutorial with some sample code on playing DVDs from c#. The only problem was, my video player code was “tightly coupled” to the form that uses it. So the form, which should just be the user interface (with the buttons to play and so on) included all the code for playing videos. Not only that, but it does some funky stuff with background threads, for example so that if you click “next”, it already knows all the files in the directory. Plus it has features like frame stepping and player speed that aren’t necessarily implemented in the DVD player code.

So, to change my player so that it could play files or DVDs, I had two options:

  1. Use inheritance. This would involve defining a base “player” class, and having two derived classes. One would be the file player, with all the existing code moved to it, and another would be a DVD player class.
  2. Define a “player” interface. This interface would contain the definitions for all the stuff the player did, but only the definitions. Then I’d have two implementations of this interface, one with my existing code, and another for DVDs. (The DVD player would then not implement the methods or properties that were specific to the file player, or at least fail gracefully at those things.)

Apparently I decided on option two. “Apparently” is quoted because I was so high, I don’t remember any of that. But it’s there – I found that I went as far as defining the interface. Then I stopped there, because it would be a couple more days work to refactor my code, and then implement the DVD playing code, as well as having some way (an “abstract factory” probably) of deciding an runtime which implementation to use based on what was being played. The bulk of the work would be the refactoring… There’s a lot more that I’m not mentioning, such as the peripheral details around the two kinds of players. The file player has a concept of play lists, which involves relative paths to the locations of files on disk, and it can also persist the starting position (and ending position which allows for playback loops because I was tweaking) within files, while a DVD player would need to be able to navigate a menu system, and switch between different tracks. The code for the file player to “know” the difference between playing files in a list verses playing whatever is in the directory, is messy. Not to mention repeat modes… on reaching the end of a file, it must decide, based on the repeat mode, whether to go to the next file, or repeat the file, or if set to repeat the whole list/directory, decide what to do then based on the index within the list/directory (and lastly if super-duper tweaker pervert porno repeat cumshot loop is engaged, repeat that part of the file when it gets to the end of the section, or check if there is a loop to repeat when loading a new file. Sigh… Tweaking leads to strange complications). That shit would be complicated to refactor, and even on meth I was too lazy to do all that.

The point is, I did some hard-core programming shit on meth. This is unfinished code, but I have had the dubious “pleasure” of working with some less talented programmers over the years, programmers who were incapable of doing what I could do when I was on meth.

Don’t judge people just because they’re on drugs. Being an addict doesn’t make anyone stupid, although it certainly does lead to them doing some stupid things. (For example, writing video players when you’re tweaking on porn – then not actually watching the porn but rather going off on a tangent writing a fairly feature-rich video player.) While you’re laughing at people and putting them down, there are some good people out there who just made some bad choices. Some of them are more clever or gifted than you can imagine, and a little empathy goes a long way.

Another way addicts are often judged, and sorry if you’ve read what I’ve written about this before, is the so called “faces of meth”, photos shared online with the pretence of it being about deterring others from using meth. It’s never about that. It’s about laughing at people less fortunate than yourself. It’s also about missing the point.

I won’t share such images myself, but I will state an example. I remember seeing one of those images of a girl who supposedly used meth for ten years. She was a pretty girl, probably about seventeen in the first image, then more or less a year older in every subsequent image. But here’s the problem: The first image, where she looked pretty, was a police mug shot. She was arrested for drug possession and prostitution, and was probably already living on the street. Do you see where I’m going with this? In the before image, she was probably already using meth for at least five years, maybe longer. And as for the rest, they were pictures of a woman living on the street, most likely using multiple drugs, including but not limited to meth. Once you get to the point of living on the street, meth is soon out of range of what you can afford, unless of course you happen to be a career criminal. And of course, career criminals and long time prostitutes have more factors affecting their appearance than the number of years they use meth.

Edit: This needs to be expanded on… Career criminals and the people associated with them, who are committing crimes for their drugs, don’t have normal lives. Contrast this with normal people who happen to be addicts… who still go home to their houses where they shower, brush their teeth, get dressed and go to work every day. (And then maybe party all night and every weekend, sometimes disappearing for a day or two each month after they get paid.) They’re nothing like those pitiful looking photos you see in mug shots online.

So while you look at those photos and laugh at the subjects in them, you miss that most addicts look nothing like those people. Most addicts are working normal jobs, and you would never guess they’re using drugs. People might work while using for up to twenty years, before they reach that point where they can’t work any more. And it’s all too easy to judge them while you have a drink every day, or do cocaine occasionally. You might find yourself judging them even after you’ve already become one of them. And when that happens, you might realize as I did, that those “photos of meth” are not a deterrent at all. They’re one of many ways to misunderstand how widespread and dangerous addiction really is, allowing you to see addicts in terms of stereotypes rather than reality.

More good code I wrote when I was high

Again I was surprised to find some good code that I wrote way back when I was high. I might post this one to my programming blog tomorrow as well, slightly repurposed without the mention of drugs, and a title “How to load a cursor from embedded resources in C#”.

Anyway, that’s what it does. Via some code that I found and then modified, my image viewer, when viewing an image that’s larger than the viewable area, allows you to use the mouse to drag around and pan to different parts of the image. When doing this, the program changes the mouse cursor, to one of two cursor images that I designed myself and drew pixel-by-pixel (I was indeed tweaking my ass off), one for a hand that’s up and one for a hand that’s down.

Here’s what it looks like when the hand down cursor is displayed. (Main mouse button is pressed so you can pan the image… in the application – not here because this is just a fucking screenshot.)

Viewer

And here’s the code (that I took ages to figure out) that loads the cursor, which is saved as a file resource, from the applications resources:

using System;
using System.Runtime.InteropServices;
using System.Security;
using System.Windows.Forms;

namespace Romy.Core
{
    public static class CursorResourceLoader
    {
        #region Methods

        public static Cursor LoadEmbeddedCursor(byte[] cursorResource, int imageIndex = 0)
        {
            var resourceHandle = GCHandle.Alloc(cursorResource, GCHandleType.Pinned);
            var iconImage = IntPtr.Zero;
            var cursorHandle = IntPtr.Zero;

            try
            {
                var header = (IconHeader)Marshal.PtrToStructure(resourceHandle.AddrOfPinnedObject(), typeof(IconHeader));

                if (imageIndex >= header.count)
                    throw new ArgumentOutOfRangeException("imageIndex");

                var iconInfoPtr = resourceHandle.AddrOfPinnedObject() + Marshal.SizeOf(typeof(IconHeader)) + imageIndex * Marshal.SizeOf(typeof(IconInfo));
                var info = (IconInfo)Marshal.PtrToStructure(iconInfoPtr, typeof(IconInfo));

                iconImage = Marshal.AllocHGlobal(info.size + 4);
                Marshal.WriteInt16(iconImage + 0, info.hotspot_x);
                Marshal.WriteInt16(iconImage + 2, info.hotspot_y);
                Marshal.Copy(cursorResource, info.offset, iconImage + 4, info.size);

                cursorHandle = NativeMethods.CreateIconFromResource(iconImage, info.size + 4, false, 0x30000);
                return new Cursor(cursorHandle);
            }
            finally
            {
                if (cursorHandle != IntPtr.Zero)
                    NativeMethods.DestroyIcon(cursorHandle);

                if (iconImage != IntPtr.Zero)
                    Marshal.FreeHGlobal(iconImage);

                if (resourceHandle.IsAllocated)
                    resourceHandle.Free();
            }
        }

        #endregion Methods

        #region Native Methods

        [SuppressUnmanagedCodeSecurity]
        static class NativeMethods
        {
            [DllImportAttribute("user32.dll", CharSet = CharSet.Unicode)]
            [return: MarshalAs(UnmanagedType.Bool)]
            public static extern bool DestroyIcon(IntPtr hIcon);

            [DllImport("user32.dll", SetLastError = true)]
            public static extern IntPtr CreateIconFromResource(IntPtr pbIconBits, int dwResSize, bool fIcon, int dwVer);
        }

        #endregion Native Methods

        #region Native Structures

        [StructLayout(LayoutKind.Explicit, Pack = 1)]
        struct IconHeader
        {
            [FieldOffset(0)]
            public short reserved;

            [FieldOffset(2)]
            public short type;

            [FieldOffset(4)]
            public short count;
        }

        /// <summary>Union structure for icons and cursors.</summary>
        /// <remarks>For icons, field offset 4 is used for planes and field offset 6 for 
        /// bits-per-pixel, while for cursors field offset 4 is used for the x coordinate 
        /// of the hotspot, and field offset 6 is used for the y coordinate.</remarks>
        [StructLayout(LayoutKind.Explicit, Pack = 1)]
        struct IconInfo
        {
            [FieldOffset(0)]
            public byte width;

            [FieldOffset(1)]
            public byte height;

            [FieldOffset(2)]
            public byte colors;

            [FieldOffset(3)]
            public byte reserved;

            [FieldOffset(4)]
            public short planes;

            [FieldOffset(6)]
            public short bpp;

            [FieldOffset(4)]
            public short hotspot_x;

            [FieldOffset(6)]
            public short hotspot_y;

            [FieldOffset(8)]
            public int size;

            [FieldOffset(12)]
            public int offset;
        }

        #endregion Native Structures
    }
}

The code that uses it, in another class, is just this:

        /// <summary>Loads the two hand cursors from project resources.</summary>
        private static void InitializePanBoxCursors()
        {
            if (handUpCursor == null && handDownCursor == null)
            {
                handUpCursor = CursorResourceLoader.LoadEmbeddedCursor(Properties.Resources.Hand_up);
                handDownCursor = CursorResourceLoader.LoadEmbeddedCursor(Properties.Resources.Hand_down);
            }
        }

It still amazes me that I wrote some more than decent code back when I was tweaking my stupid head off.

This will be the last late night post for a while. My son gets back tomorrow, and since we share a room, I normally go to bed the same time he does. Actually I’m tired and am going to sleep right after posting this. Good night…

I’m still baffled by source code I wrote when I was on meth

Apologies to most people reading this who are not programmers. This post won’t make much sense. But I try to avoid drug references on my programming blog, so this belongs here… And also an apology to anyone who saw this post published by mistake the first time, before I added the image.

I still use this monstrosity of a program I wrote a few years ago. I shouldn’t, because it tries to do too many different things in that it was my scratchpad for all new code I learned for a few years, but it works well for some of them, so I use it even though I know it has its quirks. It’s more or less a file browser, image viewer, video and audio player (via Direct Show which is now obsolete), and can do some minor image editing. But mostly it’s an image viewer. It builds and maintains its own cache of thumbnails, which looks kind of like the large icons view in Windows Explorer. Then double-clicking those thumbnails opens the program’s built in image viewer.

Here’s what it looks like:

RomyView

Anyway, one of its quirks is that there’s a bug somewhere in the custom TaskScheduler (I think) and that can have weird effects like hanging the whole application after deleting a directory. (Sometimes.) So while looking at all the code that references my own TaskSchedulers, I came across this code, written while I was super duper high…

/// <summary>Load a Shell thumbnail image and add it to the cache.</summary>
public static async Task<ThumbnailCacheItem> LoadAndCacheThumbnailAsync(string path, CancellationToken token, bool requiresCurrentDirectory = false)
{
    var item = ThumbnailCacheItem.Invalid;
    var tcs = new TaskCompletionSource<ThumbnailCacheItem>();
    var isSmallImage = false;
    var failed = false;

    try
    {
        using (CancellationTokenSource cts = new CancellationTokenSource(),
            linked = CancellationTokenSource.CreateLinkedTokenSource(token, cts.Token))
        {
            Action checkCancelled = () =>
            {
                if (requiresCurrentDirectory && !Path.GetDirectoryName(path).EqualsIgnoreCultureAndCase(IO.CurrentDirectory))
                    linked.Cancel();

                linked.Token.ThrowIfCancellationRequested();
            };

            await Tasks.Run(() =>
            {
                checkCancelled();
                var fileSystemInfo = IO.Exists(path);

                if (!fileSystemInfo.Item1)
                {
                    /* Neither a file nor a directory exists. This is possible if it was deleted after this 
                        * method was called but before we got here, and just means we have nothing to do here. */
                    linked.Cancel();
                    linked.Token.ThrowIfCancellationRequested();
                }

                var isDirectory = fileSystemInfo.Item2;
                var isFile = fileSystemInfo.Item3;

                var fileSystemType = isDirectory ? FileSystemType.Directory : FileSystemType.File;

                var isMedia = isFile && IO.IsMediaFile(path);
                var isImage = isFile && IO.IsImageFile(path);
                var isPng = isImage && IO.IsPng(path);
                var isZip = isFile && IO.IsZip(path);
                var isPsd = isFile && IO.IsPsdFile(path);
                var isTextFile = IO.IsTextFile(path);

                Bitmap cacheBitmap = null;
                Bitmap fullsizeImage = null;
                try
                {
                    // For simplicity, we define a small bitmap as one with file size less than 1MB.
                    var isBitmapGlyph = IO.IsBmp(path) && new FileInfo(path).Length < 1024L * 1024L;

                    /* Don't use the shell for icon images. It will
                        * display them with shadows and looks like shit. */
                    if (isFile && IO.IsIcon(path))
                    {
                        // Load the largest icon.
                        using (var iconImage = (new IconFileReader { Filename = path }.FirstIcon).ToBitmap())
                        {
                            if (iconImage == null)
                                throw new FileReadException(string.Format("Error reading '{0}'", path));

                            fullsizeImage = iconImage.Clone() as Bitmap;
                            isSmallImage = true;
                        }
                    }
                    else if (isPng || isBitmapGlyph || isPsd)
                    {
                        /* Also don't use the shell for png images, or gifs, for similar reasons as for icons. */
                        fullsizeImage = ImageFile.OpenBitmap(path);

                        if (isBitmapGlyph)
                            isSmallImage = true;

                        if (fullsizeImage == null)
                            throw new FileReadException(string.Format("Error reading '{0}'", path));
                    }
                    checkCancelled();

                    isSmallImage |= IO.IsGif(path);

                    if (fullsizeImage != null && (isSmallImage || isPng || isPsd))
                    {
                        /* If this is a small image, or if it is likely that conversion to jpeg will
                            * produce a thumbnail of inferior quality, we store the actual image in the
                            * cache, instead of a thumbnail.
                            *
                            * Also, the method to get the thumbnail from the shell below will lose the
                            * transparency for small png images, whereas this way, we will display them
                            * with transparency, even in the thumbnails. */
                        cacheBitmap = new Bitmap(fullsizeImage);

                        if (cacheBitmap.Width > 256 || cacheBitmap.Height > 256)
                            cacheBitmap = cacheBitmap.Resize(256, 256) as Bitmap;
                    }
                    else
                    {
                        cacheBitmap = !isZip ? ShellItemImageFactory.GetImage(path) : Icon.ExtractAssociatedIcon(path).ToBitmap();

                        if (cacheBitmap == null)
                            throw new FileReadException(string.Format("Error reading '{0}'", path));
                    }

                    checkCancelled();

                    if (cacheBitmap != null)
                        item = ThumbnailCache.AddNewCacheItem(path, cacheBitmap, fileSystemType, isSmallImage);
                }
                catch (Exception ex)
                {
                    /* An exception here is not necesarily an error. e.g. It will throw 
                        * if you deliberately delete images as they're being cached. */
                    ex.Log();
                    failed = tcs.TrySetException(ex);
                }
                finally
                {
                    if (fullsizeImage != null)
                        fullsizeImage.Dispose();
                }
                return Task.FromResult(item);
            }, token, TaskCreationOptions.LongRunning | TaskCreationOptions.PreferFairness).ConfigureAwait(false);

            /* The TaskCreationOptions are critically important here.
                * We do not want to be running on the main thread. */

            if (!failed)
                tcs.TrySetResult(item);
        }
    }
    catch (OperationCanceledException) { tcs.TrySetCanceled(); }

    // Prevent the UI from becoming unresponsive when adding many thumbnails.
    await tcs.Task.YieldTo(uiScheduler);

    return await tcs.Task;
}

That’s the code that adds a new thumbnail object to the thumbnail cache, which is a special kind of object cache where the objects are reused once the configurable size is exceeded, and is also persisted to disk, in my own bastardized binary format.

This code showed up in my search results because I was looking for all references to Tasks.Run, which is not standard code, but that calls my own TaskScheduler instead of the built in one.

And yet, this is good code. It’s not verbose, which is surprising. The code is easy to read and it calls out to loads of extension methods and other complex code. So depending on the file type that it finds, it might decide to cache the actual image directly for small files, use my custom icon reader that reads all icons from an ICO file directly, use my custom image reader that can read all kinds of image files, including PSD (Photoshop files), or invoke the Windows shell interfaces, in code that I also managed to figure out myself (because that shit is not implemented in the dot net Framework), which then uses different interfaces depending on the version of Windows. All in all, this is really good code… better than what I write at work nowadays.

I’m baffled.


Also, I found that the bug has nothing to do with my custom TaskScheduler, because it still happens after all references to it are removed. I’ve given up looking for the bug for now.

Found some source code I wrote while high that I don’t understand

I have a long and difficult post in mind… It’s been in the back of my head for over a week now and still not getting anywhere. I haven’t had time to write lately, but I did think this code I just found, which baffles me, might be worth sharing.

I’m doing something at work where I need to decrement a counter from multiple threads, and I knew I did something like this before, so I decided to search through my project of old code… Believe it or not, I wrote a lot of good code around 2011 to 2012, while I was very very high. I also wrote plenty bad code too, some of it bad because, well, it’s just fucking bad, some of it bad because it is so complicated that I can no longer understand it, although it works and does what it was designed to do, and some of it that leaves me wondering what the fuck I was thinking.

This is one of the latter examples… It wraps some Windows API code to suspend or resume the drawing of a window (I don’t remember why I would do this), and was written in such a way that this could be called from multiple threads… Enjoy.

Of interest here is the comment in the remarks section of the comment block describing the class:

Calls may be nested, but should not be made from any other than the GUI thread. (This code tries to work around such an error,  but is not guaranteed to succeed.)

Also, the way it works around the issue is, um… creative.
 

using System;
using System.Runtime.InteropServices;
using System.Security;
using System.Threading;
using System.Windows.Forms;

namespace Romy.Controls
{
    /// <summary>Allows suspending and resuming redrawing a Windows Forms window via the <b>WM_SETREDRAW</b> 
    /// Windows message.</summary>
    /// <remarks>Usage: The window for which drawing will be suspended and resumed needs to instantiate this type, 
    /// passing a reference to itself to the constructor, then call either of the public methods. For each call to 
    /// <b>SuspendDrawing</b>, a corresponding <b>ResumeDrawing</b> call must be made. Calls may be nested, but
    /// should not be made from any other than the GUI thread. (This code tries to work around such an error, but 
    /// is not guaranteed to succeed.)</remarks>
    public class DrawingHelper
    {
        #region Fields

        private int suspendCounter;

        private const int WM_SETREDRAW = 11;

        private IWin32Window owner;

        private SynchronizationContext synchronizationContext = SynchronizationContext.Current;

        #endregion Fields

        #region Constructors

        public DrawingHelper(IWin32Window owner)
        {
            this.owner = owner;
        }

        #endregion Constructors

        #region Methods

        /// <summary>This overload allows you to specify whether the optimal flags for a container 
        /// or child control should be used. To specify custom flags, use the overload that accepts 
        /// a <see cref="Romy.Controls.RedrawWindowFlags"/> parameter.</summary>
        /// <param name="isContainer">When <b>true</b>, the optimal flags for redrawing a container 
        /// control are used; otherwise the optimal flags for a child control are used.</param>
        public void ResumeDrawing(bool isContainer = false)
        {
            ResumeDrawing(isContainer ? RedrawWindowFlags.Erase | RedrawWindowFlags.Frame | RedrawWindowFlags.Invalidate | RedrawWindowFlags.AllChildren :
                RedrawWindowFlags.NoErase | RedrawWindowFlags.Invalidate | RedrawWindowFlags.InternalPaint);
        }

        [CLSCompliant(false)]
        public void ResumeDrawing(RedrawWindowFlags flags)
        {
            Interlocked.Decrement(ref suspendCounter);

            if (suspendCounter == 0)
            {
                Action resume = new Action(() =>
                {
                    NativeMethods.SendMessage(owner.Handle, WM_SETREDRAW, new IntPtr(1), IntPtr.Zero);
                    NativeMethods.RedrawWindow(owner.Handle, IntPtr.Zero, IntPtr.Zero, flags);
                });
                try { resume(); }
                catch (InvalidOperationException)
                {
                    synchronizationContext.Post(s => ((Action)s)(), resume);
                }
            }
        }

        public void SuspendDrawing()
        {
            try
            {
                if (suspendCounter == 0)
                {
                    Action suspend = new Action(() => NativeMethods.SendMessage(owner.Handle, WM_SETREDRAW, IntPtr.Zero, IntPtr.Zero));
                    try { suspend(); }

                    catch (InvalidOperationException)
                    {
                        synchronizationContext.Post(s => ((Action)s)(), suspend);
                    }
                }
            }
            finally { Interlocked.Increment(ref suspendCounter); }
        }

        #endregion Methods

        #region NativeMethods

        [SuppressUnmanagedCodeSecurity]
        internal static class NativeMethods
        {
            [DllImport("user32.dll")]
            public static extern bool RedrawWindow(IntPtr hWnd, IntPtr lprcUpdate, IntPtr hrgnUpdate, RedrawWindowFlags flags);

            [DllImport("user32.dll")]
            public static extern IntPtr SendMessage(IntPtr hWnd, Int32 wMsg, IntPtr wParam, IntPtr lParam);
        }

        #endregion NativeMethods
    }

    #region RedrawWindowFlags

    [Flags(), CLSCompliant(false)]
    public enum RedrawWindowFlags : uint
    {
        ///<summary>Invalidates lprcUpdate or hrgnUpdate (only one may be non-NULL). 
        ///If both are NULL, the entire window is invalidated.</summary>
        Invalidate = 0x1,

        ///<summary>Causes a WM_PAINT message to be posted to the window regardless of 
        ///whether any portion of the window is invalid.</summary>
        InternalPaint = 0x2,

        ///<summary>Causes the window to receive a WM_ERASEBKGND message when the window 
        ///is repainted. The <b>Invalidate</b> flag must also be specified; otherwise, 
        ///<b>Erase</b> has no effect.</summary>
        Erase = 0x4,

        ///<summary>Validates lprcUpdate or hrgnUpdate (only one may be non-NULL). If both 
        ///are NULL, the entire window is validated. This flag does not affect internal 
        ///WM_PAINT messages.</summary>
        Validate = 0x8,

        ///<summary>Suppresses any pending internal WM_PAINT messages. This flag does not 
        ///affect WM_PAINT messages resulting from a non-NULL update area.</summary>
        NoInternalPaint = 0x10,

        ///<summary>Suppresses any pending WM_ERASEBKGND messages.</summary>
        NoErase = 0x20,

        ///<summary>Excludes child windows, if any, from the repainting operation.</summary>
        NoChildren = 0x40,

        ///<summary>Includes child windows, if any, in the repainting operation.</summary>
        AllChildren = 0x80,

        ///<summary>Causes the affected windows (as specified by the <b>AllChildren</b> and <b>NoChildren</b> flags) to 
        ///receive WM_NCPAINT, WM_ERASEBKGND, and WM_PAINT messages, if necessary, before the function returns.</summary>
        UpdateNow = 0x100,

        ///<summary>Causes the affected windows (as specified by the <b>AllChildren</b> and <b>NoChildren</b> flags) 
        ///to receive WM_NCPAINT and WM_ERASEBKGND messages, if necessary, before the function returns. 
        ///WM_PAINT messages are received at the ordinary time.</summary>
        EraseNow = 0x200,

        ///<summary>Causes any part of the nonclient area of the window that intersects the update region 
        ///to receive a WM_NCPAINT message. The <b>Invalidate</b> flag must also be specified; otherwise, 
        ///<b>Frame</b> has no effect. The WM_NCPAINT message is typically not sent during the execution of 
        ///RedrawWindow unless either <b>UpdateNow</b> or <b>EraseNow</b> is specified.</summary>
        Frame = 0x400,

        ///<summary>Suppresses any pending WM_NCPAINT messages. This flag must be used with <b>Validate</b> and 
        ///is typically used with <b>NoChildren</b>. <b>NoFrame</b> should be used with care, as it could cause parts 
        ///of a window to be painted improperly.</summary>
        NoFrame = 0x800
    }

    #endregion RedrawWindowFlags
}

An example of madness. Some c# code I wrote a few years ago when I was ridiculously high.

I’m not posting this to my programming blog because it’s an example of really really bad code.

It seems that one fine morning while tweaking on having my source code all be perfectly formatted, I created this monstrosity. It compiles to a console application that’s included in my solution, one that searches back a couple of directories and formats all the source code files that it finds according to my drug-induced maniacal specifications. That is, it modifies hundreds of my source code files in parallel in a few milliseconds. By some miracle it works. Had it failed, the results would have been spectacular.

(Here’s the kicker… It doesn’t really format anything. The tool I used for formatting code inserted blank lines and omitted blank lines where I wanted extra whitespace. So all this does is insert and remove empty lines. So it parses files and determines where to insert and where to delete lines. That’s why it had the potential, if my calculations while coding when I was super-high, of deleting source code and making the files useless. But somehow it worked as intended.)

I can’t even understand this code while I am clean and sober (and sane).

There are some ridiculously long logic statements in this code. Also check out my essay-style comments. As I recall, I was explaining the code to the voices in my head.

The main file:

using System;
using System.IO;
using System.Linq;
using System.Security.Permissions;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace FormatCSFiles
{
    /// <summary>Some quick 'n dirty CS code formatting.</summary>
    /// <remarks>Because the RegionErate Addin that I use to sort my code into regions does some screwy
    /// things with blank lines, and I am obsessively fussy about my code format. This processes all CS
    /// files in the solution in parallel and fixes what it can. This is not an extension. I don't know
    /// how to write one. This processes <b>files</b>, so save all before running this in the debugger,
    /// or wave your latest changes goodbye.</remarks>
    internal class Program : Romy.Core.Console.ConsoleApplicationBase
    {
        [STAThread, SecurityPermission(SecurityAction.Demand, Flags = SecurityPermissionFlag.ControlAppDomain)]
        private static void Main()
        {
            var program = new Program();
            program.InitializeConsoleApplication();

            /* I'm being lazy and assuming this project is always in a child directory of my solution and processing the parent directory
             * (+ all the parent's siblings, as well as children, which includes this file). i.e. 4 levels up from the Debug directory. */
            var directory = Environment.GetCommandLineArgs()[0];

            for (var i = 0; i < 4; i++)
            {
                directory = Path.GetDirectoryName(directory);
            }

            LogInfo("FormatCSFiles\tProcessing the .CS files in \"{0}\" and its subdirectories.", directory);

            var files = Directory.GetFiles(directory, "*.cs", SearchOption.AllDirectories).Where(
                f => !Path.GetFileName(f).StartsWith("TemporaryGeneratedFile"));

            Parallel.ForEach(files, new ParallelOptions { MaxDegreeOfParallelism = Environment.ProcessorCount * 2 }, f => ProcessFile(directory, f));

            LogInfo("FormatCSFiles\tDone processing the .CS files in \"{0}\" and its subdirectories.", directory);
        }

        private static string Pad(string textToPad, int length)
        {
            var builder = new StringBuilder();
            builder.Append(textToPad);
            while (builder.Length < length)
            {
                builder.Append(' ');
            }
            return builder.ToString();
        }

        // My one and only failed attempt at reducing the code complexity made it even more complex.
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity")]
        private static void ProcessFile(string directory, string filename)
        {
            try
            {
                var formattedThreadId = Thread.CurrentThread.ManagedThreadId.ToString().PadLeft(2, '0');
                var formattedFilename = filename.Substring(directory.Length + 1);
                LogInfo(Pad(string.Format("Thread {0}", formattedThreadId), "FormatCSFiles".Length) + string.Format("\tProcessing \"{0}\"", formattedFilename));

                var lines = File.ReadAllLines(filename, Encoding.Default).ToList();

                for (var i = lines.Count - 1; i >= 0; i--)
                {
                    var results = new AnalysisResults();
                    var line = lines[i].Trim();

                    if (i < lines.Count - 1)
                    {
                        var nextLine = lines[i + 1].Trim();
                        var lineIsEmpty = string.IsNullOrEmpty(line);
                        var nextLineIsEmpty = string.IsNullOrEmpty(nextLine);
                        var lineAfterNext = i < lines.Count - 2 ? lines[i + 2].Trim() : string.Empty;

                        results.RemoveNext = (!lineIsEmpty && line.StartsWith("[STAThread") && nextLineIsEmpty) || // Remove blank line below STAThread attribute.
                            // Remove a blank line between a property getter and setter.
                            (!lineIsEmpty && nextLineIsEmpty && line.StartsWith("get") && i < lines.Count + 2 && !string.IsNullOrEmpty(lineAfterNext) &&
                            (lineAfterNext.StartsWith("set") || lineAfterNext.StartsWith("private set") || lineAfterNext.StartsWith("protected set") ||
                            lineAfterNext.StartsWith("internal set") || lineAfterNext.StartsWith("public set"))) ||
                            (!lineIsEmpty && line.StartsWith("[") && nextLineIsEmpty && !string.IsNullOrEmpty(lineAfterNext)) ||
                            (!lineIsEmpty && line.StartsWith("{") && nextLineIsEmpty) ||
                            (!lineIsEmpty && line.StartsWith("[STAThread]") && nextLineIsEmpty);

                        if (!results.RemoveNext)
                        {
                            results.RemoveCurrent = (lineIsEmpty && nextLineIsEmpty) ||      // Remove extra blank line.
                                (i == 0 && lineIsEmpty) ||                                   // Remove empty first line.
                                (lineIsEmpty && !nextLineIsEmpty && nextLine.EndsWith("}")) || // Remove blank line before closing brace.
                                (lineIsEmpty && !nextLineIsEmpty && nextLine.StartsWith("static void Main("));

                            if (!results.RemoveCurrent)
                            {
                                results.InsertNext = (!lineIsEmpty && nextLine.StartsWith("static") && !nextLine.StartsWith("static void Main(") && nextLine.EndsWith("()")) || // Add a blank line before a static constructor.
                                    ((line.EndsWith("}") || line.EndsWith(";")) && nextLine.StartsWith("[")) || // Insert blank lines between consecutively declared structs. (Regionerate removed them.)
                                    (line.EndsWith(";") && (nextLine.StartsWith("public") || nextLine.StartsWith("private") ||
                                    nextLine.StartsWith("internal") || nextLine.StartsWith("protected") || nextLine.StartsWith("~"))) || // Insert blank lines between class-level fields.
                                    (!lineIsEmpty && line.StartsWith("#endregion") && !nextLineIsEmpty &&
                                    !nextLine.StartsWith("{") && !nextLine.StartsWith("}")) || // Insert a blank line between two subregions and anything else that doesn't start with an opening brace.
                                    (!lineIsEmpty && !nextLineIsEmpty && line.StartsWith("}") && (nextLine.StartsWith("#endregion") || nextLine.StartsWith("#endif"))) || // Insert a blank line between a closing brace and an #endregion or #endif.
                                    (!lineIsEmpty && line.StartsWith("#region") && !nextLineIsEmpty && nextLine.StartsWith("[")) || // Insert a blank line between an #endregion and an attribute.
                                    (!lineIsEmpty && (line.StartsWith("#region") || line.StartsWith("#if")) && !nextLineIsEmpty) || // Add blank line after #region or #pragma or #if.
                                    (!nextLine.StartsWith("private set") &&
                                    line.EndsWith("}") && !line.StartsWith("///") &&
                                    (nextLine.StartsWith("public") || nextLine.StartsWith("internal") || nextLine.StartsWith("private") ||
                                    nextLine.StartsWith("protected") || nextLine.StartsWith("///") || nextLine.StartsWith("async"))) || // Insert a line between a closing brace and a method declaration.
                                    (!lineIsEmpty && !nextLineIsEmpty && nextLine.Length > 1 && line.Length > 2 &&
                                    line.Contains('{') && line.EndsWith("}") && !line.StartsWith("get {") && !line.StartsWith("catch") &&
                                    !line.StartsWith("try") && !line.StartsWith("finally")) ||                                         // Insert a blank line between properties declared in an interface.
                                    (!lineIsEmpty && line.Length > 1 && !line.StartsWith("///") && (nextLine.StartsWith("///") || nextLine.StartsWith("/*"))) || // Insert a blank line between a field and method declaration.
                                    (!lineIsEmpty && !nextLineIsEmpty && line.StartsWith("using") && nextLine.StartsWith("namespace")) || // Add a blank line between a using clause and namespace name
                                    (!lineIsEmpty && !nextLineIsEmpty && line.StartsWith("private") && nextLine.StartsWith("#endregion") ||
                                    !lineIsEmpty && !nextLineIsEmpty && nextLine.StartsWith("#endregion"));

                                if (!results.InsertNext)
                                {
                                    if (!lineIsEmpty && line.EndsWith("</summary>") && !nextLineIsEmpty && nextLine.EndsWith(";") && !nextLine.StartsWith("event") && !string.IsNullOrEmpty(lines[i + 2].Trim()))
                                    {
                                        /* If a field declaration has a summary XML comment, add a blank
                                         * line after it as well. It makes the code easier to follow. */
                                        results.InsertAfterNext = true;
                                    }
                                    else if (!lineIsEmpty && line.EndsWith("{") && !nextLineIsEmpty && nextLine.Equals("}"))
                                    {
                                        // I hate javascript style braces. Just because.
                                        lines[i] += nextLine;

                                        results.RemoveNext = true;
                                    }
                                }
                            }
                        }

                        if (results.RemoveCurrent)
                            lines.RemoveAt(i);
                        else if (results.RemoveNext)
                            lines.RemoveAt(i + 1);
                        else if (results.InsertNext)
                            lines.Insert(i + 1, string.Empty);
                        else if (results.InsertAfterNext)
                            lines.Insert(i + 2, string.Empty);
                    }
                }

                /* It seems that using any encoding other than Encoding.UTF8, including my failed attempts
                 * to detect it, end up encoding the text in such a way that the hidden unicode characters
                 * that Regionerate uses in its region names, get scrambled. */
                File.WriteAllLines(filename, lines, Encoding.UTF8);
                LogInfo(Pad(string.Format("Thread {0}", formattedThreadId), "FormatCSFiles".Length) + string.Format("\tSaved \"{0}\"", formattedFilename));
            }
            catch (Exception ex) { LogError(ex); }
        }

        private class AnalysisResults
        {
            public bool InsertAfterNext { get; set; }

            public bool InsertNext { get; set; }

            public bool RemoveCurrent { get; set; }

            public bool RemoveNext { get; set; }
        }
    }
}

And my base console application class that it derived from (which isn’t too bad).

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;

namespace Romy.Core.Console
{
    /// <summary>A base console type that enables some logging methods. Logs
    /// via TraceListener, to both the console and a file.</summary><remarks>
    /// See Zipper\Program.cs or FormatCSFiles\Program.cs for examples.</remarks>
    public class ConsoleApplicationBase
    {
        private string logFilename;

        /// <summary>Delete the file or directory specified,
        /// without throwing an exception on failure.</summary>
        public static bool DeleteFileSystemObject(string path)
        {
            try
            {
                /* File.Exists seems to return true for directories,
                 * so always check with Directory.Exists first... */
                if (Directory.Exists(path))
                {
                    var info = new DirectoryInfo(path);

                    // If path == current directory, change the current directory.
                    if (string.Compare(Directory.GetCurrentDirectory(), path, StringComparison.InvariantCultureIgnoreCase) == 0 && Directory.Exists(Path.GetDirectoryName(path)))
                        Directory.SetCurrentDirectory(Path.GetDirectoryName(path));

                    // Try to silently delete readonly/hidden directories.
                    if ((info.Attributes & FileAttributes.ReadOnly) == FileAttributes.ReadOnly || (info.Attributes & FileAttributes.Hidden) == FileAttributes.Hidden)
                        info.Attributes = FileAttributes.Directory & FileAttributes.Archive;

                    Directory.Delete(path, true);
                }
                else if (File.Exists(path))
                {
                    // Try to silently delete readonly/hidden files.
                    if ((File.GetAttributes(path) & FileAttributes.ReadOnly) == FileAttributes.ReadOnly || (File.GetAttributes(path) & FileAttributes.Hidden) == FileAttributes.Hidden)
                        File.SetAttributes(path, FileAttributes.Normal);

                    File.Delete(path);
                }
                return true;
            }
            catch (IOException) { }
            catch (UnauthorizedAccessException) { }
            catch (Exception ex) { LogError(ex); }
            return false;
        }

        public static void LogError(Exception ex)
        {
            LogInfo("Error: {0}", ex.Message);
        }

        public static void LogError(string message)
        {
            LogInfo(message);
        }

        public static void LogInfo(IEnumerable<string> lines)
        {
            foreach (var line in lines)
            {
                Trace.WriteLine(line);
            }
        }

        public static void LogInfo(string format, params object[] args)
        {
            var formattedDate = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.ff\t");
            Trace.WriteLine(formattedDate + (args.Length > 0 ? string.Format(format, args) : format));
        }

        /// <summary>This must be the first method called from Main,
        /// to be able to use the logging helper methods.</summary>
        public void InitializeConsoleApplication()
        {
            /* I prefer removing the parameters from Main and using this technique. It is always
             * consistent; the path to this exe is the first argument, and subsequent arguments
             * were passed by the user. */
            var args = Environment.GetCommandLineArgs();

            logFilename = Path.ChangeExtension(args[0], ".log");

            InitializeTraceListeners(logFilename);
        }

        private static void InitializeTraceListeners(string logFilename)
        {
            DeleteFileSystemObject(logFilename);

            Trace.Listeners.Clear();

            TextWriterTraceListener logFileTraceListener = new TextWriterTraceListener(logFilename);
            logFileTraceListener.Name = "FileLogger";

            ConsoleTraceListener consoleTraceListener = new ConsoleTraceListener(false);
            consoleTraceListener.Name = "ConsoleLogger";

            Trace.Listeners.Add(logFileTraceListener);
            Trace.Listeners.Add(consoleTraceListener);
            Trace.AutoFlush = true;
        }
    }
}

The curious case of the generic complimentary comment. I hate SPAM!

Recently I received this comment to one of my posts:

Hello! I’ve been reading your site for a long time now and finally got the bravery to go ahead and give you a shout out from Huffman Tx! Just wanted to say keep up the great work!

So I thought to myself, “That’s odd“. Reading this new blog for a long time? Sure, the old one redirects here, but judging by the number of page views (on average at the old blog, around 70 per day, but up to a max of about 400, while the most ever here was 15 on one day), most of my old readers haven’t found this one, and my Google indexing is pretty much gone. (Which makes me sad, by the way.) Then I followed the link, and it led to a membership page of a site that contained another link advertising a website for painters. A painters’ website in Toronto, Canada! So I’m getting a shout out from Texas advertising a website in Canada? Those crazy Canaditexans…

So sure enough, a quick search for similar comments elsewhere turned up a blog with this:

Hey there! I’ve been following your blog for some time now and finally got the bravery to go ahead and give you a shout out from Humble Texas! Just wanted to say keep up the great job!

And this:

Hello! I’ve been reading your blog for a long time now and finally got the bravery to go ahead and give you a shout out from Lubbock Texas! Just wanted to tell you keep up the excellent job!

And this:

Hi! I’ve been reading your website for a while now and finally got the courage to go ahead and give you a shout out from Huffman Texas! Just wanted to say keep up the fantastic work!

As a general rule, generic compliments in comments don’t come from readers actually reading the content and commenting, they are generated and bulk-submitted SPAM. They usually contain a single link to an ad as the commenter’s “website”. Since it’s only one link and SPAM filters like Akismet normally look for two or more, these are often not detected by SPAM filters, but any human reader/moderator/blogger can spot them. In this case, the comments were built programmatically from a template, by a despicable program (like this one) that posts comments in bulk to blogs. There are many other examples. I’m leaving the comment here for educational purposes, after removing the spammer’s URL and mailto link of course.

Two years ago Scott Hanselman wrote about such a template. This is clearly generated from that template, which the spammers are still using. Here is the relevant bit that generated all of those comments:

{Hola|Hey there|Hi|Hello|Greetings}! I’ve been {following|reading} your {site|web site|website|weblog|blog} for {a long time|a while|some time} now and finally got the {bravery|courage} to go ahead and give you a shout out from {New Caney|Kingwood|Huffman|Porter|Houston|Dallas|Austin|Lubbock|Humble|Atascocita} {Tx|Texas}! Just wanted to {tell you|mention|say} keep up the {fantastic|excellent|great|good} {job|work}!

The bottom line is this: Beware of generic compliments in comments. They are not what they seem. (I shouldn’t even have followed the link. Merely clicking may have generated revenue for somebody, via their affiliate program that pays according to the number of clicks. Also, such links may take you to porn or malware sites.) Fortunately the people who generate this kind of SPAM are idiots; were they not it might not be so easy to detect.

Then again, any generic comment that’s not related in any way whatsoever to your written content should be a huge red flag. A challenge for a good programmer would thus be to generate a comment that somehow relates to the article being commented on. (To be clear, I mean a purely intellectual challenge. Anybody who publishes or uses such a program deserves to be shot in the stomach, doused with petrol, set on fire and thrown off a cliff.) At the very least, it could quote a random paragraph of your content and then proceed to “comment” in a generic way on that content. (This would be fairly easy to do and would look more like a real comment, but might not be detected so easily fool bloggers desperate for comments.) Of course that would require actually reading your site or blog’s content, at least programatically, and would defeat the purpose and likely the profit of bulk SPAM comment publishing. (Assuming that there is a profit. Do people actually follow those SPAM comment links by clicking on the commenter’s name? Are there bloggers so desperate for comments that they appreciate generic compliments?)

Here’s the full SPAM template:

{
{I have|I've} been {surfing|browsing} online more than {three|3|2|4} hours today, yet I never found any interesting article like yours. {It's|It
is} pretty worth enough for me. {In my opinion|Personally|In my view}, if all {webmasters|site owners|website owners|web owners} and bloggers made good content as
you did, the {internet|net|web} will be {much more|a lot more}
useful than ever before.|
I {couldn't|could not} {resist|refrain from} commenting. {Very well|Perfectly|Well|Exceptionally well} written!|
{I will|I'll} {right away|immediately} {take hold of|grab|clutch|grasp|seize|snatch}
your {rss|rss feed} as I {can not|can't} {in finding|find|to find} your {email|e-mail} subscription {link|hyperlink} or {newsletter|e-newsletter} service. Do {you have|you've} any?
{Please|Kindly} {allow|permit|let} me {realize|recognize|understand|recognise|know} {so that|in order that} I {may just|may|could} subscribe.
Thanks.|
{It is|It's} {appropriate|perfect|the best} time to make some plans for the future and {it is|it's} time to be happy.
{I have|I've} read this post and if I could I {want to|wish to|desire to} suggest you {few|some} interesting things or {advice|suggestions|tips}. {Perhaps|Maybe} you {could|can} write next articles referring to this article. I {want to|wish to|desire to} read {more|even more} things about it!|
{It is|It's} {appropriate|perfect|the best} time to make {a few|some} plans for {the future|the
longer term|the long run} and {it is|it's} time to be happy. {I have|I've} {read|learn} this {post|submit|publish|put up} and
if I {may just|may|could} I {want to|wish to|desire to} {suggest|recommend|counsel} you {few|some} {interesting|fascinating|attention-grabbing} {things|issues} or {advice|suggestions|tips}.
{Perhaps|Maybe} you {could|can} write {next|subsequent} articles {relating to|referring to|regarding} this article.
I {want to|wish to|desire to} {read|learn} {more|even
more} {things|issues} {approximately|about} it!|
{I have|I've} been {surfing|browsing} {online|on-line} {more than|greater than} {three|3} hours {these days|nowadays|today|lately|as of late}, {yet|but} I {never|by no means} {found|discovered} any {interesting|fascinating|attention-grabbing} article like yours. {It's|It is} {lovely|pretty|beautiful} {worth|value|price} {enough|sufficient} for
me. {In my opinion|Personally|In my view},
if all {webmasters|site owners|website owners|web owners} and bloggers made {just right|good|excellent} {content|content material} as {you did|you probably did}, the {internet|net|web} {will be|shall be|might
be|will probably be|can be|will likely be} {much
more|a lot more} {useful|helpful} than ever before.|
Ahaa, its {nice|pleasant|good|fastidious} {discussion|conversation|dialogue} {regarding|concerning|about|on the topic of} this {article|post|piece of writing|paragraph} {here|at this place} at this
{blog|weblog|webpage|website|web site}, I have read all
that, so {now|at this time} me also commenting {here|at this
place}.|
I am sure this {article|post|piece of writing|paragraph}
has touched all the internet {users|people|viewers|visitors}, its really really {nice|pleasant|good|fastidious} {article|post|piece of writing|paragraph} on
building up new {blog|weblog|webpage|website|web site}.
|
Wow, this {article|post|piece of writing|paragraph} is {nice|pleasant|good|fastidious}, my
{sister|younger sister} is analyzing {such|these|these kinds of} things, {so|thus|therefore} I am going to {tell|inform|let
know|convey} her.|
{Saved as a favorite|bookmarked!!}, {I really like|I
like|I love} {your blog|your site|your web site|your website}!
|
Way cool! Some {very|extremely} valid points! I
appreciate you {writing this|penning this} {article|post|write-up} {and the|and also the|plus the}
rest of the {site is|website is} {also very|extremely|very|also really|really} good.
|
Hi, {I do believe|I do think} {this is an excellent|this
is a great} {blog|website|web site|site}. I stumbledupon it 😉 {I will|I am going
to|I'm going to|I may} {come back|return|revisit} {once again|yet again} {since I|since i have} {bookmarked|book marked|book-marked|saved as a favorite} it. Money and freedom {is the best|is the greatest} way to change, may you be rich and continue to {help|guide} {other people|others}.|
Woah! I'm really {loving|enjoying|digging} the template/theme of this {site|website|blog}.
It's simple, yet effective. A lot of times it's {very
hard|very difficult|challenging|tough|difficult|hard} to
get that "perfect balance" between {superb usability|user friendliness|usability} and {visual appearance|visual appeal|appearance}.
I must say {that you've|you have|you've} done a {awesome|amazing|very good|superb|fantastic|excellent|great} job with this.
{In addition|Additionally|Also}, the blog loads {very|extremely|super} {fast|quick} for me on {Safari|Internet explorer|Chrome|Opera|Firefox}.
{Superb|Exceptional|Outstanding|Excellent} Blog!
|
These are {really|actually|in fact|truly|genuinely} {great|enormous|impressive|wonderful|fantastic} ideas
in {regarding|concerning|about|on the topic of} blogging.
You have touched some {nice|pleasant|good|fastidious} {points|factors|things}
here. Any way keep up wrinting.|
{I love|I really like|I enjoy|I like|Everyone loves} what you guys
{are|are usually|tend to be} up too. {This sort
of|This type of|Such|This kind of} clever work and {exposure|coverage|reporting}!
 
Keep up the {superb|terrific|very good|great|good|awesome|fantastic|excellent|amazing|wonderful} works guys I've {incorporated||added|included} you guys to {|my|our||my personal|my own} blogroll.|
{Howdy|Hi there|Hey there|Hi|Hello|Hey}! Someone in my {Myspace|Facebook} group shared this {site|website} with us so I came to {give it a look|look it over|take a look|check it out}. I'm definitely {enjoying|loving} the information.
I'm {book-marking|bookmarking} and will be tweeting this to my followers! {Terrific|Wonderful|Great|Fantastic|Outstanding|Exceptional|Superb|Excellent} blog and {wonderful|terrific|brilliant|amazing|great|excellent|fantastic|outstanding|superb} {style and design|design and style|design}.|
{I love|I really like|I enjoy|I like|Everyone loves} what you guys {are|are usually|tend to be} up too. {This sort of|This type of|Such|This kind of} clever work and {exposure|coverage|reporting}! Keep up the {superb|terrific|very good|great|good|awesome|fantastic|excellent|amazing|wonderful} works guys I've {incorporated|added|included} you guys to
{|my|our|my personal|my own} blogroll.|
{Howdy|Hi there|Hey there|Hi|Hello|Hey} would you mind {stating|sharing} which blog platform you're {working with|using}? I'm {looking|planning|going} to start my own blog {in the near future|soon} but I'm having a {tough|difficult|hard} time {making a decision|selecting|choosing|deciding} between BlogEngine/Wordpress/B2evolution and Drupal. The reason I ask is because your {design and style|design|layout} seems different then most blogs and I'm looking for something {completely
unique|unique}.                  P.S {My apologies|Apologies|Sorry} for {getting|being} off-topic but
I had to ask!|
{Howdy|Hi there|Hi|Hey there|Hello|Hey} would you mind letting
me know which {webhost|hosting company|web host} you're {utilizing|working with|using}? I've
loaded your blog in 3 {completely different|different} {internet browsers|web browsers|browsers} and I must say this blog loads a lot {quicker|faster} then most.
 
Can you {suggest|recommend} a good {internet
hosting|web hosting|hosting} provider at a {honest|reasonable|fair}
price? {Thanks a lot|Kudos|Cheers|Thank you|Many thanks|Thanks}, I
appreciate it!|
{I love|I really like|I like|Everyone loves} it {when people|when individuals|when folks|whenever people} {come together|get
together} and share {opinions|thoughts|views|ideas}. Great {blog|website|site}, {keep it up|continue the good work|stick with
it}!|
Thank you for the {auspicious|good} writeup. It in fact was a amusement account it.
Look advanced to {far|more} added agreeable from you! {By the way|However}, how {can|could} we communicate?
|
{Howdy|Hi there|Hey there|Hello|Hey} just wanted to give you a quick heads up.
 
The {text|words} in your {content|post|article} seem to be running off
the screen in {Ie|Internet explorer|Chrome|Firefox|Safari|Opera}.
I'm not sure if this is a {format|formatting} issue or something to do with {web browser|internet browser|browser} compatibility but I {thought|figured} I'd
post to let you know. The {style and design|design
and style|layout|design} look great though! Hope you get the {problem|issue} {solved|resolved|fixed} soon.
 
{Kudos|Cheers|Many thanks|Thanks}|
This is a topic {that is|that's|which is} {close to|near to} my heart... {Cheers|Many thanks|Best wishes|Take care|Thank you}! {Where|Exactly where} are your contact details though?|
It's very {easy|simple|trouble-free|straightforward|effortless}
to find out any {topic|matter} on {net|web} as compared to {books|textbooks}, as I found this {article|post|piece of writing|paragraph} at this {website|web site|site|web
page}.|
Does your {site|website|blog} have a contact page?
I'm having {a tough time|problems|trouble} locating it but, I'd
like to {send|shoot} you an {e-mail|email}. I've got some {creative ideas|recommendations|suggestions|ideas} for your blog you might be interested in hearing. Either way, great {site|website|blog} and I look forward to seeing it {develop|improve|expand|grow} over time.|
{Hola|Hey there|Hi|Hello|Greetings}! I've been {following|reading} your {site|web site|website|weblog|blog} for {a long time|a while|some time} now and finally got the {bravery|courage} to go ahead and give you
a shout out from  {New Caney|Kingwood|Huffman|Porter|Houston|Dallas|Austin|Lubbock|Humble|Atascocita} {Tx|Texas}!
Just wanted to {tell you|mention|say} keep up the {fantastic|excellent|great|good}
{job|work}!|
Greetings from {Idaho|Carolina|Ohio|Colorado|Florida|Los angeles|California}!
 
I'm {bored to tears|bored to death|bored} at work so I decided to {check out|browse} your {site|website|blog} on my iphone during lunch break. I {enjoy|really like|love} the {knowledge|info|information} you {present|provide} here and can't wait to
take a look when I get home. I'm {shocked|amazed|surprised} at how {quick|fast} your blog loaded on my {mobile|cell phone|phone} .. I'm not even
using WIFI, just 3G .. {Anyhow|Anyways}, {awesome|amazing|very good|superb|good|wonderful|fantastic|excellent|great} {site|blog}!
|
Its {like you|such as you} {read|learn} my {mind|thoughts}!
You {seem|appear} {to understand|to know|to grasp} {so much|a lot} {approximately|about} this,
{like you|such as you} wrote the {book|e-book|guide|ebook|e book} in it or something.
{I think|I feel|I believe} {that you|that you simply|that you just} {could|can} do with
{some|a few} {%|p.c.|percent} to {force|pressure|drive|power} the message {house|home} {a bit|a little bit}, {however|but} {other than|instead of} that, {this is|that is} {great|wonderful|fantastic|magnificent|excellent} blog. {A great|An excellent|A fantastic} read. {I'll|I will} {definitely|certainly} be back.|
I visited {multiple|many|several|various} {websites|sites|web sites|web pages|blogs} {but|except|however} the audio {quality|feature} for audio songs {current|present|existing} at this {website|web site|site|web page} is {really|actually|in fact|truly|genuinely} {marvelous|wonderful|excellent|fabulous|superb}.|
{Howdy|Hi there|Hi|Hello}, i read your blog {occasionally|from time to time} and i own a similar one and i was just {wondering|curious} if you get a lot of spam {comments|responses|feedback|remarks}? If so how do you {prevent|reduce|stop|protect against} it, any plugin or anything you can {advise|suggest|recommend}? I get so much lately it's driving me {mad|insane|crazy} so any {assistance|help|support} is very much appreciated.|
Greetings! {Very helpful|Very useful} advice {within this|in this particular} {article|post}! {It is the|It's the} little changes {that make|which will make|that produce|that will make} {the biggest|the largest|the greatest|the most important|the most significant} changes. {Thanks a lot|Thanks|Many thanks} for sharing!|
{I really|I truly|I seriously|I absolutely} love {your blog|your site|your website}.. {Very nice|Excellent|Pleasant|Great} colors & theme. Did you {create|develop|make|build} {this website|this site|this web site|this amazing site} yourself? Please reply back as I'm {looking to|trying to|planning to|wanting to|hoping to|attempting to} create {my own|my very own|my own personal} {blog|website|site} and {would like to|want to|would love to} {know|learn|find out} where you got this from or {what the|exactly what the|just what the} theme {is called|is named}. {Thanks|Many thanks|Thank you|Cheers|Appreciate it|Kudos}!|
{Hi there|Hello there|Howdy}! This {post|article|blog post} {couldn't|could not} be written {any better|much better}! {Reading through|Looking at|Going through|Looking through} this {post|article} reminds me of my previous roommate! He {always|constantly|continually} kept {talking about|preaching about} this. {I will|I'll|I am going to|I most certainly will} {forward|send} {this article|this information|this post} to him. {Pretty sure|Fairly certain} {he will|he'll|he's going to} {have a good|have a very good|have a great} read. {Thank you for|Thanks for|Many thanks for|I appreciate you for} sharing!|
{Wow|Whoa|Incredible|Amazing}! This blog looks {exactly|just} like my old one! It's on a {completely|entirely|totally} different {topic|subject} but it has pretty much the same {layout|page layout} and design. {Excellent|Wonderful|Great|Outstanding|Superb} choice of colors!|
{There is|There's} {definately|certainly} {a lot to|a great deal to} {know about|learn about|find out about} this {subject|topic|issue}. {I like|I love|I really like} {all the|all of the} points {you made|you've made|you have made}.|
{You made|You've made|You have made} some {decent|good|really good} points there. I {looked|checked} {on the internet|on the web|on the net} {for more info|for more information|to find out more|to learn more|for additional information} about the issue and found {most individuals|most people} will go along with your views on {this website|this site|this web site}.|
{Hi|Hello|Hi there|What's up}, I {log on to|check|read} your {new stuff|blogs|blog} {regularly|like every week|daily|on a regular basis}. Your {story-telling|writing|humoristic} style is {awesome|witty}, keep {doing what you're doing|up the good work|it up}!|
I {simply|just} {could not|couldn't} {leave|depart|go away} your {site|web site|website} {prior to|before} suggesting that I {really|extremely|actually} {enjoyed|loved} {the standard|the usual} {information|info} {a person|an individual} {supply|provide} {for your|on your|in your|to your} {visitors|guests}? Is {going to|gonna} be {back|again} {frequently|regularly|incessantly|steadily|ceaselessly|often|continuously} {in order to|to} {check up on|check out|inspect|investigate cross-check} new posts|
{I wanted|I needed|I want to|I need to} to thank you for this {great|excellent|fantastic|wonderful|good|very good} read!! I {definitely|certainly|absolutely} {enjoyed|loved} every {little bit of|bit of} it. {I have|I've got|I have got} you {bookmarked|book marked|book-marked|saved as a favorite} {to check out|to look at} new {stuff you|things you} post�\

On figuring out the appropriate bitrate for video conversions

Sometimes I look at source code I wrote a couple of years ago, when I was high on meth, and I think to myself, “You are a fucking imbecile”. Other times it seems I was much brighter then than I am now.

Anyway, I’m watching The Flash. I downloaded episodes 1 to 14 in MP4 format (DVD Rip), and then downloaded episodes 15 to 22 in the only format I could find, which turned out to be MKV (HD Rip). Incidentally, you can find the latest episode, when it gets released, by searching Google for the string “The Flash S1E23 – 350mb – kakashihatake2”, then find the torrent.

They all play on my TV, but unfortunately the MKV sorts before the MP4, which means I have episodes 15 to 22 displaying before episodes 1 to 14. (I can change the default sort order, but the TV doesn’t persist that setting, so it would be worthwhile to force the sort order to be correct by manipulating the files.) So I figured I may as well try converting the MKV to MP4. But what bitrate to choose?

Actually I came up with something a couple of years ago, when I was high, and wrote my own little GUI that wraps ffmpeg. The formula I came to then, which is of course not my own, was buried in this code:

        /// <summary>Calculates an appropriate bitrate. (Actually this probably only applies to mp4.)</summary>
        /// <remarks>Options.EncoderOptions is dynamic. Depending on the format, it may not have a VideoBitRate
        /// or TwoPassEncoding property. We thus try to set them, then handle and ignore any exceptions.</remarks>
        private void CalculateBitrate(Size value = default(Size))
        {
            var factor = 1;

            try
            {
                /* A compromise: ffmpeg is failing on pass 2 with the error: The requested bitrate is too low.
                 * This is after applying the calculation below and a factor of 1. So for two-pass encoding, 
                 * increase the factor to 2. So far this works OK. */
                if (Options.EncoderOptions.TwoPassEncoding)
                    factor = 2;
            }
            catch { }

            try
            {
                /* Using the "Kush Gauge" to calculate the bitrate: 
                 * Pixel count (wxh) * fps * motion factor (1, 2, or 4) * 0.07 = bitrate/1000 
                 * 
                 * If this method is passed a valid Size parameter, use it. Otherwise, if the options specify 
                 * the video is being cropped and scaled, use Options.Scale; otherwise use Options.Size. */
                var newSize = value != default(Size) ? value :
                    Options.Crop.Size == Options.Size && Options.Scale.Size != Options.Size ?
                    Options.Scale.Size : Options.Size;

                Options.EncoderOptions.VideoBitRate = ((double)newSize.Width * newSize.Height * Options.FrameRate * 0.07D * factor / 1000D).ToString("F2") + "k";
                encoderGrid.Refresh();
            }
            catch { }
        }

My implementation uses something called the “Kush Guage”, whatever that is. I remember neither reading about it nor implementing it. As you can see, my meth-high-implementation doesn’t really follow the formula exactly. But anyway, it works quite well, so I’m running my ffmpeg wrapper to do the conversion. (After doing a test on a small part of the video to confirm that the result is good quality.)

I’m using the 64-bit static build version of ffmpeg, which I found here. My generated command-line to use, for H264 MP4 that converts fairly quickly is this:

ffmpeg.exe  -i “G:\Videos\Series\The Flash S1E15.mkv” -c:v libx264 -vprofile Main -preset Faster -b:v 1546.74k -maxrate 1546.74k -bufsize 1200k -threads 0 -acodec libvo_aacenc -b:a 128k -r 23.976 -ar 44100 -ac 2 -y “G:\Videos\Series\The Flash S1E15.mp4”

That command-line should work for all MKV to MP4 conversions, where the bitrate was calculated as:

Width*Height*Frame-rate*0.07*motion-factor/1000, where motion-factor is supposed to be 1, 2, or 4, but my implementation always uses a factor of 1 (for single-pass encoding and a factor of 2 for two-pass encoding). This command-line is doing the encoding in one pass. That works out to:
1280*720*23.976*0.07/1000 = 1546.74k

Actually there were some bugs in my code, which is why I shouldn’t be sharing my ffmpeg wrapper. (Actually all my code and the compiled application is shared, but I’m not linking to it here because I have not uploaded the version with bug fixes.) For one thing, it was using a lower “max bitrate” than the specified bitrate (which totally fucked up the video quality), so I worked around that now by hacking my code to always specify the same rate for both. The code I wrote back then to generate the command line is so complicated, I can no longer understand it. Modifying it now was like changing somebody else’s code. Some guy who is both a genius and an idiot simultaneously. Yet another reason not to use crystal meth.

[Other things worth noting… The audio bitrate is based on the source rate, so that is something that should be set dynamically, depending on the source. Disabling multi-threaded encoding with “-threads 0” is probably unnecessary, but back when I wrote that code, I mostly encoded to a DivX-compatible format, and my DVD player at the time couldn’t play files properly if they were encoded with more than one thread.]

I may share my video converting application once I get to understand the code enough again to clean it up a little.

Update: According to this site, this bitrate calculation is about right for H264 mp4. But it looks like the max rate should be 150% of it, not the same value. But it gets confusing. For VBR (variable bit rate), the bitrate should be about 75% of this value. I will have to adjust my code and play around to find the optimum bitrate.

We never perform optimally when using drugs–another example of source code I wrote while high on meth

One of the sites I visit daily is The Daily WTF. It’s a place where programmers go to laugh at badly written source code (and sometimes badly written embellished articles but that’s another story). You go there for examples of the kind of source code that, when you see it in real life, you react with a loud exclamation of “What the fuck?!”

A couple of weeks ago, someone posted an example of his own code in their “Sidebar WTF” section, and commented something like “What kind of crack was I smoking when I wrote this?” Of course he meant it as a figure of speech, but I couldn’t help but reply with some code that was really written while I was tweaking on meth. Today, I’ll share that same code here.

The message in this post is not really about the code, so I’ll paste it at the end. The message is about how drugs affect our performance, even when we may think it does not.

The code in question is part of my “for fun” little GUI that allows editing of zip files. It’s the method that populates my GUI, which results in something like the screenshot below, which I just made while browsing a random zip file with it:

image

Actually the code works, and it works very well. I could almost be proud of it. Almost, but not quite.

It works by enumerating all of the contents of a zip file. It allows recursing into the directories inside the file as well, depending on what parameter it’s passed. When passed a null parameter, it displays the root entries; otherwise it enumerates the entries of a sub-directory of the zip file. It has to be a little intelligent about how it identifies the directories inside the zip file, because zip files may or may not contain separate entries for directories. And it gets all of those things right.

But this code has a number of problems… Some of them are:

  1. The difference between enumerating files and directories is minimal, yet it uses two very similar blocks of code. This could have been made far simpler.
  2. In some lines, it uses constants and string literals that represent the same values, in the same line. That’s just poor programming right there. Nobody who isn’t high as a kite would ever do that.
  3. It always enumerates everything in the zip file, then discards the entries it doesn’t need. That’s a known anti-pattern and a big no-no in programming. What it should have done was to cache the contents of the zip file. i.e. only enumerate it once, unless it changes. The reason was pure laziness… My GUI also allows editing of the zip, which meant that this code would somehow need to be aware of changes to cached entries, possibly by implementing an observer pattern. It is fast though, even for zip files containing thousands of entries, but that’s no excuse for poor code.
  4. It uses separate collections for directories and files; then sorts them separately just so that directories will always be displayed before files. Again, this is pure laziness, considering that the same application, which also features a file browser, knows how to sort a collection that contains both files and directories. i.e. I implemented a Comparer<T> somewhere else in the same application that could do this, but used different, less efficient logic here.
  5. Probably the worst part is that it then builds ListView items directly to populate my custom “Shell ListView” control. This code should have built some sort of structure or collection of the data, but it should not have been creating controls to use on the GUI directly. Now I can’t use the code anywhere else…

Granted, this is not terrible code. It’s my own, and it does its intended job. Sadly I have known many programmers who wouldn’t be able to do this even though they have never used drugs. (But those people are not real programmers in my view. Copying and pasting or downloading others’ source code is not programming; real programmers write their own code.) The code does some clever stuff, like sorting in parallel (via some extension methods that use Microsoft sample code that I modified but did not write – I’m not that smart), and the other code not shown, such as the custom ListView that looks similar to the Windows shell one, and displays shell icons, is pretty good. Also not shown are my methods for doing everything with zip file contents asynchronously. So the code works well… It’s functional, but at the end of the day it is competent. I can be so much better than competent. I can be excellent but on meth, competent is all I’ll ever be.

So that’s the point of this post. When we use drugs we often fool ourselves into thinking that we can still perform well enough at our jobs. (This was my own private code, but still, it is programming and that’s what I do for a living.) Especially on drugs like meth or cocaine, we think it makes us alert and clever. We think we are doing well when we use drugs, but we are not.

Here is the shoddy code described above: (Sorry, it would be too much effort to make this wrap well in the tiny width of this post. The tool I use to generate code snippets in the blog does add a scrollbar, but only at the bottom… I haven’t found a better one yet.)

/// <summary>Populate the file and directory list from the zip file entries, keeping track of the current directory
/// in a class-level property. We always only display the files and directories contained by the current directory.
/// path == null indicates that the current directory is the root directory of the zip file.</summary>
private void Populate(string path = null)
{
    CurrentZipDirectory = path;

    // Use threadsafe collections to hold temporary lists of files and directories.
    var directoryBag = new ConcurrentBag<ListViewItem>();
    var fileBag = new ConcurrentBag<ListViewItem>();

    // This list will be filtered for the current directory.
    var zipFileEntries = Enumerable.Empty<ZipArchiveEntry>().ToList();

    try
    {
        using (var zipArchive = ZipFile.Open(Filename, ZipArchiveMode.Read))
        {
            try
            {
                zipFileEntries = zipArchive.Entries.ToList();
            }
            catch (Exception ex)
            {
                ex.Log();
                MessageBox.Show(Browser.Instance, 
                    string.Format("The zip file appears to be invalid and could not be read.\n{0}", ex.Message), 
                    "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }

            // Discard everything that is not nested in/below the current directory
            if (path != null)
                zipFileEntries.RemoveAll(
                    entry => !(entry.FullName.StartsWith(
                        path + Romy.Core.Constants.DelimiterChars[0]) || 
                        entry.FullName.StartsWith(path + Romy.Core.Constants.DelimiterChars[1])));

            /* Get the directories to display. Zip files sometimes contain entries for directories, but often
             * do not, and when we parse the entries paths, there will be many recurrences of each directory.
             * Thus use a dictionary to keep track of the directories we have already found. */
            var directories = new ConcurrentDictionary<string, string>();

            var directoryEntries = zipFileEntries.Where(e =>
            {
                // Filter for subdirectories of the current directory.
                var filenameInZip = e.FullName;

                /* Remove current directory from string, so that the same
                 * string-manipulation logic applies to all directries. */
                if (path != null)
                    filenameInZip = filenameInZip.Substring(path.Length + 1);

                /* With the current directory removed, any string that contains one slash (forward or
                 * backslash; whatever this zip file uses) is a sub-directory of the current directory. */
                if (filenameInZip.Count(c => c == '\\' || c == '/') > 0)
                {
                    var directory = filenameInZip.Substring(0, filenameInZip.IndexOfAny(Romy.Core.Constants.DelimiterChars));

                    if (!directories.Values.Contains(directory))
                    {
                        directories[e.FullName] = directory;
                        return true;
                    }
                }
                return false;
            });

            try
            {
                directoryEntries.AsParallel().ForAll(entry =>
                {
                    var index = path == null ? 0 : path.Length + 1;
                    var relativePath = entry.FullName.Substring(0, entry.FullName.IndexOfAny(Romy.Core.Constants.DelimiterChars, index));

                    /* Use my SimpleFileInfo helper class to get the file or directory description and image
                     * index from the SystemImageList. (The SystemImagelist is used by the listview.) */
                    var simpleFileInfo = new SimpleFileInfo
                    {
                        Name = directories[entry.FullName],
                        FileSystemType = Romy.Core.FileSystemType.Directory,
                        //DateModified = entry.ModifyTime,  // This date in this entry refers to a file, not the directory. As we built the
                        Size = 0                            // dictionary of directories, we kind of hijacked a file entry to use for the directory.
                    };

                    directoryBag.Add(ShellListView.CreateListViewItem(new ZipEntryInfo
                    {
                        SimpleFileInfo = simpleFileInfo,
                        DisplayName = relativePath,
                        CompressedLength = entry.CompressedLength,
                        FullName = entry.FullName,
                        LastWriteTime = entry.LastWriteTime,
                        Length = entry.Length,
                        Name = entry.Name
                    }, simpleFileInfo));
                });
            }
            catch (AggregateException ax)
            {
                var handled = false;

                ax.Handle(ex => handled = ex is ArgumentOutOfRangeException);

                if (!handled)
                    throw;
            }

            /* Get the files. The logic is almost identical to the directories. */
            var fileEntries = zipFileEntries.Where(e =>
            {
                return path != null ? 
                    e.FullName.IndexOfAny(Romy.Core.Constants.DelimiterChars, path.Length + 1) == -1 
                    : e.FullName.IndexOfAny(Romy.Core.Constants.DelimiterChars) == -1;
            });

            try
            {
                fileEntries.AsParallel().ForAll(entry =>
                {
                    var relativePath = entry.FullName;

                    if (path != null)
                        relativePath = relativePath.IndexOf(Path.DirectorySeparatorChar) != -1 ? 
                            relativePath.Replace(path + Path.AltDirectorySeparatorChar, string.Empty) 
                            : relativePath.Replace(path + '/', string.Empty);

                    if (!string.IsNullOrEmpty(relativePath) && 
                        !(relativePath.EndsWith(Path.DirectorySeparatorChar.ToString()) && 
                        !(relativePath.EndsWith(Path.AltDirectorySeparatorChar.ToString()) && 
                        entry.Length == 0)))
                    {
                        var simpleFileInfo = new SimpleFileInfo
                        {
                            Name = relativePath,
                            FileSystemType = FileSystemType.File,
                            DateModified = entry.LastWriteTime.LocalDateTime,
                            Size = entry.Length
                        };

                        fileBag.Add(ShellListView.CreateListViewItem(new ZipEntryInfo
                        {
                            SimpleFileInfo = simpleFileInfo,
                            DisplayName = relativePath,
                            CompressedLength = entry.CompressedLength,
                            FullName = entry.FullName,
                            LastWriteTime = entry.LastWriteTime,
                            Length = entry.Length,
                            Name = entry.Name
                        }, simpleFileInfo));
                    }
                });
            }
            catch (AggregateException ax)
            {
                var handled = false;

                ax.Handle(ex => handled = ex is ArgumentOutOfRangeException);

                if (!handled)
                    throw;
            }

            // Copy our ConcurrentBag lists to arrays, and sort them in parallel.
            var directoryItemArray = directoryBag.ParallelSort(Comparer<ListViewItem>.Create((x, y) =>
            {
                return string.Compare(
                    ((ZipEntryInfo)x.Tag).DisplayName, ((ZipEntryInfo)y.Tag).DisplayName, 
                    StringComparison.InvariantCultureIgnoreCase);
            })).ToArray();

            var fileItemArray = fileBag.ParallelSort(Comparer<ListViewItem>.Create((x, y) =>
            {
                string xString = ((ZipEntryInfo)x.Tag).DisplayName;
                string xExtension = Path.GetExtension(xString);
                xString = Path.GetFileNameWithoutExtension(xString);

                string yString = ((ZipEntryInfo)y.Tag).DisplayName;
                string yExtension = Path.GetExtension(yString);
                yString = Path.GetFileNameWithoutExtension(yString);

                return (xExtension + xString).CompareIgnoreCultureAndCase(yExtension + yString);
            })).ToArray();

            listView.BeginUpdate();
            try
            {
                listView.Items.Clear();

                listView.Items.AddRange(directoryItemArray);
                listView.Items.AddRange(fileItemArray);

                if (fileItemArray.Length == 0)
                {
                    sizeHeader.Text = string.Empty;
                    modifiedHeader.Text = string.Empty;
                }
                else
                {
                    sizeHeader.Text = "Size";
                    modifiedHeader.Text = "Modified Date";
                }

                if (listView.Items.Count > 0)
                    listView.AutoResizeColumns(ColumnHeaderAutoResizeStyle.ColumnContent);
            }
            finally { listView.EndUpdate(); }
        }

        validZipFile = true;
    }
    catch (InvalidDataException ex)
    {
        ex.Log();
        MessageBox.Show(Browser.Instance, 
            string.Format("The zip file appears to be invalid and could not be read.\n{0}", ex.Message), 
            "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
        return;
    }

    UpdateStatusStripInfo();
    SelectLastDirectory();

    // The vertical scrollbar is not being painted unless we mouse-over it or force a repaint.
    // Thanks to writing my own crappy control instead of downloading a decent one.
    listView.Invalidate(true);
    listView.Update();

    InitializeControls();
}

And this is why you should never write code while you’re high

I’m sorry, this post is far too technical. But other programmers will follow what I’m ranting about… I could post this to my programming blog, but since the topic is the effect of meth on the way I thought and the quality of the code I wrote, I’m posting it here instead.

For no particular reason, I was thinking of reusing the video player that I wrote a few years ago while I was still using, and it turned out to be a very bad idea. The thing is, I did a good job of the GUI. The player looks nice enough…

image

And it also has some cool features, not that anybody in their right mind would ever want to watch Depeche Mode at 25% of normal speed, or 200% – yes, it does have some goofy features, but they seemed important at the time. Anyway, I like the GUI, which has three different themes, and looks prettier than any of the other players I have. The problem is, I totally mixed the video player logic with the user interface. If I’d made a nice abstracted player class of some sort, it would be reusable, but as is, it would take many hours to separate the logic from the UI.

But that’s not the worst of it. The video I played now was higher resolution that my screen size, and my player would not play full screen. Whenever I tried, it played at “Auto 3/4 screen size” instead. (A calculated size that my player exposes as one of the possible options, but it’s not supposed to behave that way when you select full screen.) i.e. These…

image

So off I go, debugging back into the world of the over-engineered monstrosity I coded about three years ago while I was as high as a satellite:

        /// <summary>Common handler for zoom controls.</summary>
        /// <remarks>Each zoom control's Tag property is set to the
        /// numerical value of the appropriate MediaZoom.</remarks>
        private void Zoom_Click(object sender, EventArgs e)
        {
            var zoom = MediaZoom.ActualSize;
            var item = sender as ToolStripItem;

            if (item != null)
            {
                if (Enum.TryParse((string)item.Tag, out zoom))
                {
                    zoom = AdjustOversizeVideo(zoom);

                    var transitionToFullScreen = zoom == MediaZoom.FullScreen && MediaZoom != MediaZoom.FullScreen;

                    ZoomTo(zoom == MediaZoom.FullScreen ? MediaZoom == MediaZoom.FullScreen ? Settings.Default.MediaPlayer_PreviousZoom : zoom : zoom);

                    if (zoom == MediaZoom.FullScreen)
                        TaskbarList.MarkFullscreenWindow(this.Handle, transitionToFullScreen);

                    if (zoom != UI.MediaZoom.FullScreen || !transitionToFullScreen)
                    {
                        /* Unfortunately, we have to jump through some hoops to avoid losing the Windows
                         * Aero visual affects on the windows border.
                         * i.e. Need to recreate the window handle, but that will leave the Video window
                         * with an invalid handle for an owner, so first remove the owner, then restore
                         * it afterwards. */
                        if (!isAudioOnly && videoWindow != null)
                        {
                            if (videoWindow.put_Visible(OABool.False) == 0 && videoWindow.put_Owner(IntPtr.Zero) == 0 &&
                                mediaEventEx != null && mediaEventEx.SetNotifyWindow(IntPtr.Zero, 0, IntPtr.Zero) == 0)
                            {
                                reinitializing = true;
                                this.RecreateHandle();

                                ReinitializeVideoWindow();
                                mediaEventEx.SetNotifyWindow(this.Handle, WMGraphNotify, IntPtr.Zero);
                                reinitializing = false;
                            }
                        }
                    }
                    BringToForegroundAndActivate();
                }
            }
        }

Ohh, that’s some shitty code. It’s mostly crap, written on Windows 7 and working around a strange issue where resizing my player window would lose the Windows 7 Aero crap, so I had to jump through some hoops. None of that shit is necessary anymore.

So I set a breakpoint on the line that begins with “var transitionToFullscreen =”, thanking my former self for at least using verbose and descriptive variable names. Lo and behold, the zoom variable, which as I recall holds the user’s selected choice for the screen view size, is set to 3/4 screen. What the fuck? I know I chose full screen.

Oh dear. Since I coded this in another lifetime, and don’t recall what I was thinking after being awake for around a week, let’s go see what AdjustOversizeVideo does…

        private MediaZoom AdjustOversizeVideo(MediaZoom zoom)
        {
            // Adjust zoom if it is bigger than screen size
            var videoSize = VideoSize;
            var screenSize = Screen.FromControl(this).Bounds.Size;
            var factor = 1D;

            switch (zoom)
            {
                case UI.MediaZoom.ActualSize:
                    factor = 1D;
                    break;
                case UI.MediaZoom.DoubleSize:
                    factor = 2D;
                    break;
                case UI.MediaZoom.HalfSize:
                    factor = 0.5D;
                    break;
            }

            if (!isAudioOnly && videoSize != Size.Empty
                && (videoSize.Width * factor > screenSize.Width && videoSize.Height * factor > screenSize.Height))
            {
                zoom = UI.MediaZoom.AutoTwoThirdScreen;
            }

            return zoom;
        }

Fuck. In my infinite (lacking) wisdom of tweaking, I went to an awful lot of trouble to adjust the video size, for cases when the video size is bigger than the screen. In the event of the video size being greater than the screen size, I change the value of the variable that represents the user selection to be 3/4 screen size automatically – without even checking if the user actually wanted to go full screen. Why? Why not just use full screen anyway, when I know the video is bigger than the fucking screen? (Maybe because I was high.)

Anyway, this will fix it. Actually I also didn’t check for my two calculated video sizes being passed in. The solution is that the code should do nothing if any of those were passed in.

        private MediaZoom AdjustOversizeVideo(MediaZoom zoom)
        {
            if (zoom != MediaZoom.FullScreen &&
                zoom != MediaZoom.AutoThreeQuarterScreen &&
                zoom != MediaZoom.AutoTwoThirdScreen)
            {
                // Adjust zoom if it is bigger than screen size
                var videoSize = VideoSize;
                var screenSize = Screen.FromControl(this).Bounds.Size;
                var factor = 1D;

                switch (zoom)
                {
                    case UI.MediaZoom.ActualSize:
                        factor = 1D;
                        break;
                    case UI.MediaZoom.DoubleSize:
                        factor = 2D;
                        break;
                    case UI.MediaZoom.HalfSize:
                        factor = 0.5D;
                        break;
                }

                if (!isAudioOnly && videoSize != Size.Empty
                    && (videoSize.Width * factor >= screenSize.Width ||
                    videoSize.Height * factor >= screenSize.Height))
                {
                    zoom = UI.MediaZoom.AutoThreeQuarterScreen;
                }
            }
            return zoom;
        }

Hey, I guess I should be thankful that this thing works at all.

Here’s some more awfully messy code from the same form… I would never have written anything like this sober – with the video player and UI code all jumbled together.

And this is why you should never code while using drugs.

        private async void PlayMovieInWindow(string file)
        {
            Action<Exception> handleException = ex =>
            {
                var errorMessage = ex.Message;

                if (!string.IsNullOrEmpty(errorMessage) && ex.HResult != (int)HResult.E_FAIL)
                {
                    ex.Log();
                    MessageBox.Show(errorMessage, "Error playing file", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }

                Dispose();

                // Experimental (and probably unwise). Sets the now dangling singleton pointer to a new instance.
                Singleton<MediaViewer>.Reinitialize(new MediaViewer());
            };

            var hr = 0;

            if (string.IsNullOrEmpty(file))
                return;

            // Get the graphbuilder object
            graphBuilder = new FilterGraph() as IGraphBuilder;

            try
            {
                var hres = (HResult)graphBuilder.RenderFile(file, null);

                // Query for video interfaces, which may not be relevant for audio files
                videoWindow = graphBuilder as IVideoWindow;
                basicVideo = graphBuilder as IBasicVideo;

                // QueryInterface for DirectShow interfaces
                mediaControl = graphBuilder as IMediaControl;
                mediaEventEx = graphBuilder as IMediaEventEx;
                mediaSeeking = graphBuilder as IMediaSeeking;

                // Query for audio interfaces, which may not be relevant for video-only files
                basicAudio = graphBuilder as IBasicAudio;
                HasAudio = basicAudio != null;

                if (!Visible)
                    await WaitVisibleAsync();

                ReinitializeVideoWindow();

                // Is this an audio-only file (no video component)?
                CheckVisibility();

                // Have the graph signal event via window callbacks for performance
                hr = mediaEventEx.SetNotifyWindow(Handle, WMGraphNotify, IntPtr.Zero);
                DsError.ThrowExceptionForHR(hr);

                /* When the clip has no video, we remove the Form borders and add borders to the controls instead.
                 * The normal controls' height is not enough (causes the volume slider's thumb image to be clipped). */
                var controlsSize = new Size(0, isAudioOnly ? ControlsHeightAudioOnly : ControlsHeightNormal);

                if (controlsPanel.MaximumSize != controlsSize)
                    controlsPanel.MaximumSize = controlsSize;

                if (controlsPanel.MinimumSize != controlsSize)
                    controlsPanel.MinimumSize = controlsSize;

                if (!isAudioOnly)
                    GetFrameStepInterface();

                ZoomTo(mediaZoom = AdjustOversizeVideo(mediaZoom));
                InitializeZoomControls();
                Seeking = true;
                SetRate(Settings.Default.MediaPlayer_ResetPlayRateOnFileOpen ? 1.0D : Settings.Default.MediaPlayer_Rate);

                // Run the graph to play the media file
                hr = mediaControl.Run();
                DsError.ThrowExceptionForHR(hr);

                PlayState = PlayState.Playing;
                mute = VolumeController.Mute;
                currentVolume = Settings.Default.MediaPlayer_Volume;
                volumeSlider.Value = currentVolume;
                VolumeController.Volume = (int)volumeSlider.Value;
                UpdateVolumeControls();
            }
            catch (Exception ex) { handleException(ex); }
        }

        private async Task WaitVisibleAsync()
        {
            /* Filename is set and PlayMovieInWindowAsync is called before showing this form the first time.
             * This ensures that we start off with the right size, but we need to wait for the form to be visible
             * so that the video window has a valid window to which to render. */
            while (!Visible)
                await Task.Delay(1);
        }