MAIN.CPP

/************************************************************************* 
**
** This is a part of the Microsoft Source Code Samples.
**
** Copyright 1992 - 1998 Microsoft Corporation. All rights reserved.
**
** This source code is only intended as a supplement to Microsoft Development
** Tools and/or WinHelp documentation. See these sources for detailed
** information regarding the Microsoft samples programs.
**
** OLE Automation TypeLibrary Browse Helper Sample
**
** main.cpp
**
** new and delete operator redefinition to use memory manager of calling
** task.
** LibMain, WEP, DllGetClassObject, DllCanUnloadNow, DLL initialization.
** Procedure to create standard dispatch implementation.
**
** Written by Microsoft Product Support Services, Windows Developer Support
**
*************************************************************************/
#include <windows.h>
#include <windowsx.h>
#ifdef WIN16
#include <ole2.h>
#include <compobj.h>
#include <dispatch.h>
#include <variant.h>
#include <olenls.h>
#endif
#include <initguid.h>
#include "browseh.h"

// Globals
HINSTANCE g_hinst; // Instance of application
//Count number of objects and number of locks.
ULONG g_cObj=0;
ULONG g_cLock=0;

// String resource buffers
TCHAR g_szServerName[STR_LEN];


/*
* new
*
* Purpose:
* Since this is an InProcServer object, the memory allocator used by
* the calling task must be used.
* This is done by redefining the global new operator and using new
* for all memory allocations.
*/
void FAR* operator new(size_t size)
{
IMalloc FAR* pMalloc;
LPVOID lpv;

if (CoGetMalloc(MEMCTX_TASK, &pMalloc) == NOERROR)
{
lpv = pMalloc->Alloc(size);
pMalloc->Release();
return lpv;
}
return NULL;
}

/*
* delete
*
* Purpose:
* Use the memory manager of the calling task to free memory.
*/
void operator delete(void FAR* lpv)
{
IMalloc FAR* pMalloc;

if (lpv == NULL) return;

if( CoGetMalloc(MEMCTX_TASK, &pMalloc) == NOERROR)
{
if (pMalloc->DidAlloc(lpv))
pMalloc->Free(lpv);
pMalloc->Release();
}
}


#ifdef WIN16
/*
* LibMain
*
* Purpose:
* Called by Win16 on DLL load. Does any one-time initializations.
*
*/
int PASCAL LibMain (HINSTANCE hinst, WORD wDataSeg, WORD cbHeapSize, LPSTR lpCmdLine)
{
if (cbHeapSize != 0)
UnlockData(0);

g_hinst = hinst;

if (!InitDLL(hinst))
return FALSE;

return TRUE;
}

/*
* WEP
*
* Purpose:
* Called by Windows on DLL unload.
*
*/
extern "C" void FAR PASCAL _WEP(int bSystemExit)
{
return;
}

#else //Win 32

BOOL WINAPI DllMain (HINSTANCE hinst, DWORD dwReason, LPVOID lpReserved)
{
switch (dwReason)
{
case DLL_PROCESS_ATTACH:
if (!InitDLL(hinst))
return FALSE;
else return TRUE;

default:
return TRUE;
}
}

#endif

/*
* DLLGetClassObject
*
* Purpose:
* OLE calls this funtion to obtain the class factory. Note that the class
* factory is not registered by the inproc server.
*
*/
STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid,
LPVOID FAR *ppv)
{
LPCLASSFACTORY pcf;
HRESULT hr;

*ppv = NULL;

// Check if this CLSID is supported.
if (rclsid != CLSID_BrowseHelper)
return E_FAIL;

// Create class factory and return it
pcf = new CBrowseHelperCF;
if (!pcf)
return E_OUTOFMEMORY;
hr = pcf->QueryInterface(riid, ppv);
if (FAILED(hr))
{
delete pcf;
return hr;
}
return NOERROR;
}

/*
* DLLCanUnloadNow
*
* Purpose:
* DllCanUnloadNow is called by OLE to determine if the DLL can be unloded.
*
*/
STDAPI DllCanUnloadNow(void)
{
if (g_cObj==0L && g_cLock==0L)
return S_OK;
else return S_FALSE;
}

/*
* InitDLL
*
* Purpose:
* Load strings & Registers the window class
*
* Parameters:
* hinstance hinstance of application
*
*/
BOOL InitDLL (HINSTANCE hinst)
{
return LoadString(hinst, IDS_SERVERNAME, g_szServerName, sizeof(g_szServerName));
}

/*
* Quick & Dirty ANSI/Unicode conversion routines. These routines use a static
* buffer of fixed size to hold the converted string. Consequently these
* routines are limited to strings of size STRCONVERT_MAXLEN. Also the same
* buffer is reused when the routine is called a second time. So make sure
* that the converted string is used before the conversion routine is called
* again
*/
#ifdef WIN32

#ifndef UNICODE
char* ConvertToAnsi(OLECHAR FAR* szW)
{
static char achA[STRCONVERT_MAXLEN];

WideCharToMultiByte(CP_ACP, 0, szW, -1, achA, STRCONVERT_MAXLEN, NULL, NULL);
return achA;
}

OLECHAR* ConvertToUnicode(char FAR* szA)
{
static OLECHAR achW[STRCONVERT_MAXLEN];

MultiByteToWideChar(CP_ACP, 0, szA, -1, achW, STRCONVERT_MAXLEN);
return achW;
}
#endif

#endif