Windows Via C/Cpp:Appendix A

It will never be too early to think about performance.

Time:2011_10_25
Appendix A:The Build Environment
[
TAG001:
appendix  [ə'pendiks]
n. 附录,盲肠
]

Overview

   To build the sample applications in this book,
   you must deal with compiler and linker switch settings.
   I have tried to isolate these details from the sample applications by putting almost all of these settings in a single header file,
   called CmnHdr.h,which is included in all of the sample application source code files.
[
TAG002:
isolate  ['aisəleit]
vt. 使隔离,使孤立,使绝缘

n. 隔离种群
SOME OTHER CUSTOMAL BASIC USAGES:

1.We should never isolate ourselves from the masses.
我们永远不要脱离群众。
2.Otherwise we shall isolate ourselves from the masses.
否则我们就会脱离群众。
3.To set apart from others;isolate.
使孤立;使隔绝
4.He has isolated an amino acid.
他已把氨基酸分解出来。
5.Do not isolate onese1f from others.
不要把自己孤立起来。

]


   Because i wasn't able to put all of the settings in this header file,
   i made some changes to each sample application's project properties.
   After selecting all projects,i displayed the Properties dialog box and then
   made the  following changes from the Configuration Properties section:

   a)On the General tab,i set the Output Directory so that all final   .exe and .dll files go to a single directory.
   //hyp:the details show below
   //Output Directory: .\..\x86\Debug\ (. means current dir,./.. means uper-level dir is the current dir ,./../x86 means folder x86 in upper level is the current dir.Beautiful and customal.)
   //Intermediate Directory:.\Debug\
   [
   TAG003:
   intermediate  [,intə'mi:djət]
    n. 中间物,调停者;

     a. 中间的,中级的;

   n 中间体;泛指有机合成过程中所得的各种中间产物

    vi 做(...的)中间人,仲裁调停

   ]
   b)On the C/C++,Code Generation tab,i selected the Multi-Threaded DLL value for the RunTime Library field.
   c)On the C/C++ tab,I selected Yes(/Wp64) for the Detect 64-Bit Portability Issues field.
   {HYP:To tell the truth,i did not find this option in my Visual Studio  2010.
   why?Expected to be solved..}

   That's it.
   These are the only settings that i explicitly changed;
   i accepted the default settings for everything else.
   Note that i made the changes mentioned for both the Debug and Release builds of each project.
   I was able to set all other compiler and linker settings in the source code,
   so these settings will be in effect if you use any of my source code modules in your projects.

   [
   TAG004:
   explicitly  [iks'plisitli]
   adv. 明白地


    Note that.....好句子。

    Be in effect.
    1.side effect
n.(药物等到的)副作用

2.stage effect
n. 舞台效果

3.take effect
v.见效,生效

4.field-effect transistor
场效晶体管

5.ground effect
地面效应,大地效应
hyp:need to know more about va. debug build is different from release build.
What is that?

   ]
The CmnHdr.h Header File

   All of the sample programs include the CmnHdr.h header file before any other header file.
   I wrote CmnHdr.h, shown on page 767,to make my life a little easier.
   The file contains macros,linker directives,and other code that is common across all the applications.
   When i want to try something ,
   all i do is modify CmnHdr.h and rebuild all the sample applications.
   CmnHdr.h is in the root directory on the companion content Web page.
   [
   TAG005:
   HYP:HOW TO UNDERSTAND THE LAST SENTENCE,especially the "on the companion content web page"?
   companion  [kəm'pænjən]
n. 朋友,陪伴,指南手册,升降口
vt. 陪伴
  CUSTOMAL BASIC USEFUL USAGES:
  1.I'd like to be her intimate friend and good companion.
我愿做她的挚友良朋。
2.The little girl will be a companion for my small daughter.
那小女孩将做我小女儿的同伴。
3.Companionate:Having the qualities of a companion.
结伴的;同伴的:具有同伴性质的.
4.RoBBed the old couple Blind while employed as a companion.
当被雇佣作同伴时向这对老盲人夫妻进行qiangjie
5.I am your lifetime companion--the spring mattress.
我是您的人生伴侣——席梦思床垫。
   ]


   The reminder of this appendix discusses each section of the CmnHdr.h header file.
   I'll explain the rationale for each section and describle
   how and why you might want to make changes before rebuilding all the sample applications.
   [
   TAG006:
   reminder  [ri'maində]
   n. 起提醒作用的东西

   USAGE:
   A relic is a historical object and reminder of the past.
   relic指历史遗物、遗迹以及纪念物品.

   rationale  [ræʃiə'nɑ:li]
   n. 基本原理



   ]

Microsoft Windows Version Build Options

   Because some of the sample applications call functions that are new in Microsoft Windows Vista,
   this section of CmnHdr.h defines the _WIN32_WINNT and WINVER symbols as follows:

   //= 0x0600 for VISTA level from sdkddkver.h  {HYP:This file is small,see my appendix file--sdkddkver.zip }
   #define _WIN32_WINNT  _WIN32_WINNT_LONGHORN
   #define WINVER        _WIN32_WINNT_LONGHORN


   I have to do this because the new Windows Vista functions are prototyped in the Windows header files like this:

   [
   TAG007:
   prototype  ['prəutətaip]
   n. 原型

   hyp:CreateMutexExW prototype can be found in file WinBase.H,SEE MY APPENDIX FILE WinBase.zip
   ]



   #if (_WIN32_WINNT>=0x0600)
   ...


  WINBASEAPI
  __out_opt
  HANDLE
  WINAPI
  CreateMutexExW(
    __in_opt LPSECURITY_ATTRIBUTES lpMutexAttributes,
    __in_opt LPCWSTR lpName,
    __in     DWORD dwFlags,
    __in     DWORD dwDesiredAccess
    );

   ...
   #endif  /* _WIN32_WINNT>=0x0600 */



   Unless you specifically define _WIN32_WINNT as i have (before including Windows.h),
   the prototypes for the new functions will  not be declared and the compiler will generate errors if you attempt to call these functions.
   Microsoft has protected these functions with the _WIN32_WINNT symbol to help ensure that applications you develop can run on multiple versions of Microsoft Windows.
    [
    TAG008:
    HYP:WHY HERE COMES WITH Windows.h?what is the relationship between windows.h and winbase.h?  i opened the windows.h and found it is a very small file,see appendix windows.zip.
   Unless it's swiftly rooted out, it takes hold and grows, crippling and eventually even killing those who insist on clinging determinedly to it
   如果不尽快铲除仇恨,它就会生根发芽,使那些执意仇恨无法释怀的人致残甚至死亡。

   Unless...,...
   如果不...,那么就会...
]
Unicode Build Option

   I wrote all the sample applications so that they can be compiled as either Unicode or ANSI.
   To enforce consistency with Unicode builds,both UNICODE and _UNICODE symbols are defined in CmnHdr.h.
   For more information on Unicode,see Chapter 2,"Working with Characters and Strings."

   [
   TAG009:
   consistency  [kən'sistənsi]
    n. 坚固性,浓度,一致性
    CUSTOMAL USEFUL USAGES:
1.Resembling mush in consistency;soft.
烂糊的黏得象烂糊食物一样;软的
2.A substance with an oily consistency.
油状物具有滑腻的粘稠度的物质
3.There is no consistency between the movie and the book.
这部电影与书中的情节完全不符。
4.These accounts show no consistency.
这些报道前后不一。
5.Mix flour and liquid to the right consistency.
把面粉和液体混合到适当的浓度.


   ]
Windows Definitions and Warning Level4
   When i develop software, i always try to ensure that the code compiles free of errors and warnings.
   I also like to compile at the highest possible warning level
   so that the compiler does the most work for me and examines even the most minute details for my code.
   For the Microsoft C/C++ compilers,this means that i built all the sample applications using warning level 4.
   [
   TAG010:
   minute  ['minit]
n. 分,分钟,片刻,备忘录,笔记
vt. 记录,摘录,测定时间
a. 微小的,详细的
SO ,here it means "微小的,细微的"
Hyp:From words above we can conclude that the author is very strict with himself at programmiing 。。

hyp:want to know details about C++ warning level?Just see my other passage written today.

   ]
   Unfortunately,Microsoft's operating systems group doesn't share my sentiments about compiling using warning level 4.
   As a result,when i set the sample applications to compile at warning level 4,
   many lines in the Windows header files cause the compiler to generate warnings.
   Fortunately,these warnings do not represent problems in the code.
   Most are generated by unconventional uses of the C language that rely on compiler extensions that
    almost all vendors of Windows-compatible compilers implement.

   In this section of CmnHdr.h,i make sure that the warning level is set to 3 and that CmnHdr.h includes the standard Windows.h header file.
   Once Windows.h is included,i set the warning level to 4 when i compile the rest of the code.
   At warning level 4,the compiler emits "warnings" for things that i don't consider problems,
   So i explicitly tell the compiler to ignore certain benign warnings by using the #pragma warning directive.
   [
   TAG011:
   sentiment  ['sentimənt]
   n. 感情,感伤,情操,情趣,感想,意见;祝愿;贺词

   unconventional  [ʌnkən'venʃənl]
  a. 非传统的

  vendor  ['vendə]
n. 小贩,卖主,自动售货机
   emit  [i'mit]
vt. 发出,放射,吐露,散发,发行

{   --classical and useful basic usages:
1.A volcano emits smoke, lava and ashes.
火山喷出烟、熔岩和灰烬。
2.He emitted a roar of rage.
他发出愤怒的吼叫。
3.Cole often emits a loud sneeze.
科尔常常大声打喷嚏。
4.Animal bodies emit perspiration.
动物身体会出汗。
5.An engine emits smoke from its funnel into the air.
机车通过烟囱把烟排入空气里。

}
  benign  [bi'nain]
a. 良性的
  {   --classical and useful basic usages:
  1.This old man has a benign countenance.
这位老人生得慈眉善目。
2.A benign tumour will not cause you harm.
良性肿瘤不会对你有害。

  }

  pragma   n.
编译注解


   ]


The pragma message Helper Macro

   When i wrote on code,I often like to get something working immediately and then make it bullet-proof later.
   [
   TAG012:
   bullet-proof
   n. 防弹的
   {   --classical and useful basic usages:
1.A thick,down vest;a bulletproof vest.
厚实的羽毛背心;防弹背心
2.A bullet-proof car stops bullets from passing through it.
防弹车防止子弹穿透。
3.The policeman survived because of his bulletproof vest.
警察因穿有防弹背心而幸免于难。

   }]
   To remind myself that some code needs additional attention, i used to include a line like this:

   #pragma message("Fix this later")

   When the compiler compiled this line,it would output a string reminding me that i had some more work to do.
   This message was not that helpful,however.I decided to find a way for the compiler to output the name of the source code file
   and the line number that the pragam appears on.
   Not only would i know that i had additional work to do,but i could also locate the surrounding code immediately.

   To get this behaviour, you have to trick the pragma message directive using a series of macros.
   The result is that you can use the chMSG macro like this:

   #pragma chMSG(Fix this later)

   when the preceding line is compiled ,the compiler produces a line that looks like this:

   c:\cd\commonfiles\cmnhdr.h(82):Fix this later

   Now,using Microsoft Visual Studio,you can double-click on this line in the output window and
   be automatically positioned at the correct place in the correct file.

   As a convenience,the chMSG macro does not require quotes to be used around the text string.


The chINRANGE  Macro

   I freqently use this handy macro in my applications.
   The chINRANGE macro checks to see whether a value is between two other valus.

The chBEGINTHREADEX Macro

   All the multithreaded samples in this book use the beginthreadex function,which is in Microsoft's C/C++ run-time library,
   instead of the operating system's CreateThread function.
   I use the function because the _beginthreadex function prepares the new thread so that it can use the C/C++ run-time library functions
   and because it ensures that the per-thread C/C++ run-time library information is destroyed when the thread returns.
   (See Chapter 6,"Thread Basics,"for more details.)Unfortunately,the _beginthreadex function is prototyped as follows:

    unsigned long  __cdecl  _beginthreadex(
       void *,
       unsigned,
       unsigned (__stdcall  *)(void *),
       void *,
       unsigned,
       unsigned  *
    );


    Although the parameter values for _beginthreadex are identical to the parameter values for the CreateThread functioo,
    the parameters' data types do not match.
    Here is the prototype for the CreateThread function:

    [
    TAG013:
    identical  [ai'dentikəl]
    a. 同一的;完全相同的,相等的;有同一原因的,有同一来源的
    {----CUSTOM BASIC USEFUL  USAGES:
1.The twins are identical.
这对双胞胎长得完全一样。
2.Duplicate: Identical items produced from the same original.
复制:用同一原稿制成相似物品。
3.To consider as identical or united;equate.
认为等同于或完全一致;使相等
4.My opinion is identical with his.
我的意见和他相同。
5.The two photos are identical.
这两张照片完全一样。

    }


    ]
    typedef  DWORD  (WINAPI  * PTHREAD_START_ROUTINE)(PVOID pvParam);

    HANDLE  CreateThread(
         PSECURITY_ATTRIBUTES psa,
         SIZE_T cbStackSize,
         PTHREAD_START_ROUTINE pfnStartAddr,
         PVOID pvParam,
         DWORD dwCreateFlags,
         PDWORD pdwThreadId
         ) ;

    Microsoft did not use the Windows data types when creating the _beginthreadex function's prototype
    because Microsoft's C/C++ run-time group does not want to have any dependencies on the operating system group.
    I commend this decision;however ,this makes using the _beginthreadex function more difficult.

    [
    TAG014:
    hyp:reading this,i just feel not very understanding about it...need to read and think more...
    commend  [kə'mend]
    vt. 委托给,推荐,嘉奖
    {--Basic Custom Useful Usages:

1.His work was highly commended.
他的工作大受称赞。
2.We commended them for their enthusiasm.
我们赞扬了他们的热情。
3.The method commends itself.
这种方法的优点不言自明。


    }

    ]
    There are really two problems with the way Microsoft prototyped the _beginthreadex function.
    First,some of the data types used for the function do not match the primitive types used by the CreateThread function.
    For example,the Windows data type DWORD is defined as follows:

    typedef unsigned long DWORD;

    [
    TAG015:
    primitive  ['primitiv]
n. 原始人,早期艺术家
a. 原始的,上古的,旧式的

    ]
    This data type is used for CreateThread's dwCreateFlags parameter.
    The problem is that _beginthreadex prototypes these two parameters as unsigned,which really means unsigned int.
    The compiler considers an unsigned int  to be different from an unsigned long and generates a warning.
    Because the _beginthreadex function is not a part of the standard C/C++ run-time library and
     exists only as an alternative to calling the CreateThread function ,
    i believe that Microsoft should have prototyped _beginthreadex this way so that warnings are not generated:


     unsigned long__cdecl _beginthreadex(
     void *psa,
     unsigned long cbStackSize,
     unsigned (__stccall *)(void * pvParam),
     void *pvParam,
     unsigned long dwCreateFlags,
     unsigned long *pdwThreadId
     );

     The second problem is just a small variation of the first.
     The _beginthreadex function returns an unsigned long representing the handle of the newly created thread.
     An application typically wants to store this return value in a data variable of type HANDLE as follows:

     HANDLE hThread=_beginthreadex(...);

     The preceding code causes the compiler to generate another warning.
     To avoid the compiler warning,you must rewrite the line just shown,
     introducing a cast as follows:
     [
     TAG016:
     preceding  [pri(:)'si:diŋ]
a. 在先的,在前的,前面的


     ]

     HANDLE hThread=(HANDLE) _beginthreadex(...);

     Again,this is inconvenient.To make life a little easier,
     i defined a chBEGINTHREADEX macro in CmnHdr.h to perform all of this casting for me:

     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

    I sometimes want to force a breakpoint in my code even if the process is not running under a debugger.
    You can do this in Windows by having a thread call the DebugBreak function.
    This function,which resides in Kernel32.dll,lets you attach a debugger to the process.
    Once the debugger is attached ,the instruction pointer is positioned on the CPU instruction that caused the breakpoint.
    This instruction is contained in the DebugBreak function in Kernel32.dll,
    so to see my source code i must single-step out of   the DebugBreak function.
    [
    TAG017:
    reside  [ri'zaid]
   v. 居住,留驻,存在,属于

    ]

    On the X86 architectrue ,you perform a breakpoint by executing an "int 3" CPU instruction.
    So,on x86 platforms,i redefine DebugBreak as this inline assembly language instruction.
    When my DebugBreak is executed,i do not call into Kernel32.dll;
    the breakpoint occurs right in my code and the instruction pointer is positioned to the
    nexe C/C++ language statement.
    This just makes things a little more convenient.

Creating Software Exception Codes

   When you work with software exceptions, you must create your own 32-bit exception codes.
   These codes follow a specific format(discussed in Chapter24,"Exception Handlers and Software Exceptions".
   To make creating these codes easier,i use  the MAKESOFTWAREEXCEPTION macro.

THE chMB Macro
    The chMB macro simply displays a message box.
    The caption is the full pathname of the executable file for the calling process.

The chASSERT and chVERIFY Macros
    To find potential problems as i developed the sample applications,
    I sprinkled chASSERT macros throughout the code.
    This macro tests whether the expression identified by x is TRUE and,
    if it isn't,displays a  message box indicating the file,line,and expression that failed.
    In release builds of the applications,this macro expands to nothing.
    The chVERIFY macro is almost identical to the chaASSERT macro except that
    the expression is evaluated in release builds as well as in debug builds.
     [
     TAG018:
     potential  [pə'tenʃəl]
n. 潜在性,可能性,潜力,潜能,势,位
a. 有潜力的,可能的,潜在的


sprinkle  ['spriŋkl]
vt. 洒,散置,撒,点缀
vi. 洒,下小雨
n. 洒,散置,小雨,少量
{--Basic custom useful usages:
1.Grandma sprinkle the flowers with water.
祖母将水洒在花上。
2.She put a sprinkle of sugar on the top of her cake.
她在蛋糕上洒了一点糖。
3.It began to sprinkle.
下起小雨了。
4.Sprinkle a little salt on the rice.
在米饭上撒点盐.
5.I sprinkle salt on the salad.
我在沙拉上撒盐



}


]
The chHANDLE_DLGMSG Macro

    When you use message crackers with dialog boxes,you should not use the HANDLE_MSG macro from Microsoft's WindowsX.h header file
    because it doesn't return TRUE or FALSE
    to indicate whether a message was handled by the dialog box procedure .
    My chHANDLE_DLGMSG macro messages the window message's return value and handles it properly for use in a dialog box procedure.

The chSETDLGICONS Macro
    Because most of the sample applicatons use a dialog box as their main window,
    you must change the dialog box icon manually so that it is displayed correctly on the taskbar,
    in the task switch window,and in the application's caption itself.
    The chaSETDLGICONS macro is always called when dialog boxes receive a WM_INITDIALOG message so that
    the icons are set correctly.

Forcing the Linker to Look for a (w)WinMain Entry-Point Function

    Some reader of previous editions of this book who added my source code modules to a new Visual Studio project received linker errors when buildign the project.
    The problem was that they created a Win32 Console Application Project,causing the linker to look for a (w)main entry-point function.
    Because all of the book's sample applications are GUI applications,my source code has a _tWinMain entry-point function instead;
    this is why the linker complained.


    My standard reply to readers was that they should delete the project and create a new Win32 project(note that the word "Console" doesn't appear
    in this project type) with Visual Studio and  add my source code files to it.
    The linker looks for a (w)WinMain entry-point function,which i do supply in my code,and the project will build properly..

    To reduce the amount of e-mail i get on this issue,
    i added a pragma to CmnHdr.h that forces the linker to look for the (w)WinMain entry-point function even if you create a Win32 Console Application project with
    Visual Studio.

    In chapter 4,"Processes,"i go into great detail about what the Visual Studio project types are all about,
    how the linker chooses which entry-point function to look for,and how to override the linker's default behavior.

Support XP-Theming of the User Interface with pragma

   Since Windows XP,the system provides glossy-like styles called themes for most of the controls you are using to build your application
   user interface.However,the applications do not support theming by default.An easy way to enable  theme support is to provide with your
   application an XML manifest that requires the binding to the right version of the ComCtl32.DLL module,which takes care of repainting the
   Windows controls the right way.
   The Microsoft C++ linker provides the manifestdependency switch that is set through a pragma directive with the right parameters in CmnHdr.h.
   (Read the "Using Windows XP Visual Styles" page at http://msdn2.microsoft.com/enus/library/ms997646.aspx for more details about theming support.)




   CmnHdr.h
   -------------------------------------------------
   /*************************************************
   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 //////////////////////////////////////
   //If we are not compiling for an x86 CPU,we always compile using Unicode.
   #ifndef  _M_IX86
      #define  UNICODE
   #endif


   //To compile using Unicode on the x86 CPU,uncomment the line below.
   #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)

   /////////////////////////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 chROUNDUUP(TV Value,TM Multiple){
     return (chROUNDDOWN(Value,Multiple)+
     (((Value % Multiple) > 0) ? Multiple : 0));
   }

   //////////////////////////////chBEGINTHREADEX Macro /////////////////////////


   //This macro functin  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(pas,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


   /////////////////////////////////////////////////



   //Useful macro for creating your own software exception codes
   #define MAKESOFTWAREEXCEPTION(Severity,Facility,Exception)   \
       ((DWORD)(\
       /*Severityu 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 chASSERTEAIL(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 chaASSERT(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 WndProc).
       //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 ind){
   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)));
   }


   ////////////////////////////////// Force Windows subsystem///////////////////////

   #pragma comment(linker,"/subsystem:Windows")

   //needed for supporting XP/Vista stylels.

    #pragma  comment(linker,"/manifestdependency:\"type='win32'
    name='Microsoft.Windows.Common-Controls' Version='6.0.0.0'
    processorArchitecture='x86'
    publicKeyToken='6595b64144ccf1df'
    language='*'\"")

  /////////////////////////////////////End of File///////////////////////////////////////

你可能感兴趣的:(windows)