Jay Harris is Cpt. LoadTest

a .net developers blog on improving user experience of humans and coders
Home | About | Speaking | Contact | Archives | RSS
 
Filed under: Programming | Tools | Visual Studio

Most of our Visual Studio solutions contain hundreds of files (classes) organized neatly into dozens of folders (namespaces), but despite all of this organization the vertical content size of the Solution Explorer can get quite large. Finding a particular file when the majority of the tree is expanded is tedious and time-consuming, considering it should be a simple effort of less than five seconds. Fortunately, all of this is solved by the click of a button (assigned to handy macro).

The most useful macro for Visual Studio that I have ever encountered (and in the running for most useful VS tool, period) is the CollapseAll macro authored by one current and one former colleague, Dennis Burton and Mike Shields. In a quick XP effort, Dennis and Mike created a handy macro that recursively collapses the entire Solution Explorer tree down to just the solution and its projects.

With the tree collapsed, it is easy to find that desired file.

The macro is functional in all versions of Visual Studio for the Microsoft.Net framework, including Visual Studio 2003, Visual Studio 2005, and Visual Studio 2008.

CollapseAll Macro for Microsoft Visual Studio
Dennis Burton & Mike Shields | Published with Permission

Imports System
Imports EnvDTE
Imports System.Diagnostics

Public Module CollapseAll
    Sub CollapseAll()
        ' Get the the Solution Explorer tree
        Dim UIHSolutionExplorer As UIHierarchy
        UIHSolutionExplorer = DTE.Windows.Item(Constants.vsext_wk_SProjectWindow).Object()
        ' Check if there is any open solution
        If (UIHSolutionExplorer.UIHierarchyItems.Count = 0) Then
            ' MsgBox("Nothing to collapse. You must have an open solution.")
            Return
        End If
        ' Get the top node (the name of the solution)
        Dim UIHSolutionRootNode As UIHierarchyItem
        UIHSolutionRootNode = UIHSolutionExplorer.UIHierarchyItems.Item(1)
        UIHSolutionExplorer = Nothing
        UIHSolutionRootNode.DTE.SuppressUI = True
        ' Collapse each project node
        Dim UIHItem As UIHierarchyItem
        For Each UIHItem In UIHSolutionRootNode.UIHierarchyItems
            'UIHItem.UIHierarchyItems.Expanded = False
            If UIHItem.UIHierarchyItems.Expanded Then
                Collapse(UIHItem)
            End If
        Next
        ' Select the solution node, or else when you click
        ' on the solution window
        ' scrollbar, it will synchronize the open document
        ' with the tree and pop
        ' out the corresponding node which is probably not what you want.
        UIHSolutionRootNode.Select(vsUISelectionType.vsUISelectionTypeSelect)
        UIHSolutionRootNode.DTE.SuppressUI = False
        UIHSolutionRootNode = Nothing
    End Sub

    Private Sub Collapse(ByVal item As UIHierarchyItem)
        For Each eitem As UIHierarchyItem In item.UIHierarchyItems
            If eitem.UIHierarchyItems.Expanded AndAlso eitem.UIHierarchyItems.Count > 0 Then
                Collapse(eitem)
            End If
        Next
        item.UIHierarchyItems.Expanded = False
    End Sub
End Module

Based on code from Edwin Evans

Here, the macro is so popular that it is a part of our default developer’s build for every new machine, and is conveniently assigned to a toolbar button. The default button icon list contains an Up Arrow (in the Change Button Image menu when customizing the toolbar) that seems quite appropriate. That little button has saved us all from a lot of pain, five seconds at a time.

Wednesday, 31 May 2006 10:19:55 (Eastern Daylight Time, UTC-04:00)  #    Comments [2] - Trackback

Filed under: Business

Steve Yegge blogged an interesting article, yesterday, on (Not) Managing Software Developers. I feel that it is a very interesting article, and definitely worth a read. I agree with most of it, though I do warn you that it should be read with an open mind to prevent feeling “slighted” if you are the managing type.

