.: Home :: Contact Us :.  
  



Hans Dietrich Software

free and licensed software

   

Tips & Tricks

Tip Index

  1. Convert a VS2008 Project to VS2005
  2. Detect whether operating system is 32-bit or 64-bit
  3. Font Type Images
  4. Fatal error C1083: Cannot open include file: 'uxtheme.h': No such file or directory
  5. Stop ESC from closing your dialog-based app

VS Macro Index

  1. Decrease/Increase editor font size
  2. Use google to search MSDN
  3. Toggle between .h and .cpp files

Convert a VS2008 Project to VS2005

  1. Make backup copies of the .sln and .vcproj files of the project you want to convert.
  2. Edit the .sln files and replace
    Microsoft Visual Studio Solution File, Format Version 10.00
    # Visual Studio 2008
    with
    Microsoft Visual Studio Solution File, Format Version 9.00
    # Visual Studio 2005
  3. Edit the .vcproj files and replace
    <?xml version="1.0" encoding="Windows-1252"?>
    <VisualStudioProject
    	ProjectType="Visual C++"
    	Version="9.00"
    with
    <?xml version="1.0" encoding="Windows-1252"?>
    <VisualStudioProject
    	ProjectType="Visual C++"
    	Version="8.00"

Detect whether operating system is 32-bit or 64-bit

Sometimes you need to know when you are running on a 64-bit OS such as Win7x64. For example, you may need to install a shell extension. On 64-bit Windows, the shell extension DLL must be 64-bit, and so you must register a 64-bit DLL rather than a 32-bit DLL (you would include both of these DLLs in the setup package). There are some complicated ways (such as WMI) to find out if the app is running on a 64-bit OS, but by using the IsWow64Process() API, you can determine this very easily:
// Detect whether OS is 32-bit or 64-bit 
BOOL Is64BitOS()
{
    BOOL bIs64Bit = FALSE;

    #if defined(_WIN64)

    bIs64Bit = TRUE;  // 64-bit programs run only on Win64

    #elif defined(_WIN32)

    // 32-bit programs run on both 32-bit and 64-bit Windows

    typedef BOOL (WINAPI *LPFNISWOW64PROCESS) (HANDLE, PBOOL);
    LPFNISWOW64PROCESS pfnIsWow64Process = 
        (LPFNISWOW64PROCESS)GetProcAddress(GetModuleHandle(_T("kernel32")), "IsWow64Process");

    if (pfnIsWow64Process)
        pfnIsWow64Process(GetCurrentProcess(), &bIs64Bit);

    #endif

    return bIs64Bit;
}

Font Type Images

