HelloSFL’s Message Loop
Many application architectures hard code the message loop in the framework as part of the base application class. Instead of hard coding the message loop into the framework, SFL’s message loop is componentized and added to the base application class as a template parameter. In most cases, the job of the message loop component is to create the window on the screen and pump messages. The base class for SFL’s message loop classes is named CMessageLoopBase. -CMessageLoopBase is an abstract class—it has two pure virtual functions CreateMainWindow() and DestroyMainWindow() that SFL expects to be implemented by classes derived from CMessageLoopBase. You’ll see how that’s done in a minute.
Pseudo-code for SFL’s message loop shows the pseudo-code for CMessageLoopBase:
Pseudo-code for SFL’s message loop
class CMessageLoopBase
{
public:
int Run()
{
CreateMainWindow()
RunMessageLoop()
DestroyMainWindow()
}
protected:
virtual void CreateMainWindow() = 0;
virtual void DestroyMainWindow() = 0;
int RunMessageLoop()
{
while (not quit message) {
while(PeekMessage() {
if (OnIdle()) {
}
}
GetMessage()
PreTranslateMessage()
DispatchMessage()
}
}
virtual bool PreTranslateMessage ()
{
::TranslateMessage()
}
// override to change idle processing
virtual bool OnIdle ()
{
}
};
SFL has two classes filling in the implementation of the message loops—-CCreateWindowMessageLoop and CCreateDialogMessageLoop. Both template classes accept a window type and a message loop type. The window type parameter names the kind of window to create and the message loop type (which defaults to CMessageLoopBase) determines how the message loop is to run. SFL’s CCreateWindowMessageLoop class illustrates the declaration of CCreateWindowMessageLoop.
SFL’s CCreateWindowMessageLoop class
template <typename _WindowClass,
typename _Base = CMessageLoopBase>
class CCreateWindowMessageLoop:
public _Base
{
typedef _Base _baseClass;
public:
typedef _WindowClass WindowClass;
void CreateMainWindow();
void DestroyMainWindow();
protected:
_WindowClass* m_pwndMain;
};
For convenience, SFL defines a generic window message creation loop named CMessageLoop. Notice that CMessageLoop is the second template parameter passed into HelloSFL’s CApp class. SFL’s generic message loop shows the CMessageLoop class.
template <typename WindowClass>
class CMessageLoop :
public CCreateWindowMessageLoop<WindowClass,
CMessageLoopDefaultImpl<> >
{
…
};
Once an SFL-based application declares a class derived from CApp, a global instance of the class must appear once in the application. Furthermore, the single application class must be named “_Module” and be derived from ATL’s -CComModule class. (These are ATL’s requirements.)
The _Module class is usually declared externally in the STDAFX.H file. The declaration needs to appear globally because ATL makes several references to the name _Module. HelloSFL’s STDAFX.H file shows how the _Module class is defined within HelloSFL’s stdafx.h file.
-----------------------------------
// stdafx.h : include file for standard system include files,
// or project specific include files that are used frequently, but
// are changed infrequently
//
#pragma once
#define WIN32_LEAN_AND_MEAN
#define _WIN32_WINNT 0x0400
#include <atlbase.h>
#include <Foundation\apps\Application.h>
using namespace stingray;
using namespace foundation;
#include "HelloSFL.h" // CHelloSFLApp class definition
extern CHelloSFLApp _Module;
#include <atlwin.h>
If you go back and look at the definition of HelloSFL’s CApp class, you’ll notice that the second template parameter, the message loop, requires its own template parameters. SFL’s message loop class is responsible for actually creating the application’s main window. The message loop class needs to know what kind of window to create, so that’s passed in as a template parameter. Next you’ll take a look at HelloSFL’s main window.






