Multiple Projects and Include Paths

Posted by Matt | Filed under ,

One thing that I am struggling with in working in new development projects is how to deal with multiple vcproj projects and the include paths that go with them.  What is the best schema for dealing with include folders?  Currently, we copy files that we know are needed in other projects to a common include folder. 

For example, if we have projects A.vcproj and B.vcproj, and B.vcproj requires A.h from A.vcproj, then in A.vcproj we will have a custom build step for A.h to copy it to the common include folder.  B.vcproj will then add the common include folder to it’s include path.  This method avoids having to know which project and which directory contains the header file.  It works well for the 60 projects involved in our main solution file.

There is a caveat to this system:  sometimes it’s not possible to keep a strict dependency tree for projects.  For example, occasionally, there may be 2 projects which create a circular dependency based on include requirements.  We work very hard to avoid this for DLLs.  However, for LIBs, we are less strict.  As such, we cannot rely on one project’s header files being copied before it’s needed by another project.  Our solution was to create a pre-process build step that would parse the project files and perform the copy for all projects before the first one was built.

It’s not elegant, but it works.  And sometimes that’s what matters.

What I’m wondering now is how other companies deal with similar issues.  How do you deal with including files from other projects?  Do you use a common include folder?  Do you hard code the paths to the included files in your #include statement?  Or do you have another system that’s working well for you?

Allowing CView Classes to Handle Tab Navigation

Posted by Matt | Filed under , , ,

Working on a recent project, I wanted to give my CView-derived view class Tab navigation (like CFormView has).  By default, if you add CEdit and other controls to your CView-derived view, pressing Tab will do nothing.  Also, adding CStatic with & accelerators are ignored.

Doing some Googling, I found the following solution.  Add the following function to your CView-derived class:

BOOL CMyView::PreTranslateMessage(MSG* pMsg)
{
  if(IsDialogMessage(pMsg))
    return TRUE;
  else
    return CWnd::PreTranslateMessage(pMsg);
}

At first, it was working great.  However, I noticed that my overall application accelerators were not working.

Looking deeper into CFormView, I found the solution. The above code is not enough.  The following is a more complete solution.

BOOL CMyView::PreTranslateMessage(MSG* pMsg)
{
  ASSERT(pMsg != NULL);
  ASSERT_VALID(this);
  ASSERT(m_hWnd != NULL);

  // allow tooltip messages to be filtered
  if (CView::PreTranslateMessage(pMsg))
    return TRUE;

  // don't translate dialog messages when in Shift+F1 help mode
  CFrameWnd* pFrameWnd = GetTopLevelFrame();
  if (pFrameWnd != NULL && pFrameWnd->m_bHelpMode)
    return FALSE;

  // since 'IsDialogMessage' will eat frame window accelerators,
  //   we call all frame windows' PreTranslateMessage first
  pFrameWnd = GetParentFrame();   // start with first parent frame
  while (pFrameWnd != NULL)
  {
    // allow owner & frames to translate before IsDialogMessage does
    if (pFrameWnd->PreTranslateMessage(pMsg))
      return TRUE;

    // try parent frames until there are no parent frames
    pFrameWnd = pFrameWnd->GetParentFrame();
  }

  // don't call IsDialogMessage if form is empty
  if (::GetWindow(m_hWnd, GW_CHILD) == NULL)
    return FALSE;

  // filter both messages to dialog and from children
  return PreTranslateInput(pMsg);
}

I will admit, this code came directly from CFormView in the MFC source for Visual Studio 2008 (give credit where credit is due).

After including this code in my class, tab navigation is working as well as overall application accelerators.

Unresolved CLSID and IID identifiers

Posted by Matt | Filed under , ,

When using COM objects, occasionally, you may run into “LNK2001 unresolved external” errors.  This is often because the header file that declares the GUID for the COM object or interface is using DEFINE_GUID.  This macro is setup to declare the GUID as extern, meaning it needs to finally reside somewhere.  The error you are getting means that it has no home.

So solve this issue, include “InitGuid.h” before your header file that is declaring the GUID.  Ultimately, it actually needs to be before guiddef.h so you may need to include it in your precompiled headers if guiddef.h is being included somewhere in there.

In my case, I was including “Evalcom2.h” and CLSID_EvalCom2 and IID_IValidate were unresolved.  To solve it, I did this:

// So the GUIDs get defined (and not just declared)
#include <InitGuid.h>
#include <Evalcom2.h>

More information can be found on Microsoft’s page, here.

Is Direct2D the Next 2D API?

Posted by Matt | Filed under , ,

I have been doing some work with Direct2D over the last couple of weeks converting our current GDI-based 2D-cad application over to a Direct2D-based application.  One huge problem for us though is XP support.  Direct2D is available for Windows 7 and Vista only.  So what do we do for our XP customers?

Currently, I’m having to basically abstract the rendering.  So essentially, I’ve created a rendering interface with 2 implementations:  Direct2D and GDI.  In the end, this actually will work out in our favour because we’ll be able to do an OpenGL implementation for the Mac.  I suppose I could do a Direct3D9 implementation for XP customers as well.

