Vista Style CFileDialog and the compiling OS

Posted by Matt | Filed under , , , ,

A reader asks:

“To set bVistaStyle to FALSE, under which OS, we need to compile my project.
[…]
in the MSDN I found that the “This parameter is applicable only if you are compiling in Windows Vista.
Please see the following MSDN link: http://msdn.microsoft.com/en-us/library/wh5hz49d.aspx
Kindly let us know your feedback on this.”

I took a look at the documentation and it does indeed say that.  However, the documentation is incorrect.

There are no #defines or #pragmas around the constructor for CFileDialog that would restrict the OS at compile time.  What they may be intending to say is that the parameter is applicable only if you are running in Windows Vista.

I wrote a test program that shows a CFileDialog and I explicity set the bVistaStyle flag to TRUE.  I Compiled it on XP and I got the XP-style file open dialog (which is to be expected).  I then copied the EXE to my Vista computer (I did not recompile).  There, I got the Vista style dialog.

So you can safely compile on XP and it will still show the Vista dialog on Vista.

Note that this is restricted to Visual Studio 2008.  The parameter is not present in Visual Studio 2005 (out of the box).

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Two Different Ways to Show Enum Values in WPF

Posted by Matt | Filed under ,

For an application, I wanted to show the values from an Enum in a combo box.  While Googling, I found two different ways to do it.

  1. There’s the brute force way, shown here by Sasha Barber, and
  2. The fancier, but in the end simpler, way shown here by Andrew Smith

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Automated Testing

Posted by Matt | Filed under ,

In a previous post, I talked about my experiences with Automated Build Studio.  My company is looking at automated testing tools to help augment manual Q/A testing.  We’ve looked at TestComplete and thought about developing unit tests.  But with a codebase pushing 2 million lines of code, where do you begin writing unit tests?  And when you have pressures to deliver products, when do you find time to write unit tests?  How do you develop automated test scripts for a graphical CAD-type application?

What automated testing techniques do you use?  Did you use them from the start?  If not, when did you start adding tests to your codebase?  What approach did you take?

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Automated Build Studio

Posted by Matt | Filed under , ,

As a developer, I’ve worked on my fair share of projects.  Some were quite small, and some were very, very large.  When you have a large project with many million lines of code, building the projects can become a large task.  My company has one flagship product.  This product’s build procedure is quite complex.  It includes:

  • Retrieving the latest source from our source control tools
  • Translating all of our resources into 13+ languages
  • Editing the build number and build date in a few key header files
  • Building the main product and up to 10 derivatives
  • Building the product installations
  • Copying the completed distributibles to the appropriate locations (network drives, FTP)
  • Archive the source code

In the past, each build would occupy about 30 minutes of my time as I manually performed each of the above steps.  However, after visiting SDWest last year, I learned about a product called Automated Build Studio by AutomatedQA.  The idea intrigued me.  Can I automate 30 minutes of my life?

After downloading the trial version, I set out to create an ABS macro that would do all of the aforementioned steps.  It took a few days, but it worked.  And it works well. Now, getting a build going takes only 10 seconds of my time (honestly).  We have now been using it for the past 8 months. 

ABS can interoperate with many development tools:  Microsoft Visual Studio (6, 2003, 2005, 2008), Perforce, InstallShield, InstallAware.  And if there’s something that it doesn't work with, it can run basic DOS commands, batch files, executables, or VBScripts.  Our entire translations process was built on a handful of AWK and KSH scripts.  I was able to port them over to VBScript and now they run inside ABS (and much faster… for AWK and KSH, the process took over an hour, but for ABS/VBScript, the same process takes only 20 minutes).

I can get a build started by a few clicks on a Windows Vista Sidebar gadget.  And I don’t need to watch the build machine anymore to see if the build is done:  when the build is done, I get an email to my BlackBerry with a log of any errors encountered.  It’s so easy to stat a build now that I can have someone else start a build.  Now the company doesn’t come to a halt if I’m on vacation.  I can also queue up build requests.  Previously, I pretty much had to be there to start the second build once the first was done.  Now, I can just queue up any additional builds and they’ll run sequentially.

