Showing posts with label how to. Show all posts
Showing posts with label how to. Show all posts

Thursday, November 20, 2008

Make CMD Useful

Cmd is the command line processor in Windows. This post will describe a few of the absolutely required things you need to do to make cmd a useful tool.

Step #1: Stop using cmd and use Powershell.

I'm only half joking. Powershell is much more powerful and useful, so if you can use it, you really really should.

But if you can't or can't always use Powershell, here's the short list on how to make cmd useful:
  1. Use auto-completion (the Tab key)
  2. Use macros
  3. Setup colors
Auto-completion
Auto-completion is on by default. For example, go to C: and type "cd Win<Tab>". Cmd will automatically complete your thought and replace Win with WINDOWS. If that's not what you wanted, hit Tab again and it will go to the next likely match.

Macros
Macros are like abbrievations. They allow you to create a shorter name for something. For example, suppose you are looking for a certain file but you can't remember exactly where you put it on your file system. You'll be moving from one directory to another. Every time you arrive in a new directory you'll want to see if the file you're looking for is there. The command dir shows you that. But dir gives you a list with file names in one column and all kinds of information you don't care about in the other columns. That's not a very efficient use of space when all you care about is the file names.

What you really want to see is just the names, laid out in a many columned format. dir /w will do that. But you want it to pause after each page to give you a chance to read. dir /w /p does that. Finally, you want it to sort alphabetically with folders on top, then files. dir /w /p /O:GN does that.

Clearly, dir /w /p /O:GN is way too much to type over and over again as you navigate around. What we need is a macro so we can shorten that up. I use the name dw for my macro.

So how do we create macros? We use a program in cmd called doskey. First, create a text file and call it "doskeyMacros.cmd." In this file define all your macros, one per line. For example:
dw=dir /O:GN /w /p $*
Now, in cmd type:
doskey /macrofile="doskeyMacros.cmd"
This will load in all your macros. So you can now type dw instead of dir /w /p /O:GN.

There is still a problem. Who wants to execute that doskey command everytime they open cmd? We need that to happen automatically. To do this we will have to edit the registry. But first, create a text file called "cmdAutoRun.cmd" and type this in it:
@echo off
doskey /macrofile="C:\full\path\to\your\doskeyMacros.cmd"

Now we edit the registry. Start->Run->regedit.exe. Navigate to HKEY_CURRENT_USER\Software\Microsoft\Command Processor and in the AutoRun key (create it if it's missing) type the full path to your cmdAutoRun.cmd file enclosed in quotes.

Close and reopen cmd and your macros will be loaded.

Setup Colors
If you like the white on black you're done! I like the powershell look, so I change my colors in cmd. Right click on the window header and click "defaults" then switch to the "Colors" tab.

I set Screen Text to r:238, g:237, b:240 and Screen Background to r:1, g:36, b:86

And there you go! Cmd is now a bit more useful than it was before. Enjoy.

Monday, June 30, 2008

WPF ListBoxItem Double Click

The WPF ListBox does not have an event which fires when an item in the list is double clicked. As far as I can tell, there is no simple mechanism to accomplish this.

The best solution I've found is using the ListBox.MouseDoubleClick event. This event fires every time the mouse is double clicked anywhere in the listbox. This includes the background (if your items don't completely fill your list) and the scroll bar.

What you have to do is use the ListBox.InputHitTest method to get the element in the ListBox's Visual Tree which was clicked. Then you have to loop up the VisualTree until you find either a ListBoxItem (which means an item was double clicked), or the ListBox (which means an item was not double clicked).

Here's the code where ctlList is the ListBox:
void ctlList_MouseDoubleClick( object sender, MouseButtonEventArgs e )
{
UIElement elem = (UIElement)ctlList.InputHitTest( e.GetPosition( ctlList ) );
while ( elem != ctlList )
{
if ( elem is ListBoxItem )
{
object selectedItem = ( (ListBoxItem)elem ).Content;
// Handle the double click here
return;
}
elem = (UIElement)VisualTreeHelper.GetParent( elem );
}
}

I haven't been able to find another way to do this yet. There may be one flaw with this: If you use a DataTemplate in your list box, and a control in that template handles the MouseDoubleClick, I think it's possible the ListBox's event wont fire. Again, I haven't verified this, so it might work just fine.

If you know of a better way to get the double click on a list box item in WPF, please let me know!

UPDATE: Some commenters found a possible problem with the approach demonstrated in this post and offered an alternative method.

The problem is that it's possible the InputHitTest method could return something that is not a UIElement. This might happen if you had a Span element in your list box item template, for example.

The alternative method is to define a style for your list box's item container than includes an event hook for MouseDoubleClick.

<ListBox.ItemContainerStyle>
<Style TargetType="{x:Type ListBoxItem}">
<EventSetter Event="MouseDoubleClick" Handler="listBoxItem_DoubleClick" />
</Style>
</ListBox.ItemContainerStyle>

Thanks to Steve and Mark for pointing this out!


Monday, June 23, 2008

Custom Drop Downs

For at least the last year I have had an unhealthy obsession with drop downs. Custom drop downs really.

That is, combo boxes. But when you click on the down arrow, you get a list with check boxes. Or a tree control. Or a tree control with check boxes. Or a custom edit surface with a text box and an "Apply" button. Or anything you can possibly imagine, really.

All of these things are immensely useful. And if the story ended there I would never have become so obsessed. Sadly, the story continues. It turns out, such things are not exactly easy to build.

My first attempt involved Subclassing the .NET combo box. I got a working drop down in the end, but it had some odd behavior, and was overall just a huge hack.