I read some of the questions and answers over at Responding to comments - 2D drawing APIs in Windows.  One of the comments was:

The vision going forward is that D2D is *the* 2D API. We are very interested in any feedback that could tell us what is blocking this going forward. 

I think that lack of XP support is what is keeping Direct2D from becoming *the* 2D API.  At this stage, it’s very difficult for a developer to create a Direct2D-exclusive application.  Many developers still need to support customers who still don’t have motivation to upgrade to Vista or Windows 7.  Maybe this will change come October 22.

Another thing (which I commented on at the above blog entry) is that I think if they want Direct2D to become *the* 2D API, then they need to add it to the application wizards and do some hide-behind with MFC.  The reason is that currently, a developer can create a new app using the wizards, and immediately draw to the GDI device context.  They don’t have to set anything up, they don’t have to do any checks for hardware, etc.  Microsoft needs to have this same thing for Direct2D.  Let MFC deal with the factory creation, render target creation, begin scene, end scene etc. and just provide to a render function a final ready-to-use render target.

I am not saying that this will be the most optimal way of using it in applications, but it will reduce the learning curve for people.

I do want to add that I really like Direct2D in and of itself.  It’s a very clean interface and does everything that I would need it to do.  And it does it fast. 

To answer the initial question:  I think it is the next 2D API, but I don’t think that it, Microsoft, and customers are ready for it to be the current 2D API.

Direct2D Resources

Template Functions, Part 2

Posted by Matt | Filed under , ,

In a previous post, I gave you the basics for template functions in C++.  One of the issues I find when I have a problem and am looking for examples of the solution is that many times the examples are so basic that they don’t really demonstrate the solution.  Today, I want to show you a complex solution that I had to create using templates.  Hopefully this will give you a better idea of what we can do.

In my real-world case, I had a potential file system of files and a database.  Files had to be defined in a data structure (read from Xml), traversed and put into a database.  The database contained different table definitions for different types of files (binary files, document files, etc.).

At first, the data structures looked like this:

class CBinaryFile
{
public:
  // Data

  typedef CList<CBinaryFile> List;
};

class CContentFile
{
public:
  // Data

  typedef CList<CContentFile> List;
};

class CFolder
{
public:
  CBinaryFile::List BinaryFiles;
  CContentFile::List ContentFiles;

  typedef CList<CFolder> List;

  CFolder::List Folders;
};

CFolder::List TheFolders;

You’ll notice that this is a recursive list of Folders that contains binary files and content files.  However, additional requirements came into play:  in memory, the binary file hierarchy needed to be separated from the content file hierarchy.  This means that I needed to have one set of folders for binary files and a different set of folders for content files.  I could have very well kept the data structure the same, but just had two top-level variables for the folders:

CFolder::List BinaryFolders;
CFolder::List ContentFolders;

Using this, I’d basically have wasted memory.  No one likes that :)

So I changed to use templates.  My CFolder class changed to this:

template <class T>
class CFolder
{
  T::List Files;

  typedef CList< CFolder<T> > List;

  CFolder::List Folders;
};

This way, my two top-level variables become:

CFolder<BinaryFile>::List BinaryFolders;
CFolder<ContentFile>::List BinaryFolders;

So far though, all I’ve shown you was class templates.  Where does the function template come into the picture?

I now need to traverse the folders and process the files into the database.  I did not want to add the functions to the class.  I’ll explain later.

void Traverse(CFolder<BinaryFile>::List &folders)
{
  // ...
}

void Traverse(CFolder<ContentFile>::List &folders)
{
  // ...
}

Again, duplication of code.  And we don’t want that either.  So I did this:

template <class T>
void Traverse(CFolder<T>::List &folders)
{
  // ...
}

This gave me a single function that does the work of traversing the folders.  But what about the end?  The 2 classes needed to be processed differently.  For this, I created an abstract item handler class that was implemented for each file type.  Here is the final code:

class CBinaryFile
{
public:
  // Data

  typedef CList<CBinaryFile> List;
};

class CContentFile
{
public:
  // Data

  typedef CList<CContentFile> List;
};

template <class T>
class CFolder
{
public:
  typename T::List Files;
	
  typedef CList< CFolder<T> > List;

  List Folders;
};

template<class T>
class IItemHandler
{
public:
  virtual void ProcessItem(T &item) = 0;
};

class BinaryFileHandler : public IItemHandler<CBinaryFile>
{
public:
  void ProcessItem(CBinaryFile &item)
  {
    // Insert into the database
  }
};

class ContentFileHandler : public IItemHandler<CContentFile>
{
public:
  void ProcessItem(CContentFile &item)
  {
    // Insert into the database
  }
};

