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

	Copyright (C) 1995

	Rolling Thunder Computing, Inc.
	25 Heartbreak Rd
	Ipswich MA 01938

	E-Mail: 73540.3430@compuserve.com

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


/*
*****************************************************************************
System header files
*****************************************************************************
*/
#define _WIN32_DCOM

#include	<windows.h>
#include 	<initguid.h>

/*
*****************************************************************************
Application header files
*****************************************************************************
*/


#include "main.h"
#include "cclassf.h"


/*
*****************************************************************************
Function prototype files
*****************************************************************************
*/


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


HINSTANCE hInst;
HWND  hMainWnd ;

UINT cfTimeData, cfThreadId ;


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

// {FE202EF1-8057-11d0-90B8-00608C86B89C}
static const GUID GUID_ApartmentThreadedTimeDataLocal = 
{ 0xfe202ef4, 0x8057, 0x11d0, { 0x90, 0xb8, 0x0, 0x60, 0x8c, 0x86, 0xb8, 0x9c } };

// {FE202EF2-8057-11d0-90B8-00608C86B89C}
static const GUID GUID_FreeThreadedTimeDataLocal = 
{ 0xfe202ef5, 0x8057, 0x11d0, { 0x90, 0xb8, 0x0, 0x60, 0x8c, 0x86, 0xb8, 0x9c } };


CRITICAL_SECTION csShutdown ;
BOOL bShuttingDownNow = FALSE ;

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, 
	LPSTR lpCmdLine, int nCmdShow)
{
    MSG msg;
    WNDCLASS  wc;
 	CLSID ClsidToRegister ;

	hInst = hInstance ;
	char *Class = "Ole Demo" ;
	HRESULT	hr ;
	InitializeCriticalSection (&csShutdown) ;

/*
Initialize OLE Libraries
*/

	BOOL bApartment ;

	if (strstr (lpCmdLine, "-Apt"))
	{
		bApartment = TRUE ;
		ClsidToRegister = GUID_ApartmentThreadedTimeDataLocal ;
		hr = CoInitializeEx (NULL, COINIT_APARTMENTTHREADED) ;
	}
	else
	{
		ClsidToRegister = GUID_FreeThreadedTimeDataLocal ;
		bApartment = FALSE ;
		hr = CoInitializeEx (NULL, COINIT_MULTITHREADED) ;
	}

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

	wc.style = CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW; 			              
    wc.lpfnWndProc = MainWndProc;       
    wc.cbClsExtra = 0;                 
    wc.cbWndExtra = 0;                 
    wc.hInstance = hInst;          
    wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    wc.hCursor = LoadCursor(NULL, IDC_ARROW);
    wc.hbrBackground = GetStockObject(WHITE_BRUSH);
    wc.lpszMenuName =  NULL;    
    wc.lpszClassName = Class;

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



/*
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 Title [256] ;
	wsprintf (Title, "Data6 Local Server, Thread ID == 0x%x,", GetCurrentThreadId( )) ;

	if (bApartment)
	{
		strcat (Title, " Apartment Threaded") ;
	}
	else
	{
		strcat (Title, " Free Threaded") ;
	}

    hMainWnd = CreateWindow (Class,                    
        Title,     
        WS_OVERLAPPEDWINDOW | WS_VISIBLE ,         
	 	CW_USEDEFAULT,  CW_USEDEFAULT,   
	 	600, 200,
	 	NULL, NULL, hInst, NULL);


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

/*
Register private clipboard formats
*/

	cfTimeData = RegisterClipboardFormat ("TimeDataObject") ;
	cfThreadId = RegisterClipboardFormat ("ThreadId") ;

/*
Check command line to see if launched as an OLE server.  If so, register
the class factory for this app.
*/

	DWORD dwRegister ;
	BOOL bRegister = FALSE ;

	if (strstr (lpCmdLine, "-Embedding"))
	{
		LPCLASSFACTORY pCF = new CClassFactory ( ) ;

		hr = CoRegisterClassObject(
			ClsidToRegister, pCF, 
			CLSCTX_LOCAL_SERVER,
			REGCLS_MULTIPLEUSE | REGCLS_SUSPENDED,
			&dwRegister) ;

		if (hr == S_OK)
		{
			bRegister == TRUE ;
		}
		else
		{
			MessageBox (NULL, "Couldn't register class factory", "", 0) ;
		}
	}
/*
Resume class objects, telling server that it's open for business.
*/

	hr = CoResumeClassObjects ( ) ;

	if (hr != S_OK)
	{
		MessageBox (NULL, "Couldn't resume class objects", "", 0) ;
	}

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

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

/*
App going down, shut down class factory
*/

	if (bRegister)
	{
		CoRevokeClassObject (dwRegister) ;
	}


/*
Shut down OLE libraries
*/

	CoUninitialize ( ) ;

/*
Finished with WinSv application.  Return value from PostQuitMessage
*/                                  
	DeleteCriticalSection (&csShutdown) ;

	 return (msg.wParam);

}


void LockThisObjectsServer ( ) 
{
	CoAddRefServerProcess( ) ;
}

void UnlockThisObjectsServer ( ) 
{
	EnterCriticalSection (&csShutdown) ;

	int count = CoReleaseServerProcess( ) ;

	if (count == 0)
	{
		PostMessage (hMainWnd, WM_CLOSE, 0, 0) ;
		bShuttingDownNow = TRUE ;
	}

	LeaveCriticalSection (&csShutdown) ;
}