MakeXXX macros (MAKEWORD, MAKELONG etc)

Post your working scripts, libraries and tools for AHK v1.1 and older
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

MakeXXX macros (MAKEWORD, MAKELONG etc)

27 Sep 2019, 13:51

INTRO

Every so often I see MakeXXX macros in C++/Winapi code. I tried to decide upon/collect a list of the main ones, and convert them to AHK code.

Do notify of any issues.

LIST

Appear here and in AutoHotkey_H:
AutoHotkey_H New Features
https://hotkeyit.github.io/v2/docs/AHKH_Features.htm
HIBYTE Get high byte from a value.
HIWORD Get high word from a value.
LOBYTE Get low byte from a value.
LOWORD Get low word from a value.
MAKELANGID Make LANGID.
MAKELCID Make LCID.
MAKELONG Make LONG. ['concatenate' two shorts]
MAKELPARAM Make LPARAM. ['concatenate' two shorts, similar to MAKELONG]
MAKELRESULT Make LRESULT. ['concatenate' two shorts, similar to MAKELONG]
MAKEWORD Make WORD. ['concatenate' two bytes]
MAKEWPARAM Make WPARAM. ['concatenate' two shorts, similar to MAKELONG]

Also appear here:
PRIMARYLANGID
SUBLANGID
MAKESORTLCID
LANGIDFROMLCID
SORTIDFROMLCID
SORTVERSIONFROMLCID

Note: there aren't convenient macros above to 'concatenate' two Ints/UInts (32-bit) to a UInt64.

C++ CODE FOR REFERENCE

Code: Select all

==================================================

[source: minwindef.h]

#define MAKEWORD(a, b)      ((WORD)(((BYTE)(((DWORD_PTR)(a)) & 0xff)) | ((WORD)((BYTE)(((DWORD_PTR)(b)) & 0xff))) << 8))
#define MAKELONG(a, b)      ((LONG)(((WORD)(((DWORD_PTR)(a)) & 0xffff)) | ((DWORD)((WORD)(((DWORD_PTR)(b)) & 0xffff))) << 16))
#define LOWORD(l)           ((WORD)(((DWORD_PTR)(l)) & 0xffff))
#define HIWORD(l)           ((WORD)((((DWORD_PTR)(l)) >> 16) & 0xffff))
#define LOBYTE(w)           ((BYTE)(((DWORD_PTR)(w)) & 0xff))
#define HIBYTE(w)           ((BYTE)((((DWORD_PTR)(w)) >> 8) & 0xff))

==================================================

[source: WinUser.h]

#define IS_INTRESOURCE(_r) ((((ULONG_PTR)(_r)) >> 16) == 0)
#define MAKEINTRESOURCEA(i) ((LPSTR)((ULONG_PTR)((WORD)(i))))
#define MAKEINTRESOURCEW(i) ((LPWSTR)((ULONG_PTR)((WORD)(i))))
...
#define POINTSTOPOINT(pt, pts)                          \
        { (pt).x = (LONG)(SHORT)LOWORD(*(LONG*)&pts);   \
          (pt).y = (LONG)(SHORT)HIWORD(*(LONG*)&pts); }

#define POINTTOPOINTS(pt)      (MAKELONG((short)((pt).x), (short)((pt).y)))
#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))

==================================================

[source: winnt.h]

#define MAKELANGID(p, s)       ((((WORD  )(s)) << 10) | (WORD  )(p))
#define PRIMARYLANGID(lgid)    ((WORD  )(lgid) & 0x3ff)
#define SUBLANGID(lgid)        ((WORD  )(lgid) >> 10)
...
#define MAKELCID(lgid, srtid)  ((DWORD)((((DWORD)((WORD  )(srtid))) << 16) |  \
                                         ((DWORD)((WORD  )(lgid)))))
#define MAKESORTLCID(lgid, srtid, ver)                                            \
                               ((DWORD)((MAKELCID(lgid, srtid)) |             \
                                    (((DWORD)((WORD  )(ver))) << 20)))
#define LANGIDFROMLCID(lcid)   ((WORD  )(lcid))
#define SORTIDFROMLCID(lcid)   ((WORD  )((((DWORD)(lcid)) >> 16) & 0xf))
#define SORTVERSIONFROMLCID(lcid)  ((WORD  )((((DWORD)(lcid)) >> 20) & 0xf))

==================================================
Note: didn't implement:
IS_INTRESOURCE, MAKEINTRESOURCEA, MAKEINTRESOURCEW
POINTSTOPOINT, POINTTOPOINTS

AHK CODE

Code: Select all

;==================================================

;source: minwindef.h

MAKEWORD(l, h)
{
	return (l & 0xff) | (h & 0xff) << 8
}
MAKELONG(l, h)
{
	return (l & 0xffff) | (h & 0xffff) << 16
}
LOWORD(l)
{
	return l & 0xffff
}
HIWORD(l)
{
	return (l >> 16) & 0xffff
}
LOBYTE(w)
{
	return w & 0xff
}
HIBYTE(w)
{
	return (w >> 8) & 0xff
}

