Wednesday, February 08, 2006

Visual Studio Hacks posted a new "Ask the Pros" article detailing some of the pros' favorite keyboard shortcuts. Check it out here. There are quite a few good shortcuts in there, like the Comment and Uncomment code blocks (Ctrl-K-C and Ctrl-K-U respectively). Some of my new favorites have to do with additional functionality provided by snippets in Visual Studio 2005, specifically the Edit.SurroundWith command, which is Ctrl-K-S by default. It makes it a cinch to add code to new regions, much like the Visual Studio 2003 Region add-in. As the article says, a nice way to learn more shortcuts is to check them out in Visual Studio for yourself - under Tools, Options, and Keyboard.

Try them yourself and become a true Keyboard Ninja!

posted on Wednesday, February 08, 2006 7:53:13 AM (Central Standard Time, UTC-06:00)  #    Comments [0]
 Monday, February 06, 2006

There has been a lot of talk recently about VMware releasing a version of their VMware server product for free. The beta version was released today, though the big news to me is that there are a multitude of free "pre-built, ready-to-run virtual appliances" available for use with VMware server. Of course, as these "appliances" are free, don't expect to see a Windows VM image. It WOULD be a good way to easily play around with different versions of Linux like Red Hat or Ubuntu. I'm curious how Microsoft will respond with their Virtual PC product.

posted on Monday, February 06, 2006 12:43:11 PM (Central Standard Time, UTC-06:00)  #    Comments [0]
 Friday, February 03, 2006

Check this out.

For those who are unfamiliar, Lisp is a functional language often associated with AI programming. I took an AI class in college and Lisp was the primary language used to explain the AI concepts. It is very cryptic to look at if you haven't ever used it, because it makes heavy use of parentheses. It also makes a lot of use of recursion. If I remember correctly, it doesn't actually have any looping structure (i.e. while, for, etc.) other than making use of recursion. It can really help with looking at common programming problems in a different way.

CORRECTION: After looking over the book just a little bit, it appears that Lisp DOES have loop operators in addition to recursion. I wonder if it was one of those academic things, sort of like how they don't tell you about the STL until you've made it through the data structures class and coded your own linked list, binary search tree, and graph. Oh well.

posted on Friday, February 03, 2006 4:04:14 PM (Central Standard Time, UTC-06:00)  #    Comments [0]
 Sunday, January 29, 2006

I just finished reading an article from Hacknot that describes the predicament that developers are in while attempting to define a software product's requirements as specified by the user. Here is a quote from the article that I find quite telling:

In their efforts to be "user focused", guided by simplistic notions of "usability", many managers and programmers uncritically accept whatever users tell them as a mandate. "The customer is always right" makes a nice slogan but a poor substitute for critical thought. If you want to deliver a product that is genuinely useful, it is important to moderate the user feedback you receive with your own knowledge of usability principles, and to seek independent confirmation of the information they relate. For it is a fact seldom acknowledged in the text books that users are frequently uninformed, mistaken or deliberately deceptive.

I work in an organization which is highly user focused, as opposed to product focused. Essentially, whatever the customer says goes.

Here is a little background: My employer has been relatively slow in adopting new technologies. A large portion of the software that runs is what might be called "legacy" code (i.e. COBOL, JCL, and even Assembly); however, there is still new development being written in that environment. Thankfully, much of the front-end has been moved to an intranet base. Quite recently, there has even been a push to Windows Forms development with .NET.

The problems that the users have is that they do their business work in three different environments at a bare minimum: green screens, intranet webpages, and Windows applications. When my company first began the move to intranet pages, the user requirements would basically be, "make it look like what we have." They had no idea of what the capabilities were with webpages. The first few webpages all looked just like their green screen counterparts, except that they were black text on a white background, instead of green text on a black background.

