How do I send floats in window messages
What is the best way to send a float in a windows message using c++ casting operators?
The reason I ask is that the approach which first occurred to me did not work. For the 开发者_JS百科record I'm using the standard win32 function to send messages:
PostWindowMessage(UINT nMsg, WPARAM wParam, LPARAM lParam)
What does not work:
-
Using
static_cast<WPARAM>()
does not work sinceWPARAM
is typedef'ed toUINT_PTR
and will do a numeric conversion from float to int, effectively truncating the value of the float. -
Using
reinterpret_cast<WPARAM>()
does not work since it is meant for use with pointers and fails with a compilation error.
I can think of two workarounds at the moment:
-
Using
reinterpret_cast
in conjunction with the address of operator:float f = 42.0f; ::PostWindowMessage(WM_SOME_MESSAGE, *reinterpret_cast<WPARAM*>(&f), 0);
-
Using an union:
union { WPARAM wParam, float f }; f = 42.0f; ::PostWindowMessage(WM_SOME_MESSAGE, wParam, 0);
Which of these are preffered? Are there any other more elegant way of accomplishing this?
Use reinterpret_cast< WPARAM &>(f)
. This cast is not restricted to pointers, it also works with references.
You could use memcpy:
#include <memory.h>
int main() {
float f = 1.0;
int n;
memcpy( &n, &f, sizeof(f) );
}
I don't think there is an elegant solution to this, but whatever you do, I'd wrap it in a function to make it obvious what I was up to:
int FloatToInt( float f ) {
int n;
assert( sizeof(n) == sizeof(f) );
memcpy( &n, &f, sizeof(f) );
return n;
}
I would prefer the union. It is the clearest and easiest to understand. It also probably has the least amount of undefined behavior.
I'd go the simple way of taking a pointer to your float
, casting it to a pointer to UINT
, and then dereferencing the resulting pointer:
WPARAM wParam = *((UINT*)(&f));
To convert it back you do the opposite. Doing the cast at pointer-level makes sure the compiler won't try any "conversion" behind your back.
float f = *((float*)(&wParam))
精彩评论