Tip: Install the MFC Source Code

Posted by Matt | Filed under ,

I cannot express how many times I’ve needed to step through the MFC source code in order to debug a problem I was having.  Often, the problem ends up being my own issue, but by stepping through the MFC source code, I was able to get a better understanding of what exactly the issue is.

So today’s tip:  make sure you install the MFC source code when you’re installing Visual Studio.  It’s an optional component, so best to do a custom install to ensure it’s selected.

Windows Error Reporting

Posted by Matt | Filed under , , ,

Microsoft has created their own error reporting system that’s built into Windows XP and Vista.  These operating systems will automatically collect crash data for any application that crashes and upload it to their servers.  There the data is collected, sorted, and distributed to the companies creating the offending software.  I’ve been using the system with my software for quite some time now, so I figured I’m collect my thoughts on the system for people thinking about using it.

From your software’s point of view, there’s nothing you really need to do to get it working.  When your software crashes, Windows will automatically catch the error, as long as you’re not catching it yourself.  It’s helpful though if you properly version your binaries (EXE and all DLLs).  This makes reading the logs later on easier.

In order to see your software crash logs, you need to have a code signing certificate.  This is required to create your companies account with winqual, and this costs some money.  I’d prefer if we were able to use the system without needing this requirement.

Once logged in, you’ll notice that the winqual system does more than just error reporting, but that will be outside the scope of this article. 

In order to view reports, you’ll need to inform the system about your product.  Winqual has a small downloadable application that will inspect your binaries and create a file mapping XML file for your product.  Once you upload the XML file to winqual, the system will start collecting data for your product.

The system allows you to see a couple of different reports:  all crashes by version and hottest crashes by version.  These are the most common ones you’ll use.  It’s nice that it breaks the reports down by product and version.  You’re able to see a list of crashes, sorted by occurrences and counted.  You can see a date break-down for each crash of when the crash occurred.  For many of the crashes, you’re then able to download the crash data for debugging.

What’s missing though is the ability to search for crashes by date.  Given a date, you cannot see what crashes occurred.  This would be useful if you knew that a crash occurred on a certain day, then it would be easier to track down.

As it is now, the system is great for fixing your most common crashes.  However, the system is not good for finding and fixing particular crashes.  There’s no way to link a crash to a customer.  Microsoft says this is intentional.  However, in the end, as a support tool, it fails.

Also, it often takes a week to a week-and-a-half to get updated with crash data.  So you’ll be waiting a while for a particular crash to appear.

On the good side, when you do look at a particular crash and download the crash data, you’re able to easily load the data in Visual Studio 2008 and see the crash as if it occurred locally.  Nice touch.  The initial data does not contain heap data, but you can later instruct the system collect heap data on subsequent crashes.  So produce debugging information for your release binaries and keep archive them.

If you’re planning on certifying your product, the use of winqual error reporting is a requirement.  We were disappointed with this because we had our own error reporting system that we feel better serves support issues.  We got our report data immediately, and we are able to search the data any way we see fit.  Because we certified our product, we had to abandon our better system for Microsoft’s.

Useful Links

Internet Explorer 8 Breaks Visual Studio 2008, Update

Posted by Matt | Filed under , ,

I thought I’d update you on my post from last week regarding how IE8 breaks some wizards in Visual Studio 2008.

On Microsoft Connect, they have confirmed that they can reproduce the issue.  Also, the Visual C++ team has confirmed that they found the issue in other wizards as well.  They don’t mention my issue directly, but I have confirmed that their fix does address my issue as well.

Internet Explorer 8 Breaks Visual Studio 2008

Posted by Matt | Filed under , , ,

Be careful, some of the dialogs in Visual Studio 2008 break if you install Internet Explorer 8.  Here’s one example.

In an ATL project, in the Class View, right click on an interface and select “Add Property”.  The following error appears now.

Internet Explorer Script Error
Line: 731
Char: 5
Error: Object doesn't support this property or method
Code: 0
URL: file:///C:/Program%20Files/Microsoft%20Visual%20Studio%209.0/VC/VCWizards/CodeWiz/ATL/Property/HTML/1033/default.htm

The property creation dialog that follows does not work anymore.  Here’s what the dialog looks like now.  Notice the Internet Explorer information bar at the top.

image

I have submitted the issue to Microsoft.  The Connect bug report can be read here.

