Thursday, December 15, 2011

WINDOW_MESSAGE_DEFINITION

WINDOW_MESSAGE_DEFINITION is used with #include to stamp out code for each window message. One example is when generator is defined.

template<typename WindowClassTag, typename Target>
struct generator {
  typedef
    typename generator_root < WindowClassTag, Target
#   define WINDOW_MESSAGE_DEFINE_BEGIN_GENERATOR
#   include "win32_messages.h"
#   undef WINDOW_MESSAGE_DEFINE_BEGIN_GENERATOR

#   define WINDOW_MESSAGE_DEFINE_END_GENERATOR
#   include "win32_messages.h"
#   undef WINDOW_MESSAGE_DEFINE_END_GENERATOR
    >::type
  type;
};

win32_messages.h contains a #define and #include for each supported window message.

#define WINDOW_MESSAGE_DEFINITION (PAINT,   Paint,   0, ())
#include "win32_message_define.h"

#define WINDOW_MESSAGE_DEFINITION (NCPAINT, NCPaint, 1, (HRGN))
#include "win32_message_define.h"

win32_message_define.h then uses that #define to stamp out code for that message. Here are the salient parts of win32_message_define for the generator definition.

#define WINDOW_MESSAGE_CAPITAL_NAME           TPLT_CALL(TPLT_EXTRACT, TPLT_ARGUMENTS_APPEND_LIST(4, WINDOW_MESSAGE_DEFINITION, 0))
#define WINDOW_MESSAGE_CASED_NAME             TPLT_CALL(TPLT_EXTRACT, TPLT_ARGUMENTS_APPEND_LIST(4, WINDOW_MESSAGE_DEFINITION, 1))
#define WINDOW_MESSAGE_PARAMETER_COUNT        TPLT_CALL(TPLT_EXTRACT, TPLT_ARGUMENTS_APPEND_LIST(4, WINDOW_MESSAGE_DEFINITION, 2))
#define WINDOW_MESSAGE_PARAMETER_LIST         TPLT_CALL(TPLT_EXTRACT, TPLT_ARGUMENTS_APPEND_LIST(4, WINDOW_MESSAGE_DEFINITION, 3))

#if defined(WINDOW_MESSAGE_DEFINE_BEGIN_GENERATOR)

#define WINDOW_MESSAGE_OPTIONAL TPLT_CALL(MAKE_IDENTIFIER_EXPLICIT, (optional, WINDOW_MESSAGE_CASED_NAME))

  , generator<WindowClassTag, Target, decltype(WINDOW_MESSAGE_OPTIONAL(instance_of<Target>::value, instance_of<Context<WindowClassTag>*>::value, 0)) 

#undef WINDOW_MESSAGE_OPTIONAL 

#elif defined(WINDOW_MESSAGE_DEFINE_END_GENERATOR)
  >
#endif

#undef WINDOW_MESSAGE_PARAMETER_LIST
#undef WINDOW_MESSAGE_PARAMETER_COUNT
#undef WINDOW_MESSAGE_CASED_NAME
#undef WINDOW_MESSAGE_CAPITAL_NAME
#undef WINDOW_MESSAGE_DEFINITION

First the arguments are pulled out of the WINDOW_MESSAGE_DEFINITION. Then one of the #if blocks is selected and the parameters are used to fill in the name of a message specific identifier. Now that the macro machinery is exposed, here is the generator definition that is stamped out.

template<typename WindowClassTag, typename Target>
struct generator {
  typedef
    typename generator_root < 
      WindowClassTag, 
      Target
      , generator<
          WindowClassTag, 
          Target, 
          decltype(
            optionalPaint(
              instance_of<Target>::value,
              instance_of<Context<WindowClassTag>*>::value, 
              0)) 

          , generator<
              WindowClassTag, 
              Target, 
              decltype(
                optionalNCPaint(
                  instance_of<Target>::value,
                  instance_of<Context<WindowClassTag>*>::value, 
                  0)) 
         >
       >
    >::type
  type;
};

The 'optional' methods are also generated via the same macros. The only piece missing is another #if block in win32_message_define.h That will be next up..

No comments:

Post a Comment