VS Project Templates are Aggravating

I love Visual Studio, but some of the work I have to do to make things work the way I want is aggravating.  I just started a new WPF solution to follow along with a chapter in the book, and decided to give it a descriptive name so the directories would look all nice: "Chapter 8 – Styles".  Visual Studio assumes you want to use the solution name as the default namespace for all projects (unless you specify different project and solution names; then it uses the project name).  Of course, the namespace naming rules are more strict than file naming rules, so I end up with the lovely namespace name "Chapter_8___Styles".  Lame.

What’s worse is even if I go into project settings and change this, it only affects new files added to the project, so I have to go through the solution and change every namespace reference.  For the WPF application project template, that’s changes to 3 files before I can build and run.  It sure would be nice if I had an easy way to change this.

Posted in .NET, Rants | Leave a comment

"Out of Memory" Errors with GDI+ TextureBrush

The TextureBrush class lets you draw a shape using an image as a texture, giving you some control over the way the texture is tiled.  I encountered a forum post where a user was trying to use TextureBrush to draw sprites to the screen, but he was upset because as he moved the rectangle around it wasn’t moving the texture; the result was similar to having a tiled background covered up and viewed through a small window, then moving the window around.

I looked at the documentation, and saw constructors that let you specify a bounding rectangle.  I misinterpreted what the bounding rectangle did, and thought it specified where the top-left corner of the tiling should start.  The odd thing was introducing this rectangle led to a generic GDI exception with the message "Out of memory."  I found this curious.  At this point I realized that for the problem at hand, there was no reason to use a TextureBrush as opposed to Graphics.DrawImage, so I suggested this course of action.  Of course, I was curious why there was an out of memory exception, so I dug deeper.

Google was no real help; there were basically two forum threads about the problem, and none had a resolution (one suggested a possible accidental recursive paint handler, but that’s ridiculous since the second message wouldn’t be processed until the first completes and it had nothing to do with this case.)  I was about to turn to the MSDN forums when I dug about in the Connect area for any bug reports concerning this.  I found my answer, but it’s somewhat unsatisfactory.

Consider the example image below; it’s a 50×40 image lifted from the VS 2008 image library that represents 2 16×16 images:

Back_Forward

We can use a TextureBrush to draw rectangles using this image; by default the result is a silly tiling of back/forward buttons, and if we move the rectangle around it will look as if we’re sliding a window over a fixed pattern, as described above.  If we specify a bounding rectangle, only the part of the image within the bounding rectangle will be used as the tile.  For example, the following paint handler would tile only the left-facing arrow from the above image:

    Protected Overrides Sub OnPaint(ByVal e As PaintEventArgs)
        Dim g As Graphics = e.Graphics
        Dim boundRect As Rectangle = New Rectangle(7, 12, 15, 15)
        Dim brush As New TextureBrush(drawImage, boundRect)
        g.FillRectangle(brush, Me.ClientRectangle)
    End Sub

If the bounding rectangle that is specified is outside the bounds of the image that is to be tiled, you get the "Out of Memory" exception.  I don’t understand why there’s no error checking done; it would be trivial to check whether dstRect is outside of the bounds of image, but for whatever reason this was left out of the method and instead you get a cryptic error message that doesn’t really tell you what is wrong.

I hope this ends up on Google and anyone who has the problem in the future finds it helpful.

To demonstrate using TextureBrush in the manner the user wanted, the application below animates a left or right arrow back and forth across the form.  I don’t believe this is the best way to do this, and I’m almost certain that one of the Graphics.DrawImage overloads would be more appropriate, but there could be a use for this I have not forseen:

