Running State Machines Based Win32/WinCE Programs

The Code

In UML StateWizard (An UML dynamic model tool for concurrent, distributed real time application development ); the procedure is defined as follows :

1. Hooking window messages

The following function MfcHookWnd() hooks a HWND object by subclassing it, in the Windows sense that is by inserting its own window proc ahead of whatever procedure is there currently, usually AfxWndProc. [3]

class CEgnSubclassWnd: public CSubclassWnd 




virtual ~CEgnSubclassWnd();

virtual LRESULT WindowProc(HWND hwnd, UINT msg, WPARAM wp,LPARAM lp);

LRESULT OnExtEvent(MSG& WinMsg);


LRESULT CEgnSubclassWnd::WindowProc(HWND hwnd, UINT msg, WPARAM wp,LPARAM lp)
struct SME_EVENT_T* pExtEvent=NULL;
MSG WinMsg;
WinMsg.hwnd = hwnd;
WinMsg.message =msg;
WinMsg.wParam = wp;
WinMsg.lParam = lp;
LRESULT ret = 0;
switch (msg)
// External event is triggered. App go to running state.
ret = CSubclassWnd::WindowProc(hwnd,msg,wp,lp);
return ret;

2. Dispatching events to state machines

Usually all applications (state machines) run at one thread only. However, state machine engine allows applications to be divided to some groups and the applications in each group runs at its separate thread at one time. The following Figure: Run State Machines Based Win32/WinCE Programs illustrates some groups of applications run at each group respective thread. At each thread, the state machine engine hooks a window which runs at this thread. 

Figure: Running State Machine Based Win32/WinCE Programs

When the state machine engine receives a message dedicated to state machine applications, the state machine engine translates this message to an external event, and dispatch it to the destination application port if it is not null; otherwise dispatch it to all active applications which run in the same application thread context.

When the hooked window is destroyed, the window message hook is removed automatically.

* DESCRIPTION: Just like SmeRun(), this function dispatches external event to applications.
* OUTPUT: None.
struct SME_EVENT_T * GetEventFromQueue();
BOOL DispatchInternalEvents(SME_THREAD_CONTEXT_PT pThreadContext);
BOOL DispatchEventToApps(SME_THREAD_CONTEXT_PT pThreadContext,SME_EVENT_T *pEvent);

LRESULT CEgnSubclassWnd::OnExtEvent(MSG& WinMsg)
SME_APP_T *pApp;
SME_EVENT_T *pEvent=TranslateEvent(&WinMsg);

if (pEvent==NULL)
return 0;

if (g_pfnGetThreadContext)
pThreadContext = (*g_pfnGetThreadContext)();
if (!pThreadContext) return 0;

pApp = pThreadContext->pActAppHdr;

/* Call hook function on an external event coming. */
if (pThreadContext->fnOnEventComeHook)
(*pThreadContext->fnOnEventComeHook)(SME_EVENT_ORIGIN_EXTERNAL, pEvent);

/* Dispatch it to active applications.*/
DispatchEventToApps(pThreadContext, pEvent);


/* Free external event if necessary. */
if (pThreadContext->fnDelExtEvent && pEvent)
// Engine should delete this event, because translation of external event will create an internal event.

return 0;

CEgnSubclassWnd EngSubclassWnd;

BOOL MfcHookWnd(HWND hWndHooked)
if (hWndHooked==NULL || !IsWindow(hWndHooked)) return FALSE;

CWnd *pWnd = CWnd::FromHandle(hWndHooked);
return EngSubclassWnd.HookWindow(pWnd);

BOOL MfcUnhookWnd(HWND hWndHooked)
if (hWndHooked==NULL || !IsWindow(hWndHooked)) return FALSE;

CWnd *pWnd = CWnd::FromHandle(hWndHooked);
return EngSubclassWnd.HookWindow(pWnd);


You might also like...



Why not write for us? Or you could submit an event or a user group in your area. Alternatively just tell us what you think!

Our tools

We've got automatic conversion tools to convert C# to VB.NET, VB.NET to C#. Also you can compress javascript and compress css and generate sql connection strings.

“An idiot with a computer is a faster, better idiot” - Rich Julius