template <class T>
void Traverse(typename CFolder<T>::List &folders, 
    IItemHandler<T> *pHandler)
{
  POSITION pos = folders.GetHeadPosition();
  while (pos != NULL)
  {
    CFolder<T> &folder = folders.GetNext(pos);

    // Process our items
    POSITION p2 = folder.Items.GetHeadPosition();
    while (p2 != NULL)
    {
      T &item = folder.Items.GetNext(pos);
      pHandler->ProcessItem(item);
    }

    // Do the sub-folders
    Traverse(folder.Folders, pHandler);
  }
}

BinaryFileHandler bfh;
Traverse(binaryFolders, &bfh);

ContentFileHandler cfh;
Traverse(contentFolders, &cfh);

Sometimes, it seems like alot of work and code just to avoid duplicating code or wasting memory.  These are judgement calls. The nice thing is that if I needed to add another file type later on, the groundwork is already done.  All I need to do is define my file type class and then create the handler class to insert it into the database.  Obviously, the more file types that are needed, the better looking this solution is.  It’s questionable whether this work is beneficial for only 2 file types.  But if you had 25 or 50, I think it’s obvious that this solution is better than code duplication.  Especially if you find a bug in the traversal code :)

Template Functions

Posted by Matt | Filed under , ,

Many people know about template classes in C++.  When you start working with templates, this is usually what you’re looking for.  The staple of template demonstrations is the linked list class.  This one is a common need from developers.  The good news is that the STL libraries implement this one very well.  Anyways, what many people don’t know about templates is that you can create template functions just as easily.  Sometimes, you may not even know you’re calling a template function.

Let’s create a min function.  It’s common to use macros, but macros don’t always maintain type-safeness.

template <class T>
T Min(T a, T b)
{
  if (b < a)
    return b;
  else
    return a;
}

You’ll notice that the first line is the same as when you’re creating a template class.  And just like a template class, you just reference your template parameter normally.

However, now, we can write code like this:

int a = 5;
int b = 6;
int m = Min(a, b);

This will generate a function Min using int as a base type.  And it’s type-safe.  You can easily change it to:

double a = 5;
double b = 6;
double m = Min(a, b);

This will call a double version of the same function.  If you wanted to do this without templates, you’d have to either (a) use macros, or (b) create 2 different functions.

The following code will generate an error:

int a = 5;
double b = 6;
int m = Min(a, b);

“error C2782: 'T Min(T,T)' : template parameter 'T' is ambiguous”

To fix the above issue, you can call Min as this instead:

int m = Min<int>(a, b);

This will disambiguate the parameters giving you a solid definition.  Note that b will be casted to an int as the call commences.

You get the idea now.  This is a very basic example.  I always hate it when you needs to see how to use something, but they always give very basic examples which don’t show the solution to the problem you’re having.  In an upcoming post, I’ll show you a much more complex solution using templates that I actually needed to develop.

Three Ways to SQL

Posted by Matt | Filed under , , , ,

In the colourful land of .NET, the database gods have bestowed upon us lowly peasants (atleast) 3 ways to access ye olde SQL databases.  Each has their pros and their cons.   Some more so than others.  Below are some of those options.  As a developer, it is up to you to choose which is right for (a) you, and (b) your situation.

1. DataSource, DataTable, DataProvider, and the visual editor

Microsoft used to promote this quite a bit.  It’s the primary means to access SQL databases from some of the out-of-the-box .NET controls (for both ASP.NET and Windows Forms).  Using this method, you drag database objects onto your forms and configure them using the visual SQL editor.  As I understand it, this is very good for RAD (Rapid Application Development) developers.  However, for me, it’s quite slow to use because of the visual editing elements.

2. SQLConnection and SQLCommand classes

This used to be my favourite way to work with SQL databases.  Not being a fan of the DataSource classes, I found it easier to use the SQLConnection and SQLCommand classes directly.  I also felt that I had more control over the commands and the data.  Using this method, I was able to setup my own connections and do my own calls without needing to hide behind a data abstraction.  The only problem with this was that there was alot of repeated code.  Often, I’d just have to copy and paste an existing connection and change a couple of lines here or there.  It was different enough that I couldn’t make a general purpose handler though.  But I had my control.  And that’s how the SQL world was to me until…

3.  LINQ to SQL

In my opinion, this is the database gods’ gift to mankind.  Using LINQ to SQL, I can use a visual editor to define the relationships between my SQL tables (notice that I’m back on the visual editor bandwagon).  Afterwards, I have a strongly-typed set of classes that I can use to access my data.  No more casting data out of the database classes. Instead, it’s already in the proper types.  No longer do I have to create SQL statements and be required to run my program to find out how incorrect the statement is.  LINQ to SQL is done natively in the programming language (C# for me), so incorrect syntax is caught by the compiler.  My latest project to access a database took me 2 hours to complete using LINQ.  If I had been using method #2, I think it would have taken me closer to a day, but it would have worked just as a well in the end.  LINQ let me complete the job faster.

In summary, LINQ to SQL == goodness.  Others are still good, just not as good (for me anyways).

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

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).

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