その1 「WinMainのクラス化」
Windowsアプリを開発する上で、最初に出てくる面倒な奴「WinMain」
これを、アプリケーションを作るたびに書かなきゃいけない状況が億劫なので、
ライブラリ内に隠ぺいしてしまいます。
こちらのサイト様を参考にしました。
>> http://code4th.blogspot.jp/2011/06/winmain.html
とても感謝です!!
参考サイトのやり方から私なり作りましたコードは下記
ちなみに、今回のコードは全4ファイルから構成されています
Main.h
Main.cpp
この二つのファイルは、ライブラリ内に入るものではなく実際にライブラリを使用した際に
作成するものとなります
MNMainApp.h
MNMainApp.cpp
この二つのファイルが実際にWinMainを隠ぺいしているライブラリとなります。
補足:今回作っているのは「MNLib」と言うライブラリです。名前だけは一著前にもうつけていますbb
Main.h==================================================
class Main : public MNMainApp
{
public:
Main(void){}
~Main(void){}
void Init();
bool MainLoop();
};
========================================================
Main.cpp================================================
Main main_app;
void Main::Init()
{
bool Main::MainLoop()
{
return true;
}
========================================================
MNMainApp.h=============================================
class MNMainApp
{
public:
// WinMainを丸めこむ為、
static MNMainApp* my_instance;
MNMainApp(void);
virtual ~MNMainApp(void);
virtual bool MainLoop(){return false;}
int Boot();
void SetWindowSize(int w, int h);
void SetWindowName(LPCSTR window_name);
void SetAppName(LPCSTR app_name);
virtual void Init(){};
private:
int InitWindow();
private:
HWND hWnd_;
int window_w_;
int window_h_;
LPCSTR window_name_;
LPCSTR app_name_;
};
//====================================================
MNMainApp.cpp=========================================
HINSTANCE hInstance_;
HINSTANCE prev_instance_;
PSTR cmd_lin_;
int cmd_show_;
LRESULT CALLBACK WndProc(HWND hwnd , UINT msg , WPARAM wp , LPARAM lp) {
switch (msg) {
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hwnd , msg , wp , lp);
}
// WinMain
// windowsアプリが始まると最初にここへ入ります。
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE prev_instance, PSTR cmd_lin, int cmd_show )
{
hInstance_ = hInstance;
prev_instance_ = prev_instance;
cmd_lin_ = cmd_lin;
cmd_show_ = cmd_show;
return MNMainApp::my_instance->Boot();
}
MNMainApp* MNMainApp::my_instance = NULL;
MNMainApp::MNMainApp(void)
: window_w_(800)
, window_h_(600)
, window_name_("MNWindow")
, app_name_("MNApp")
{
my_instance = this;
}
MNMainApp::~MNMainApp(void){}
int MNMainApp::Boot()
{
MNMainApp();
Init();
InitWindow();
MSG msg;
do{
Sleep(1);
if( PeekMessage(&msg, NULL, 0, 0, PM_REMOVE) ){ DispatchMessage(&msg);}
else{
if(!MainLoop())
{
msg.message = WM_QUIT;
}
}
}while(msg.message != WM_QUIT);
return 0;
}
int MNMainApp::InitWindow()
{
WNDCLASS winc;
winc.style = CS_HREDRAW | CS_VREDRAW;
winc.lpfnWndProc = WndProc;
winc.cbClsExtra = winc.cbWndExtra = 0;
winc.hInstance = hInstance_;
winc.hIcon = LoadIcon(NULL , IDI_APPLICATION);
winc.hCursor = LoadCursor(NULL , IDC_ARROW);
winc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
winc.lpszMenuName = NULL;
winc.lpszClassName = window_name_;
if (!RegisterClass(&winc)) return 0;
hWnd_ = CreateWindow(
window_name_ , app_name_ ,
WS_OVERLAPPEDWINDOW ,
100 , 100 , window_w_ , window_h_ , NULL , NULL ,
hInstance_ , NULL
);
if (hWnd_ == NULL) return 0;
ShowWindow(hWnd_ , SW_SHOW);
return 0;
}
void MNMainApp::SetWindowSize(int w, int h)
{
window_w_ = w;
window_h_ = h;
}
void MNMainApp::SetWindowName(LPCSTR window_name)
{
window_name_ = window_name;
}
void MNMainApp::SetAppName(LPCSTR app_name)
{
app_name_ = app_name;
}
//====================================================
基本的な所は、先ほど乗せたサイト様に乗っているので、
実際私が作った所をメインに書いていきます
「int MNMainApp::Boot()」内に入った時に、Windowの生成を行い、
メインループを行います。
この時、ユーザーが諸々の初期化(WindowSizeや名前等)を行えないとまったくもって使えない子になります
そこで、Windowの生成の前に直接Init()を呼び出す事によって、初期化を行えるようにしました。
つまり、Main.cpp内の「void Main::Init()」に「SetWindowSize(1280, 720);」という風に記述するだけで、
Windowのサイズを変更する事が可能になります。
これからDirectXを使ってデバイスの使用をすると思いますが、これらの管理もこのクラスが行う事が出来るので
非常に使い勝手がいい物になるのではないでしょうか?
ただ、今のまんまだとコードが汚い気がするので書きなおそうかしら?
その1はこれにてお終いです。
果たしてサイト様の意図を汲んだコードになったのか不安が残りますが・・・。