/*
*********************************************************************
*
*	The Essence of OLE
*
*	Source code sample
*
*	Copyright (c) 1996, Rolling Thunder Computing, Ipswich MA
*
*	e-mail: essence@rollthunder.com
*	CompuServe: 73540.3430
*	Web: http://www.rollthunder.com
*
*	File Name: MAINWIND.CPP
*
*	Purpose: Main window response function
*
*********************************************************************
*/


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

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


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

#include "main.h"
#include "resource.h"
#include "cdroptgt.h"   
#include "cdropsrc.h"
#include "ctxtdata.h"

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

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

LPCDROPTARGET lpDropTarget ;
char DisplayText [DISPLAY_TEXT_LENGTH] = {0x00};          
int xText, yText ;
                               
/*
*****************************************************************************
EXTERNS ofglobal variables defined in other files
*****************************************************************************
*/

extern HWND	hMainWnd ;
extern HINSTANCE hInst ;


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

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

    PURPOSE:  Processes messages


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

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


	switch (message)
	{

		case WM_CREATE:
		{   
					                                       
			HRESULT hr ;
/*
Set up a drop target.  Instantiate a CDropTarget object and AddRef( ) it
to keep it in memory.  Register it with OLE.  
*/

			lpDropTarget = new CDropTarget ( ) ;     
			lpDropTarget->AddRef( ) ;
           	hr = CoLockObjectExternal (lpDropTarget, TRUE, FALSE) ;     
            
			hr = RegisterDragDrop (hWnd, lpDropTarget) ;
					
			return 0 ;
		
		}
		
/*
Menu is starting to be displayed. Ask OLE for the clipboard contents packaged
into a data object.  Then use the object's QueryGetData( ) method to see
if it contains data that can be rendered as CF_TEXT in and HGLOBAL medium.
If so, enable the menu item, otherwise gray it out.  Do the same for
the metafile format.
*/

		case WM_INITMENU:
       	{   
       		FORMATETC fe ; 
       		LPDATAOBJECT lpd ; 
       		HRESULT hr ;  
		
       		fe.cfFormat = CF_TEXT ;
    		fe.ptd = NULL ;
    		fe.tymed = TYMED_HGLOBAL ;  
    		fe.dwAspect = DVASPECT_CONTENT ; 
    		fe.lindex = -1 ;
    		
       		hr = OleGetClipboard (&lpd) ;  
       		
			if (!lpd ||  lpd->QueryGetData (&fe) != S_OK)
			{            
       	    	EnableMenuItem ((HMENU)wParam, ID_DEMO_PASTETEXT, MF_GRAYED) ;
       		}      
       		else
       		{   
       			EnableMenuItem ((HMENU)wParam, ID_DEMO_PASTETEXT, MF_ENABLED) ;
       		} 
       		
			fe.cfFormat = CF_METAFILEPICT ;
    		fe.tymed = TYMED_MFPICT ;  
			if (!lpd ||  lpd->QueryGetData (&fe) != S_OK)
			{            
       	    	EnableMenuItem ((HMENU)wParam, ID_DEMO_PASTEMETAFILE, MF_GRAYED) ;
       		}      
       		else
       		{   
       			EnableMenuItem ((HMENU)wParam, ID_DEMO_PASTEMETAFILE, MF_ENABLED) ;
       		} 

       		if (lpd) lpd->Release( ) ;
       		
       		return 0 ;
       	}
       			
/*
WM_COMMAND is a command from the application menu
*/

		case WM_COMMAND:
		{
                    
			switch (wParam)
			{
				case ID_DEMO_EXIT:
				{
					SendMessage (hWnd, WM_CLOSE, 0, 0L) ;        
					return 0 ;
				}
				
/*
User wants to paste clipboard text into the app.  Get the clipboard contents
packaged as a data object.  Use the data object's GetData( ) method to 
retrieve the data from the object. Release the storage medium in which the
data was transferred, and also the data object itself.
*/
				case ID_DEMO_PASTETEXT:
				{   
					LPDATAOBJECT lpd ;     
					STGMEDIUM stg ; FORMATETC fe ; HRESULT hr ;
					LPSTR cp ; 
									        
					OleGetClipboard (&lpd) ;  
							
    				fe.cfFormat = CF_TEXT ;
    				fe.ptd = NULL ;
		    		fe.tymed = TYMED_HGLOBAL ;  
    				fe.dwAspect = DVASPECT_CONTENT ; 
    				fe.lindex = -1 ;
                   
					hr = lpd->GetData (&fe, &stg) ;
					cp = (LPSTR) GlobalLock (stg.hGlobal) ;
					lstrcpyn (DisplayText, cp, 127) ;
					GlobalUnlock (stg.hGlobal) ;
					
					ReleaseStgMedium (&stg) ;
					lpd->Release( ) ;
					
					xText = 0 ;
					yText = 0 ;	
					InvalidateRect (hMainWnd, NULL, TRUE) ;
			        					
					return 0 ;
				
				}  

				case ID_DEMO_PASTEMETAFILE:
				{
				 	LPDATAOBJECT lpd ;     
					STGMEDIUM stg ; FORMATETC fe ; HRESULT hr ;
					METAFILEPICT *pMF ;
							        
					OleGetClipboard (&lpd) ;  
							
    				fe.cfFormat = CF_METAFILEPICT ;
    				fe.ptd = NULL ;
		    		fe.tymed = TYMED_MFPICT ;  
    				fe.dwAspect = DVASPECT_CONTENT ; 
    				fe.lindex = -1 ;
                   
					hr = lpd->GetData (&fe, &stg) ;
					pMF = (METAFILEPICT *) stg.hGlobal	;			
					
					HDC hDC = GetDC (hWnd) ;
					PlayMetaFile (hDC,pMF->hMF) ;
					ReleaseDC (hWnd, hDC) ;
				
					ReleaseStgMedium (&stg) ;
					lpd->Release( ) ;

				}

/*
Copy data to clipboard
*/

				case ID_DEMO_COPYTEXT:
				{
					LPCTEXTDATA lpd = new CTextData (DisplayText) ;
					OleSetClipboard (lpd) ;
					lpd->Release ( ) ;
					return 0 ;
				}

				case ID_DEMO_EDITTEXT:
				{
					if (DialogBox (hInst, MAKEINTRESOURCE (IDD_DIALOG1), 
						hWnd, (DLGPROC) EditDlgProc))
					{
						InvalidateRect (hWnd, NULL, TRUE) ;
					}
					return 0 ;
				}
			}

			return 0 ;

		}



		case WM_LBUTTONDOWN:
		{
			DWORD dwEffect ;

			LPCTEXTDATA lpd = new CTextData (DisplayText) ;
			LPDROPSOURCE lps = new CDropSource ( ) ;


			if (DoDragDrop (lpd, lps, DROPEFFECT_COPY | DROPEFFECT_MOVE,
				&dwEffect) == DRAGDROP_S_DROP)
			{
			 	if (dwEffect & DROPEFFECT_MOVE)
				{
					DisplayText [0] = 0x00 ;
					InvalidateRect (hWnd, NULL, TRUE) ;
				}
			}

			lpd->Release( ) ;
			lps->Release( ) ;

			return 0 ;
		}
  
/*
Shutdown time.  Revoke the drag and drop operation and Release( ) the drop
target object.  Then uninitialize the OLE libraries.
*/

		case WM_CLOSE:
		{
			RevokeDragDrop (hWnd) ;
			CoLockObjectExternal (lpDropTarget, FALSE, TRUE) ;
			lpDropTarget->Release( ) ;
			 
			DestroyWindow (hWnd) ;
			return 0 ;
			
		}

	
		case WM_DESTROY:
		{           
		  	PostQuitMessage (0) ;
		  	return 0 ;
		}
		
		case WM_PAINT:
		{
			PAINTSTRUCT ps ;
			HDC hDC ;
			
			hDC = BeginPaint (hWnd, &ps) ;
			
			TextOut (hDC, xText, yText, DisplayText, lstrlen(DisplayText)) ;

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

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


