text: /******************************************************************************
  Module:  CmnHdr.h
  Notices: Copyright (c) 2008 Jeffrey Richter & Christophe Nasarre
  Purpose: Common header file containing handy macros and definitions
           used throughout all the applications in the book.
           See Appendix A.
  ******************************************************************************/
  
  
  #pragma once   // Include this header file once per compilation unit
  
  
  //////////////////////// Windows Version Build Option /////////////////////////
  
  
  // = 0x0600 for VISTA level from sdkddkver.h
  #define _WIN32_WINNT _WIN32_WINNT_LONGHORN 
  #define WINVER       _WIN32_WINNT_LONGHORN 
  
  
  //////////////////////////// Unicode Build Option /////////////////////////////
  
  
  // Always compiler using Unicode.
  #ifndef UNICODE
  	#define UNICODE
  #endif
  
  // When using Unicode Windows functions, use Unicode C-Runtime functions too.
  #ifdef UNICODE
     #ifndef _UNICODE
        #define _UNICODE
     #endif
  #endif
  
  
  ///////////////////////// Include Windows Definitions /////////////////////////
  
  #pragma warning(push, 3)
  #include <Windows.h>
  #pragma warning(pop) 
  #pragma warning(push, 4)
  #include <CommCtrl.h>
  #include <process.h>       // For _beginthreadex
  
  
  ///////////// Verify that the proper header files are being used //////////////
  
  
  #ifndef FILE_SKIP_COMPLETION_PORT_ON_SUCCESS
  #pragma message("You are not using the latest Platform SDK header/library ")
  #pragma message("files. This may prevent the project from building correctly.")
  #endif
  
  
  ////////////// Allow code to compile cleanly at warning level 4 ///////////////
  
  
  /* nonstandard extension 'single line comment' was used */
  #pragma warning(disable:4001)
  
  // unreferenced formal parameter
  #pragma warning(disable:4100)
  
  // Note: Creating precompiled header 
  #pragma warning(disable:4699)
  
  // function not inlined
  #pragma warning(disable:4710)
  
  // unreferenced inline function has been removed
  #pragma warning(disable:4514)
  
  // assignment operator could not be generated
  #pragma warning(disable:4512)
  
  // conversion from 'LONGLONG' to 'ULONGLONG', signed/unsigned mismatch
  #pragma warning(disable:4245)
  
  // 'type cast' : conversion from 'LONG' to 'HINSTANCE' of greater size
  #pragma warning(disable:4312)
  
  // 'argument' : conversion from 'LPARAM' to 'LONG', possible loss of data
  #pragma warning(disable:4244)
  
  // 'wsprintf': name was marked as #pragma deprecated
  #pragma warning(disable:4995)
  
  // unary minus operator applied to unsigned type, result still unsigned
  #pragma warning(disable:4146)
  
  // 'argument' : conversion from 'size_t' to 'int', possible loss of data
  #pragma warning(disable:4267)
  
  // nonstandard extension used : nameless struct/union
  #pragma warning(disable:4201)
  
  ///////////////////////// Pragma message helper macro /////////////////////////
  
  
  /* 
  When the compiler sees a line like this:
     #pragma chMSG(Fix this later)
  
  it outputs a line like this:
  
    c:\CD\CmnHdr.h(82):Fix this later
  
  You can easily jump directly to this line and examine the surrounding code.
  */
  
  #define chSTR2(x) #x
  #define chSTR(x)  chSTR2(x)
  #define chMSG(desc) message(__FILE__ "(" chSTR(__LINE__) "):" #desc)
  
  
  ////////////////////////////// chINRANGE Macro ////////////////////////////////
  
  
  // This macro returns TRUE if a number is between two others
  #define chINRANGE(low, Num, High) (((low) <= (Num)) && ((Num) <= (High)))
  
  
  
  ///////////////////////////// chSIZEOFSTRING Macro ////////////////////////////
  
  
  // This macro evaluates to the number of bytes needed by a string.
  #define chSIZEOFSTRING(psz)   ((lstrlen(psz) + 1) * sizeof(TCHAR))
  
  
  
  /////////////////// chROUNDDOWN & chROUNDUP inline functions //////////////////
  
  
  // This inline function rounds a value down to the nearest multiple
  template <class TV, class TM>
  inline TV chROUNDDOWN(TV Value, TM Multiple) {
     return((Value / Multiple) * Multiple);
  }
  
  
  // This inline function rounds a value down to the nearest multiple
  template <class TV, class TM>
  inline TV chROUNDUP(TV Value, TM Multiple) {
     return(chROUNDDOWN(Value, Multiple) + 
        (((Value % Multiple) > 0) ? Multiple : 0));
  }
  
  
  
  ///////////////////////////// chBEGINTHREADEX Macro ///////////////////////////
  
  
  // This macro function calls the C runtime's _beginthreadex function. 
  // The C runtime library doesn't want to have any reliance on Windows' data 
  // types such as HANDLE. This means that a Windows programmer needs to cast
  // values when using _beginthreadex. Since this is terribly inconvenient, 
  // I created this macro to perform the casting.
  typedef unsigned (__stdcall *PTHREAD_START) (void *);
  
  #define chBEGINTHREADEX(psa, cbStackSize, pfnStartAddr, \
     pvParam, dwCreateFlags, pdwThreadId)                 \
        ((HANDLE)_beginthreadex(                          \
           (void *)        (psa),                         \
           (unsigned)      (cbStackSize),                 \
           (PTHREAD_START) (pfnStartAddr),                \
           (void *)        (pvParam),                     \
           (unsigned)      (dwCreateFlags),               \
           (unsigned *)    (pdwThreadId)))
  
  
  ////////////////// DebugBreak Improvement for x86 platforms ///////////////////
  
  
  #ifdef _X86_
     #define DebugBreak()    _asm { int 3 }
  #endif
  
  
  /////////////////////////// Software Exception Macro //////////////////////////
  
  
  // Useful macro for creating your own software exception codes
  #define MAKESOFTWAREEXCEPTION(Severity, Facility, Exception) \
     ((DWORD) ( \
     /* Severity code    */  (Severity       ) |     \
     /* MS(0) or Cust(1) */  (1         << 29) |     \
     /* Reserved(0)      */  (0         << 28) |     \
     /* Facility code    */  (Facility  << 16) |     \
     /* Exception code   */  (Exception <<  0)))
  
  
  /////////////////////////// Quick MessageBox Macro ////////////////////////////
  
  
  inline void chMB(PCSTR szMsg) {
     char szTitle[MAX_PATH];
     GetModuleFileNameA(NULL, szTitle, _countof(szTitle));
     MessageBoxA(GetActiveWindow(), szMsg, szTitle, MB_OK);
  }
  
  
  //////////////////////////// Assert/Verify Macros /////////////////////////////
  
  
  inline void chFAIL(PSTR szMsg) {
     chMB(szMsg);
     DebugBreak();
  }
  
  
  // Put up an assertion failure message box.
  inline void chASSERTFAIL(LPCSTR file, int line, PCSTR expr) {
     char sz[2*MAX_PATH];
     wsprintfA(sz, "File %s, line %d : %s", file, line, expr);
     chFAIL(sz);
  }
  
  
  // Put up a message box if an assertion fails in a debug build.
  #ifdef _DEBUG
     #define chASSERT(x) if (!(x)) chASSERTFAIL(__FILE__, __LINE__, #x)
  #else
     #define chASSERT(x)
  #endif
  
  
  // Assert in debug builds, but don't remove the code in retail builds.
  #ifdef _DEBUG
     #define chVERIFY(x) chASSERT(x)
  #else
     #define chVERIFY(x) (x)
  #endif
  
  
  /////////////////////////// chHANDLE_DLGMSG Macro /////////////////////////////
  
  
  // The normal HANDLE_MSG macro in WindowsX.h does not work properly for dialog
  // boxes because DlgProc returns a BOOL instead of an LRESULT (like
  // WndProcs). This chHANDLE_DLGMSG macro corrects the problem:
  #define chHANDLE_DLGMSG(hWnd, message, fn)                 \
     case (message): return (SetDlgMsgResult(hWnd, uMsg,     \
        HANDLE_##message((hWnd), (wParam), (lParam), (fn))))
  
  
  //////////////////////// Dialog Box Icon Setting Macro ////////////////////////
  
  
  // Sets the dialog box icons
  inline void chSETDLGICONS(HWND hWnd, int idi) {
     SendMessage(hWnd, WM_SETICON, ICON_BIG,  (LPARAM) 
        LoadIcon((HINSTANCE) GetWindowLongPtr(hWnd, GWLP_HINSTANCE), 
           MAKEINTRESOURCE(idi)));
     SendMessage(hWnd, WM_SETICON, ICON_SMALL, (LPARAM) 
        LoadIcon((HINSTANCE) GetWindowLongPtr(hWnd, GWLP_HINSTANCE), 
        MAKEINTRESOURCE(idi)));
  }
      
  
  /////////////////////////// Common Linker Settings ////////////////////////////
  
  
  #pragma comment(linker, "/nodefaultlib:oldnames.lib")
  
  // Needed for supporting XP/Vista styles.
  #if defined(_M_IA64)
  #pragma comment(linker, "/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='IA64' publicKeyToken='6595b64144ccf1df' language='*'\"")
  #endif
  #if defined(_M_X64)
  #pragma comment(linker, "/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.6000.0' processorArchitecture='amd64' publicKeyToken='6595b64144ccf1df' language='*'\"")
  #endif
  #if defined(M_IX86)
  #pragma comment(linker, "/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='x86' publicKeyToken='6595b64144ccf1df' language='*'\"")
  #endif
  
  
  ///////////////////////////////// End of File /////////////////////////////////
  