Today, with some of our new development in .NET, we're running into the same problem again. The users know webpages and their capabilities, but not those of Windows applications. There is a fundamental misunderstanding about what these new applications are. They want a button for everything, when a toolbar or menustrip might be more appropriate. I've really been encouraging my users to look at examples like Office applications for ideas while thinking about what they want the new software to do. Some might argue that Office applications aren't the best example, but the truth is that Office is one application that the users really know.

As software developers, I really think that, to be user focused, you can't always give the user exactly what they asked for. Alternatives can, and often are, much better in the end. The difficult part is communicating that. Is this a common scenario for others? (I know it is!)

posted on Sunday, January 29, 2006 7:53:16 PM (Central Standard Time, UTC-06:00)  #    Comments [0]
 Thursday, January 26, 2006

Check this out.

"The A to Z of Programmer Predilictions" is a funny little article that categorizes programmers into various stereotypes, most of which are surprisingly accurate. As I read through the descriptions, I started spotting people in my organization. Though I (and everyone else) can probably fit into a variety of different personas described there, I probably am most like "Zealous Zack." I DO download all of the betas (even at work!) and, when someone blogs about the "Next New Thing," I've got the download started before I've finished reading the post about it.

Speaking of, I need to download the newest WinFX bits...

(via Digg)

posted on Thursday, January 26, 2006 7:41:44 AM (Central Standard Time, UTC-06:00)  #    Comments [0]
 Tuesday, January 24, 2006

I've been experimenting with the FlowLayoutPanel. There are a few catches to using it that can cause some confusion. In my case, the confusion came from anchoring and/or docking. I was dynamically adding some listviews to my panel to display results of data. There would be one to many listviews depending on the type of report the user requested. Having come from developing in ASP, it is still my first inclination to just create a table for each section and add it. The flow of the HTML would handle the rest. I figured I could get a FlowLayoutPanel and just add controls as needed and get similar functionality.

That was true to a degree; however, anchoring doesn't perform as you might think. If you anchor to the left and right after setting the width, if there is only one control in the panel, it will drop down to a zero width. The actual behavior is that, if you anchor to the left and right, it will assume the width of the widest control already on the FlowLayoutPanel. The same is true if you set the Dock property to Fill. Check out this article on MSDN to see what I mean. The behavior also depends on the FlowDirection property.

Everything works great if your panel isn't going to resize itself. You can just set the first control's width to the width of the panel minus a few pixels and Dock.Fill everything else. If you want it to resize as you resize the form, though, it is looking like you'll have to handle some layout events.

Here's some code to get you started:

Public Class Form1

    Private WithEvents flowPanel As New FlowLayoutPanel()

 

    Public Sub New()

        ' This call is required by the Windows Form Designer.

        InitializeComponent()

 

        ' Add any initialization after the InitializeComponent() call.

 

        ' DON'T FORGET THESE LINES!

        flowPanel.Dock = DockStyle.Fill

        flowPanel.FlowDirection = FlowDirection.TopDown

 

        Me.Controls.Add(flowPanel)

 

        AddListView()

        AddListView()

    End Sub

 

    Private Sub AddListView()

        Dim totalList As New ListView()

        totalList.View = View.Details

 

        ' If first control, then set a width; otherwise, Dock.Fill it.

        If Me.flowPanel.Controls.Count > 0 Then

            totalList.Dock = DockStyle.Fill

        Else

            totalList.Width = Me.flowPanel.Width - 10

        End If

 

        totalList.Columns.AddRange(New ColumnHeader() _

            {GetColumnHeader("Col 1"), _

            GetColumnHeader("Col 2"), _

            GetColumnHeader("Col 3")})

 

        Dim item As ListViewItem = totalList.Items.Add("Row 1")

        item.SubItems.Add("1234.00")

        item.SubItems.Add("5678.00")

 

        item = totalList.Items.Add("Row 1")

        item.SubItems.Add("1234.00")

        item.SubItems.Add("5678.00")

 

        item = totalList.Items.Add("Row 1")

        item.SubItems.Add("1234.00")

        item.SubItems.Add("5678.00")

 

        Me.flowPanel.Controls.Add(totalList)

    End Sub

 

    Private Function GetColumnHeader(ByVal text As String) As ColumnHeader

        Dim col As New ColumnHeader()

        col.Text = text

        Return col

    End Function

 

    Private Sub flow_Layout(ByVal sender As Object, _

        ByVal e As System.Windows.Forms.LayoutEventArgs) _

        Handles flowPanel.Layout

 

        Dim flowLayout As FlowLayoutPanel = DirectCast(sender, FlowLayoutPanel)

        If flowLayout.Controls.Count > 0 Then

            flowLayout.Controls(0).Width = flowLayout.Width - 10

        End If

    End Sub

