microsoft / CsWin32

A source generator to add a user-defined set of Win32 P/Invoke methods and supporting types to a C# project.
MIT License
2.07k stars 87 forks source link

Addition of MAKELPARAM, MAKEWPARAM, MAKELRESULT macro #997

Closed vitkuz573 closed 1 year ago

vitkuz573 commented 1 year ago

Is your feature request related to a problem? Please describe. While it's not precisely a problem, I've noticed that the codebase could benefit from the inclusion of the macros MAKELPARAM, MAKEWPARAM, and MAKELRESULT.

Describe the solution you'd like I suggest the addition of the macros MAKELPARAM, MAKEWPARAM, and MAKELRESULT to the codebase. These macros would simplify the process of combining two separate values into one, enhancing efficiency and readability of the code.

Describe alternatives you've considered The alternative is to continue with the current method of manually merging these values. However, this isn't as efficient or tidy as using the proposed macros, and it could potentially introduce errors. Therefore, the implementation of these macros would be a valuable improvement to code.

AArnott commented 1 year ago

For reference, the C definitions for these macros are:

#define MAKELONG(a, b)        ((LONG)(((WORD)(a)) | ((DWORD)((WORD)(b))) << 16))
#define MAKEWPARAM(l, h)      ((WPARAM)(DWORD)MAKELONG(l, h))
#define MAKELPARAM(l, h)      ((LPARAM)(DWORD)MAKELONG(l, h))
#define MAKELRESULT(l, h)     ((LRESULT)(DWORD)MAKELONG(l, h))

Some observations/questions to decide on before implementation starts (if we take this suggestion): This looks effectively equivalent in effect. The only difference between them is the return type. The 'macros' would need to be methods on a type somewhere. We have a precedent for this.

AArnott commented 1 year ago

Each of these types (WPARAM, LPARAM, LRESULT) are pointer-sized values. But MAKELONG takes 2 16-bit values and always creates a 32-bit value. In which case I guess the 'high' 32-bits (in a 64-bit process) will always be zero. Is this correct?

vitkuz573 commented 1 year ago

As I understand it, yes, your understanding is correct.

The MAKELONG macro combines two 16-bit values into a 32-bit DWORD (or LONG) value. The lower 16 bits of the result are filled with the wLow word and the higher 16 bits are filled with the wHigh word.

When using this in a 64-bit process, the 'high' 32-bits of the resulting LONG value would indeed be zeros, because the MAKELONG macro is only designed to create a 32-bit value. The remaining 32-bits in a 64-bit context would not be utilized by the result of MAKELONG, and would be zeros unless manipulated separately.