MAKEWPARAM, HIWORD, LOWORD マクロとは?
マクロの定義は次です。
#define LOWORD(l) ((WORD)((DWORD_PTR)(l) & 0xffff)) #define HIWORD(l) ((WORD)((DWORD_PTR)(l) >> 16)) #define MAKELONG(a, b) ((LONG)(((WORD)((DWORD_PTR)(a) & 0xffff)) | ((DWORD)((WORD)((DWORD_PTR)(b) & 0xffff))) << 16)) #define MAKEWPARAM(l, h) ((WPARAM)(DWORD)MAKELONG(l, h))
MAKEWPARAM, HIWORD, LOWORD, MAKEWORD などのマクロ郡では、「下位ワード」「上位ワード」 等の言葉が出てきます。
コードを見て一目瞭然という方は問題ないでしょうが、いまひとつピンと来ない人のために、 実験をしてみました。
テストコードはこちら。
#include <windows.h> #include <stdio.h> void PrintHexDump (DWORD length, PBYTE buffer) { DWORD i,count,index; CHAR rgbDigits[]="0123456789abcdef"; CHAR rgbLine[100]; char cbLine; for(index = 0; length; length -= count, buffer += count, index += count) { count = (length > 16) ? 16:length; sprintf(rgbLine, "%4.4x ",index); cbLine = 6; for(i=0;i<count;i++) { rgbLine[cbLine++] = rgbDigits[buffer[i] >> 4]; rgbLine[cbLine++] = rgbDigits[buffer[i] & 0x0f]; if(i == 7) { rgbLine[cbLine++] = ':'; } else { rgbLine[cbLine++] = ' '; } } for(; i < 16; i++) { rgbLine[cbLine++] = ' '; rgbLine[cbLine++] = ' '; rgbLine[cbLine++] = ' '; } rgbLine[cbLine++] = ' '; for(i = 0; i < count; i++) { if(buffer[i] < 32 || buffer[i] > 126) { rgbLine[cbLine++] = '.'; } else { rgbLine[cbLine++] = buffer[i]; } } rgbLine[cbLine++] = 0; printf("%s\n", rgbLine); } } void print_desc ( char* s ) { HANDLE hStdOut = (HANDLE) GetStdHandle(STD_OUTPUT_HANDLE); CONSOLE_SCREEN_BUFFER_INFO csbi; ::ZeroMemory(&csbi, sizeof(CONSOLE_SCREEN_BUFFER_INFO)); if(!GetConsoleScreenBufferInfo ( hStdOut, &csbi) ) { printf("GetConsoleScreenBufferInfo failed. %u\n", GetLastError()); return; } SetConsoleTextAttribute ( hStdOut, FOREGROUND_GREEN | FOREGROUND_INTENSITY ); printf("%s\n", s); SetConsoleTextAttribute ( hStdOut, csbi.wAttributes ); } void print_value_addr( char* s, int size, void* pv) { printf( "[%s 0x%p]\n", s, pv ); PrintHexDump( size, (PBYTE) pv ); char* pch = (char*) pv; for( int i=0; i < size; i++ ){ printf( " %p - %c\n", pch, *pch ); pch++; } } int main(int argc, char* argv[]){ WORD w1 = MAKEWORD('a','b'); print_desc(" w1 = MAKEWORD('a', 'b')"); print_value_addr ( "w1", sizeof(WORD), &w1 ); WORD w2 = MAKEWORD('c','d'); print_desc(" w2 = MAKEWORD('c', 'd')"); print_value_addr ( "w2", sizeof(WORD), &w2 ); WPARAM wParam = MAKEWPARAM( w1, w2 ); print_desc(" wParam = MAKEWPARAM(w1, w2)"); print_value_addr ( "wParam", sizeof(DWORD), &wParam ); WORD w3 = LOWORD( wParam ); WORD w4 = HIWORD( wParam ); print_value_addr ( "LOWORD(wParam)", sizeof(WORD), &w3 ); print_value_addr ( "HIWORD(wParam)", sizeof(WORD), &w4 ); return 0; }
MAKEWPARAM マクロで WPARAM 値 wParam を作っています。 WPARAM は DWORD (ダブル・ワード) で、4バイトなのですが、それを構成する WORD は MAKEWORD で作っています。
MAKEWPARAM は (「下位ワード」, 「上位ワード」) です。 一方、MAKEWORD は ( 「下位バイト」, 「上位バイト」) です。
> test1 w1 = MAKEWORD('a', 'b') [w1 0x0012FF38] 0000 61 62 ab 0012FF38 - a 0012FF39 - b w2 = MAKEWORD('c', 'd') [w2 0x0012FF2C] 0000 63 64 cd 0012FF2C - c 0012FF2D - d wParam = MAKEWPARAM(w1, w2) [wParam 0x0012FF30] 0000 61 62 63 64 abcd 0012FF30 - a 0012FF31 - b 0012FF32 - c 0012FF33 - d [LOWORD(wParam) 0x0012FF3C] 0000 61 62 ab 0012FF3C - a 0012FF3D - b [HIWORD(wParam) 0x0012FF34] 0000 63 64 cd 0012FF34 - c 0012FF35 - d
以上から下位バイト、下位ワードに値をセットすることは、 アドレスの小さい側にデータを詰めてセットすることに他ならないことが確認できます。