WinAPI不定期小話 『第1話. 怖くない! WinMain』
Windowsアプリケーションを開発するときに欠かせない, WinAPIのMain関数, WinMainについて説明します.
1. WinMainとは
WinMainとは, Windowsアプリケーションを作成するときに必要なやつです. Windowsアプリケーションでは,
int main(){ return 0; }
int WINAPI WinMain(Arg...){ /*なんか処理を行う*/ return 0; }
2. Conclusion
結論から先に書いておくと, 使うべき関数は_tWinMainで、こいつの引数はほぼ要らないよ! っていう話です. 後述しますが, これらの引数はここで保存しなくても必要になったら取得できるのでマジで要らないんです.
3. WinMainを詳しく見る
そもそもWinMain関数ですが, WinMain, wWinMain, _tWinMainの3種類があります.
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow);
int WINAPI wWinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR pCmdLine, int nCmdShow);
#include<tchar.h> int WINAPI _tWinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow);
さて, こちらの3つの関数ですが, まず違いが分かるでしょうか?
そう!! 第3引数が違いますね! LPSTR
とLPWSTR
とLPTSTR
の3種類があることが分かります. ではこれらの違いは何でしょうね. また, 他の意味の分からない引数も一体何なのでしょうね.
あと, 引数名ですが, そもそも言ってしまえば引数名とかどうでもいいんですが, 大体みんなこんな感じの名前を付けるのでそれに倣ってこんな感じの命名で進めていきます.
3-1. 第1引数 hInstance
まずこのHINSTANCE型は一体何でしょうか.
これはHandle of Instance, インスタンスのハンドルです.
は?
何言ってんだ意味分かんねぇんだけど?
ってなると思います. これは雑に説明してしまうと、各アプリケーションに割り当てられた番号の値が保持されていて, つまりこの数字を参照することによって各アプリケーションを参照することが出来るのです.
ところで, この値はGetModuleHandle(nullptr);
関数を使う事によって取得できたりするんですよ. だからこの値保持する必要ないんですよね.
結論: 第1引数 hInstanceは要らない
3-2. 第2引数 hPrevInstance
これなんですけど, Windowsアプリケーションにおいて常にNULLです. 要りません. 結論: 第2数 hPrevInstanceは要らない
3-3. 第3引数
さて, ここで問題の第3引数です.
こいつのやってること自体は簡単で, コマンドライン引数を取得しているだけなんです. ちなみにこの値もGetCommandLine();
関数で取得できるんですよね. まぁちょっと得られる値が微妙に違うんですけど大体同じです. じゃあ保持しなくていいですよね.
そもそもLPSTR
とLPWSTR
とLPTSTR
の意味なんですけど, それぞれLong PointerのSTRとWSTRとTSTRです. Longってのは"歴史的に"以前より長い(大きい)バイト長ってだけで, Pointerはポインター, STRはStringの意味で, C++ではchar型のことを指しています. つまり, それぞれ
LPSTR; //Long Pointer to STRing. char型のポインター LPWSTR; //Long Pointer to WSTRing. wchar型のポインター LPTSTR; //Long Pointer to TSTRing. tchar型のポインター
となります. じゃあchar
とかwchar
とかtchar
ってなんやねんってなりますよね. ここら辺は難しい文字コードの話なんですが, 早い話がchar
ってのが普通のやつで, wchar
はワイド文字ってやつでtchar
ってのは環境によってchar
とwchar
のどちらかに変化する万能君です. つまり, tchar
を使うのがいいぞって話です.
つまり, LPTSTR
を使っている_tWinMain
が一番賢いWinMain
となります.
結論: 要らないけどtchar
が一番賢いのでLPTSTR, つまり_tWinMainを使おう
3-4. 第4引数 nCmdShow
これだけがちょっとクセモノです. この値はShowWindow
っていうウィンドウの表示方法, フルスクリーンとか通常モードとか最小化とかそういう関数の引数として使います。ここだけは唯一保持しておいて同じ値を上記の関数の引数に使用しなければいけないんですが、大体の場合SW_SHOW
か, ラッパしていたらSW_SHOWDEFAULT
が値として入っていると思うので、それを直接指定してもオーケーです.
結論: 時々使うかもしれないんだけど、基本的に要らない
4. 終わりに
WinAPIはとても複雑なので,WinMain関数を語るだけでもこれだけかかってしまいました. しかし普通に使う分にはそこまで考える必要はありませんので, 結果的には_tWinMain
をほとんどの引数を無視して使えばいいわけです. こう言ってしまうとプロに怒られてしまうかもしれませんが, もっと軽い気持ちでいろんな人にWindowsのネイティブ開発をしてもらいたいものです.次回以降ではウィンドウの作成のお話しをしたいと思います. お楽しみに~