Fixing up MFC Office 2007 Ribbon Applications, Part 3

Posted by Matt | Filed under , , , ,

In my continuing series, I am providing some workarounds/solutions to some issues in the Visual Studio 2008 SP1 projects created that use the new “MFC Feature Pack”.

Today’s issue is Print Preview.

In a new Office 2007 Ribbon application, if you tell the MFC Application Wizard to not include Print Preview support, it will still include it in the File/Application menu.  Once you create your new project, you’ll still see Print, Print Preview, etc. in the File menu (by clicking the “Pearl” on the top-left corner of the window).

To fix this, locate and remove the following code in MainFrm.cpp:

bNameValid = strTemp.LoadString(IDS_RIBBON_PRINT);
ASSERT(bNameValid);
CMFCRibbonButton* pBtnPrint = 
	new CMFCRibbonButton(ID_FILE_PRINT, 
		strTemp, 6, 6);
pBtnPrint->SetKeys(_T("p"), _T("w"));
bNameValid = strTemp.LoadString(IDS_RIBBON_PRINT_LABEL);
ASSERT(bNameValid);
pBtnPrint->AddSubItem(new CMFCRibbonLabel(strTemp));
bNameValid = strTemp.LoadString(IDS_RIBBON_PRINT_QUICK);
ASSERT(bNameValid);
pBtnPrint->AddSubItem(
	new CMFCRibbonButton(ID_FILE_PRINT_DIRECT, 
		strTemp, 7, 7, TRUE));
bNameValid = strTemp.LoadString(IDS_RIBBON_PRINT_PREVIEW);
ASSERT(bNameValid);
pBtnPrint->AddSubItem(
	new CMFCRibbonButton(ID_FILE_PRINT_PREVIEW, 
		strTemp, 8, 8, TRUE));
bNameValid = strTemp.LoadString(IDS_RIBBON_PRINT_SETUP);
ASSERT(bNameValid);
pBtnPrint->AddSubItem(
	new CMFCRibbonButton(ID_FILE_PRINT_SETUP, 
		strTemp, 11, 11, TRUE));
pMainPanel->Add(pBtnPrint);

Also, when you run the application, if you customize the Quick Access Toolbar, you’ll notice that Print Preview commands are still available.  To remove this, add the following code just after the ribbon is created, before the call to CMainFrame::InitializeRibbon():

m_wndRibbonBar.EnablePrintPreview(FALSE);

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

Fixing up MFC Office 2007 Ribbon Applications, Part 2

Posted by Matt | Filed under , , , ,

In my continuing series, I am providing some workarounds/solutions to some issues in the Visual Studio 2008 SP1 projects created that use the new “MFC Feature Pack”.

Today’s issue is the recent file list.

If you create a new project using the MFC Application Wizard, and you specify an Office 2007 Ribbon user interface, then your application will be created with the ability to have a recent file list.  This list is located in the File or “Application” menu (the “Pearl” in the top-left corner of the application).  The space is there, but if you run your application, you’ll notice that the recent file list is never populated with files you open or save.

The reason for this is because the project was created using a maximum of 0 files for the recent file list.  Take a look in your application’s main .cpp file in InitInstance() of your class.  You’ll notice a call to LoadStdProfileSettings().  It is passing as a parameter ‘0’.  This means to make the recent file list 0 elements long, or empty. 

To fix this issue, set the parameter to LoadStdProfileSettings() to something realistic, or remove the parameter completely since it has a default value of 4.

In summary: you need to change this:

LoadStdProfileSettings(0);  // Load standard INI file options

to:

LoadStdProfileSettings();  // Load standard INI file options

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

Fixing up MFC Office 2007 Ribbon Applications, Part 1

Posted by Matt | Filed under , , , ,

I am in process of converting some of my application’s sub-applications over to the new MFC feature pack.  They’re rather simple applications that I think will work nicely under the Office 2007 Ribbon framework.  As such, I’ve run into some headaches with the new applications and have submitted some bugs to microsoft via Microsoft Connect.

Today’s issue is regarding the version of the MFC and MSVCR90 libraries that a new application will link to.

The VC9 (Visual Studio 2008) compiler will always use the first version of MSVCR90 and MFC (9.0.21022.8).  Please see here for more details.  In order to override this, the developer must #define _BIND_TO_CURRENT_VCLIBS_VERSION in some place like stdafx.h (near the top).  This will make the linker link to the current/latest version of MSVCR90 and MFC90 (9.0.30729.1).