As the title proclaims, he covers how to (not) manage your developers, advising managing types to be open to new processes and practices, be reflective in a quest for constant self-improvement, and above all to be empathetic–developers are people, too. As his posts often are, his pessimism starts at “We are all bad managers!” to aid in his self-improvement quest, forcing an ego-driven drive to improvement. Again, this is not for everyone, as he already has a few flames in his comments, though perhaps if you are on the flaming side, you may most benefit from his words; everyone should pursue self-improvement if for only to improve their craft.

One modification that I would make is that this is not just for managers. It applies to everyone on the quality assurance team, too. (I am sure it applies to everyone, everywhere, but I only speak of what I know.) We all-to-often attack our developers–even if unintentionally, and if only from their point of view–over bug-ridden code and underperforming applications. Steve’s advice will help everyone have a better understanding of everyone else. Empathy is all too uncommon in our world.

Tuesday, 30 May 2006 10:28:27 (Eastern Daylight Time, UTC-04:00)  #    Comments [0] - Trackback

Filed under: JavaScript | Programming

Recently, here at the ranch, we have been experiencing a few issues with Internet Explorer’s javascript functionality. It’s not that IE is doing anything wrong, but rather that it performs unexpectedly. When opening a new window in javascript [window.open()], the height and width dimensions are relative to the size of the canvas / stage / content area (depending on what discipline you are from), all commonly referred to as innerHeight and innerWidth. However, when you execute a resize function in javascript [window.resizeTo()], the height and width dimensions are relative to the size of the entire window, including any chrome, commonly referred to as outerHeight and outerWidth.

Thus, if you create a window (500px x 300px), then resize it to (505px x 305px), the window will actually get smaller, since the chrome adds more than 5 pixels to height and width.

The problem: SCOs (Courseware) can be of any size, depending on the specifications, requirements, and whims of the original clients and developers. To keep courses in their most visual-appealing state, we need to size the content window to precise innerHeight and innerWidth pixel dimensions. Due to our site’s design, the link that launches the Course Shell window has no idea what the size of the SCO is. The Course Shell (LMS) knows how big the SCO is, but it is loaded into the Course Shell window, which is obviously done after the window is created and initially sized. We need a way to size the window to content-dimensions after the window is created.

The catch: Internet Explorer has no native support for innerHeight and innerWidth, let alone a way to resize to those dimensions. Furthermore, the difference between the inner- and outer-dimensions due to window chrome can change from OS to OS and from theme to theme. For example, in Windows XP’s default “bubbly” themes, the title and status bars are much taller than in Windows “Classic” themes. Internet Explorer has no native way to identify the difference in inner- and outer-dimensions, making it difficult to resize to an inner size using an outer size command.

I hacked together some (perhaps mediocre, but still effective) javascript to resize a window to its inner dimensions rather than the outer dimensions, regardless of the amount of chrome that the OS adds.

HTML

<div id="resizeReference"
    style="position: absolute; top: 0px; left: 0px; width: 100%; height: 100%; z-index: -1;">
    &nbsp;
</div>

Javascript

function resizeWindow(iWidth, iHeight){
    var resizeRef = document.getElementById('resizeReference');
    var iOuterWidth = iWidth + 10;
    var iOuterHeight = iHeight + 29;
 
    if (resizeRef) {
        var iPreWidth = resizeRef.offsetWidth;
        var iPreHeight = resizeRef.offsetHeight;
        window.resizeTo(iPreWidth,iPreHeight);
        var iPostWidth = resizeRef.offsetWidth;
        var iPostHeight = resizeRef.offsetHeight;
        iOuterWidth = iWidth + (iPreWidth-iPostWidth);
        iOuterHeight = iHeight + (iPreHeight-iPostHeight);
    }
    window.resizeTo(iOuterWidth, iOuterHeight);
}

The HTML tag creates a hidden DIV whose height and width match the window. This provides innerHeight and innerWidth. The JS takes the dimensions of that DIV and resizes the window to those measured dimensions. Since this transfers the inner-dimensions to the outer-dimensions, this provides the exact size of the window chrome. We can now resize to the input parameter height and width, plus the height and width of window chrome, to give us a resize to inner-dimensions.

Execute resizeWindow no sooner than below the closing Body tag, so that the DIV is rendered.

It is a bit of a hack, but it works for now.

Tuesday, 02 May 2006 10:23:23 (Eastern Daylight Time, UTC-04:00)  #    Comments [3] - Trackback