The only thing that is not automated yet is the dispatching of the changelist email.  This requires some time in Lotus Notes and I haven’t figured out how to automate that yet.  The only issue I’ve run into so far is that it’s zipping macro cannot handle archives as big as we need.  So I need to launch WinZip instead to archive our source code.

During these poor economic times, we had to lay off a developer.  As a consequence, I took over some of his duties.  One such duty (which I as unaware of beforehand) was spending about 3 hours a week creating custom installs for some smaller products in a very manual manner.  I let ABS take over.  After 2 days of creating a new ABS macro, these custom installs are now created in 5 minutes.  On top of that, I am not the one to initiate the build process:  instead, someone else copies assets for the install to a network drive, ABS notices the new files, automatically launches the build, and emails that other person when their new install is ready.  I am now 100% out of the picture.

Basically, ABS has allowed me to spend less time on build management, and more time in development.

If the build process for your product is more than just opening the project in Visual Studio and pressing F7, then I’d recommend taking a serious look at Automated Build Studio.  It’s a fantastic tool, and it’s definitely worth it’s price.

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Selecting Multiple Files using CFileDialog, Properly

Posted by Matt | Filed under , , , ,

I ran into an issue today.  I had a CFileDialog object set to select multiple files (using OFN_ALLOWMULTISELECT).  When I launched the dialog, I selected 24 files.  However, after looping through the files using CFileDialog::GetNextPathName(), there were only 10 being returned.

The problem is that there wasn’t an error being set anywhere (that I could find).  CFileDialog was being quite sneaky in that it wasn’t giving me any signal that 14 of the selected files were basically being ignored.  At first, I thought it was just a bug in Windows.  After some thinking, it turns out that there’s an internal buffer used to store these files.  This may seem very obvious to some people, but it wasn’t obvious to me.

Part of the OPENFILENAME structure is a buffer for holding (a) the default file when the dialog is opened, and (b) the selected files when the dialog is closed.  This member is called lpstrFile.  nMaxFile is also used in conjunction to specify the length of the buffer pointed to by lpstrFile.

By default, CFileDialog uses a buffer 260 characters long.  In my problem above, 260 characters is basically able to only hold 10 of the selected files.  The rest were just dropped quietly.

The workaround is to use a larger buffer.  It’s quite easy to do this:

// Create our dialog object
CFileDialog dialog(TRUE, NULL, NULL, OFN_HIDEREADONLY | 
  OFN_ALLOWMULTISELECT);

// This is the trick
const int nBufferSize = 128*1024; // May be excessive?
TCHAR *szBuffer = new TCHAR[nBufferSize];
memset(szBuffer, 0, sizeof(TCHAR) * nBufferSize);
dialog.m_ofn.lpstrFile = szBuffer;
dialog.m_ofn.nMaxFile = nBufferSize - 1;

// Show the dialog
if (dialog.DoModal() == IDOK)
{
  POSITION pos = dialog.GetStartPosition();
  while (pos != NULL)
  {
    CString sFile = dialog.GetNextPathName(pos);
    // Process the file
  }
}

delete[] szBuffer; // No leaks

The trick is to set lpstrFile and nMaxFile to a larger buffer.  128k may be excessive, but at least it will work.  Feel free to use whatever size buffer you want to.

Note: Above, I created the buffer on the heap using ‘new’.  If you don’t want to deal with ‘new’ and ‘delete’, you could create it on the stack like:

TCHAR szBuffer[nBufferSize];

and skip the ‘delete’ call.  However, this will eat up a good chunk of your stack space.  The default stack is 1 MB.  So 128k is 10% of your stack.  For this reason, I created it on the heap.

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Extreme ListBox Customization

Posted by Matt | Filed under , ,

Just a short note that I wanted to share with all of you.  While searching on how to customize ListBox controls in WPF, I came across this post from 2007: The power of Styles and Templates in WPF.  In this article, Bea demonstrates how to make an everyday WPF ListBox control look like our solar system.  The items in the list are the planets, and she has orbit trails and everything.  Below is the results of her changes.

