WinMain函数をエントリーにしない方法

各プラットフォームで互換性のあるプログラムを書こうとする場合にどうしても邪魔になるのが、WinMain函数。他のプラットフォームは大概main函数をエントリーとして使っているのに、Windowsだけ、WinMain函数を使わなければなりません。
これがとても鬱陶しいので、WindowsAPIを使うアプリケーションの構築時に、main函数をエントリーポイントにすげかえます。


まず、Visual C++ の場合は、プロジェクトのプロパティを以下のようにします。
リンカ->システム->サブシステム: Windows(/SUBSYSTEM:WINDOWS)
リンカ->詳細->エントリポイント: mainCRTStartup
ちなみに、MinGWの場合は、コンパイル時にオプションとして、"-mwindows"を付加します。


さて、これでmain函数をエントリーポイントにする事ができました。おめでとうございます。


ところで、main函数は、

int main(void);
int main(int argc, char* argv[]);

のどちらかです。
このままでは、WinMain函数のパラメータとして渡されるアプリケーションのインスタンスハンドルなどが取得できません。


というわけですので、取得しましょう。


WinMain函数の引数の内、実際使用されるのは、第一引数のアプリケーションのインスタンスハンドル、第三引数のコマンドラインパラメータ、そして第四引数のデフォルトウィンドウの状態。


これら三種、わざわざWinMain函数の引数から取得しなくても、各々別の函数経由で取得可能です。


アプリケーションのインスタンスハンドルは、

HINSTANCE ApplicationInstance = GetModuleHandle(NULL);

のように、GetModuleHandleにNULLを渡すとその戻り値として取得できます。


またコマンドラインパラメータは、

LPTSTR CommandLineParams = GetCommandLine();

で取得できます。なお、この場合、コマンドラインパラメータの最初のパラメータはアプリケーションのファイルパスです。


最後に、ウィンドウの初期状態ですが、

  STARTUPINFO StartupInfo;

  GetStartupInfo(&lpStartupInfo);

でSTARTUPINFOを取得し、wShowWindowフィールドを参照する事で、ウィンドウの初期状態を取得できます。


あーほんと、Windowsって面倒臭いですねー。