すでに知っていることを繰り返している場合は、事前にお詫び申し上げます。
歴史的な理由から (そして便宜上)、文字列パラメーターを受け取る関数 (CreateWindow など) には、ASCII でエンコードされた文字列または Unicode でエンコードされた文字列を受け取る 2 つの実装があることがよくあります。慣例により、それらを区別するために A または W で名前が付けられます (例: CreateWindowA と CreateWindowW)。
通常、生の関数名はマクロ UNICODE に基づいて #define されます (WinUser.h の CreateWindow の定義を見ればわかります)。これが、CreateWindow の使用が CreateWindowW への参照に変わる理由です。
場合によっては、別のパラメーターを追加して CreateWindow などの関数を拡張する必要があります。ここでも慣例により、これらの関数は元の関数名に Ex サフィックスを追加して名前が付けられることがよくあります。それはCreateWindowで起こりました。
CreateWindowとCreateWindowExの定義を比較すると、CreateWindowEx には追加のパラメーター (リストの最初のパラメーター: DWORD dwExStyle) があることがわかります。
WinUser.h の CreateWindowW の定義を見ると、最初のパラメーターの値として 0L を使用し、2 番目から 12 番目の CreateWindowExW パラメーターとして 11 個の CreateWindowW パラメーターを使用して、CreateWindowW が CreateWindowExW の呼び出しに展開されることがわかります。
@Jonathan Wood が既に提案したように、CreateWindow の代わりに CreateWindowEx を使用してコンパイルするコードを取得できます。これを行うには、宣言に dwExStyle パラメータも追加する必要があります。例えば
HWND (WINAPI *pCreateWindow)(DWORD dwExStyle, LPCWSTR lpClassName,
LPCWSTR lpWindowName, DWORD dwStyle,
int x, int y, int nWidth, int nHeight,
HWND hWndParent, HMENU hMenu, HINSTANCE hInstance,
LPVOID lpParam) = CreateWindowEx;
潜在的な「落とし穴」の 1 つは、LPCTSTR ではなく LPCWSTR を使用して lpClassName などのパラメーターを宣言したことです。つまり、非 Unicode ビルドでは CreateWindowEx は ASCII バージョンの CreateWindowExA に展開されますが、文字列パラメーターの型は引き続き W バージョンに展開されるため、不一致が生じます。
一貫性を保つために、LPCWSTR パラメータを LPCTSTR に変更するか、宣言で CreateWindowExW を明示的に使用する必要があります。将来の混乱を避けるために、パラメーター リストと実装に一致するようにポインターの名前を変更することもお勧めします。
HWND (WINAPI *pCreateWindowExW)(DWORD dwExStyle, LPCWSTR lpClassName,
LPCWSTR lpWindowName, DWORD dwStyle,
int x, int y, int nWidth, int nHeight,
HWND hWndParent, HMENU hMenu, HINSTANCE hInstance,
LPVOID lpParam) = CreateWindowExW;