;==================================================

;source: WinUser.h
;note: AHK stores integers (including UInt64 integers) as Int64
;note: wParam is UPtr (AHK 64-bit: UInt64, AHK 32-bit: UInt)
;note: lParam/lResult are Ptr (AHK 64-bit: Int64, AHK 32-bit: Int)

MAKEWPARAM(l, h)
{
	return (l & 0xffff) | (h & 0xffff) << 16
}
MAKELPARAM(l, h)
{
	;note: equivalent to MAKELRESULT
	ret := (l & 0xffff) | (h & 0xffff) << 16

	;UInt to Int if necessary on 32-bit AHK:
	if (A_PtrSize == 4) && (ret >= 0x80000000)
		return ret - 0x80000000
	return ret
}
MAKELRESULT(l, h)
{
	;note: equivalent to MAKELPARAM
	ret := (l & 0xffff) | (h & 0xffff) << 16

	;UInt to Int if necessary on 32-bit AHK:
	if (A_PtrSize == 4) && (ret >= 0x80000000)
		return ret - 0x80000000
	return ret
}

;==================================================

;source: winnt.h

MAKELANGID(p, s)
{
	return (s << 10) | p
}
PRIMARYLANGID(lgid)
{
	return lgid & 0x3ff
}
SUBLANGID(lgid)
{
	return lgid >> 10
}

MAKELCID(lgid, srtid)
{
	return (srtid << 16) | lgid
}
MAKESORTLCID(lgid, srtid, ver)
{
	lcid := (srtid << 16) | lgid
	return lcid | (ver << 20)
}
LANGIDFROMLCID(lcid)
{
	return lcid & 0xffff
}
SORTIDFROMLCID(lcid)
{
	return (lcid >> 16) & 0xf
}
SORTVERSIONFROMLCID(lcid)
{
	return (lcid >> 20) & 0xf
}

;==================================================
LINKS

[ahkdll-v2-release-master\Compiler\Lib\MAKELONG.ahk contains some versions, however they depend on an undefined 'getvar' function]
AutoHotkey_H
https://hotkeyit.github.io/v2/

Window Macros - Windows applications | Microsoft Docs
https://docs.microsoft.com/en-gb/windows/win32/winmsg/window-macros
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
robodesign
Posts: 934
Joined: 30 Sep 2017, 03:59
Location: Romania
Contact:

Re: MakeXXX macros (MAKEWORD, MAKELONG etc)

28 Sep 2019, 07:16

Superb. Thank you for this. Very useful when dealing with DLL calls.
-------------------------
KeyPress OSD v4: GitHub or forum. (presentation video)
Quick Picto Viewer: GitHub or forum.
AHK GDI+ expanded / compilation library (on GitHub)
My home page.
iPhilip
Posts: 822
Joined: 02 Oct 2013, 12:21

Re: MakeXXX macros (MAKEWORD, MAKELONG etc)

13 Jun 2022, 18:24

jeeswg wrote:
27 Sep 2019, 13:51

Code: Select all

MAKELPARAM(l, h)
{
	;note: equivalent to MAKELRESULT
	ret := (l & 0xffff) | (h & 0xffff) << 16

	;UInt to Int if necessary on 32-bit AHK:
	if (A_PtrSize == 4) && (ret >= 0x80000000)
		return ret - 0x80000000
	return ret
}
MAKELRESULT(l, h)
{
	;note: equivalent to MAKELPARAM
	ret := (l & 0xffff) | (h & 0xffff) << 16

	;UInt to Int if necessary on 32-bit AHK:
	if (A_PtrSize == 4) && (ret >= 0x80000000)
		return ret - 0x80000000
	return ret
}
I believe that these definitions of MAKELPARAM and MAKELRESULT are incorrect. For AHK 32-bit (A_PtrSize = 4), l = 0, and h = 32768 (0x8000), both functions return 0. Microsoft's definition of MAKELPARAM is

Code: Select all

MAKELPARAM(l, h)      ((LPARAM)(DWORD)MAKELONG(l, h))
Because LPARAM is a typedef for Int on AHK 32-bit and Int64 on AHK 64-bit, a proper version of the function might be expressed as:

Code: Select all

MAKELPARAM(X, Y) {
   static Buffer := "0000"
   lParam := (X & 0xFFFF) | ((Y & 0xFFFF) << 16)  ; MAKELONG
   NumPut(lParam, Buffer, A_PtrSize = 8 ? "UInt64" : "UInt")
   return NumGet(Buffer, A_PtrSize = 8 ? "Int64" : "Int")
}
In practice, the following version of MAKELPARAM is sufficient as, for AHK 32-bit, only the first 32 bits of the LPARAM value are used in a DllCall.

Code: Select all

MAKELPARAM(X, Y) {
   return (X & 0xFFFF) | ((Y & 0xFFFF) << 16) 
}
Windows 10 Pro (64 bit) - AutoHotkey v2.0+ (Unicode 64-bit)

Return to “Scripts and Functions (v1)”

Who is online

Users browsing this forum: No registered users and 98 guests