Public Class Form1

    Dim drawImage As Image
    Dim boundRect As Rectangle
    Dim leftPoint As New Point(7, 12)
    Dim rightPoint As New Point(28, 12)
    Dim tileSize As New Size(15, 15)
    Dim viewRect As New Rectangle(New Point(0, 0), tileSize)
    Dim goingLeft As Boolean = False

    Public Sub New()

        ' This call is required by the Windows Form Designer.
        InitializeComponent()

        ' Add any initialization after the InitializeComponent() call.

        drawImage = Image.FromFile("Back_Forward.png")

        Dim timer As New Timer()
        timer.Interval = 100
        AddHandler timer.Tick, AddressOf TimerOnTick
        timer.Start()

        boundRect = New Rectangle(rightPoint, tileSize)
    End Sub

    Protected Overrides Sub OnPaint(ByVal e As PaintEventArgs)
        Dim g As Graphics = e.Graphics

        Dim brush As New TextureBrush(drawImage, boundRect)
        brush.TranslateTransform(viewRect.X, viewRect.Y)
        g.FillRectangle(brush, viewRect)
    End Sub

    Private Sub TimerOnTick(ByVal sender As Object, ByVal e As EventArgs)
        Dim increment As Integer

        If goingLeft Then
            increment = -10
        Else
            increment = 10
        End If

        viewRect.X += increment

        If viewRect.X <= 0 Then
            goingLeft = False
            boundRect = New Rectangle(rightPoint, tileSize)
        ElseIf viewRect.X + viewRect.Width >= Me.ClientRectangle.Width Then
            goingLeft = True
            boundRect = New Rectangle(leftPoint, tileSize)
        End If

        Me.Invalidate()
    End Sub

End Class
Posted in .NET | 3 Comments

I’m trying Windows Live Writer

From a post on lifehacker I saw that Picasa had labeling/tags (which I didn’t know existed and ended up buying Photoshop Album to make up for).  However, the next post pointed me to Windows Live Photo Gallery, which doesn’t have quite as much polish as Picasa but makes labeling pictures part of the UI instead of a secondary feature.  This Windows Life software is pretty nice, and made this blog post (if nothing goes wrong!).

Now I have to tag all of my pictures again :/

Posted in life | Leave a comment

Managed DirectX Documentation is Installed in VS 2005 Help

I’m working on some research that involves managed DirectX, and after I read a few chapters of the book Managed DirectX 9 Graphics and Game Programming (which I really recommend — more later) I wanted to look at the documentation for some of the classes that were discussed to get a more in-depth understanding. Try as I might, I couldn’t find the documentation, so I turned to Google for answers. The only reasonably decent hits I found were forum posts dated in 2005 discussing how it was still beta and there was no documentation. Useless. I had almost completed an email to Tom Miller, the author of the book, when I noticed the sentence, “I have looked in the VS 2008, VS 2005, and Windows SDK help…” was false. I had looked in VS 2008 and Windows SDK, but not VS 2005.

So, I’m continuing my series of posts inspired by things I tried to use Google to find but failed. If you want to know where the Managed DirectX documentation is in the March 2008 DirectX SDK, look in the Visual Studio 2005 help.

It’s possible I overlooked an installer option but I’m too lazy to check again.

Posted in .NET | 1 Comment

Making a control that accepts arrow keys

I’m working on a project with a custom control on which I want to implement the arrow keys.  I was completely mystified as to why I wasn’t getting KeyUp events when I pressed the arrow keys. I started using Reflector to hunt for where the event was raised in controls I was familiar with, and I stumbled upon the Control.IsInputKey method.  What does this method do? The remarks told me what I needed to know.

Call the IsInputKey method to determine whether the key specified by the keyData parameter is an input key that the control wants. This method is called during window message preprocessing to determine whether the specified input key should be preprocessed or sent directly to the control. If IsInputKey returns true, the specified key is sent directly to the control. If IsInputKey returns false, the specified key is preprocessed and only sent to the control if it is not consumed by the preprocessing phase. Keys that are preprocessed include the TAB, RETURN, ESCAPE, and the UP ARROW, DOWN ARROW, LEFT ARROW, and RIGHT ARROW keys.

I had no idea this existed. It turns out to get events from these keys in any control, you have to override this method and return true. Here’s an example control in C# 3.0 to demonstrate (conversion to C# 2.0 is trivial; just make a backing field for the property). When it has focus (you’ll know because it is white instead of gray), if you push an arrow key the text name of the key you pressed is displayed. If you press any other key, you’ll get “Unknown”. The documentation does seem a little off, as I’m not doing anything special for Esc or Return but they still cause the events to be raised. Still, if you set CustomInput to false, you won’t ever get an arrow key message displayed (the arrow keys seem to move the focus).

using System;
using System.Windows.Forms;
using System.Drawing;

namespace TestIsInput
{
    public class InputField : Control
    {
        public InputField()
        {
            this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);
            this.SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
            this.SetStyle(ControlStyles.Selectable, true);
        }

        public bool CustomInput
        {
            get;
            set;
        }

