/*
			 Siemens AG
		 Mobile Radio Terminals
		  Munich, Germany

.AUTHOR         P. Lefèvre, PN KE T CP 33

.SHORT_DESCR    Algemeines Windowhandling fuer PC-Testumgebung

.SW_COMPONENT   PC-MMI-Testumgebung

.SW_TYPE        Support-File

.VERSION        0.6

.DATE           11.06.03

.STATUS         FIRST VERSION

.CHANGE_CONTROL
Version |  Date  | Changed by | Reason for Change
  0.0    19.07.96  B. Baier     file created......
  0.1    18.10.96  A. Gräupel   bei der GetPointer,SetPointer Definition
                                 das Flat memory model ergänzt.
  0.2    25.01.00  N. Faisst    added check for _WIN32 defined due to migration
                                Borland -> MS-VC).
  0.3    23.06.00  N. Faisst    changeded call of internal WNDProc to StdWndProc 
								in case of WM_CREATE message
  0.4	 14.12.00  Niels Does	Added a destruction message for the stackwindow
  0.5	 29.04.03  W. Stroell	adaptations for MOPI
  0.6    11.06.03  M. Korkmaz   Added new check algorithm in MainApp::PollMessage function 
                               for new PC-SIMU UI 
*/

#include "smsafxh.h"
#include "simuapph.h"
#include "simu_inith.h"

extern "C"
{
#include <global.h>
#include "listview.h"
}

#include <stdlib.h>

#include "winmain.h"
#include "winrc.h"

HINSTANCE MainApp::hInstance = 0;
HINSTANCE MainApp::hPrevInstance = 0;
int MainApp::nCmdShow = 0;




void MainApp::PollMessage( void )
{
	MSG msg;
	
#if PC_SIMU_USE_NEW_UI
    BOOL bIdle      = TRUE;
	LONG lIdleCount = 0;

	// check to see if we can do idle work.
    // Call OnIdle to do any idle-time processing that the framework may need done. 
    // we need this check for the new user interface of of PC-MMI-Test Environment.
    // For example onupdate functions or during resizing, changing of docking windows (Murat Korkmaz)
	while (bIdle && !::PeekMessage(&msg, NULL, NULL, NULL, PM_NOREMOVE))
	{
		// call OnIdle while in bIdle state
		if (!::AfxGetApp()->OnIdle(lIdleCount++))
			bIdle = FALSE; // assume "no idle" state
	}
#endif // PC_SIMU_USE_NEW_UI

	if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE) == 0)
		return;

	TranslateMessage(&msg);
	DispatchMessage(&msg);
}

void MainApp::Init(HINSTANCE hInstance, HINSTANCE hPrevInstance, int nCmdShow)
{
	MainApp::hInstance = hInstance;
	MainApp::hPrevInstance = hPrevInstance;
	MainApp::nCmdShow = nCmdShow;
}

///////////////////////////////////////////////////////////////////////////

// If data pointers are near pointers
#if defined(__SMALL__) || defined(__MEDIUM__)
inline Window *GetPointer( HWND hWnd )
{
	 return (Window *) GetWindowWord( hWnd, 0 );
}

inline void SetPointer( HWND hWnd, Window *pWindow )
{
	 SetWindowWord( hWnd, 0, (WORD) pWindow );
}

// else pointers are far
#elif defined(__LARGE__) || defined(__COMPACT__) || defined (__FLAT__) || defined (_WIN32)
inline Window *GetPointer( HWND hWnd )
{
	 return (Window *) GetWindowLong( hWnd, 0 );
}
inline void SetPointer( HWND hWnd, Window *pWindow )
{
	 SetWindowLong( hWnd, 0, (LONG) pWindow );
}

#else
	 #error Choose another memory model!
#endif
#ifdef _MSC_VER
__declspec( dllexport ) LRESULT  CALLBACK StdWndProc( HWND hWnd, UINT iMessage, WPARAM wParam, LPARAM lParam )
#else
LRESULT  CALLBACK _export StdWndProc( HWND hWnd, UINT iMessage, WPARAM wParam, LPARAM lParam )
#endif
{
	 // Pointer to the (C++ object that is the) window.
	Window *pWindow = GetPointer( hWnd );

	 // The pointer pWindow will have an invalid value if the WM_CREATE
	 // message has not yet been processed (we respond to the WM_CREATE
	 // message by setting the extra bytes to be a pointer to the
	 // (C++) object corresponding to the Window identified
	 // by hWnd).  The messages that
	 // precede WM_CREATE must be processed without using pWindow so we
	 // pass them to DefWindowProc.
	 // How do we know in general if the pointer pWindow is invalid?
	 // Simple: Windows allocates the window extra bytes using LocalAlloc
	 // which zero initializes memory; thus, pWindow will have a value of
	 // zero before we set the window extra bytes to the 'this' pointer.
	 // Caveat emptor: the fact that LocalAlloc will zero initialize the
	 // window extra bytes is not documented; therefore, it could change
	 // in the future.

	if ( pWindow == 0 )
	{
		if ( iMessage == WM_CREATE )
		{
			LPCREATESTRUCT lpcs;

			lpcs = (LPCREATESTRUCT) lParam;
			pWindow = (Window *) lpcs->lpCreateParams;

			// Store a pointer to this object in the window's extra bytes;
			// this will enable us to access this object (and its member
			// functions) in WndProc where we are
			// given only a handle to identify the window.
			SetPointer( hWnd, pWindow );
			// Now let the object perform whatever
			// initialization it needs for WM_CREATE in its own
			// WndProc.
			// N.F.: as WM_CREATE is called before CreateWindow returns and
			// class member hWnd is initialized with the return value of CreateWindow
			// hWnd member is ont yet initilized at this stage of program execution
			// So calls using hWnd inside of pWindow->WndProc may lead to errors.
			// As no special handling for WM_CREATE messages is used in any of
			// these Window message handling functions just call DefWindowProc
//			return pWindow->WndProc( iMessage, wParam, lParam );
		}
		return DefWindowProc( hWnd, iMessage, wParam, lParam );
	}
	else
	{

		if (iMessage == WM_DESTROY)
		{
			// send childs destroy message
			DestroyListView();
		}
		
		return pWindow->WndProc( iMessage, wParam, lParam );
        }
}

void MMIWindowPoll(void)
{
	MainApp::PollMessage();
}

//////////////////////////////////////////////////////////////////////////



