ここに記載した情報は Microsoft Visual C++ 4.2 Enterprise Edition の オンラインヘルプから WIN32 - WIN32SDK - WIN32 Programmer's Reference - Overviews - International Features - Unicode and Character Sets を たどって得た情報を基に、筆者の理解で記述したものです。 誤解、誤読があるかも知れません。
MS-Windows(3.1/95)は、MS-DOS から出発している。Windows-NT は、MS-DOS とは独立に書かれた OS であったが、MS-ODS (like) のアプリケーションを 実行させることも強く意識されている。従って、Microsoft が扱う OS 群に おける文字セットを調べようとすると、まず MS-DOS で使っている(いた) 文字セットを知る必要がある。
OEM コードページMS-DOS は、基本的に PC ベンダーによる提供であった。使う PC により、 MS-DOS は(核の部分は同じでも)異なるものであった、文字セットに ついても同様で、使う PC により、文字セットは異なっていた。 この文字セットを Microsoft は OEM 文字セットと呼び、各 OEM 文字 セットをコードページと呼ばれる番号で区別していた。例えば日本語 MS-DOS で使われている文字セットのコードページは 932 であり、 アメリカ合衆国 MS-DOS で使われている文字セットのコードページは 437 という具合である(本当は、日本語 MS-DOS でも例えば NEC と富士通 では異なる文字があったりしたのだが、どちらも 932)。
当然のことながら、Windows-95 や Windows-NT でも、この OEM コード ページの概念がある。WIN32-SDK には、GetOEMCP() という OEM コード ページを得る関数が用意されている。例えば、次のような簡単なプログラム を作って、コンパイル・リンクして MS-DOS プロンプトで実行してみれば OEM コードページがわかる。
/* Test of the GetOEMCP */ #include <windows.h> #include <stdio.h> void main() { printf( "OEM Code Page:%d\n", (int)GetOEMCP() ); }
Windows の時代になって、Graphical User Interface (GUI) で用いる文字は ソフトウェア的に生成されるようになる。そこで、ここでも文字コードページ の概念が必要になる。例えば東ヨーロッパ用 Windows 3.1 の文字セットの コードページとか、ギリシャ用 Windows 3.1 の文字セットのコードページ などと言ったものが導入される。これらが本当に ANSI で定められたものに なっているかどうか筆者は知らないが、Microsoft は Windows で使用する これらのコードページを ANSI コードページと呼び、先に述べた OEM コード ページと区別する。また、GetOEMCP() に対応した、GetACP() なる関数が用意されている。
しかし、一方 Windows 3.x ではファイルシステムは MS-DOS のファイルシステムのままであるために、Windows 3.x の GUI は ANSI コードページで指定される文字セット、一方ファイルシステム (MS-DOS FAT ファイルシステム)は OEM コードページで指定される 文字セットということになった。当然、この OEM コードページの文字と ANSI コードページの文字との対応(相互変換)が必要となるが、WIN32-SDK では
ネットワークが発達し、文書ファイルが文字セットの異なる国々で交換 されるようになると、異なる文字セット間の変換とか、複数文字セットを 一つの文書ファイルに納める必要が出てくる。そこで、「世界中の文字を 全部含んだ一つの文字セット」を使おうと考えるのは、当然の成り行きで あろう。Windows-NT では文字セットとして、 Unicode 文字セット(正しくは、国際符号化文字集合(UCS) の基本多言語面(BMP - Basic Multilingual Plane)とでも言うのかな)が選べる ようになった。
さて、こうなると話は更にややこしくなる。OEM 文字セット、 Microsoft の言うところの ANSI 文字セット(この言葉は誤解を招く。 ANSI コードページにより指定される文字セットとでも呼ぶべきもの) 及び Unicode 文字セットの間でコード変換が必要になる。 WIN32 では、これらを行う関数として
名前のまぎらわしさはともかく、変換用の関数が用意されているので、変換 そのものは簡単である。例として、OEM コードで入れた文字を Unicode に 変換して、16進でダンプするプログラムを示す。
/* OEM code to Unicode converter */ #include <stdio.h> #include <windows.h> #define MAX_WBUF 255 static WCHAR wbuf[(MAX_WBUF+1)]; void main(int argc, char* argv[]) { int i, n; if(argc != 2) { fprintf(stderr, "Usage: %s string\n", argv[0]); return; } n = MultiByteToWideChar(CP_OEMCP, MB_PRECOMPOSED, argv[1], -1, wbuf, MAX_WBUF ); for( i = 0; i < n; i++ ) printf( "%5d: 0x%04x\n", i, wbuf[i] ); return; }このプログラムを oemtouni という名前にしよう。例えば
0: 0x85e4 1: 0x4e95 2: 0x0020 3: 0x5553 4: 0x6587 5: 0x0000という結果が得られる(コンパイル・リンク済みの実行ファイルと、この ソースを一緒にした tar ファイルは oemtouni.tar (26624 bytes))。