        protected override bool IsInputKey(Keys keyData)
        {
            if (CustomInput)
            {
                bool isInput = false;

                switch (keyData)
                {
                    case Keys.Up:
                    case Keys.Down:
                    case Keys.Left:
                    case Keys.Right:
                        isInput = true;
                        break;
                    default:
                        isInput = false;
                        break;
                }
                return isInput;
            }
            else
            {
                return base.IsInputKey(keyData);
            }
        }

        protected override void OnPaint(PaintEventArgs e)
        {
            base.OnPaint(e);

            Brush backBrush = this.Focused ? Brushes.White : Brushes.LightGray;

            e.Graphics.FillRectangle(backBrush, this.ClientRectangle);
            ControlPaint.DrawBorder3D(e.Graphics, this.ClientRectangle, Border3DStyle.Sunken);
            StringFormat f = new StringFormat(StringFormatFlags.NoWrap);
            f.Alignment = StringAlignment.Center;
            f.LineAlignment = StringAlignment.Center;

            e.Graphics.DrawString(this.Text, this.Font, Brushes.Black, (RectangleF)this.ClientRectangle, f);
        }

        protected override void OnKeyUp(KeyEventArgs e)
        {
            base.OnKeyUp(e);

            switch(e.KeyCode)
            {
                case Keys.Up :
                    this.Text = "Up";
                    break;
                case Keys.Down :
                    this.Text = "Down";
                    break;
                case Keys.Left :
                    this.Text = "Left";
                    break;
                case Keys.Right :
                    this.Text = "Right";
                    break;
                default :
                    this.Text = "Unknown";
                    break;
            }

            this.Invalidate();
        }

        protected override void OnEnter(EventArgs e)
        {
            base.OnEnter(e);
            this.Invalidate();
        }

        protected override void OnLeave(EventArgs e)
        {
            base.OnLeave(e);
            this.Invalidate();
        }
    }
}

So, if you need to accept input from one of those keys, keep in mind that you need to override IsInputKey. This was completely new to me!

Posted in .NET, tricks | 1 Comment

Some Consistency, Please

Let’s look at the signatures for constructors of ArgumentNullException and ArgumentException:

public ArgumentException(
	string message,
	string paramName
)
public ArgumentNullException(
	string paramName,
	string message
)

Notice how they both take two string parameters, but each has opposite order. This drives me bonkers and I can never get the right one. I kind of wish MS would make a breaking change and fix it one way or the other.

Posted in .NET | Leave a comment

Mixing numbers and replacement strings

This is yet another thing that I found took me too long to find on Google. I’m using the .NET regular expressions, and looking to replace values in a string with numbers, and I need to use the special $1 symbols to keep some of my capture groups around.

So, suppose I have the text:
something.2005.txt

The pattern:
(.*)2005(.*)

And the replacment string:
$12008$2

This produces the undesirable result $12008.txt. Why? Well, the $1 has to be escaped in some way. Whatever it is that scans for variables is obviously interpreting this as $12008 instead of $1; either that’s invalid or the group doesn’t exist so it just uses the text. Personally I think I should be getting “2008.txt” in this case, as a raw $ should take $$ to create, but I won’t complain.

The solution? Surround the number of the group index in brackets:
${1}2008$2

Posted in .NET, tricks | 1 Comment

Windows ComboBox keyboard shortcuts

I use the keyboard a ton, and I found myself almost twice a week having to look up the keys to drop the menu in a ComboBox control. The right stuff tends to be buried in large documents, and I wasted a lot of time digging through them. No more! Now I can just check my blog, and hopefully Google will index it and others can find it more quickly.

F4 works, and so does ALT + DOWN. I like F4 better, because it can’t accidentally activate the window’s menu.

Posted in tricks | Leave a comment

So I’m getting married

7 years, 8 months, and a week ago I made a decision that has affected my life more than any other I have made, and asked a girl if she would go out with me. Since then, we’ve been through a lot. We’ve had some awful fights and occasionally said things to each other we didn’t mean, but nothing has changed the fact that since that day I’ve been completely certain that this girl was perfect for me.

I’ve met some interesting women in my still short lifetime, but ever since I met this one I have never desired another woman. We’ve put this day off at the advice of others for what feels like decades, but is honestly perhaps 2 years longer than when I think we were tired of rationalizing waiting.

Out of all that I have done, and out of all of the accomplishments that others tell me I should be proud of, I don’t believe there will ever come a day when I look back at my life and place anything over what is going to happen this Saturday. I love her, and this is the final step in the process of declaring my love but the first step in proving this love.

