Run

Run関数は次のようになっています。

int Run(LPTSTR /*lpstrCmdLine*/ = NULL, int nCmdShow = SW_SHOWDEFAULT)
{
	CMessageLoop theLoop;
	_Module.AddMessageLoop(&theLoop);

	CMainFrame wndMain;

	if(wndMain.CreateEx() == NULL)
	{
		ATLTRACE(_T("Main window creation failed!¥n"));
		return 0;
	}

	wndMain.ShowWindow(nCmdShow);

	int nRet = theLoop.Run();

	_Module.RemoveMessageLoop();
	return nRet;
}

やっていることは、

  1. CMessageLoopのインスタンスを作成し、それを_Moduleに追加する。
  2. メインウィンドウを作成し、表示する。
  3. CMessageLoopのRunを呼び出して、メッセージポンプを回す。(この関数から抜けたときはアプリケーションが終了するとき。)
  4. _ModuleからCMessageLoopを抜く。

なぜ、_ModuleにCMessageを追加しているかといえば、グローバルなオブジェクトの_Moduleに追加しておけば、後ほどどこかで必要になったときにひょいと取れるからです。実際SDIのデフォルトのアプリケーションでは、CMainFrameのOnCreateに次のように書かれています。

	// register object for message filtering and idle updates
	CMessageLoop* pLoop = _Module.GetMessageLoop();
	ATLASSERT(pLoop != NULL);
	pLoop->AddMessageFilter(this);
	pLoop->AddIdleHandler(this);

逆に言えば、この部分がなければ、(WTLのウィザードのSDIデフォルトのスケルトンでは)_Moduleに追加する必要はないので、_Module.AddMesssageLoppと_Module.RemoveMessageLoopは、削除しても動きます。