Next I learned that Infragistics had a component that you could use to create custom drop downs. Put any control in it you want and you're off to the races. For a time, my obsession was sated. Until we learned that this component could not be resized after it was opened. To resize it, you had to close it and reopen it. This results in noticeable, seizure inducing, flickering. And that = bad.

Later, I learned about how easy this was to do with WPF. In fact, it was the very first thing I ever tried in WPF. But that doesn't help me much at work where our software is all WinForms.

Fortunately, this story has a happy ending! It turns out that .NET 2.0 introduced a component much like the Infragistics one but without the added suck!

It is called the ToolStripDropDown. Basically it's just a Form with special properties that make it behave like a popup. It doesn't steal focus when it opens. It closes as soon a user clicks off it. It can have a shadow border (if you'd like) like a context menu. You can override its default close behavior by using the Closing event and checking the e.CloseReason enumeration value and setting e.Cancel = true. And best of all, it can host any .NET control you want to put in it, as long as you host that control in a TreeStripControlHost.

I stumbled on it at jfo's blog here and immediately put it into use. In the process of trying to do some wacky custom stuff I found the same material from jfo's blog, but on msdn here which you might prefer. Both of those show example code for putting a treeview in a custom drop down.

I must have spent months working on this problem. I probably executed thousands of Google searches looking for solutions. All I ever came across was people using borderless forms and the deactivate event, which doesn't quite cut it for all cases. So when I finally discovered this, my obsession compelled me to post about it.

The only thing that I haven't tried yet is making a "suggest" combo box using this technique. This is a control in which when the user types, you execute a stored procedure and fill the drop down with matching items. The potential problem spot here is that you need focus on the text box so you can type, but you need the drop down to be open. I'm guessing you could pull this off with the ToolStripDropDown though. If anyone knows for sure, please leave a comment!

Thursday, February 21, 2008

Restore the Master Boot Record

When I got my laptop about 1.5 years ago one of the first things I did was install Linux on it. I can't remember now if I installed SUSE first, or went straight to Ubuntu. I'd been through Slackware, Debian, Suse, OpenSuse, SLED10, and Ubuntu in the past on other computers. In any event, I stopped with Ubuntu.

I've always had a few reasons for playing with linux
  1. To learn
  2. To feel cool, in a super nerd kind of way
  3. To not pay for software
Probably more or less in that order. My adventures with Linux ultimately ended with me deciding that I just wasn't that impressed. I wont go into the details here, because that is not what this post is about. The short list is:
  1. the file system is stupid (unless you're using GoboLinux),
  2. package managers are a double edged sword,
  3. the battery life on my Thinkpad in Linux sucked,
  4. it didn't have any apps that were far and away better than what I was using in Windows.
Keep in mind, I spent about 4 or 5 years coming to this conclusion, and I frequently still find myself drawn to the Open Source world. And for what it's worth, I don't personally view myself as a Microsoft fan boy. In any event, I retain the right to change my mind at any point and for any reason!

So I've had Ubuntu installed on my laptop, but I haven't used it in a year. Every now and then I would use it to pull songs off an iPod, that's about it. So it was just sitting there wasting 20Gb of my Hard Drive. This post is about how I removed it and restored the MBR. (really? you'd better get to the point then!)

Problem #1: Get rid of GRUB and replace it with the Windows boot loader

I'm pretty sure you do have to start here. If you remove the partitions first, GRUB will complain and refuse to let you boot into the remaining partitions... That happened to me once before, it wasn't nice.

How do you do this? It's easy, insert a Win XP disk and boot into the Recovery Console. Once there, execute fixmbr. When it warns you that "all hell will break loose, are you sure you know what you're doing?", tell it yes.

Problem #2: Umm... The Recovery Console wants an Administrator password. Leaving it blank doesn't work, and none of my passwords work... How do I get into the Recovery Console?

The first thing I tried was to go into Control Panel -> Performance and Maintenance -> Administrative Tools -> Computer Management -> Local Users and Groups -> Users. Once there, I right clicked on the Administrator and selected "Set Password..." then entered a password. Sadly, after rebooting back into the Recovery Console (and waiting forEVER while it loads...) it still wouldn't take my password.

So how do you fix it? Go back to Administrative Tools and this time go to Local Security Policy -> Local Policies -> Security Options. In the list, scroll to the bottom and find "Recovery Console: Allow automatic administrative logon." Double click and switch it to Enabled. Now you wont have to supply a password to get into the Recovery Console and you'll be good to go.

Problem #3: Remove the linux partitions and resize the windows partition.

I tried to use Partition Magic to do this, but it blew up with an error when I ran it, something about how some partition didn't have a drive letter. I think it was afraid of the IBM recovery partition.

How do you do this? I downloaded an Ubuntu install/live CD and used the gnome partition manager (gparted). First unlock the swap partition. This crashed gparted... But when I ran it again the unlock had succeeded, so everything seemed good. Then I deleted the swap and the linux partitions. Then I resized my windows data partition (fat32). Click Apply and go take a shower cause its gonna take a while.

After all that, I now have my drive space back and GRUB is gone. I still have two windows partitions C (ntfs) and D (fat32)... I wish I could convert D to ntfs but the only way I know to do that would be to copy all the data on D to some other drive, format D to ntfs, then copy all the data back. Maybe I'll do that when I get my backup solution in place. Actually, I'd like to get rid of D altogether. It made sense to have an applications partition and a data partition when I wasn't backing up my drive. But once I have a backup I'm not sure I still need two partitions.

How do you have your drive space setup?