You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
668 lines
18 KiB
668 lines
18 KiB
|
|
/****************************** 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.
|
|
* curts Create portable version for win16/32.
|
|
*
|
|
\***************************************************************************/
|
|
|
|
#include <windows.h>
|
|
#include <reghelp.hxx>
|
|
|
|
#include "dll.h"
|
|
#include "strsafe.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;
|
|
|
|
/* 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 = 0; // index to handler than can be freed up
|
|
|
|
char packageClass[] = "Package";
|
|
|
|
// For QuerySize() API & methods.
|
|
extern OLESTREAMVTBL dllStreamVtbl;
|
|
extern CLIENTDOC lockDoc;
|
|
|
|
|
|
// LOWWORD - BYTE 0 major verision, BYTE1 minor version,
|
|
// HIWORD reserved
|
|
|
|
DWORD dwOleVer = 0x0901L; // change this when we want to update dll version
|
|
// number
|
|
|
|
WORD wReleaseVer = 0x0001; // 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;
|
|
|
|
|
|
|
|
HANDLE hModule;
|
|
|
|
#define MAX_HIMETRIC 0x7FFF
|
|
|
|
int maxPixelsX = MAX_HIMETRIC;
|
|
int maxPixelsY = MAX_HIMETRIC;
|
|
void SetMaxPixel (void);
|
|
|
|
VOID FAR PASCAL WEP (int);
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// 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:
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
|
|
#ifdef WIN32
|
|
BOOL LibMain(
|
|
HANDLE hInst,
|
|
ULONG Reason,
|
|
PCONTEXT Context
|
|
#endif // WIN32
|
|
|
|
){
|
|
WNDCLASS wc;
|
|
int i;
|
|
#ifdef WIN32
|
|
char szDocClass[] = "OleDocWndClass" ;
|
|
char szSrvrClass[] = "OleSrvrWndClass" ;
|
|
#endif
|
|
|
|
Puts("LibMain");
|
|
|
|
|
|
#ifdef WIN32 // begin WIN32
|
|
UNREFERENCED_PARAMETER(Context);
|
|
if (Reason == DLL_PROCESS_DETACH)
|
|
{
|
|
WEP(0);
|
|
UnregisterClass (szDocClass, hInst) ;
|
|
UnregisterClass (szSrvrClass, hInst) ;
|
|
return TRUE;
|
|
}
|
|
else if (Reason != DLL_PROCESS_ATTACH)
|
|
return TRUE;
|
|
#endif // end WIN32
|
|
|
|
bLibInit = TRUE;
|
|
hInstDLL = hInst;
|
|
hModule = GetModuleHandle ("OLECLI");
|
|
|
|
// REGISTER LINK FORMAT
|
|
|
|
cfObjectLink = (OLECLIPFORMAT)RegisterClipboardFormat("ObjectLink");
|
|
cfLink = (OLECLIPFORMAT)RegisterClipboardFormat("Link");
|
|
cfOwnerLink = (OLECLIPFORMAT)RegisterClipboardFormat("OwnerLink");
|
|
cfNative = (OLECLIPFORMAT)RegisterClipboardFormat("Native");
|
|
cfBinary = (OLECLIPFORMAT)RegisterClipboardFormat("Binary");
|
|
cfFileName = (OLECLIPFORMAT)RegisterClipboardFormat("FileName");
|
|
cfNetworkName = (OLECLIPFORMAT)RegisterClipboardFormat("NetworkName");
|
|
|
|
if (!(cfObjectLink && cfOwnerLink && cfNative && cfLink))
|
|
return 0;
|
|
|
|
// SET UP OLEWNDCLASS
|
|
wc.style = 0;
|
|
wc.lpfnWndProc = DocWndProc;
|
|
wc.cbClsExtra = 0;
|
|
wc.cbWndExtra = sizeof(LONG_PTR); //we are storing longs
|
|
wc.hInstance = hInst;
|
|
wc.hIcon = NULL;
|
|
wc.hCursor = NULL;
|
|
wc.hbrBackground= NULL;
|
|
wc.lpszMenuName = NULL;
|
|
wc.lpszClassName= szDocClass;
|
|
if (!RegisterClass(&wc))
|
|
return 0;
|
|
|
|
wc.lpfnWndProc = SrvrWndProc;
|
|
wc.lpszClassName = szSrvrClass ;
|
|
|
|
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 = (ATOM)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");
|
|
stdRender[3].aClass = GlobalAddAtom ("ENHMETAFILE");
|
|
|
|
SetMaxPixel();
|
|
|
|
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 (int nParameter)
|
|
{
|
|
int i;
|
|
|
|
|
|
Puts("LibExit");
|
|
|
|
#ifdef WIN32 // begin WIN32
|
|
UNREFERENCED_PARAMETER(nParameter);
|
|
DEBUG_OUT ("---L&E DLL EXIT---\n",0)
|
|
#endif // end WIN32
|
|
// case when the DLLs are missing
|
|
|
|
if (!bLibInit)
|
|
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);
|
|
}
|
|
|
|
|
|
|
|
/* !!! Add this when bug in WEP is fixed
|
|
|
|
if (lpDllTable)
|
|
GlobalUnlock (hDllTable);
|
|
|
|
if (hDllTable)
|
|
GlobalFree (hDllTable);
|
|
*/
|
|
}
|
|
|
|
int FARINTERNAL LoadDll (LPCSTR lpClass)
|
|
{
|
|
char str[MAX_STR];
|
|
char str1[MAX_STR];
|
|
ATOM aDll = (ATOM)0;
|
|
int index;
|
|
int iEmpty;
|
|
BOOL found = FALSE;
|
|
HANDLE hDll;
|
|
LONG cb = MAX_STR;
|
|
|
|
if (!lstrcmpi (lpClass, "Pbrush"))
|
|
return 0;
|
|
|
|
if (FAILED(StringCchCopy(str, sizeof(str)/sizeof(str[0]), lpClass)))
|
|
return 0;
|
|
if (FAILED(StringCchCat(str, sizeof(str)/sizeof(str[0]), "\\protocol\\StdFileEditing\\handler32")))
|
|
return 0;
|
|
if (QueryClassesRootValueA (str, str1, &cb))
|
|
return INVALID_INDEX;
|
|
|
|
if (aDll = GlobalFindAtom (str1)) {
|
|
for (index = 1; index <= iLast && index < sizeof(lpDllTable)/sizeof(lpDllTable[0]); 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 = 0;
|
|
}
|
|
|
|
return index;
|
|
}
|
|
}
|
|
}
|
|
|
|
aDll = GlobalAddAtom (str1);
|
|
|
|
// Look for an empty entry
|
|
for (iEmpty = 1; iEmpty <= iLast && iEmpty < sizeof(lpDllTable)/sizeof(lpDllTable[0]); 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;
|
|
}
|
|
}
|
|
}
|
|
*/
|
|
#ifdef WIN32
|
|
hDll = LoadLibrary ((LPSTR) str1);
|
|
#endif
|
|
|
|
if (MAPVALUE(hDll < 32, !hDll))
|
|
goto errLoad;
|
|
|
|
if (!(lpDllTable[iEmpty].Load = (_LOAD)GetProcAddress(hDll,
|
|
"DllLoadFromStream")))
|
|
goto errLoad;
|
|
|
|
if (!(lpDllTable[iEmpty].Clip = (_CLIP)GetProcAddress (hDll,
|
|
"DllCreateFromClip")))
|
|
goto errLoad;
|
|
|
|
if (!(lpDllTable[iEmpty].Link = (_LINK)GetProcAddress (hDll,
|
|
"DllCreateLinkFromClip")))
|
|
goto errLoad;
|
|
|
|
if (!(lpDllTable[iEmpty].CreateFromTemplate = (_CREATEFROMTEMPLATE)
|
|
GetProcAddress (hDll,
|
|
"DllCreateFromTemplate")))
|
|
goto errLoad;
|
|
|
|
if (!(lpDllTable[iEmpty].Create = (_CREATE)GetProcAddress (hDll,
|
|
"DllCreate")))
|
|
goto errLoad;
|
|
|
|
if (!(lpDllTable[iEmpty].CreateFromFile = (_CREATEFROMFILE)GetProcAddress (hDll,
|
|
"DllCreateFromFile")))
|
|
goto errLoad;
|
|
|
|
if (!(lpDllTable[iEmpty].CreateLinkFromFile = (_CREATELINKFROMFILE)GetProcAddress (hDll,
|
|
"DllCreateLinkFromFile")))
|
|
goto errLoad;
|
|
|
|
lpDllTable[iEmpty].CreateInvisible = (_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 (MAPVALUE(hDll >= 32, !hDll))
|
|
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 (iUnloadableDll >= sizeof(lpDllTable)/sizeof(lpDllTable[0]))
|
|
return;
|
|
|
|
if (lpDllTable[iUnloadableDll].aDll)
|
|
GlobalDeleteAtom (lpDllTable[iUnloadableDll].aDll);
|
|
lpDllTable[iUnloadableDll].aDll = (ATOM)0;
|
|
FreeLibrary (lpDllTable[iUnloadableDll].hDll);
|
|
lpDllTable[iUnloadableDll].hDll = NULL;
|
|
|
|
iUnloadableDll = 0;
|
|
}
|
|
|
|
|
|
//
|
|
// 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 (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 (
|
|
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 0:
|
|
return OLE_ERROR_FORMAT;
|
|
|
|
case CF_ENHMETAFILE:
|
|
return EmfPaste (lpclient, lhclientdoc, lpobjname,
|
|
lplpobj, objType);
|
|
|
|
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 = (OLECLIPFORMAT)EnumClipboardFormats (0);
|
|
while ((cfFormat) && (retVal > OLE_WAIT_FOR_RELEASE)) {
|
|
switch (cfFormat) {
|
|
|
|
case CF_ENHMETAFILE:
|
|
retVal = EmfPaste (lpclient, lhclientdoc, lpobjname,
|
|
lplpobj, objType);
|
|
break;
|
|
|
|
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 = (OLECLIPFORMAT)EnumClipboardFormats (cfFormat);
|
|
}
|
|
}
|
|
|
|
return retVal;
|
|
}
|
|
|
|
|
|
|
|
OLESTATUS FARINTERNAL CreatePackageFromClip (
|
|
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) {
|
|
StringCchCopy(file, sizeof(file)/sizeof(file[0]), lpFileName);
|
|
StringCchCat(file, sizeof(file)/sizeof(file[0]), "/Link");
|
|
lpFileName = (LPSTR) file;
|
|
}
|
|
|
|
GlobalUnlock (hData);
|
|
|
|
return CreateEmbLnkFromFile (lpclient, packageClass, lpFileName,
|
|
NULL, lhclientdoc, lpobjname, lplpobj,
|
|
optRender, cfFormat, OT_EMBEDDED);
|
|
}
|
|
|
|
|
|
|
|
void FARINTERNAL RemoveLinkStringFromTopic (
|
|
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);
|
|
}
|
|
}
|