image 

Yes, that is a ListBox control.  Pretty amazing!

Go read her full article on how she did this.

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Wrapping ListBox using Silverlight

Posted by Matt | Filed under , , , ,

While working on a current project, I wanted to create a wrapping ListBox.  This is one where the items are not simply stacked on top of each other.  Instead, the items either travel left-to-right, then wrap back around (like when you’re typing) with a vertical scrollbar, or travel top-to-bottom, then wrap around to the top again with a horizontal scrollbar.  For examples, look at Windows Vista Explorer.  Tiles view is a left-to-right wrapping ListBox, and List view is a top-to-bottom wrapping ListBox.

The Silverlight Toolkit includes a WrapPanel.  So I thought I could do the following:

<ListBox x:Name="lboWrapListBox">
  <ListBox.ItemsPanel>
    <ItemsPanelTemplate>
      <controls:WrapPanel Orientation="Horizontal" />
    </ItemsPanelTemplate>
  </ListBox.ItemsPanel>
</ListBox>

After adding my items, I noticed that the WrapPanel was not wrapping at all.  There are 2 solutions.

The first solution is to give the WrapPanel object an explicit width.  For example:

<ListBox.ItemsPanel>
  <ItemsPanelTemplate>
    <controls:WrapPanel Orientation="Horizontal" Width="300"/>
  </ItemsPanelTemplate>
</ListBox.ItemsPanel>

This works, but it makes the ListBox non-resizable if the browser or control changes size.

After some assistance on the Silverlight.net forums, I figured out what’s needed.  An ItemsPresenter needs to be added to the template for the ListBox:

<ListBox.Template>
  <ControlTemplate>
    <ItemsPresenter />
  </ControlTemplate>
</ListBox.Template>

After adding this, the ListBox now wraps. However, there are no scrollbars, so the ListBox wraps, but you can’t get to any items offscreen.  We can remedy this by wrapping the ItemsPresenter in a ScrollViewer:

<ListBox.Template>
  <ControlTemplate>
    <ScrollViewer>
      <ItemsPresenter />
    </ScrollViewer>
  </ControlTemplate>
</ListBox.Template>

Now we have a properly wrapping and scrolling wrapping ListBox. 

image

But what about a vertically wrapping ListBox?

If I change the Orientation from Horizontal to Vertical on the WrapPanel, we lose wrapping, but we’ve kept scrolling.  If we now remove the ScrollViewer from around the ItemsPresenter, wrapping is restored, but we’ve now lost the scrolling capability.

image

At this point, I am unaware of the solution.  Hopefully I’ll come up with something.  Maybe the Silverlight Toolkit Team can fix this in the WrapPanel itself.  In the meantime, below are some final styles which you can use to create a wrapping ListBox.

<Style x:Key="HorizontalWrapListBox" TargetType="ListBox">
  <Style.Setters>
    <Setter Property="ItemsPanel">
      <Setter.Value>
        <ItemsPanelTemplate>
          <controls:WrapPanel Orientation="Horizontal" />
        </ItemsPanelTemplate>
      </Setter.Value>
    </Setter>
    <Setter Property="Template">
      <Setter.Value>
        <ControlTemplate TargetType="ListBox">
          <ScrollViewer>
            <ItemsPresenter />
          </ScrollViewer>
        </ControlTemplate>
      </Setter.Value>
    </Setter>
  </Style.Setters>
</Style>
		
<Style x:Key="VerticalWrapListBox" TargetType="ListBox">
  <Style.Setters>
    <Setter Property="ItemsPanel">
      <Setter.Value>
        <ItemsPanelTemplate>
          <controls:WrapPanel Orientation="Vertical" />
        </ItemsPanelTemplate>
      </Setter.Value>
    </Setter>
    <Setter Property="Template">
      <Setter.Value>
        <ControlTemplate TargetType="ListBox">
          <ItemsPresenter />
        </ControlTemplate>
      </Setter.Value>
    </Setter>
  </Style.Setters>
</Style>

You can use it as follows:

