/*
**************************************************************************

	Filename: WINMAIN.C

	Purpose:  Initial entry point for WINSV, the Windows Server


	Rev #		Date	Engineer			Reason
	--------------------------------------------------------------------------
	1.0									Initial Release


	--------------------------------------------------------------------------

	Copyright (C) 1990

	Rolling Thunder Computing, Inc.
	20 Hilltop Terrace
	Woburn MA 01801 USA

*****************************************************************************
*/


/*
*****************************************************************************
System header files
*****************************************************************************
*/

#include	<windows.h>
/*
*****************************************************************************
Application header files
*****************************************************************************
*/


#include "main.h"
#include "resource.h"
/*
*****************************************************************************
Function prototype files
*****************************************************************************
*/


/*
*****************************************************************************
Global Variables defined here
*****************************************************************************
*/


HINSTANCE hInst;
HWND  hMainWnd ;
HWND  hMdiClient ;

/*
*****************************************************************************
EXTERNS of global variables defined in other files
*****************************************************************************
*/




/*
**************************************************************************
*
*		Function Name:  WinMain
*
*		Purpose: initializes, processes message loop
*        Windows recognizes this function by name as the initial entry point
*        for the program.  This function calls the application initialization
*        routine, if no other instance of the program is running, and always
*        calls the instance initialization routine.  It then executes a message
*        retrieval and dispatch loop that is the top-level control structure
*        for the remainder of execution.  The loop is terminated when a WM_QUIT
*        message is received, at which time this function exits the application
*        instance by returning the value passed by PostQuitMessage().
*
*
*		Calling Parmeters, provided automatically by Windows
*			HANDLE hInstance:	 current instance	handle
*			HANDLE hPrevInstance: previous instance handle
*			LPSTR lpCmdLine: command line
*			int nCmdShow:  show-window type (open/icon)
*
*		Returns:
*			NULL if terminated before window message loop activates, otherwise
*			value provided by call elsewhere to PostQuitMessage
*
*		Side Effects: None Known
*
*		Caveats: None Known
*
*
**************************************************************************
*/


int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, 
	LPSTR lpCmdLine, int nCmdShow)
{
    MSG msg;
    WNDCLASS  wc;
 	
	hInst = hInstance ;
	char *Class = "Ole Demo" ;

	
/*
Check for presence of the function CoCreateInstanceEx() in the operating
system DLL Ole32.dll. If not found, then the free threading model is
not supported. Inform user and exit.
*/

	HANDLE hMod = GetModuleHandle ("ole32.dll") ;


	typedef HRESULT (WINAPI *MYPTR)(void *, DWORD);

	MYPTR fpCoInitializeEx = (MYPTR) GetProcAddress (hMod, "CoInitializeEx") ;

	if (fpCoInitializeEx == NULL)
	{
		MessageBox (NULL, "This version of the operating system does not support\
			the free threading model", "Error", MB_OK) ;

		return -1 ;
	}

/* 
Initialize COM for free-threading model.
*/

	HRESULT hr = fpCoInitializeEx (NULL, COINIT_MULTITHREADED) ;


/*
Initialize window classes, exits if it can't
First for the main window
*/

	wc.style = CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW; 			 /* Class style(s).                    */
    wc.lpfnWndProc = MainWndProc;       /* Function to retrieve messages for  windows of this class	*/
    wc.cbClsExtra = 0;                  /* No per-class extra data.           */
    wc.cbWndExtra = 0;                  /* No per-window extra data.          */
    wc.hInstance = hInst;           /* Application that owns the class.   */
    wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    wc.hCursor = LoadCursor(NULL, IDC_ARROW);
    wc.hbrBackground = GetStockObject(WHITE_BRUSH);
    wc.lpszMenuName =  "MainMenu";   /* Name of menu resource in .RC file. */
    wc.lpszClassName = Class; /* Name used in call to CreateWindow. */

	if (RegisterClass(&wc) == FALSE)
	{
		MessageBox (NULL, "FATAL ERROR\nCould not register Main window class", "ERROR", MB_ICONSTOP) ;
		return FALSE ;
	}

	wc.lpszClassName = "FreeChildClass" ;
	wc.lpfnWndProc = FreeChildWndProc ;
	wc.cbWndExtra = 8 ;
	RegisterClass (&wc) ;

	wc.lpszClassName = "AptChildClass" ;
	wc.lpfnWndProc = AptChildWndProc ;
	wc.cbWndExtra = 8 ;
	RegisterClass (&wc) ;


/*
Create a main window for this application instance.
Position and size it as it was the last time it was shut down with SAVE
CHANGES checked
If window could not be created, return "failure"
*/

	char WinText [256] ;
	wsprintf (WinText, "Data6, Free-Threaded Client, Main Thread ID == 0x%x", GetCurrentThreadId( )) ;

    hMainWnd = CreateWindow(Class, WinText, WS_CLIPCHILDREN |WS_OVERLAPPEDWINDOW , 
		CW_USEDEFAULT,  CW_USEDEFAULT, 500, 400,
	 	NULL, NULL, hInst, NULL);


    if (!hMainWnd)
	{
		MessageBox (NULL, "FATAL ERROR\nCould not create Main window", ERROR, MB_ICONSTOP) ;
        return (FALSE);
	}
/*
Create MDI client window
*/

	CLIENTCREATESTRUCT ccs ;

	ccs.hWindowMenu = GetSubMenu (GetMenu(hMainWnd), 1) ;
	ccs.idFirstChild = 100 ;

	hMdiClient = CreateWindow ("MDICLIENT", "", WS_CLIPCHILDREN | WS_CHILD | WS_VISIBLE,
		CW_USEDEFAULT,  CW_USEDEFAULT, 500, 400,
		hMainWnd, (HMENU)1, hInst, &ccs) ;	
/*
Create new threads for MDI child windows -- two free threads and
one apartment thread for demonstration serv
*/

	DWORD ThreadId ;
	HANDLE hThread ;
	
	hThread = CreateThread (NULL, 0, FreeThreadProc, NULL, 0, &ThreadId) ;
	hThread = CreateThread (NULL, 0, FreeThreadProc, NULL, 0, &ThreadId) ;
	hThread = CreateThread (NULL, 0, AptThreadProc, NULL, 0, &ThreadId) ;

/*
Make main window visible; update its client area
Zoom if was zoomed last time changes were saved
*/

    ShowWindow(hMainWnd, nCmdShow);             
	Sleep(0) ;
	PostMessage (hMdiClient, WM_MDITILE, MDITILE_HORIZONTAL , 0) ;

/*
Acquire and dispatch messages until a WM_QUIT message is received.
*/

	while (GetMessage(&msg, NULL, NULL, NULL))		   				
	{
	 	TranslateMessage(&msg);	 
		DispatchMessage(&msg);	   
	}


/*
Shut down OLE libraries
*/

	CoUninitialize ( ) ;


/*
Finished with WinSv application.  Return value from PostQuitMessage
*/                                  

	 return (msg.wParam);

}