In previous versions of Windows, you could load font type images from COMDLG32.DLL (bitmap resource #38). In recent versions of Windows, this resource does not exist in COMDLG32.DLL. You can load the bitmap yourself using this code:
void CMyClass::CreateFontTypeImages()
{
    ASSERT(m_FontType.GetSafeHandle() == 0);

    HBITMAP hBmp = (HBITMAP)::LoadImage(AfxGetResourceHandle(), 
                    MAKEINTRESOURCE(IDB_FONTTYPES), IMAGE_BITMAP, 100, 24,
                    LR_DEFAULTCOLOR);
    ASSERT(hBmp);
    if (!hBmp)
        return;

    CClientDC dcClient(this);
    const int GLYPH_SIZE = 12;

    // We create one image list for the selected and non-selected 
    // glyphs.  The images are:
    //    0 - TrueType non-selected
    //    1 - OpenType non-selected
    //    2 - TrueType selected
    //    3 - OpenType selected

    if (m_FontType.Create(GLYPH_SIZE, GLYPH_SIZE, 
            ILC_COLOR32 | ILC_MASK, 4, 1))
    {
        CDC dcMem;
        dcMem.CreateCompatibleDC(&dcClient);
        CBitmap *pBmp = CBitmap::FromHandle(hBmp);
        CBitmap *pOldBitmap = dcMem.SelectObject(pBmp);

        // dcMem now contains the 100 x 24 bitmap (2 rows).
        // The individual images are at 0, 20, 40, 60, and 80.
        // We want the images at 0 and 40 in each row.

        CDC dcBitmap1;
        dcBitmap1.CreateCompatibleDC(&dcClient);
        CBitmap bmp1;
        bmp1.CreateCompatibleBitmap(&dcClient, 2*GLYPH_SIZE, GLYPH_SIZE);

        // extract non-selected images from top row
        CBitmap *pOldBitmap1 = dcBitmap1.SelectObject(&bmp1);
        dcBitmap1.FillSolidRect(0, 0, 2*GLYPH_SIZE, GLYPH_SIZE, 
            GetSysColor(COLOR_WINDOW));
        // we want 1st (TrueType) and 3rd (OpenType) images
        dcBitmap1.BitBlt(0, 0, GLYPH_SIZE, GLYPH_SIZE, &dcMem, 
            3, 0, SRCCOPY);
        dcBitmap1.BitBlt(GLYPH_SIZE, 0, GLYPH_SIZE, GLYPH_SIZE, 
            &dcMem, 43, 0, SRCCOPY);
        dcBitmap1.SelectObject(pOldBitmap1);

        m_FontType.Add(&bmp1, RGB(0,0,255));  // different mask color
                                              // for each row

        // extract selected images from 2nd row
        dcBitmap1.SelectObject(&bmp1);
        dcBitmap1.FillSolidRect(0, 0, 2*GLYPH_SIZE, GLYPH_SIZE, 
            GetSysColor(COLOR_WINDOW));
        // we want 1st (TrueType) and 3rd (OpenType) images
        dcBitmap1.BitBlt(0, 0, GLYPH_SIZE, GLYPH_SIZE, &dcMem, 
            3, GLYPH_SIZE, SRCCOPY);
        dcBitmap1.BitBlt(GLYPH_SIZE, 0, GLYPH_SIZE, GLYPH_SIZE, 
            &dcMem, 43, GLYPH_SIZE, SRCCOPY);
        dcBitmap1.SelectObject(pOldBitmap1);

        m_FontType.Add(&bmp1, RGB(255,0,255));  // different mask color
                                                // for each row

        dcBitmap1.DeleteDC();
        bmp1.DeleteObject();

        dcMem.SelectObject(pOldBitmap);
        dcMem.DeleteDC();
    }
    ::DeleteObject(hBmp);
}
The variable m_FontType is a CImageList. You can download the font type bitmap (IDB_FONTTYPES) here: http://www.hdsoft.org/download/fonttype.zip.

Fatal error C1083: Cannot open include file: 'uxtheme.h': No such file or directory

Many of the HDSoft components require the Microsoft Platform SDK, which includes uxtheme.h. If you do not need (or already have) .NET 3.5, then you probably want to download Windows Server 2003 R2 Platform SDK (also available as a low-cost DVD here: http://mssdk.orderport.net).

If you get compile errors because of missing header files or symbols, please be sure you have installed the Platform SDK:

  1. In VS6, the Platform SDK will appear under Tools | Options | Directories | Include Files.
  2. In VS2008, the Platform SDK will appear under Tools | Options | Projects and Solutions | VC++ Directories | Include Files.
  3. In VS2010, there are now separate UIs for the per-user and the per-project directories. Assuming you want to add the Platform SDK to the per-user directory list, go to View | Other Windows | Property Manager. In the Property Manager tree under Debug | Win32, right-click on Microsoft.Cpp.Win32.user and click Properties. In the properties dialog, click on VC++ Directories. Note that there is an entry in the Property Manager tree for both Debug and Release.

Stop ESC from closing your dialog-based app

When you create an MFC dialog-based app in Visual Studio, the default handling of the ESC key will close the app. In many cases, this is not what you want. To override this default behavior, you need to add two functions to the CDialog-based class (in this example, the XListCtrl dialog demo is used):
  1. In XListCtrlTestDlg.h, add the following message map functions:
        virtual void OnCancel();
        afx_msg void OnClose();
  2. In XListCtrlTestDlg.cpp, add the following to the message map:
        ON_WM_CLOSE()
  3. In XListCtrlTestDlg.cpp, add the following functions:
    ///////////////////////////////////////////////////////////////////////////////
    // OnCancel - don't let ESC close dialog
    void CXListCtrlTestDlg::OnCancel() 
    {
        TRACE(_T("in CXListCtrlTestDlg::OnCancel\n"));
        //CBaseDialog::OnCancel();
    }
    
    ///////////////////////////////////////////////////////////////////////////////
    // OnClose - don't let ESC close dialog
    void CXListCtrlTestDlg::OnClose() 
    {
        TRACE(_T("in CXListCtrlTestDlg::OnClose\n"));
        CBaseDialog::OnCancel();   // use CDialog if dialog class is derived from CDialog
        //CBaseDialog::OnClose();
    }
That's it! Your dialog app will now ignore the ESC key, but the Close (X) button and the system menu Close will still work.

VS Macro: Decrease/Increase editor font size

When making presentations of code to clients or in code reviews, I always have to increase the font size used in the VS editor, and then decrease it afterward. Brian Schmitt has posted macros to do this:
' Increases the font size used within the editor.
Public Sub IncreaseTextEditorFontSize()
    Dim textEditorFontsAndColors As Properties
    textEditorFontsAndColors = DTE.Properties("FontsAndColors", "TextEditor")
    textEditorFontsAndColors.Item("FontSize").Value += 1
End Sub

' Decreases the font size used within the editor.
Public Sub DecreaseTextEditorFontSize()
    Dim textEditorFontsAndColors As Properties
    Dim fontSize As [Property]

    textEditorFontsAndColors = DTE.Properties("FontsAndColors", "TextEditor")
    fontSize = textEditorFontsAndColors.Item("FontSize")

    If fontSize.Value >= minimumSupportedEditorSize Then
        fontSize.Value -= 1
    End If
End Sub
	

VS Macro: Use google to search MSDN

Let's face it. The last decent F1 help shipped with VS6. Since then it's just a lot faster (and less aggravating) to use google to search MSDN for details about APIs, etc. Here's a macro that opens a google search within the VS IDE, and searches MSDN for the highlighted text:
' Use google to search MSDN
Public Sub GoogleSearch()
    Dim strUrl As String
    Dim selection As TextSelection = DTE.ActiveDocument.Selection()
    If selection.Text <> "" Then
        strUrl = "www.google.com/search?q=msdn+" + selection.Text
        DTE.ExecuteCommand("View.URL", strUrl)
    Else
        MsgBox("Select Text first to Search")
    End If
End Sub
	

VS Macro: Toggle between .h and .cpp files

I do a lot of C++ work, so I have to constantly flip back and forth between the header and .cpp files. This macro saves me from having to first locate the file in the solution explorer:
' Toggle .h/.cpp file
Public Sub Toggle()

    Dim fileName As String = DTE.ActiveDocument.Name
    Dim oFSO As Object
    oFSO = CreateObject("Scripting.FileSystemObject")

    If (fileName.EndsWith(".cpp")) Then
        fileName = fileName.Remove(fileName.IndexOf(".")) + ".h"
    Else
        fileName = fileName.Remove(fileName.IndexOf(".")) + ".cpp"
    End If

    Dim shortPath As String
    Dim strPath As String

    strPath = DTE.ActiveDocument.Path + fileName
    shortPath = oFSO.GetFile(strPath).ShortPath
    DTE.ExecuteCommand("File.OpenFile", shortPath)

End Sub