The MFC feature pack pretty much requires the new libraries that are shipped with SP1 of Visual Studio 2008.  But, the MFC Application Wizard, when it creates a new project, does not include this #define anywhere.  So the manifest will bind to 9.0.21022.8 of the libraries.  At first, it may appear ok since the Windows SxS system will use the 9.0.30729.1 version if it’s found:  it will be found on the developer’s machine since Visual Studio was installed.

However, if you move the application to another computer where 9.0.30729.1 is not installed (nor should anyone think it should be since the application is bound to 9.0.21022.8), then it won’t work.  If the earlier version is found, it may start to run, but will run into issues when the later libraries are required.

The fix is to always, ALWSAYS #define _BIND_TO_CURRENT_VCLIBS_VERSION at the top of stdafx.h for new MFC projects using Visual Studio 2008 SP1.

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

Visual Studio 2008 Service Pack 1 Released

Posted by Matt | Filed under ,

It's official.  Service Pack 1 for Visual Studio 2008 has now been released.  It includes a whole wack of bug fixes.  In addition, it includes the MFC Feature Pack which adds many new features to MFC applications.

More information can be found at the Visual C++ Team Blog.

Unfortunately, I don't think my ifstream issue has been fixed yet.

Visual C++ 6.0 + XP Manifest == Problems

Posted by Matt | Filed under , , ,

When Windows XP was introduced in 2001, it came with the idea of "themes".  For your application to utilize these themes, you needed to add a manifest resource to your executable with the following contents:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?> 
<assembly xmlns="urn:schemas-microsoft-com:asm.v1"
          manifestVersion="1.0"> 
  <assemblyIdentity version="1.0.0.0"
                    processorArchitecture="X86"
                    name="CompanyName.ProductName.YourApp"
                    type="win32" /> 
  <description>Your application description here.</description> 
  <dependency> 
    <dependentAssembly> 
      <assemblyIdentity type="win32"
                        name="Microsoft.Windows.Common-Controls"
                        version="6.0.0.0"
                        processorArchitecture="X86"
                        publicKeyToken="6595b64144ccf1df"
                        language="*" /> 
    </dependentAssembly> 
  </dependency> 
</assembly> 

This all seems to work well. 

About a year ago, after Vista came out, we wanted to introduce the manifest to our production executable to satisfy certification requirements.  We needed to include the following section in order to turn off Vista virtualization:

<trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
  <security>
    <requestedPrivileges>
      <requestedExecutionLevel level="asInvoker" />
    </requestedPrivileges>
  </security>
</trustInfo>

At the time, we were using Microsoft Visual C++ version 6.0 for our production code.  When we added the trustInfo section, we decided to also include the dependency section as well.  We figured that we might as well take advantage of new common controls where possible.

All was good for a while.  We got a bug report for Japan that some of our edit controls were losing half of their data.  For example, if the user entered 4 Japanese characters into the edit control, we were only saving 2.

Debugging the code, we determined that the problem was with an EM_LINELENGTH message.  Sending this message to the edit box would return back "4" as the length of the text.  For 4 Japanese characters, this was incorrect because our application is compiled using Multi-byte character set (ie. not Unicode), and thus, 4 Japanese characters should have been 8 bytes.

What was happening was EM_LINELENGTH was being sent to the Unicode handler for the message instead of the MBCS handler.  English characters were fine.  It appeared that all 2 byte characters were being returned as 1 byte (or 1 character).

Trying to figure out why this was happening was not an easy feat.  Basically, it was someone's suggestion to just remove the manifest completely just to see if it had any effect. 

It did.

As it turns out, including the above XP theme section in our manifest, while using Visual C++ 6.0, causes the issue.  There appears to be some compatibility issues between that compiler and the XP themed common controls.  There is no issue if our manifest only includes the execution level section.

Since then, we have migrated our application to the Visual Studio 2008 compiler, but we have not tried restoring the manifest section.  I'll update you when we give it a try.

Deparallelizer 1.0

Posted by Matt | Filed under , ,

I've created a utility for making the Visual Studio build logs more readable when you take advantage of parallel builds.  You can read more information and download the source code here.