Tips & Tricks
Tip Index
- Convert a VS2008 Project to VS2005
- Detect whether operating system is 32-bit or 64-bit
- Font Type Images
- Fatal error C1083: Cannot open include file: 'uxtheme.h': No such file or directory
- Stop ESC from closing your dialog-based app
VS Macro Index
Convert a VS2008 Project to VS2005
- Make backup copies of the .sln and .vcproj files of the project you want to convert.
- Edit the .sln files and replace
Microsoft Visual Studio Solution File, Format Version 10.00 # Visual Studio 2008
withMicrosoft Visual Studio Solution File, Format Version 9.00 # Visual Studio 2005
- 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:
- In VS6, the Platform SDK will appear under Tools | Options | Directories | Include Files.
- In VS2008, the Platform SDK will appear under Tools | Options | Projects and Solutions | VC++ Directories | Include Files.
- 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):
-
In XListCtrlTestDlg.h, add the following message map functions:
virtual void OnCancel(); afx_msg void OnClose(); -
In XListCtrlTestDlg.cpp, add the following to the message map:
ON_WM_CLOSE()
-
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(); }
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