782 lines
20 KiB
C
782 lines
20 KiB
C
|
|
||
|
/****************************** Module Header ******************************\
|
||
|
* Module Name: MAIN.C
|
||
|
*
|
||
|
* PURPOSE: WinMain, WEP and some other misc routines
|
||
|
*
|
||
|
* Created: 1991
|
||
|
*
|
||
|
* Copyright (c) 1990, 1991 Microsoft Corporation
|
||
|
*
|
||
|
* History:
|
||
|
* Srinik (04/01/91) Pulled some routines, into this, from ole.c.
|
||
|
*
|
||
|
\***************************************************************************/
|
||
|
|
||
|
#include <windows.h>
|
||
|
#include <shellapi.h>
|
||
|
|
||
|
#include "dll.h"
|
||
|
|
||
|
#ifndef WF_WLO
|
||
|
#define WF_WLO 0x8000
|
||
|
#endif
|
||
|
|
||
|
// ordinal number new win31 API IsTask
|
||
|
#define ORD_IsTask 320
|
||
|
|
||
|
#define NUM_DLL 30 /* space for this many DLL_ENTRYs is created on */
|
||
|
/* each alloc/realloc */
|
||
|
|
||
|
OLECLIPFORMAT cfOwnerLink = 0; // global variables for clip frmats
|
||
|
OLECLIPFORMAT cfObjectLink = 0;
|
||
|
OLECLIPFORMAT cfLink = 0;
|
||
|
OLECLIPFORMAT cfNative = 0;
|
||
|
OLECLIPFORMAT cfBinary = 0;
|
||
|
OLECLIPFORMAT cfFileName = 0;
|
||
|
OLECLIPFORMAT cfNetworkName = 0;
|
||
|
|
||
|
ATOM aStdHostNames;
|
||
|
ATOM aStdTargetDevice ;
|
||
|
ATOM aStdDocDimensions;
|
||
|
ATOM aStdDocName;
|
||
|
ATOM aStdColorScheme;
|
||
|
ATOM aNullArg = 0;
|
||
|
ATOM aSave;
|
||
|
ATOM aChange;
|
||
|
ATOM aClose;
|
||
|
ATOM aSystem;
|
||
|
ATOM aOle;
|
||
|
ATOM aClipDoc;
|
||
|
ATOM aPackage;
|
||
|
|
||
|
// Used in work around for MSDraw bug
|
||
|
ATOM aMSDraw;
|
||
|
|
||
|
extern LPCLIENTDOC lpHeadDoc;
|
||
|
extern LPCLIENTDOC lpTailDoc;
|
||
|
|
||
|
extern RENDER_ENTRY stdRender[];
|
||
|
|
||
|
HANDLE hInstDLL;
|
||
|
BOOL bProtMode;
|
||
|
BOOL bWLO = FALSE;
|
||
|
|
||
|
/* HANDLE hDllTable; !!! Add this when bug in WEP is fixed */
|
||
|
DLL_ENTRY lpDllTable[NUM_DLL]; //!!! change this when WEP bug is fixed
|
||
|
DWORD dllTableSize;
|
||
|
int iLast = 0;
|
||
|
int iMax = NUM_DLL -1;
|
||
|
int iUnloadableDll = NULL; // index to handler than can be freed up
|
||
|
|
||
|
char packageClass[] = "Package";
|
||
|
|
||
|
// For QuerySize() API & methods.
|
||
|
extern OLESTREAMVTBL dllStreamVtbl;
|
||
|
extern CLIENTDOC lockDoc;
|
||
|
|
||
|
#ifdef FIREWALLS
|
||
|
BOOL bShowed = FALSE;
|
||
|
char szDebugBuffer[80];
|
||
|
short ole_flags;
|
||
|
|
||
|
void FARINTERNAL ShowVersion (void);
|
||
|
void FARINTERNAL SetOleFlags(void);
|
||
|
#endif
|
||
|
|
||
|
// LOWWORD - BYTE 0 major verision, BYTE1 minor version,
|
||
|
// HIWORD reserved
|
||
|
|
||
|
DWORD dwOleVer = 0x2001L; // change this when we want to update dll version
|
||
|
// number
|
||
|
|
||
|
|
||
|
DWORD dwVerToFile = 0x0501L; // This is used while object is being saved to
|
||
|
// file. There is no need to change this value
|
||
|
// whenever we change ole dll version number
|
||
|
|
||
|
|
||
|
|
||
|
static BOOL bLibInit = FALSE;
|
||
|
|
||
|
|
||
|
WORD wWinVer;
|
||
|
|
||
|
HANDLE hModule;
|
||
|
|
||
|
#define MAX_HIMETRIC 0x7FFF
|
||
|
|
||
|
int maxPixelsX = MAX_HIMETRIC;
|
||
|
int maxPixelsY = MAX_HIMETRIC;
|
||
|
void SetMaxPixel (void);
|
||
|
|
||
|
VOID FAR PASCAL WEP (int);
|
||
|
|
||
|
#pragma alloc_text(WEP_TEXT, WEP)
|
||
|
|
||
|
|
||
|
FARPROC lpfnIsTask = NULL; // the API IsTask() became available from
|
||
|
// win31 onwards, hence we are trying to
|
||
|
// get it's address through GetProcAddress
|
||
|
|
||
|
|
||
|
|
||
|
//////////////////////////////////////////////////////////////////////////////
|
||
|
//
|
||
|
// int FAR PASCAL LibMain (hInst, wDataSeg, cbHeapSize, lpszCmdLine)
|
||
|
//
|
||
|
// The main library entry point. This routine is called when the library
|
||
|
// is loaded.
|
||
|
//
|
||
|
// Arguments:
|
||
|
//
|
||
|
// hInst - dll's instance handle
|
||
|
// wDataSeg - DS register value
|
||
|
// cbHeapSize - heap size defined def file
|
||
|
// lpszCmdLine - command line info
|
||
|
//
|
||
|
// Returns:
|
||
|
//
|
||
|
// 0 - failure
|
||
|
// 1 - success
|
||
|
//
|
||
|
// Effects:
|
||
|
//
|
||
|
//////////////////////////////////////////////////////////////////////////////
|
||
|
|
||
|
|
||
|
int FAR PASCAL LibMain (hInst, wDataSeg, cbHeapSize, lpszCmdLine)
|
||
|
HANDLE hInst;
|
||
|
WORD wDataSeg;
|
||
|
WORD cbHeapSize;
|
||
|
LPSTR lpszCmdLine;
|
||
|
{
|
||
|
WNDCLASS wc;
|
||
|
int i;
|
||
|
|
||
|
Puts("LibMain");
|
||
|
|
||
|
#ifdef FIREWALLS
|
||
|
SetOleFlags();
|
||
|
#endif
|
||
|
|
||
|
bLibInit = TRUE;
|
||
|
hInstDLL = hInst;
|
||
|
hModule = GetModuleHandle ("OLECLI");
|
||
|
|
||
|
bProtMode = (BOOL) (GetWinFlags() & WF_PMODE);
|
||
|
bWLO = (BOOL) (GetWinFlags() & WF_WLO);
|
||
|
wWinVer = (WORD) GetVersion();
|
||
|
|
||
|
// REGISTER LINK FORMAT
|
||
|
|
||
|
cfObjectLink = RegisterClipboardFormat("ObjectLink");
|
||
|
cfLink = RegisterClipboardFormat("Link");
|
||
|
cfOwnerLink = RegisterClipboardFormat("OwnerLink");
|
||
|
cfNative = RegisterClipboardFormat("Native");
|
||
|
cfBinary = RegisterClipboardFormat("Binary");
|
||
|
cfFileName = RegisterClipboardFormat("FileName");
|
||
|
cfNetworkName = RegisterClipboardFormat("NetworkName");
|
||
|
|
||
|
if (!(cfObjectLink && cfOwnerLink && cfNative && cfLink))
|
||
|
return 0;
|
||
|
|
||
|
// SET UP OLEWNDCLASS
|
||
|
wc.style = NULL;
|
||
|
wc.lpfnWndProc = DocWndProc;
|
||
|
wc.cbClsExtra = 0;
|
||
|
wc.cbWndExtra = sizeof(LONG); //we are storing longs
|
||
|
wc.hInstance = hInst;
|
||
|
wc.hIcon = NULL;
|
||
|
wc.hCursor = NULL;
|
||
|
wc.hbrBackground= NULL;
|
||
|
wc.lpszMenuName = NULL;
|
||
|
wc.lpszClassName= "OleDocWndClass";
|
||
|
if (!RegisterClass(&wc))
|
||
|
return 0;
|
||
|
|
||
|
wc.lpfnWndProc = SrvrWndProc;
|
||
|
wc.lpszClassName = "OleSrvrWndClass";
|
||
|
|
||
|
if (!RegisterClass(&wc))
|
||
|
return 0;
|
||
|
/*
|
||
|
// !!! Add this when bug in WEP is fixed.
|
||
|
// Allocate memory for DLL table
|
||
|
dllTableSize = NUM_DLL * sizeof(DLL_ENTRY);
|
||
|
if (!(hDllTable = GlobalAlloc (GMEM_MOVEABLE | GMEM_ZEROINIT,
|
||
|
dllTableSize)))
|
||
|
return 0;
|
||
|
|
||
|
if (!(lpDllTable = (DLL_ENTRY FAR *) GlobalLock (hDllTable)))
|
||
|
return 0;
|
||
|
*/
|
||
|
|
||
|
// !!! remove the following when WEP bug is fixed
|
||
|
for (i = 0; i < NUM_DLL; i++)
|
||
|
lpDllTable[i].aDll = 0;
|
||
|
|
||
|
// !!! BEGIN hack for Pbrush.
|
||
|
|
||
|
lpDllTable[0].hDll = NULL;
|
||
|
lpDllTable[0].aDll = GlobalAddAtom ((LPSTR) "ole");
|
||
|
lpDllTable[0].Load = PbLoadFromStream;
|
||
|
lpDllTable[0].Clip = PbCreateFromClip;
|
||
|
lpDllTable[0].Link = PbCreateLinkFromClip;
|
||
|
lpDllTable[0].Create = PbCreate;
|
||
|
lpDllTable[0].CreateFromTemplate = PbCreateFromTemplate;
|
||
|
lpDllTable[0].CreateFromFile = PbCreateFromFile;
|
||
|
lpDllTable[0].CreateLinkFromFile = PbCreateLinkFromFile;
|
||
|
lpDllTable[0].CreateInvisible = PbCreateInvisible;
|
||
|
|
||
|
|
||
|
// !!! END hack for pbrush
|
||
|
|
||
|
// For ObjectSize API
|
||
|
dllStream.lpstbl = (LPOLESTREAMVTBL) &dllStreamVtbl;
|
||
|
dllStream.lpstbl->Put = DllPut;
|
||
|
|
||
|
// add the atoms required.
|
||
|
aStdDocName = GlobalAddAtom ((LPSTR)"StdDocumentName");
|
||
|
aSave = GlobalAddAtom ((LPSTR)"Save");
|
||
|
aChange = GlobalAddAtom ((LPSTR)"Change");
|
||
|
aClose = GlobalAddAtom ((LPSTR)"Close");
|
||
|
aSystem = GlobalAddAtom ((LPSTR)"System");
|
||
|
aOle = GlobalAddAtom ((LPSTR)"OLEsystem");
|
||
|
aPackage = GlobalAddAtom ((LPSTR) packageClass);
|
||
|
|
||
|
// Used in work around for MSDraw bug
|
||
|
aMSDraw = GlobalAddAtom ((LPSTR) "MSDraw");
|
||
|
|
||
|
// clipboard document name atom
|
||
|
aClipDoc = GlobalAddAtom ((LPSTR)"Clipboard");
|
||
|
|
||
|
stdRender[0].aClass = GlobalAddAtom ("METAFILEPICT");
|
||
|
stdRender[1].aClass = GlobalAddAtom ("DIB");
|
||
|
stdRender[2].aClass = GlobalAddAtom ("BITMAP");
|
||
|
|
||
|
SetMaxPixel();
|
||
|
|
||
|
if (wWinVer != 0x0003) {
|
||
|
HANDLE hModule;
|
||
|
|
||
|
if (hModule = GetModuleHandle ("KERNEL"))
|
||
|
lpfnIsTask = GetProcAddress (hModule,
|
||
|
(LPSTR) MAKELONG (ORD_IsTask, 0));
|
||
|
}
|
||
|
|
||
|
if (cbHeapSize != 0)
|
||
|
UnlockData(0);
|
||
|
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
//////////////////////////////////////////////////////////////////////////////
|
||
|
//
|
||
|
// VOID FAR PASCAL WEP (nParameter)
|
||
|
//
|
||
|
// Called just before the library is being unloaded. Delete all the atoms
|
||
|
// added by this dll and also frees up all unloaded handler dlls.
|
||
|
//
|
||
|
// Arguments:
|
||
|
//
|
||
|
// nParameter - Termination code
|
||
|
//
|
||
|
// Returns:
|
||
|
//
|
||
|
// none
|
||
|
//
|
||
|
// Effects:
|
||
|
//
|
||
|
//////////////////////////////////////////////////////////////////////////////
|
||
|
|
||
|
|
||
|
VOID FAR PASCAL WEP (nParameter)
|
||
|
int nParameter;
|
||
|
{
|
||
|
int i;
|
||
|
|
||
|
|
||
|
Puts("LibExit");
|
||
|
|
||
|
// case when the DLLs are missing
|
||
|
if (!bLibInit)
|
||
|
return;
|
||
|
|
||
|
if (nParameter == WEP_SYSTEM_EXIT)
|
||
|
DEBUG_OUT ("---L&E DLL EXIT on system exit---",0)
|
||
|
else if (nParameter == WEP_FREE_DLL)
|
||
|
DEBUG_OUT ("---L&E DLL EXIT---\n",0)
|
||
|
else
|
||
|
return;
|
||
|
|
||
|
// Delete atoms added by us
|
||
|
|
||
|
for (i = 0; i < NUM_RENDER; i++) {
|
||
|
if (stdRender[i].aClass)
|
||
|
GlobalDeleteAtom (stdRender[i].aClass);
|
||
|
}
|
||
|
|
||
|
if (aStdDocName)
|
||
|
GlobalDeleteAtom (aStdDocName);
|
||
|
if (aSave)
|
||
|
GlobalDeleteAtom (aSave);
|
||
|
if (aChange)
|
||
|
GlobalDeleteAtom (aChange);
|
||
|
if (aClose)
|
||
|
GlobalDeleteAtom (aClose);
|
||
|
if (aSystem)
|
||
|
GlobalDeleteAtom (aSystem);
|
||
|
if (aOle)
|
||
|
GlobalDeleteAtom (aOle);
|
||
|
if (aPackage)
|
||
|
GlobalDeleteAtom (aPackage);
|
||
|
if (aClipDoc)
|
||
|
GlobalDeleteAtom (aClipDoc);
|
||
|
if (aMSDraw)
|
||
|
GlobalDeleteAtom (aMSDraw);
|
||
|
|
||
|
// Free handler dlls if there are any still loaded. Entry 0 is used for
|
||
|
// Pbrush handler which is part of this dll.
|
||
|
|
||
|
|
||
|
for (i = 0; i <= iLast; i++) {
|
||
|
if (lpDllTable[i].aDll)
|
||
|
GlobalDeleteAtom (lpDllTable[i].aDll);
|
||
|
|
||
|
if (lpDllTable[i].hDll)
|
||
|
FreeLibrary (lpDllTable[i].hDll);
|
||
|
}
|
||
|
|
||
|
|
||
|
#ifdef FIREWALLS
|
||
|
ASSERT(!lpHeadDoc, "Some client doc structures are not deleted");
|
||
|
ASSERT(!lockDoc.lpHeadObj, "Some servers are left in a locked state");
|
||
|
#endif
|
||
|
|
||
|
/* !!! Add this when bug in WEP is fixed
|
||
|
|
||
|
if (lpDllTable)
|
||
|
GlobalUnlock (hDllTable);
|
||
|
|
||
|
if (hDllTable)
|
||
|
GlobalFree (hDllTable);
|
||
|
*/
|
||
|
}
|
||
|
|
||
|
|
||
|
//////////////////////////////////////////////////////////////////////////////
|
||
|
//
|
||
|
// void FARINTERNAL SetOleFlags()
|
||
|
//
|
||
|
// Sets the debug level flags for controlling the level of debug information
|
||
|
// on the comm terminal. This will be included only in the debug version.
|
||
|
//
|
||
|
// Arguments:
|
||
|
//
|
||
|
// none
|
||
|
//
|
||
|
// Returns:
|
||
|
//
|
||
|
// none
|
||
|
//
|
||
|
// Effects:
|
||
|
//
|
||
|
//////////////////////////////////////////////////////////////////////////////
|
||
|
|
||
|
#ifdef FIREWALLS
|
||
|
|
||
|
void FARINTERNAL SetOleFlags()
|
||
|
{
|
||
|
|
||
|
char buffer[80];
|
||
|
|
||
|
if(GetProfileString ("OLE",
|
||
|
"Puts","", (LPSTR)buffer, 80))
|
||
|
ole_flags = DEBUG_PUTS;
|
||
|
else
|
||
|
ole_flags = 0;
|
||
|
|
||
|
|
||
|
if(GetProfileString ("OLE",
|
||
|
"DEBUG_OUT","", (LPSTR)buffer, 80))
|
||
|
ole_flags |= DEBUG_DEBUG_OUT;
|
||
|
|
||
|
|
||
|
if(GetProfileString ("OLE",
|
||
|
"MESSAGEBOX","", (LPSTR)buffer, 80))
|
||
|
ole_flags |= DEBUG_MESSAGEBOX;
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
//////////////////////////////////////////////////////////////////////////////
|
||
|
//
|
||
|
// void FARINTERNAL ShowVersion (void)
|
||
|
//
|
||
|
// Displays version, date, time and copyright info in client app's window.
|
||
|
// Called by all the object create functions after checking the flag bShowed.
|
||
|
// This will be included only in the debug version.
|
||
|
//
|
||
|
// Arguments:
|
||
|
//
|
||
|
// none
|
||
|
//
|
||
|
// Returns:
|
||
|
//
|
||
|
// none
|
||
|
//
|
||
|
// Effects:
|
||
|
//
|
||
|
// sets bShowed
|
||
|
//
|
||
|
//////////////////////////////////////////////////////////////////////////////
|
||
|
|
||
|
void FARINTERNAL ShowVersion ()
|
||
|
{
|
||
|
|
||
|
if (!bShowed && (ole_flags & DEBUG_MESSAGEBOX)) {
|
||
|
MessageBox (NULL, "\
|
||
|
VER: 1.09.000\n\
|
||
|
TIME: 16:00:00\n\
|
||
|
DATE: 01/31/1992\n\
|
||
|
Copyright (c) 1990, 1991 Microsoft Corp.\n\
|
||
|
All Rights Reserved.",
|
||
|
"Ole Client Library",
|
||
|
MB_OK | MB_TASKMODAL);
|
||
|
bShowed = TRUE;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
#endif
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
int FARINTERNAL LoadDll (lpClass)
|
||
|
LPSTR lpClass;
|
||
|
{
|
||
|
char str[MAX_STR];
|
||
|
char str1[MAX_STR];
|
||
|
ATOM aDll = NULL;
|
||
|
int index;
|
||
|
int iEmpty;
|
||
|
BOOL found = FALSE;
|
||
|
HANDLE hDll;
|
||
|
int refcnt;
|
||
|
LONG cb = MAX_STR;
|
||
|
|
||
|
if (!lstrcmpi (lpClass, "Pbrush"))
|
||
|
return 0;
|
||
|
|
||
|
lstrcpy (str, lpClass);
|
||
|
lstrcat (str, "\\protocol\\StdFileEditing\\handler");
|
||
|
if (RegQueryValue (HKEY_CLASSES_ROOT, str, str1, &cb))
|
||
|
return INVALID_INDEX;
|
||
|
|
||
|
if (aDll = GlobalFindAtom (str1)) {
|
||
|
for (index = 1; index <= iLast; index++) {
|
||
|
if (lpDllTable[index].aDll == aDll) { // Dll already loaded
|
||
|
lpDllTable[index].cObj ++;
|
||
|
|
||
|
if (index == iUnloadableDll) {
|
||
|
// since the object count is not zero anymore, this
|
||
|
// handler can not be freed up.
|
||
|
iUnloadableDll = NULL;
|
||
|
}
|
||
|
|
||
|
return index;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
aDll = GlobalAddAtom (str1);
|
||
|
|
||
|
// Look for an empty entry
|
||
|
for (iEmpty = 1; iEmpty <= iLast; iEmpty++) {
|
||
|
if (!lpDllTable[iEmpty].aDll) {
|
||
|
found = TRUE;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (iEmpty > iMax)
|
||
|
goto errLoad;
|
||
|
/*
|
||
|
if (!found) {// no empty entry exists create a new one if necessary.
|
||
|
if (iEmpty > iMax) {
|
||
|
dllTableSize += (blockSize = NUM_DLL * sizeof(DLL_ENTRY));
|
||
|
hTable = GlobalReAlloc (hDllTable, dllTableSize,
|
||
|
GMEM_MOVEABLE | GMEM_ZEROINIT);
|
||
|
if (hTable == hDllTable)
|
||
|
iMax += NUM_DLL;
|
||
|
else {
|
||
|
dllTableSize -= blockSize;
|
||
|
iEmpty = INVALID_INDEX;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
*/
|
||
|
|
||
|
// !!! reference count of OLECLI is increasing by 2 when the handlers are
|
||
|
// are loaded, looks like windows bug. Following is a temporary fix.
|
||
|
|
||
|
refcnt = GetModuleUsage (hModule);
|
||
|
hDll = LoadLibrary ((LPSTR) str1);
|
||
|
refcnt = (GetModuleUsage (hModule) - refcnt);
|
||
|
|
||
|
while (refcnt > 1) {
|
||
|
FreeModule (hModule);
|
||
|
refcnt--;
|
||
|
}
|
||
|
|
||
|
if (hDll < 32)
|
||
|
goto errLoad;
|
||
|
|
||
|
if (!(lpDllTable[iEmpty].Load = GetProcAddress (hDll,
|
||
|
"DllLoadFromStream")))
|
||
|
goto errLoad;
|
||
|
|
||
|
if (!(lpDllTable[iEmpty].Clip = GetProcAddress (hDll,
|
||
|
"DllCreateFromClip")))
|
||
|
goto errLoad;
|
||
|
|
||
|
if (!(lpDllTable[iEmpty].Link = GetProcAddress (hDll,
|
||
|
"DllCreateLinkFromClip")))
|
||
|
goto errLoad;
|
||
|
|
||
|
if (!(lpDllTable[iEmpty].CreateFromTemplate = GetProcAddress (hDll,
|
||
|
"DllCreateFromTemplate")))
|
||
|
goto errLoad;
|
||
|
|
||
|
if (!(lpDllTable[iEmpty].Create = GetProcAddress (hDll, "DllCreate")))
|
||
|
goto errLoad;
|
||
|
|
||
|
if (!(lpDllTable[iEmpty].CreateFromFile = GetProcAddress (hDll,
|
||
|
"DllCreateFromFile")))
|
||
|
goto errLoad;
|
||
|
|
||
|
if (!(lpDllTable[iEmpty].CreateLinkFromFile = GetProcAddress (hDll,
|
||
|
"DllCreateLinkFromFile")))
|
||
|
goto errLoad;
|
||
|
|
||
|
lpDllTable[iEmpty].CreateInvisible = GetProcAddress (hDll,
|
||
|
"DllCreateInvisible");
|
||
|
|
||
|
lpDllTable[iEmpty].aDll = aDll;
|
||
|
lpDllTable[iEmpty].cObj = 1;
|
||
|
lpDllTable[iEmpty].hDll = hDll;
|
||
|
if (iEmpty > iLast)
|
||
|
iLast++;
|
||
|
return iEmpty;
|
||
|
|
||
|
errLoad:
|
||
|
if (aDll)
|
||
|
GlobalDeleteAtom (aDll);
|
||
|
if (hDll >= 32)
|
||
|
FreeLibrary (hDll);
|
||
|
return INVALID_INDEX;
|
||
|
}
|
||
|
|
||
|
|
||
|
// unload the the handler that can be free up (whose object count is NULL)
|
||
|
|
||
|
void FARINTERNAL UnloadDll ()
|
||
|
{
|
||
|
if (!iUnloadableDll)
|
||
|
return;
|
||
|
|
||
|
if (iUnloadableDll == iLast)
|
||
|
iLast--;
|
||
|
|
||
|
if (lpDllTable[iUnloadableDll].aDll)
|
||
|
GlobalDeleteAtom (lpDllTable[iUnloadableDll].aDll);
|
||
|
lpDllTable[iUnloadableDll].aDll = NULL;
|
||
|
FreeLibrary (lpDllTable[iUnloadableDll].hDll);
|
||
|
lpDllTable[iUnloadableDll].hDll = NULL;
|
||
|
|
||
|
iUnloadableDll = NULL;
|
||
|
}
|
||
|
|
||
|
|
||
|
//
|
||
|
// Reduce the object count of the handler, refered to by the index, by one.
|
||
|
// If the object count becomes NULL, free up the handler that is ready to be
|
||
|
// freed (refered to by index iUnloadableDll), and then make this handler the
|
||
|
// freeable one.
|
||
|
//
|
||
|
// As you can see we are trying to implement a simple mechanism of caching.
|
||
|
//
|
||
|
|
||
|
void FARINTERNAL DecreaseHandlerObjCount (iTable)
|
||
|
int iTable;
|
||
|
{
|
||
|
if (!iTable)
|
||
|
return;
|
||
|
|
||
|
if (iTable != INVALID_INDEX) {
|
||
|
ASSERT (lpDllTable[iTable].cObj, "Handler Obj count is already NULL");
|
||
|
if (!--lpDllTable[iTable].cObj) {
|
||
|
UnloadDll ();
|
||
|
iUnloadableDll = iTable;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
/***************************** Public Function ****************************\
|
||
|
*
|
||
|
* OLESTATUS FARINTERNAL CreatePictFromClip (lpclient, lhclientdoc, lpobjname, lplpoleobject, optRender, cfFormat, lpClass, ctype)
|
||
|
*
|
||
|
* CreatePictFromClip: This function creates the LP to an object
|
||
|
* from the clipboard. It will try to create a static picture object if
|
||
|
* it understands any rendering formats on the clipboard. Currently, it
|
||
|
* understands only bitmaps and metafiles.
|
||
|
*
|
||
|
* Effects:
|
||
|
*
|
||
|
* History:
|
||
|
* Wrote it.
|
||
|
\***************************************************************************/
|
||
|
|
||
|
OLESTATUS FARINTERNAL CreatePictFromClip (lpclient, lhclientdoc, lpobjname, lplpobj, optRender, cfFormat, lpClass, objType)
|
||
|
LPOLECLIENT lpclient;
|
||
|
LHCLIENTDOC lhclientdoc;
|
||
|
LPSTR lpobjname;
|
||
|
LPOLEOBJECT FAR * lplpobj;
|
||
|
OLEOPT_RENDER optRender;
|
||
|
OLECLIPFORMAT cfFormat;
|
||
|
LPSTR lpClass;
|
||
|
LONG objType;
|
||
|
{
|
||
|
OLESTATUS retVal = OLE_ERROR_OPTION;
|
||
|
|
||
|
*lplpobj = NULL;
|
||
|
|
||
|
if (optRender == olerender_none)
|
||
|
return OLE_OK;
|
||
|
else if (optRender == olerender_format) {
|
||
|
switch (cfFormat) {
|
||
|
case NULL:
|
||
|
return OLE_ERROR_FORMAT;
|
||
|
|
||
|
case CF_METAFILEPICT:
|
||
|
return MfPaste (lpclient, lhclientdoc, lpobjname,
|
||
|
lplpobj, objType);
|
||
|
|
||
|
case CF_DIB:
|
||
|
return DibPaste (lpclient, lhclientdoc, lpobjname,
|
||
|
lplpobj, objType);
|
||
|
|
||
|
case CF_BITMAP:
|
||
|
return BmPaste (lpclient, lhclientdoc, lpobjname,
|
||
|
lplpobj, objType);
|
||
|
|
||
|
default:
|
||
|
return GenPaste (lpclient, lhclientdoc, lpobjname, lplpobj,
|
||
|
lpClass, cfFormat, objType);
|
||
|
}
|
||
|
}
|
||
|
else if (optRender == olerender_draw) {
|
||
|
cfFormat = EnumClipboardFormats (NULL);
|
||
|
while ((cfFormat) && (retVal > OLE_WAIT_FOR_RELEASE)) {
|
||
|
switch (cfFormat) {
|
||
|
case CF_METAFILEPICT:
|
||
|
retVal = MfPaste (lpclient, lhclientdoc,
|
||
|
lpobjname, lplpobj, objType);
|
||
|
break;
|
||
|
|
||
|
case CF_DIB:
|
||
|
retVal = DibPaste (lpclient, lhclientdoc,
|
||
|
lpobjname, lplpobj, objType);
|
||
|
break;
|
||
|
|
||
|
case CF_BITMAP:
|
||
|
retVal = BmPaste (lpclient, lhclientdoc,
|
||
|
lpobjname, lplpobj, objType);
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
cfFormat = EnumClipboardFormats (cfFormat);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return retVal;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
OLESTATUS FARINTERNAL CreatePackageFromClip (lpclient, lhclientdoc, lpobjname, lplpobj, optRender, cfFormat, objType)
|
||
|
LPOLECLIENT lpclient;
|
||
|
LHCLIENTDOC lhclientdoc;
|
||
|
LPSTR lpobjname;
|
||
|
LPOLEOBJECT FAR * lplpobj;
|
||
|
OLEOPT_RENDER optRender;
|
||
|
OLECLIPFORMAT cfFormat;
|
||
|
LONG objType;
|
||
|
{
|
||
|
char file[MAX_STR+6];
|
||
|
HANDLE hData;
|
||
|
LPSTR lpFileName;
|
||
|
|
||
|
if (!(hData = GetClipboardData (cfFileName))
|
||
|
|| !(lpFileName = GlobalLock (hData)))
|
||
|
return OLE_ERROR_CLIPBOARD;
|
||
|
|
||
|
|
||
|
if (objType == OT_LINK) {
|
||
|
lstrcpy (file, lpFileName);
|
||
|
lstrcat (file, "/Link");
|
||
|
lpFileName = (LPSTR) file;
|
||
|
}
|
||
|
|
||
|
GlobalUnlock (hData);
|
||
|
|
||
|
return CreateEmbLnkFromFile (lpclient, packageClass, lpFileName,
|
||
|
NULL, lhclientdoc, lpobjname, lplpobj,
|
||
|
optRender, cfFormat, OT_EMBEDDED);
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
void FARINTERNAL RemoveLinkStringFromTopic (lpobj)
|
||
|
LPOBJECT_LE lpobj;
|
||
|
{
|
||
|
char buf[MAX_STR+6];
|
||
|
int i = 0;
|
||
|
|
||
|
if (GlobalGetAtomName (lpobj->topic, buf, sizeof(buf))) {
|
||
|
// scan the topic for "/Link"
|
||
|
while (buf[i] != '/') {
|
||
|
if (!buf[i])
|
||
|
return;
|
||
|
i++;
|
||
|
}
|
||
|
|
||
|
buf[i] = '\0';
|
||
|
if (lpobj->topic)
|
||
|
GlobalDeleteAtom (lpobj->topic);
|
||
|
lpobj->topic = GlobalAddAtom (buf);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void SetMaxPixel ()
|
||
|
{
|
||
|
HDC hdc;
|
||
|
// find out the pixel equivalent of MAX_HIMETRIC in X and Y directions
|
||
|
|
||
|
if (hdc = GetDC (NULL)) {
|
||
|
maxPixelsX = MulDiv (MAX_HIMETRIC, GetDeviceCaps(hdc, LOGPIXELSX),
|
||
|
2540);
|
||
|
maxPixelsY = MulDiv (MAX_HIMETRIC, GetDeviceCaps(hdc, LOGPIXELSY),
|
||
|
2540);
|
||
|
ReleaseDC (NULL, hdc);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|