Listing 10

struct hwnd_param {
    hwnd_param( HWND val) : val(val) {}
    operator HWND() const { return val; }
    const HWND val;
};
struct msg_param {
    msg_param( UINT val) : val(val) {}
    operator UINT() const { return val; }
    const UINT val;
};
struct w_param_lo {
    w_param_lo(int val) : val(val) {}
    operator int() const { return val; }
    const int val;
};
struct w_param_hi {
    w_param_hi(int val) : val(val) {}
    operator int() const { return val; }
    const int val;
};
template<class param_type = int> struct w_param {
    w_param(param_type val) : val((param_type)val) {}
    operator param_type() const { return val; }
    const param_type val;
};
struct enhance_msg {
    enhance_msg(HWND h, UINT msg, WPARAM w, LPARAM l) 
        : hwnd(h), msg(msg), w(w), l(l) {}
    operator hwnd_param() const { return hwnd_param( hwnd); }
    operator msg_param() const { return msg_param( msg); }
    operator w_param_hi() const { return w_param_hi( HIWORD(w)); }
    operator w_param_lo() const { return w_param_lo( LOWORD(w)); }
    template<class param_type> operator w_param<param_type>() const { return w_param<param_type>(w); }

    HWND hwnd;
    UINT msg;
    WPARAM w;
    LPARAM l;
};
#include <iostream>
void f( hwnd_param h, msg_param m, w_param_lo lo) {
    std::cout << "hwnd " << h << " msg " << m << " wparam_lo " << lo << std::endl;
}
void g( w_param_hi hi, msg_param m) {
    std::cout << "wparam hi" << hi << " msg " << m << std::endl;
}
void h( w_param_lo lo,  msg_param m, w_param<long> w, hwnd_param h) {
    std::cout << "hwnd " << h << " msg " << m << " wparam_lo " << lo << " wparam " << w << std::endl;
}
int main() {
    enhance_msg sample( (HWND)6, WM_DESTROY, 0x01000220, 3);
    g( sample, sample);
    f( sample, sample, sample);
    h( sample, sample, sample, sample);
}