I am horrible at displaying affection, and I hope that I can make her know how happy I feel about this change in our lives.

Posted in life | 1 Comment

I have the worst luck with shipping

One of the things I like best about living in a large city is I don’t have to order things online so much anymore. It’s not that I’m worried about my identity getting stolen or that I don’t trust the internet. It’s just that I can’t remember the last time I ordered something online and received it without incident.

Often, it’s not the company I order from. I know better than to use dodgy merchants, and tend to only use big guys like Amazon.com. The point of failure is always the shipping. To date, DHL is the only major shipping company that hasn’t screwed up the complicated task of “put this box on the doormat”. Next most successful is the US Postal Service. The worst? I can’t figure out if it’s UPS or FedEx. I do everything I can to avoid using either company, but unfortunately most major vendors choose the carrier that has the best price at the moment so you don’t get any say in the matter.

Why the rant? I placed an order for a book and two CDs on Wednesday morning. I need the book for research at work, and one of the CDs is needed for my wedding which is approaching very quickly. Since I leave Tuesday, I didn’t want to rely on free shipping or standard ground. Next-day was too costly, but 2-3 day ground seemed most reasonable, with an expected arrival date of Friday (today). I came home and asked the people in my apartment complex’s front lobby if any packages had been left for me, and they said no, nothing from FedEx today. I figured the delivery guy must have left it on the doorstep. Nope, no boxes. Did he even leave a sticker? Nope. Hmm, I suppose he just didn’t make it by today right?

No, the tracking system explains that “Resident was not present. Package not delivered.” This is not inaccurate. I was at work, because for some reason that eludes me most home delivery services only deliver during hours that the majority of the population is working. The procedure in my apartments is that when a resident is not home, the shipping people leave the package with the front desk. This has worked fine with the USPS so far; I’ve had two deliveries that went off without a hitch (so long as you don’t count “bending a package marked ‘Do not bend’ that had thick cardboard inside and took significant effort to bend” as a hitch). There are two suspicious things here.

  1. It is the policy of every major shipper to place a “Hey you weren’t here” label on your door when you weren’t there. This policy exists for people who don’t use the internet to track packages and to prove that drivers are actually following their routes instead of goofing off. You can’t claim the driver didn’t come by because the sticker is right there. I had no sticker, so I asked the lobby if anyone else got FedEx stuff today.
  2. The front lobby saw no FedEx trucks today.

So, I’m left with the notion that the driver had a tight quota, the cruddy traffic lights in this area slowed him down, and since no one is home at 11AM on a weekday anyway he played “Whose package can I safely pretend they weren’t home with today?”. Unfortunately for him, I’ve been selected for this game in the past.

I complained to FedEx and for a change I’m actually at least getting them to investigate what happened. It won’t do me any good, because they don’t ship on weekends. I paid 100% more than the cost of standard ground to receive my package before the weekend, and I did not receive services that match the premium I paid. The real shame here is there’s no one to complain to. In the past, I’ve complained to the shipping company, but I never get a refund of any sort nor do I ever get the package any faster. I can’t complain to the vendor, because once they put the label on the package it’s not their fault. I have complained to vendors in the past, but all I get is smug “Whatever just because USPS is cheaper, faster, and more reliable for your packages doesn’t mean we’re even going to consider letting you pay a premium to use them instead. You will get FedEx or UPS and you will like it.”

I understand this situation is kind of not a big issue, since honestly if the driver did visit (of which he left no evidence) then he is following one of the protocols (he might not know the front lobby holds packages for residents even though they have to open the gate for him). But I have a history of horrible service with the big shippers. If you care to be bored, continue reading and I will detail them so maybe some sympathetic employee will send me the $5 it would take to make me feel like the situation was resolved.

Incident 1 – FedEx Next-Day is not so fast

I was working at one of my first jobs about 6 years ago. We were assembling computers for this company that was contracted by the state government to get students to assemble computers for much cheaper than the cost of constructing a factory and hiring people that wanted benefits. It was a pretty good idea, and paid way better than anything else I could get at the time. Our paychecks came via FedEx from some state agency, and of course the first check had some hang-ups and they ended up a week late. To compensate, they sent the checks via FedEx next-day once they got them working. The day of delivery came, and as the end of the day approached we got more and more curious about the whereabouts of our checks. We went to the front of the building to find a “You weren’t here” sticker attached to the front door. We asked the office workers if they saw the delivery guy (they worked in plain sight of the door) and a few of them mentioned he just kind of walked up to the door and put a sticker on it. He didn’t even fill it out on the spot; he had it pre-filled so he could just stick it on the door and run.