End Class

Here's MSDN another article that gives some basic information on the FlowLayoutPanel.

posted on Tuesday, January 24, 2006 8:09:23 AM (Central Standard Time, UTC-06:00)  #    Comments [0]
 Saturday, January 21, 2006
I know many people have seen the excellent Cropper tool for grabbing screenshots. I found another tool very similar to it by the maker of TaskSwitchXP called WinSnap. It gives a few additional features like adding a dropshadow or rotating the image. The good thing is that it is still a very small application. Here is a screenshot I pulled with it:



Cool shadow effect, huh? I'm giving it a try right now. It seems to work well for me so far.

posted on Saturday, January 21, 2006 12:39:15 PM (Central Standard Time, UTC-06:00)  #    Comments [0]
 Friday, January 20, 2006
I discovered today that the new FtpWebRequest/FtpWebResponse classes might not be the best options for connecting to FTP servers, at least unless you're in control of the FTP server. The classes make some assumptions about the remote FTP server, like the server's file system.

I was working on converting an application that sends files to a customer's FTP server and I thought I would use the FtpWebRequest and FtpWebResponse classes. The problem is that the customer's FTP server is running on VMS! I know, that isn't very common, but the file system in VMS is NOT like Windows or Unix. Folders aren't separated by "\" or "/" so when a change directory (CWD) command is sent, you can't assume that folders are delimited by one of those characters! When you try to list the files in the directory, it sends a CWD command to change directory to the current directory (why, I don't know) with a "/" at the end. Predictably, I get a 550 error back with a "file specification syntax error."

I haven't found a workaround other than coding it myself. If anyone has any suggestions, let me know.


NOTE: I used Ethereal to observe what was being sent and received. It is a great utility for watching network traffic.
posted on Friday, January 20, 2006 4:03:07 PM (Central Standard Time, UTC-06:00)  #    Comments [0]
Here is a little gotcha with some changes to the way that .NET 2.0 handles COM interoperability. You probably won't run into this problem unless you're converting a project from 1.1 to 2.0.

We had a little command line application that took did some background processing for us that was written in 1.1. We moved it over to 2.0 because we wanted to take advantage of the new FTP capabilities in the 2.0 framework (see FtpWebRequest/FtpWebResponse). If you add a reference to a COM object in .NET 1.1, the typical object that you'll create on the managed side will have a "Class" suffix (i.e. MyCoolComObjectClass as opposed to MyCoolComObject). If you convert to 2.0, it doesn't change that code either...

However, you might see an exception like this if you start using it:

"System.InvalidCastException: Unable to cast COM object of type 'System.__ComObject' to class type 'ComLibrary.MyCoolComObjectClass'. COM components that enter the CLR and do not support IProvideClassInfo or that do not have any interop assembly registered will be wrapped in the __ComObject type. Instances of this type cannot be cast to any other class; however they can be cast to interfaces as long as the underlying COM component supports QueryInterface calls for the IID of the interface."

What do you do? Take the class off the end of your COM object (MyCoolComObjectClass -> MyCoolComObject).

That's it.

AUTOMAGICAL!

(Thanks to this forum posting for the info!)

posted on Friday, January 20, 2006 10:57:24 AM (Central Standard Time, UTC-06:00)  #    Comments [0]