RFC: Should we use the macros in windowsx.h to fix -DSTRICT w arni ngs?

Patrik Stridvall ps at leissner.se
Sat Aug 11 04:09:13 CDT 2001

> Patrik Stridvall <ps at leissner.se> writes:
> > Microsoft introduced the windowsx.h macros for a reason and
> > while without inline functions the current implementation
> > of the FORWARD_* macros was the best they could do, it
> > was at least better than nothing since it at least handled
> > the parameter marshalling even if it wasn't 100% type safe.
> I wouldn't rely on Microsoft choices to judge an API design ;-)

Point taken. :-)

However not everything Microsoft does is bad, eventhough I admit
that being sceptical is a good start.
> > Another things to think about:
> > What is the difference between calling  {Set,Get}WindowText
> > functions and calling the FORWARD_WM_{GET,SET}TEXT macros?
> It's a matter of taste. Calling a normal function is perfectly all
> right; 

But they are normal functions. It is just not that apparent that
they really are. Whether this is by design or by accident I
leave unsaid. :-)

Anyway, see below.

> but I find that using a macro (or worse an inline function
> masquerading as a macro) and having to pass it the name of the
> function you want to call is ugly and offensive. If you want to call
> SendMessage, then call SendMessage, don't hide it inside a macro.

It is not hidden in the macro. Which function to call is provided
as the last parameter of the macro.

> Just because you can do all kinds of abuses of the preprocessor in C
> doesn't mean you should.

Well actually, the so called abuses of the preprocesor was for
100% compabillity with Winelib applications, if they abuse the
fact that FORWARD_* might not always be macros (like doing undef
on them). It is possible do it cleaner that the crude example
I provide as well.

Anyway, with the exception of preprocessor abusing application,
which Wine easily can be made not to be.

We can just do it like:
#ifdef __GNUC__
extern inline void FORWARD_WM_COMMAND(HWND hwnd, int id, HWND hwndCtl, UINT
codeNotify, WNDPROC fn)
   fn(hwnd, WM_COMMAND, MAKEWPARAM(id, codeNotify), (LPARAM) hwnd);
#define FORWARD_WM_COMMAND(hwnd, id, hwndCtl, codeNotify, fn) \
            (void)(fn)((hwnd), WM_COMMAND,
MAKEWPARAM((UINT)(id),(UINT)(codeNotify)), (LPARAM)(HWND)(hwndCtl))

if you wish. And if you are worried about preprocessor abusing 
Winelib application we could do #if defined(__GNUC__) && defined(__WINE__)
instead or use some kind of macro wrap around protection of the
kind that I proposed that you didn't like.

Note that the above inline function "abuses" that fact that C autocasts
between functions and pointer to functions, but then it standard
well documented and often used "abuse", so calling it an abuse isn't
really fair (not that you did since my example contained an unnessary &)).

To sum it up:
1. The FORWARD_* API and the HANDLE_* API really are normal functions not
   macros (preprocessor abuses). The fact Micrsoft implemented them as
   because of lack of compiler support for inline functions or because of
   incompetence is irrelevant, we can do it right in a 100% compatible way.
2. The FORWARD_* API provides marshalling of parameters and the HANDLE_*
   API provides unmarshalling of parameters.     
3. The FORWARD_* API provides type safe sending of parameters and the
   HANDLE_* API provides type safe recieving of parameters.

Note that the fact that marshalling and unmarshalling of parameters are
hidden makes that code much more readable and yes, I say it again, 
the FORWARD_* API and HANDLE_* API really are normal functions, there
is no hidden traps for the unwary user. Just a nice wrapper for type safe
marshalling and unmarshalling of parameters.

PS. We could easily rewrite the HANDLE_* API as inline functions as well,
I don't think it gives us anything though. They are good as they are
AFAICS. But if you don't like macros, sure I can rewrite them as inline
functions well. It just a lot of work to no gain AFAICS. It wouldn't
hurt either though.

More information about the wine-devel mailing list