Click here to Skip to main content
Click here to Skip to main content

Tagged as

C++ Header Guard

, 17 Mar 2009 CPOL
Rate this:
Please Sign up or sign in to vote.
Create unique preprocessor macros to prevent multiple header inclusion.


This article is a rework of the idea from an existing article but with the focus on usability and ease of use.

This utility creates unique preprocessor macros to prevent multiple header inclusion. If a filename is specified as a command line argument or a file is dropped onto the dialog, it's name is also included in the macro.

The dialog stays "always on top," accepts dropped shortcuts, snaps to screen edges and can be dragged by its surface. Upon entering a key/OK button, the displayed macro is copied to the clipboard, and the program exits.


The program is designed to be used from inside VC 2005/2008 IDE to generate a unique macro for the currently opened file:



The Code

A unique macro is generated from GUID:

CString CIncludeGen::CreateGuid()
	TCHAR fmtGuid[] = _T("%08lx_%04x_%04x_%02x%02x_%02x%02x%02x%02x%02x%02x");
	GUID guid;

	CString str;
	str.Format(fmtGuid, guid.Data1,guid.Data2,guid.Data3,
			guid.Data4[0], guid.Data4[1], guid.Data4[2], guid.Data4[3],
			guid.Data4[4], guid.Data4[5], guid.Data4[6], guid.Data4[7]);
	return str;

When sending the text to a clipboard, it is necessary to use the HWND of the dialog in OpenClipboard, as stated in MSDN:

"If an application calls OpenClipboard with hwnd set to NULL, EmptyClipboard sets the clipboard owner to NULL; this causes SetClipboardData to fail."

bool CIncludeGen::copy2clipboard(HWND clipbrdowner)
	if (m_text.IsEmpty()) return false;
	bool retVal=true;
		LPTSTR lptstrCopy;
		LPCTSTR txt=m_text;
		HGLOBAL hglbCopy;
		hglbCopy = GlobalAlloc(GMEM_MOVEABLE,
                      (m_text.GetLength() + 1) * sizeof(TCHAR));
		if (hglbCopy != NULL)
			lptstrCopy = (LPTSTR)GlobalLock(hglbCopy);
			memcpy(lptstrCopy, txt, 
                               (m_text.GetLength() * sizeof(TCHAR))); 
			lptstrCopy[m_text.GetLength()] = (TCHAR) 0; // null character 
		if (NULL==::SetClipboardData(CF_UNICODETEXT,
                     hglbCopy)) MessageBeep(-1);
		else retVal=false;
	else retVal=false;
return retVal;

The font for the edit control is created by retrieving the info about current default font and modifying its properties. The edit control is read-only, so the default background color (white) is restored by handling the WM_CTLCOLORSTATIC message:

bool CMainDlg::createEditCtlFont()
	if (m_editCtlFont.IsNull()) return false;
	LOGFONT lfont={0};
	if (0==GetObject(m_editCtlFont,sizeof(LOGFONT), &lfont)) return false;
	if (IsClearTypeEnabled()) lfont.lfQuality=CLEARTYPE_QUALITY;

	lfont.lfPitchAndFamily=FIXED_PITCH | FF_MODERN;
	WCHAR fn[32]=L"Courier New";
	lfont.lfHeight=(LONG)(lfont.lfHeight*1.15);//increase size a bit

	memcpy(lfont.lfFaceName, fn, _countof(fn));
	if (NULL==m_editCtlFont.CreateFontIndirect(&lfont)) return false;
return true;


LRESULT CMainDlg::OnCtlColor(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
	if (((HWND)lParam)==GetDlgItem( IDC_EDIT1 )) return (LRESULT)GetStockObject(
             WHITE_BRUSH );
return ::DefWindowProc(m_hWnd, wParam, lParam, bHandled);

The dialog background color is changed by handling WM_CTLCOLORDLG and returning previously created brush of desired color:

#define INCLHG_DLG_BKGCOLOR RGB(198,209,223)
LRESULT CMainDlg::OnMainDialogColor(UINT uMsg, WPARAM wParam, LPARAM lParam,
    BOOL& bHandled)
return (LRESULT)m_dialogbrush.m_hBrush;

The focus in the dialog form has the OK button, set by calling GotoDlgCtrl(GetDlgItem(IDOK)) and returning FALSE in CMainDlg::OnInitDialog.

Dropped shortcuts are resolved using the function assembled by Igor Vigdorchik. I will leave other features in the code as a readers' exercise.

The project is built with VC 2008 Express, Windows SDK 6.1, WTL 8.0 and ATL 3.0 from Platform SDK R2.


This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


About the Author

Software Developer
Croatia Croatia
No Biography provided

Comments and Discussions

GeneralVery nice idea PinmemberJohn R. Shaw23-Mar-09 16:21 
GeneralJust what I was looking for... Pinmemberloreia18-Mar-09 6:30 
GeneralMy vote of 2 PinmemberRChin17-Mar-09 15:31 
GeneralMy vote of 1 Pinmemberwanft17-Mar-09 12:22 
GeneralRe: My vote of 1 [modified] Pinmemberemilio_grv17-Mar-09 23:02 
#pragma once is today still "microsoft specific" and does not solve ALL the problem a guard can solve.
#pragma once grants a header is not included more than once but doesn't make any "signature" about the presence of a header.
If you need, in another header, to declare different things depending on the fact that a given header is wanted or not, you can only rely on gurds.
think to code like:

/// \file mywindow.h

///define an abstracrtioin for a "window"
/*! implementation is in mywindow.cpp */
class window
   struct blind_data; ///< declared and defined in mywindow.cpp
   blind_data* pdata; ///< create on contruct / delete on destruct
   window(const window&); ///< not implemented - not copyable
   window& operator=(const window&); ///< not impemented - not assignable
   window(); ///<create the inner data - see mywindow.cpp
   ~window(); ///<create the inner data -see mywindow.cpp
   //whatever function you want to manipulate 
   //your window abstraction
   operator HWND() const;
where WIN32_INCLUDED is in a file like
/// \file win32.h
#ifndef WIN32_INCLUDED
#include <windows.h>
#pragma comment(lib, "kernel32.lib")
#pragma comment(lib, "user32.lib")
#pragma comment(lib, "gdi32.lib")
#define WIN32_INCLUDED
#endif //WIN32_INCLUDED
And you main have
/// \file yourfile1.cpp
#include "mywindow.h"

  your code here:
  it use window abstraction,
  but cannot use Windows native API
/// \file yourfile2.cpp
#include "win32.h"
#include "mywindow.h"

  your code here:
  it uses either window abstracction and
  Windws nativce APIs and can get a HWND for a window
  to pass to the native APIs.


2 bugs found.
> recompile ...
65534 bugs found.
D'Oh! | :doh:

modified on Thursday, March 19, 2009 5:31 AM

AnswerRe: My vote of 1 PinmemberT800G18-Mar-09 6:35 
GeneralRe: My vote of 1 PinmemberRick York18-Mar-09 9:24 
GeneralRe: My vote of 1 Pinmemberemilio_grv19-Mar-09 0:30 
GeneralRe: My vote of 1 PinmemberRick York19-Mar-09 8:33 
GeneralRe: My vote of 1 PinmemberGoran Mitrovic18-Mar-09 10:53 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web03 | 2.8.150129.1 | Last Updated 17 Mar 2009
Article Copyright 2009 by T800G
Everything else Copyright © CodeProject, 1999-2015
Layout: fixed | fluid