Unicode 関数
文字処理関数の作り方
Win32 API は、文字コードを意識せずにプログラムできるように設計されています
TextOut() 関数の TextOut 自体はプリプロセッサディレクティブで定義されたものであり
UNICODE 定数が定義されていれば TextOutW() 関数を
そうでなければ TextOutA() を呼び出す様に設計されています
基本的には、プログラマはこの詳しい実装を知る必要はありません
直接 TextOutA() をプログラムから呼ぶ必要はありませんし
直接呼び出していたのならば、Unicode 用のプログラムを書くときは
わざわざプログラム内の文字関連の処理を、全て書きなおさなければなりません
これを避けるために、TEXT() マクロや UNICODE 定数が定義されているのです
もっとも、一番良い姿は、全ての環境が UNICODE を完全にサポートすることですが…
ところが、DLL 等で文字列に関連した関数を作成し
多くのプログラムに、これを共存させるには、Win32 API の設計に従い
Unicode 用の関数と ANSI 用の関数を作り、それらを呼び出すマクロを作成します
/*test.h*/
#ifdef __cplucplus
#define DLL_EXPORT extern "C" __declspec (dllexport)
#else
#define DLL_EXPORT __declspec (dllexport)
#endif
DLL_EXPORT VOID CALLBACK SetTextPosition(int);
DLL_EXPORT BOOL CALLBACK WriteLineA(HDC , PCSTR);
DLL_EXPORT BOOL CALLBACK WriteLineW(HDC , PCWSTR);
#ifdef UNICODE
#define WriteLine WriteLineW
#else
#define WriteLine WriteLineA
#endif
/*dll_test.c*/
#include <windows.h>
#include "test.h"
int iPos = 0;
int WINAPI DllEntryPoint(HINSTANCE hInstance , DWORD fdwReason , PVOID pvReserved) {
return TRUE;
}
DLL_EXPORT VOID CALLBACK SetTextPosition(int iPosL) {
iPos = iPosL;
}
DLL_EXPORT BOOL CALLBACK WriteLineA(HDC hdc , PCSTR strText) {
BOOL iReturn;
TEXTMETRIC tm;
GetTextMetrics(hdc , &tm);
iReturn = TextOutA(hdc , 0 , iPos , strText , lstrlenA(strText));
iPos += tm.tmHeight;
return iReturn;
}
DLL_EXPORT BOOL CALLBACK WriteLineW(HDC hdc , PCWSTR strText) {
BOOL iReturn;
TEXTMETRIC tm;
GetTextMetrics(hdc , &tm);
iReturn = TextOutW(hdc , 0 , iPos , strText , lstrlenW(strText));
iPos += tm.tmHeight;
return iReturn;
}
これは、文字列描画用関数を提供する DLL のプログラムと、そのヘッダファイルです
Windows API の仕様に従い、コンパイル時に UNICODE が定義されているかどうかで
WriteLine 定数が示す関数の名前が変化します
この DLL を利用するプログラマは、この内部仕様を知らなくても
単純に WriteLine() 関数として覚え、PCTSTR 型の文字列を渡せば
コンパイルする時に、適切な関数を呼び出すようにプリプロセッサが変換してくれます