<ListBox x:Name="lboWrapListBox" 
         Style="{StaticResource HorizontalWrapListBox}" />

Note that the VerticalWrapListBox does not scroll properly.  If your ListBox has a static size (ie. is not going to change sizes), then you can get around this by explicitly setting a height on the WrapPanel control.

Currently rated 5.0 by 1 people

  • Currently 5/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Failure with Nested WebForm Callbacks

Posted by Matt | Filed under , ,

I am working on an ASP.NET application that requires some WebForm callbacks.  However, I am running into the following error:

Microsoft JScript runtime error: '__pendingCallbacks[...].async' is null or not an object

This error appears in the code below.

function WebForm_CallbackComplete() {
  for (var i = 0; i < __pendingCallbacks.length; i++) {
    callbackObject = __pendingCallbacks[i];
    if (callbackObject && callbackObject.xmlRequest && 
        (callbackObject.xmlRequest.readyState == 4)) {
      WebForm_ExecuteCallback(callbackObject);
      if (!__pendingCallbacks[i].async) {
        __synchronousCallBackIndex = -1;
      }
      __pendingCallbacks[i] = null;
      var callbackFrameID = "__CALLBACKFRAME" + i;
      var xmlRequestFrame = document.getElementById(callbackFrameID);
      if (xmlRequestFrame) {
        xmlRequestFrame.parentNode.removeChild(xmlRequestFrame);
      }
    }
  }
}

After doing some Googling, I found out that there was a previously common problem with this same line of code. The previous error had a scope issue with the variable 'i'.  However, when using Visual Studio 2008, and as you see above, this scope issue is fixed by adding ‘var’ in the for loop.

So what’s the issue now?

It appears to be an issue of calling a web callback synchronously from within the end callback of a previous web callback.  Essentially, I am nesting WebForm callbacks:  calling a second before the first is 100% complete.

Here’s what is happening.  I’m calling ‘WebForm_DoCallback’ from my Javascript and that’s going to the web server and returning.  When it returns, Microsoft’s system calls my end-of-callback event callback.  In this function, I am calling ‘WebForm_DoCallback’ again.  It looks like Microsoft’s synchronous callback system does not like nested callbacks.  The second call is destroying the __pendingCallbacks array before the first call completes.

I was able to avoid the issue by doing the following:

var __data = null;
function End_Callback_Proxy(arg, context) {
  __data = arg;
  window.setTimeout('End_Callback_Helper()', 0);
}
function End_Callback_Helper() {
  End_Callback(__data, 'ResetMarker');
}

Here, I set the event callback to be ‘End_Callback_Proxy’ instead of ‘End_Callback’.  This saves the data from the callback to a variable, and tells the window to call ‘End_Callback_Helper’ a little bit later.  This allows the current callback to complete before the next one is called.

I have submitted this issue to Microsoft Connect.  You can view the issue here.

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Windows 7 Release Candidate Released

Posted by Matt | Filed under ,

Microsoft released Windows 7 Release Candidate 1 to MSDN and TechNet subscribers yesterday.  This should have most of the new functionality we’ve been waiting for (including the new task bar and jump menus).  If you’re an MSDN subscriber, you can download it here.  If you’re not, you’ll need to wait until May 5 at which point, it will be available at the Microsoft Downloads site.

More information can be found at Channel 9.

Related, Windows 7 logo certification is now in it’s Alpha stage.  If you’re looking to get your application certified for Windows 7, take a look at the logo program requirements.  They look very similar to Vista’s.  Later this year, Microsoft will be releasing their logo toolkit which can be used to pre-test your applications.  More information can be found at Microsoft’s main Windows 7 Logo Program website.

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Creating a Twitter Client in C#, Part 4

Posted by Matt | Filed under , , , ,

I wanted to post my “final” twitter client.  I fleshed out most of the API functions and added documentation comments. 

I’ve not tested it fully yet, but for the most part, it should work.  If you find any bugs, please let me know.

You can download it here:  InsiderCoding.Twitter.zip (12.04kb)

Currently rated 1.0 by 1 people

  • Currently 1/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5