Win32 APIを使うとなると、どうしてもHSPでは使われないようなC言語の知識が必要になる部分が出てきてしまいます。この『データ型(data type)』もそういったものの1つです。
データ型とは、データの性格や数値の表現範囲などを規定するためのものです。すなわち、データのサイズや符号の有無、データが変更されるものかどうかを規定します。HSPでは符号付き32ビット整数と文字列の2種類だけですが、C言語では多くの型が存在します。
まず、Cの世界では最も基本的な型として以下のものがあります。(32ビット処理系の場合)
| データ型 | ビット幅 | 呼称 | 範囲 | |
|---|---|---|---|---|
| 文字型 | char | 8 | 文字型 | -128〜127 |
| unsigned char | 8 | 符号なし文字型 | 0〜255 | |
| 整数型 | short (int) | 16 | 符号付き短長整数型 | -32768〜32767 |
| unsigned short (int) | 16 | 符号なし短長整数型 | 0〜65535 | |
| int | 32 | 符号付き(倍長)整数型 | -2147483648〜2147483647 | |
| long (int) | ||||
| unsigned (int) | 32 | 符号なし(倍長)整数型 | 0〜4294967295 | |
| unsigned long (int) | ||||
| 浮動小数点数型 | float | 32 | 単精度実数型 | およそ10-38〜1038(有効数字7桁) |
| double | 64 | 倍精度実数型 | およそ10-308〜10308(有効数字15桁) | |
| 型なし | void | - | - | - |
データ型の中で ( ) で括った部分は省略可能です。
int型やunsigned int型のデータサイズは、16ビット環境では16ビット(2バイト)ですが、32ビット環境では32ビット(4バイト)になります。
さらに、上で示した基本データ型にアスタリスク("*")をつけたものは、そのデータ型へのポインタ(メモリアドレスを格納する変数)を表します。たとえば、「unsigned int*」は「unsignd int」型データへのポインタ、すなわち、「unsignd int」型の変数のアドレスを格納する変数の型を表しています。
また、データ型の先頭に「const」をつけると、それはデータの内容が変更されないことを示します。
さて、Win32 APIを使うプログラミングではこう言ったデータ型に別名をつけて、いろいろなデータの種類をわかりやすく表すようにしています。たとえば、「unsigned short int」に「WORD」という別名をつけて、それを1つの型として扱っています。他にも、「char*」を「LPSTR」としたりしています。以下にWin32 APIで使われる代表的なデータ型の一部を挙げておきます。
| データ型 | 意味 |
|---|---|
| BOOL | TRUE(1と定義)またはFALSE(0と定義)のブール値。通常はFALSEであるかFALSE以外であるかで識別する。 |
| BOOLEAN | TRUE(1と定義)またはFALSE(0と定義)のブール値。通常はFALSEであるかFALSE以外であるかで識別する。(1バイト) |
| BYTE | 8ビット符号なし整数(unsigned char型/1バイト) |
| CHAR | 文字型(char型/1バイト) |
| COLORREF | カラー値 |
| DWORD | 32ビット符号なし整数(unsigned long型 ) |
| HWND | ウィンドウハンドル |
| HDC | デバイスコンテキストハンドル |
| HICON | アイコンハンドル |
| HANDLE | オブジェクトハンドル |
| HBITMAP | ビットマップハンドル |
| HBRUSH | ブラシハンドル |
| HCURSOR | カーソルハンドル |
| HGDIOBJ | GDIオブジェクトハンドル |
| HGLOBAL | グローバルオブジェクトハンドル |
| HIMAGELIST | イメージリストハンドル |
| HINSTANCE | インスタンスハンドル |
| HMENU | メニューハンドル |
| INT | 符号付き整数(int型) |
| LANGID | 言語ID(WORD型/2バイト) |
| LCID | ロケールID(DWORD型/4バイト) |
| LONG | 32ビット符号付き整数(long型) |
| LONGLONG | 64ビット符号付き整数(__int64型/8バイト) |
| LPARAM | 32ビットメッセージパラメータ |
| LPBOOL/PBOOL | BOOL型へのポインタ |
| LPBYTE/PBYTE | BYTE型へのポインタ |
| LPCSTR/PCSTR | 定数ANSI(またはマルチバイト)文字列へのポインタ。(内容が変更されない) |
| LPCTSTR/PCTSTR | ANSI版では定数ANSI(またはマルチバイト)文字列へのポインタ。Unicode版では定数ワイド文字列(Unicode文字列)へのポインタ。(内容が変更されない) |
| LPCVOID | あらゆる型のデータへのポインタ。(内容が変更されない) |
| LPCWSTR/PCWSTR | 定数ワイド文字列(Unicode文字列)へのポインタ。(内容が変更されない) |
| LPDWORD/PDWORD | DWORD型へのポインタ |
| LPHANDLE/PHANDLE | HANDLE型へのポインタ |
| LPINT/PINT | INT型へのポインタ |
| LPLONG/PLONG | LONG型へのポインタ |
| LPSTR/PSTR | ANSI(またはマルチバイト)文字列へのポインタ |
| LPTSTR/PTSTR | ANSI版ではANSI(またはマルチバイト)文字列へのポインタ。 Unicode版ではワイド文字列(Unicode文字列)へのポインタ。 |
| LPVOID/PVOID | あらゆる型のデータへのポインタ |
| LPWORD/PWORD | WORD型へのポインタ |
| LPWSTR/PWSTR | ワイド文字列(Unicode文字列)へのポインタ |
| PBOOLEAN | BOOLEAN型へのポインタ |
| SHORT | 16ビット符号付き整数(short型/2バイト) |
| TCHAR | ANSI版ではCHAR型(1バイト)。Unicode版ではWCHAR型(2バイト)。 |
| UINT | 符号なし整数(unsigned int型) |
| ULONG | 32ビット符号なし整数(unsigned long型) |
| ULONGLONG | 64ビット符号なし整数(unsigned __int64型/8バイト) |
| VOID | 型なし(void型)。 |
| WCHAR | 16ビットワイド文字(Unicode文字)(2バイト) |
| WORD | 16ビット符号なし整数(unsigned short型/2バイト) |
| WPARAM | 32ビットメッセージパラメータ |
さて、HSPでWin32 APIを扱う場合には、データ型そのものは実はあまり問題になりません。問題となるのは、その型の表すデータのサイズなのです。たとえばCHAR型は8ビット(1バイト)であるとか、WORD型は16ビット(2バイト)であるといったことです。上の表で示したデータ型のデータサイズは、明示しているもの以外はすべて32ビット(4バイト)になります。Windowsは32ビット環境であるために、すべてのオブジェクトのハンドルは32ビット(4バイト)の大きさになりますし、ポインタに関しても、すべて32ビット仮想アドレスで表されているのでどのポインタも32ビット(4バイト)の大きさになります。
で、なぜこれらのサイズが問題になるのかというと、たとえばWORD型データ(サイズ2バイト)の配列をHSPで扱う場合を考えてみましょう。HSPの数値変数のサイズは4バイトであるために、スクリプト中で普通に
a = 100, 222, 314, 5413, ……
というように代入したのではWORD型の配列としては
100, 0, 222, 0, 314, 0, 5413, 0, ……
というようになってしまうのです。これでは期待したとおりの結果が得られなくなってしまうでしょう。WORD型の配列で
100, 222, 314, 5413, ……
とするためには、
a.0 = 100 + (222 << 16) ; "+"を"|"にしてもよい
a.1 = 314 + (5413 << 16)
としなくてはならないのです。そのデータ型のデータサイズがいくらかを知ることがHSPでAPIを使っていく上では非常に重要になってきます。