This guy had no intent of delivering the package; for some reason he didn’t want to waste the time.

Incident 2 – UPS Strikes out too

My first Dell laptop died the third day I had it. Actually, just the display died, but still it’s not much use without a display. I was obviously still under warranty, so a technician came over and fiddled with it and decided to order some parts to try and fix it. The parts were sent UPS next-day. Since it was near the end of Summer, we were home all that day, and in fact we had the front door wide open because it was a nice day outside. Around 4:45 I started getting kind of worried that the UPS guy might not show up, so I checked the tracking status. “Resident not home – could not deliver”. At 10:45. When we were sitting on the front porch and would have noticed a UPS truck. There was no sticker, and in fact no sighting of a UPS truck at all by the 3 people that were home at the time. Once again, I got a driver who was busy doing something else.

Several Incidents – FedEx

I had several of the same problems with FedEx when I lived in Tennessee. It was kind of a small town, and the first time I was ever making decent money, so I ordered stuff online frequently. I believe FedEx handled 6 of my packages, and I believe I received 1 without incident.

The first one I didn’t mind. It was a piece of computer junk that cost too much, so they wouldn’t leave it on the doorstep without my signed consent. I signed the door-handle thing they gave me and checked the box “Please leave it on my doorstep if someone steals it it is my fault”. They replaced it with a copy of the same label. I signed it again. This time, they replaced it with “This was the final attempt now you have to come to pick it up.” Well, it wasn’t that bad since the facility was actually half a mile from where I worked, but they were open the odd hours of 2:00-4:00 only so it took an extra day to get it.

I figured after that they had my signature on file and I’d get the next thing just fine. It was a cheap book and didn’t require signature. Except they left the door handle thing. I called and complained, but I was told that it was FedEx policy that they couldn’t leave things at apartments. Fine, I won’t fault someone for following policy. At least they were leaving notices they’d been there, right? I prepared myself to have to always pick up the packages myself from the people I was paying to deliver things to my house.

I found a loophole to their policy. If you live on the second story or higher, and your package weighs at least 30 lbs., the deliveryperson can’t be bothered to bring it back down to the truck. This was the only package that I had successfully delivered to my house.

UPS gave me no troubles, but the only thing they delivered was a this stupid 50 lb. CRT monitor whose box was so big it barely fit in the door. I suspect this has something to do with why they didn’t follow policy.

DHL delivered 4 packages without incident.

Incident 4? – Don’t ever next-day USPS from Tennessee to Mississippi

From time to time, I had the need to ship something home from Tennessee in a hurry. Since I no longer trusted UPS or FedEx, I tried using USPS and paying for next-day service. Except somehow, the package would always get delivered like this: Knoxville, TN -> Mobile, AL -> Charlotte, NC (MISROUTED) -> Mobile, AL -> Jackson, MS -> Destination. Of course, the misroute from Alabama to North Carolina caused the package to take longer than the guaranteed 24 hours.

I shipped two packages next-day. This happened twice. The only reason I’m happy is when I brought the tracking printout as proof that the package took longer than 24 hours to deliver, my money was refunded. I completely forgive and still trust the USPS because I know when they screw up they are willing to eat the cost of their screwup.

I’d comment on how they ship things but nobody uses USPS for shipping for some reason. I get my mail every day without incident though so I don’t really need a sticker to show the letter carrier came by. I guess there’s something about being reliable and cheap that scares away the big vendors.

Finally I am done

So in short, the reason I am so hacked off and motivated to waste an hour documenting my anger is because I have horrible luck with shipping companies. Over the last 7 years, in three different states, I have had the same problems happen with pretty much 4/5 of the packages I have shipped to me via FedEx and UPS. I have no one to complain to, and when they screw up your delivery they don’t have any obligation to make it right. I pay a premium in instances where I consider my package high priority, and it does nothing to guarantee that my package will make it on time because if the driver decides he’s not going to visit my house I’m just out of luck. I think I should at least get the $3-$5 that I paid for the expedited shipping back if the driver didn’t leave a label. There’s no way to scam that and get your package faster; 3-5 day is the next step up, and if you pay for 2-3 day, but purposefully make sure you can’t pick up the package until the 4th day you have gained nothing.

Posted in Rants | 1 Comment