/*** 
*
*  Copyright (C) 1993-1994, Microsoft Corporation.  All Rights Reserved.
*  Information Contained Herein Is Proprietary and Confidential.
*
*  File:
* 	main.cpp
*
*  Purpose:
*    This file contains: 
*
*      WinMain() and WndProc(), which are called by Windows when the app is run.
*      Code to initialize and uninitialize OLE.
*      Code to create and destroy the window for the application.
*
*****************************************************************************/

#include "common.h"
#include "resource.h"
#include "hello.h"

#include <string.h>


/*	Global variables.
 */
  
DWORD g_dwCHelloCF = 0;	  // Holds the return code for class factory creation.

CHello FAR* g_phello = NULL;	// Pointer to a CHello object.
                   
TCHAR g_szAppName[] = TSTR("Hello"); // Name of the application.



/*	Forward declarations.
 */
HRESULT InitOle(void);
void UninitOle(void);
BOOL InitApplication(HANDLE);
BOOL InitInstance(HANDLE, int);



/*	Let Windows call WinMain and WndProc.
 */
extern "C" 
{
	long FAR PASCAL WndProc(HWND, UINT, WPARAM, LPARAM);
	int PASCAL WinMain(HANDLE, HANDLE, LPSTR, int);
}





/*	WinMain
 *
 *	Windows calls WinMain when the application starts.
 *
 */
extern "C" int PASCAL
WinMain(
    HANDLE hinst,
    HANDLE hPrevInstance,
    LPSTR lpCmdLine,
    int nCmdShow)
{
    MSG msg;
    
	
    if(!hPrevInstance)
      if(!InitApplication(hinst))
	return FALSE;

    if(InitOle() != NOERROR)
      return FALSE;

    if(!InitInstance(hinst, nCmdShow)){
      UninitOle();
      return FALSE;
    }


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

    // Uninitialize OLE.
    UninitOle();

    return msg.wParam;
}





/*	InitApplication
 *
 *	Create a window and register it with Windows.
 *
 *	Return FALSE if an error occurs and TRUE otherwise.
 */
BOOL
InitApplication(HANDLE hinst)
{
    WNDCLASS  wc;

    wc.style		= CS_HREDRAW | CS_VREDRAW;
    wc.lpfnWndProc	= WndProc;
    wc.cbClsExtra	= 0;
    wc.cbWndExtra	= DLGWINDOWEXTRA;
    wc.hInstance	= hinst;
    wc.hIcon		= LoadIcon(hinst, g_szAppName);	// Loads hello.ico
    wc.hCursor		= LoadCursor(NULL, IDC_ARROW);	// Normal arrow pointer
    wc.hbrBackground    = (HBRUSH) (COLOR_APPWORKSPACE+1);
    wc.lpszMenuName	= NULL;				// No menus.
    wc.lpszClassName= g_szAppName;

    // Tell Windows about the window class we just created.
    // Exit if an error occurs.
    if(!RegisterClass(&wc))
      return FALSE;

    return TRUE;
}





/*	InitInstance
 *
 *	Create an instance of CHello and make g_phello
 *	point to it..
 *
 *	Return FALSE if an error occurs and TRUE otherwise.
 */
BOOL
InitInstance(HANDLE hinst, int nCmdShow)
{
    HWND hwnd;
    
    // Create the window and show it
    hwnd = CreateDialog(hinst, g_szAppName, 0, NULL);
    ShowWindow(hwnd, nCmdShow);
    g_phello->m_hwnd = hwnd;
    
    return TRUE;
}





extern "C" long FAR PASCAL
WndProc(
    HWND hwnd,
    UINT message,
    WPARAM wParam,
    LPARAM lParam)
{
    switch(message) {
      case WM_COMMAND:
	  g_phello->ProcessCommand(wParam);
	  return 0;

      case WM_DESTROY:
	   PostQuitMessage(0);
      	   return 0;
    }
    return DefWindowProc(hwnd, message, wParam, lParam);
}






HRESULT
InitOle()
{
    HRESULT hresult;
    IClassFactory FAR* pcf;
    
    if((hresult = OleInitialize(NULL)) != NOERROR)
      return hresult;

    // create the single global instance of CHello
    if((g_phello = CHello::Create()) == NULL){
      hresult = ResultFromScode(E_OUTOFMEMORY);
      return hresult;
    }

    // Create an instance of the class factory for CHello.
    // Exit if an error occurs.
    pcf = CHelloCF::Create();
    if (pcf == NULL) {
      UninitOle();
      return hresult;
    }

    // Register the class factroy.  Exit if an error occurs.
    hresult = CoRegisterClassObject(CLSID_CHello,
	    			    pcf,
		   		    CLSCTX_LOCAL_SERVER,
			   	    REGCLS_MULTIPLEUSE,
				    &g_dwCHelloCF);
    if (hresult != NOERROR) {
      pcf->Release();
      UninitOle();
      return hresult;
    }
    
    pcf->Release();

    // If execution has reached this spot, then no errors have occurred.
    return NOERROR;
}





/*	UninitOLE
 *
 *	Tell OLE that we are going away.
 *
 */
void
UninitOle()
{ 
    // If a class factory was successfully created earlier then
    // tell OLE that the object is no longer available. 
    if(g_dwCHelloCF != 0)
      CoRevokeClassObject(g_dwCHelloCF);

    // cause the remaining typeinfo to be released
    if (g_phello != NULL)
      g_phello->Release();

    // Tell OLE we are done using them.
    OleUninitialize();
}


#if defined(WIN32)

extern "C" char FAR*
ConvertStrWtoA(OLECHAR FAR* strIn, char FAR* buf, UINT size)
{
  int badConversion = FALSE;
  
  WideCharToMultiByte(CP_ACP, NULL, 
	              strIn, -1, 
		      buf, size, 
		      NULL, &badConversion);
  return buf;
}

extern "C" char FAR*
AnsiString(OLECHAR FAR* strIn)
{
  static char buf[256];
  
  return (ConvertStrWtoA(strIn, buf, 256));	
}

#endif

