/*
**************************************************************************
	Copyright (C) 1995

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

  e-mail 73540.3430@compuserve.com
*****************************************************************************
*/


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

#include <windows.h>		    /* required for all Windows applications */


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

#include "main.h"
#include "resource.h"
#include "cadvsink.h"

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

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

LPDATAOBJECT lpd = NULL ;
CAdviseSink *pAdvSink = NULL ;
DWORD dwAdviseConnection ;
DWORD LoadTime = 0, TransferTime = 0 ;
					
SYSTEMTIME st ;
                               
/*
*****************************************************************************
EXTERNS ofglobal variables defined in other files
*****************************************************************************
*/

extern HWND	hMainWnd ;
extern HINSTANCE hInst ;


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

    FUNCTION: MainWndProc(HWND, unsigned, WORD, LONG)

    PURPOSE:  Processes messages


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

static const GUID GUID_TimeData = 
{ 0xe7767a70, 0xa409, 0x11ce, { 0xad, 0xf, 0x0, 0x60, 0x8c, 0x86, 0xb8, 0x9c } };

UINT cfTimeData ;

long WINAPI MainWndProc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{


	switch (message)
	{

		case WM_CREATE:
		{
/*
Register private clipboard formats
*/

			cfTimeData = RegisterClipboardFormat ("TimeDataObject") ;
			return 0 ;
		}

/*
WM_COMMAND is a command from the application menu
*/

		case WM_COMMAND:
		{
                    
			switch (wParam)
			{
				case ID_DATAOBJECT_CREATE:
				{
					HRESULT hr ;

				  	DWORD InitTickCount = GetTickCount ( ) ;

					hr = CoCreateInstance (
						GUID_TimeData,
						NULL,
						CLSCTX_LOCAL_SERVER,
						IID_IDataObject,
						(void **) &lpd) ;

					LoadTime = GetTickCount( ) - InitTickCount ;
					InvalidateRect (hWnd, NULL, TRUE) ;

					if (!SUCCEEDED(hr))
					{
						MessageBox (hWnd, "Couldn't create object", "Error", MB_ICONSTOP) ;
					}
					return 0 ;
				}

				case ID_DATAOBJECT_CREATEDLL:
				{
					HRESULT hr ;

/*
Read class ID from registry key.
*/
					CLSID clsid ;
					hr = CLSIDFromProgID (L"EssenceofOLE.Data3", &clsid) ;
					
					DWORD InitTickCount = GetTickCount ( ) ;

					hr = CoCreateInstance (
						clsid,
						NULL,
						CLSCTX_INPROC_SERVER,
						IID_IDataObject,
						(void **) &lpd) ;

					LoadTime = GetTickCount( ) - InitTickCount ;
					InvalidateRect (hWnd, NULL, TRUE) ;

					if (!SUCCEEDED(hr))
					{
						MessageBox (hWnd, "Couldn't create object", "Error", MB_ICONSTOP) ;
					}
					return 0 ;
				}

				case ID_DATAOBJECT_RELEASE:
				{
					if (lpd)
					{
						lpd->Release( ) ;
						lpd = NULL ;
					}

					InvalidateRect (hWnd, NULL, TRUE) ;
					return 0 ;
				}

				case ID_DATAOBJECT_GETDATA:
				{
					if (lpd)
					{
						FORMATETC fe ;
						STGMEDIUM stm ;

						fe.cfFormat = cfTimeData ;
						fe.ptd = NULL ;
						fe.dwAspect = DVASPECT_CONTENT ;
						fe.lindex = -1 ;
						fe.tymed = TYMED_HGLOBAL ;

					  	DWORD InitTickCount = GetTickCount ( ) ;
					 	if (SUCCEEDED(lpd->GetData (&fe, &stm)))
						{
							TransferTime = GetTickCount( ) -  InitTickCount ;
							InvalidateRect (hWnd, NULL, TRUE) ;

							char *cp ;
							cp = (char *)GlobalLock (stm.hGlobal) ;
							memmove (&st, cp, sizeof (st)) ;
							GlobalUnlock (stm.hGlobal) ;
							ReleaseStgMedium (&stm) ;
							InvalidateRect (hWnd, NULL, TRUE) ;
						}
					}

					return 0 ;
				}

				case ID_DATAOBJECT_TIMETEST:
				{
					DialogBox (hInst, MAKEINTRESOURCE(IDD_DIALOG1) ,hWnd, (DLGPROC)TestDlgProc) ;
					return 0 ;
				}

				case ID_DATAOBJECT_DADVISE:
				{
					FORMATETC fe ;
					HRESULT hr ;

					fe.cfFormat = cfTimeData ;
					fe.ptd = NULL ;
					fe.dwAspect = DVASPECT_CONTENT ;
					fe.lindex = -1 ;
					fe.tymed = TYMED_HGLOBAL ;
				
					pAdvSink = new CAdviseSink ( ) ;					
					hr = lpd->DAdvise (&fe, 0, pAdvSink, &dwAdviseConnection) ;

					if (hr != S_OK) 
					{
						char out [256] ;
						wsprintf (out, "DAdvise failed, hr == 0x%x", hr) ;
						MessageBox (NULL, out, "", 0) ;
					}

					return 0 ;
				}

				case ID_DATAOBJECT_DUNADVISE:
				{
					lpd->DUnadvise (dwAdviseConnection) ;
					delete pAdvSink ;
					pAdvSink = NULL ;
					return 0 ;
				}

				case ID_DATAOBJECT_EXIT:
				{
					SendMessage (hWnd, WM_CLOSE, 0, 0L) ;        
					return 0 ;
				}
				
			}

			return 0 ;
		}


		case WM_INITMENU:
		{
			HMENU hMenu ;

			hMenu = GetMenu (hWnd) ;

			if (lpd)
			{
				EnableMenuItem (hMenu, ID_DATAOBJECT_CREATE, MF_GRAYED) ;
				EnableMenuItem (hMenu, ID_DATAOBJECT_CREATEDLL, MF_GRAYED) ;
				
				EnableMenuItem (hMenu, ID_DATAOBJECT_GETDATA, MF_ENABLED) ;
				EnableMenuItem (hMenu, ID_DATAOBJECT_TIMETEST, MF_ENABLED) ;
				EnableMenuItem (hMenu, ID_DATAOBJECT_RELEASE, MF_ENABLED) ;

				if (!pAdvSink)
				{
					EnableMenuItem (hMenu, ID_DATAOBJECT_DADVISE, MF_ENABLED) ;
					EnableMenuItem (hMenu, ID_DATAOBJECT_DUNADVISE, MF_GRAYED) ;
				}
				else
				{
 					EnableMenuItem (hMenu, ID_DATAOBJECT_DADVISE, MF_GRAYED) ;
					EnableMenuItem (hMenu, ID_DATAOBJECT_DUNADVISE, MF_ENABLED) ;
				}
			}
			else
			{
				EnableMenuItem (hMenu, ID_DATAOBJECT_CREATE, MF_ENABLED) ;
				EnableMenuItem (hMenu, ID_DATAOBJECT_CREATEDLL, MF_ENABLED) ;
				EnableMenuItem (hMenu, ID_DATAOBJECT_GETDATA, MF_GRAYED) ;
				EnableMenuItem (hMenu, ID_DATAOBJECT_TIMETEST, MF_GRAYED) ;
				EnableMenuItem (hMenu, ID_DATAOBJECT_DADVISE, MF_GRAYED) ;
				EnableMenuItem (hMenu, ID_DATAOBJECT_DUNADVISE, MF_GRAYED) ;
				EnableMenuItem (hMenu, ID_DATAOBJECT_RELEASE, MF_GRAYED) ;
			}

			return 0 ;
		}


/*
Shutdown time.  
*/

		case WM_CLOSE:
		{
			DestroyWindow (hWnd) ;
			return 0 ;
		}

	
		case WM_DESTROY:
		{           
		  	PostQuitMessage (0) ;
		  	return 0 ;
		}
		
		case WM_PAINT:
		{
			PAINTSTRUCT ps ;
			HDC hDC ;
			char out [256] ;
			int length ;

			
			hDC = BeginPaint (hWnd, &ps) ;
			
			if (!lpd)
			{
				TextOut (hDC, 0, 0, "<no object>", 11) ;
			}
			else
			{
				length = wsprintf (out, "%2.2d:%2.2d:%2.2d", st.wHour, st.wMinute, st.wSecond) ;
				TextOut (hDC, 0, 0, out, length) ;
			} 

	
			length = wsprintf (out, "Load Time == %d ms", LoadTime) ;
			TextOut (hDC, 0, 100, out, length) ;
			length = wsprintf (out, "Transfer Time == %d ms", TransferTime) ;
			TextOut (hDC, 0, 120, out, length) ;

			EndPaint (hWnd, &ps) ;
			return 0 ;
		}

	}
       
	return DefWindowProc(hWnd, message, wParam, lParam) ;
	
}


