windows-nt/Source/XPSP1/NT/base/mvdm/wow16/write/obj3.c
2020-09-26 16:20:57 +08:00

1991 lines
59 KiB
C
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/************************************************************/
/* Windows Write, Copyright 1985-1992 Microsoft Corporation */
/************************************************************/
#include "windows.h"
#include "mw.h"
#include "winddefs.h"
#include "obj.h"
#include "menudefs.h"
#include "cmddefs.h"
#include "str.h"
#include "objreg.h"
#include "docdefs.h"
#include "editdefs.h"
#include "propdefs.h"
#include "wwdefs.h"
#include "filedefs.h"
#include "shellapi.h"
#include <commdlg.h>
extern BOOL ferror;
extern HCURSOR vhcArrow;
extern HCURSOR vhcIBeam;
extern struct DOD (**hpdocdod)[];
extern struct PAP vpapAbs;
extern struct UAB vuab;
extern struct WWD rgwwd[];
extern BOOL bKillMe;
extern BOOL fPropsError;
extern int docScrap;
extern int docUndo;
extern PRINTDLG PD;
static BOOL DoLinksCommand(WORD wParam, DWORD lParam, HWND hDlg, BOOL *bError);
/****************************************************************/
/*********************** OLE DISPLAY HANDLING *******************/
/****************************************************************/
BOOL ObjDisplayObjectInDoc(OBJPICINFO far *lpPicInfo,
int doc, typeCP cpParaStart,
HDC hDC, LPRECT lpBounds)
{
BOOL bSuccess;
if (lpOBJ_QUERY_INFO(lpPicInfo) == NULL)
return(FALSE);
#ifndef JAPAN // added by Hiraisi (BUG#2732/WIN31)
// If we return here, we can never redraw the object again.
if (lpOBJ_QUERY_INFO(lpPicInfo)->fCantDisplay)
return(FALSE);
#endif // not JAPAN
if (otOBJ_QUERY_TYPE(lpPicInfo) == NONE)
switch(otOBJ_QUERY_TYPE(lpPicInfo))
{
case NONE:
{
#if OBJ_EMPTY_OBJECT_FRAME
extern DrawBlank(HDC hDC, RECT FAR *rc);
DrawBlank(hDC,lpBounds);
#else
#ifdef DEBUG
OutputDebugString( (LPSTR) "Displaying empty object\n\r");
#endif
#endif
return TRUE;
}
}
#ifdef DEBUG
OutputDebugString( (LPSTR) "Displaying object\n\r");
#endif
#ifdef JAPAN // added by Hiraisi (BUG#2732/WIN31)
if (lpOBJ_QUERY_INFO(lpPicInfo)->fCantDisplay)
bSuccess = (OLE_OK == OleDraw(lpOBJ_QUERY_OBJECT(lpPicInfo),hDC,lpBounds,NULL,NULL));
else
bSuccess = !ObjError(OleDraw(lpOBJ_QUERY_OBJECT(lpPicInfo),hDC,lpBounds,NULL,NULL));
if (!bSuccess)
lpOBJ_QUERY_INFO(lpPicInfo)->fCantDisplay = TRUE;
else
lpOBJ_QUERY_INFO(lpPicInfo)->fCantDisplay = FALSE;
#else
bSuccess = !ObjError(OleDraw(lpOBJ_QUERY_OBJECT(lpPicInfo),hDC,lpBounds,NULL,NULL));
if (!bSuccess)
lpOBJ_QUERY_INFO(lpPicInfo)->fCantDisplay = TRUE;
#endif // JAPAN
return bSuccess;
}
BOOL ObjQueryObjectBounds(OBJPICINFO far *lpPicInfo, HDC hDC,
int *pdxa, int *pdya)
/* return bounds in twips */
{
RECT bounds;
BOOL bRetval;
OLESTATUS olestat;
int mmOld;
POINT pt;
if (otOBJ_QUERY_TYPE(lpPicInfo) == NONE)
{
/* set to default */
*pdxa = nOBJ_BLANKOBJECT_X;
*pdya = nOBJ_BLANKOBJECT_Y;
return TRUE;
}
if ((olestat = OleQueryBounds(lpOBJ_QUERY_OBJECT(lpPicInfo),&bounds))
== OLE_ERROR_BLANK)
{
Assert(0);
if (ObjWaitForObject(lpOBJ_QUERY_INFO(lpPicInfo),TRUE))
return FALSE;
olestat = OleQueryBounds(lpOBJ_QUERY_OBJECT(lpPicInfo),&bounds);
}
if (ObjError(olestat))
return FALSE;
pt.x = bounds.right - bounds.left;
pt.y = -(bounds.bottom - bounds.top);
#ifdef DEBUG
{
char szMsg[180];
wsprintf(szMsg,"Object HIMETRIC width: %d height: %d\n\r",pt.x,-pt.y);
OutputDebugString(szMsg);
}
#endif
mmOld = SetMapMode(hDC,MM_HIMETRIC);
LPtoDP(hDC,&pt,1);
SetMapMode(hDC,MM_TWIPS);
DPtoLP(hDC,&pt,1);
SetMapMode(hDC,mmOld);
*pdxa = pt.x;
*pdya = pt.y;
return TRUE;
}
void ObjInvalidatePict(OBJPICINFO *pPicInfo, typeCP cp)
{
struct EDL *pedl;
RECT rc;
extern int wwCur;
ObjPushParms(docCur);
ObjCachePara(docCur,cp);
Select(vcpFirstParaCache,vcpLimParaCache);
FreezeHp();
if (FGetPictPedl(&pedl)) // find pedl at selCur.cpFirst;
{
ComputePictRect( &rc, pPicInfo, pedl, wwCur );
InvalidateRect(hDOCWINDOW, &rc, FALSE);
}
MeltHp();
ObjPopParms(TRUE);
UPDATE_INVALID();
}
void ObjInvalidateObj(LPOLEOBJECT lpObject)
{
typeCP cp;
OBJPICINFO picInfo;
ObjPushParms(docCur);
if (ObjGetPicInfo(lpObject,docCur,&picInfo,&cp))
ObjInvalidatePict(&picInfo,cp);
ObjPopParms(TRUE);
}
/****************************************************************/
/*********************** OLE CLIPBOARD *************************/
/****************************************************************/
BOOL ObjCreateObjectInClip(OBJPICINFO *pPicInfo)
{
LONG otobject;
szOBJNAME szObjName;
OLESTATUS olestat;
BOOL bRetval = FALSE;
Assert (lhClientDoc != NULL);
if (ObjAllocObjInfo(pPicInfo,selCur.cpFirst,NONE,TRUE,szObjName))
goto error;
if (vbObjLinkOnly)
{
if (ObjError(OleCreateLinkFromClip(PROTOCOL, (LPOLECLIENT)lpOBJ_QUERY_INFO(pPicInfo),
lhClientDoc, szObjName,
&lpOBJ_QUERY_OBJECT(pPicInfo), olerender_draw, 0)))
{
lpOBJ_QUERY_OBJECT(pPicInfo) = NULL;
goto error;
}
}
else if (vObjPasteLinkSpecial)
{
if (ObjError(OleCreateLinkFromClip(PROTOCOL, (LPOLECLIENT)lpOBJ_QUERY_INFO(pPicInfo),
lhClientDoc, szObjName,
&lpOBJ_QUERY_OBJECT(pPicInfo), olerender_format, cfObjPasteSpecial)))
{
lpOBJ_QUERY_OBJECT(pPicInfo) = NULL;
goto error;
}
}
else
{
WORD cfClipFormat=0;
OLEOPT_RENDER orRender = olerender_draw;
if (cfObjPasteSpecial && (cfObjPasteSpecial != vcfOwnerLink))
/* from PasteSpecial. There's a format on clipboard that
user wants to paste and its not the embedded object format.
So we'll do it as a static object. */
{
cfClipFormat = cfObjPasteSpecial;
orRender = olerender_format;
olestat = OLE_ERROR_CLIPBOARD; // force get static object
}
else // try for embedded
olestat = OleCreateFromClip(PROTOCOL, (LPOLECLIENT)lpOBJ_QUERY_INFO(pPicInfo),
lhClientDoc, szObjName,
&lpOBJ_QUERY_OBJECT(pPicInfo), orRender, cfClipFormat);
switch(olestat)
{
case OLE_ERROR_CLIPBOARD:
/* try static protocol */
olestat = OleCreateFromClip(SPROTOCOL, (LPOLECLIENT)lpOBJ_QUERY_INFO(pPicInfo),
lhClientDoc, szObjName,
&lpOBJ_QUERY_OBJECT(pPicInfo), orRender, cfClipFormat);
switch(olestat)
{
case OLE_ERROR_CLIPBOARD:
goto error;
case OLE_WAIT_FOR_RELEASE:
case OLE_OK:
break;
default:
lpOBJ_QUERY_OBJECT(pPicInfo) = NULL;
goto error;
}
break;
case OLE_WAIT_FOR_RELEASE:
case OLE_OK:
break;
default:
ObjError(olestat);
goto error;
}
}
/* Figure out what kind of object we have */
if (ObjError(OleQueryType(lpOBJ_QUERY_OBJECT(pPicInfo),&otobject)))
goto error;
switch(otobject)
{
case OT_LINK:
otOBJ_QUERY_TYPE(pPicInfo) = LINK;
break;
case OT_EMBEDDED:
otOBJ_QUERY_TYPE(pPicInfo) = EMBEDDED;
break;
default:
otOBJ_QUERY_TYPE(pPicInfo) = STATIC;
break;
}
if (ObjInitServerInfo(lpOBJ_QUERY_INFO(pPicInfo)))
goto error;
if (!FComputePictSize(pPicInfo, &(pPicInfo->dxaSize),
&(pPicInfo->dyaSize) ))
goto error;
return TRUE;
error:
if (lpOBJ_QUERY_INFO(pPicInfo))
ObjDeleteObject(lpOBJ_QUERY_INFO(pPicInfo),TRUE);
Error(IDPMTFailedToCreateObject);
return FALSE;
}
BOOL ObjWriteToClip(OBJPICINFO FAR *lpPicInfo)
/* return TRUE if OK, FALSE if not */
{
#ifdef DEBUG
OutputDebugString( (LPSTR) "Copying Object to Clipboard\n\r");
#endif
if (otOBJ_QUERY_TYPE(lpPicInfo) == NONE)
return FALSE;
if (ObjWaitForObject(lpOBJ_QUERY_INFO(lpPicInfo),TRUE))
return FALSE;
return (!ObjError(OleCopyToClipboard(lpOBJ_QUERY_OBJECT(lpPicInfo))));
}
/****************************************************************/
/*********************** OLE MENU HANDLING **********************/
/****************************************************************/
void ObjUpdateMenu(HMENU hMenu)
/* this *MUST* be called *AFTER* paste menuitem has already been enabled
according to presence of non-object contents of the clipboard!!! (1.25.91) D. Kent */
{
int mfPaste = MF_GRAYED;
#if !defined(SMALL_OLE_UI)
int mfPasteLink = MF_GRAYED;
int mfLinks = MF_GRAYED;
#endif
int mfPasteSpecial = MF_GRAYED;
int mfInsertNew = MF_GRAYED;
WORD cfFormat = NULL;
BOOL bIsEmbed=FALSE,bIsLink=FALSE;
extern BOOL vfOutOfMemory;
extern int vfOwnClipboard;
if (!vfOutOfMemory)
{
if (vfOwnClipboard)
{
if (CpMacText( docScrap ) != cp0) // something in scrap
mfPaste = MF_ENABLED;
}
else
{
if (OleQueryCreateFromClip(PROTOCOL, olerender_draw, 0) == OLE_OK)
mfPaste = MF_ENABLED, bIsEmbed=TRUE;
else if (OleQueryCreateFromClip(SPROTOCOL, olerender_draw, 0) == OLE_OK)
mfPaste = MF_ENABLED;
// Enable "Paste Link" if there is a link-able object in the clipboard
if (OleQueryLinkFromClip(PROTOCOL, olerender_draw, 0) == OLE_OK)
{
bIsLink=TRUE;
#if !defined(SMALL_OLE_UI)
mfPasteLink = MF_ENABLED;
#endif
}
}
/* There's no point in putting up pastespecial if there are no
alternate clip formats to choose from. */
#if defined(SMALL_OLE_UI)
/* except to get paste link */
#endif
if (OpenClipboard( hPARENTWINDOW ) )
{
int ncfCount=0;
while (cfFormat = EnumClipboardFormats(cfFormat))
switch (cfFormat)
{
case CF_TEXT:
mfPaste = MF_ENABLED;
case CF_BITMAP:
case CF_METAFILEPICT:
case CF_DIB:
++ncfCount;
break;
}
CloseClipboard();
if (bIsLink || bIsEmbed)
{
#if !defined(SMALL_OLE_UI)
if (ncfCount >= 1)
#endif
mfPasteSpecial = MF_ENABLED;
}
else if (ncfCount > 1)
mfPasteSpecial = MF_ENABLED;
}
#if !defined(SMALL_OLE_UI)
mfLinks = MF_ENABLED;
#endif
// Insert_New is always enabled?
mfInsertNew = MF_ENABLED;
}
ObjUpdateMenuVerbs( hMenu );
EnableMenuItem(hMenu, imiPaste, mfPaste);
#if !defined(SMALL_OLE_UI)
EnableMenuItem(hMenu, imiPasteLink, mfPasteLink);
EnableMenuItem(hMenu, imiProperties, mfLinks);
#endif
EnableMenuItem(hMenu, imiPasteSpecial, mfPasteSpecial);
EnableMenuItem(hMenu, imiInsertNew, mfInsertNew);
}
/****************************************************************/
/*********************** OLE DIALOG PROCS ***********************/
/****************************************************************/
#if !defined(SMALL_OLE_UI)
/* Properties... dialog */
BOOL FAR PASCAL fnProperties(HWND hDlg, unsigned msg, WORD wParam, LONG lParam)
{
ATOM aDocName = 0;
ATOM aCurName = 0;
static int idButton = 0;
OBJPICINFO picInfo;
BOOL bSelected;
int cSelected = 0;
int iListItem = 0;
HWND vhwndObjListBox = GetDlgItem(hDlg, IDD_LISTBOX);
extern HWND vhWndMsgBoxParent;
static BOOL bDidSomething;
switch (msg) {
case WM_ACTIVATE:
if (wParam)
vhWndMsgBoxParent = hDlg;
break;
case WM_UPDATELB: /* Redrawing listbox contents */
SendMessage(vhwndObjListBox, WM_SETREDRAW, 0, 0L);
case WM_UPDATEBN: /* Updating Buttons only */
case WM_INITDIALOG: {
HANDLE hData = NULL;
LPSTR lpstrData = NULL;
LPSTR lpstrTemp;
char szType[40];
char szFull[cchMaxSz];
typeCP cpPicInfo;
struct SEL selSave;
OLESTATUS olestat;
idButton = 0;
/* Reset the list box */
if (msg == WM_INITDIALOG) // see fall through above
{
SendMessage(vhwndObjListBox, LB_RESETCONTENT, 0, 0L);
EnableOtherModeless(FALSE);
selSave=selCur;
//ObjWriteFixup(docCur,TRUE,cp0);
bLinkProps = TRUE;
bDidSomething = FALSE;
ObjSetSelectionType(docCur, selSave.cpFirst, selSave.cpLim);
}
/* Insert all the items in list box */
cpPicInfo = cpNil;
while (ObjPicEnumInRange(&picInfo,docCur,cp0,CpMacText(docCur),&cpPicInfo))
{
if (otOBJ_QUERY_TYPE(&picInfo) != LINK)
{
if (msg == WM_UPDATEBN)
continue; // object ain't in list box
if (msg == WM_INITDIALOG)
fOBJ_QUERY_IN_PROP_LIST(&picInfo) = OUT;
else if (fOBJ_QUERY_IN_PROP_LIST(&picInfo) == IN)
/** then this is an object which was in the list and
has been frozen */
{
fOBJ_QUERY_IN_PROP_LIST(&picInfo) = DELETED;
SendMessage(vhwndObjListBox, LB_DELETESTRING, iListItem, 0L);
}
else
continue; // object ain't in list box
continue;
}
else if (msg == WM_INITDIALOG)
{
fOBJ_QUERY_IN_PROP_LIST(&picInfo) = IN;
/**
This flag causes object to be cloned if any changes
are made to it. Clone will be used for cancel button.
**/
if (ObjLoadObjectInDoc(&picInfo,docCur,cpPicInfo) == cp0)
goto onOut;
}
if (msg == WM_INITDIALOG) // select in list if selected in doc
{
if (OBJ_SELECTIONTYPE == LINK)
bSelected = (cpPicInfo >= selSave.cpFirst &&
cpPicInfo < selSave.cpLim);
else // no selection, select first item
bSelected = iListItem == 0;
/* OR if its a bad link, take the liberty of selecting it */
if (fOBJ_BADLINK(&picInfo))
bSelected = TRUE;
}
else // select in list if already selected in list
bSelected = SendMessage(vhwndObjListBox, LB_GETSEL, iListItem, 0L);
/* Get the update options */
if (fOBJ_BADLINK(&picInfo))
{
LoadString(hINSTANCE, IDSTRFrozen, szType, sizeof(szType));
if (bSelected)
idButton = -1;
}
else switch (ObjGetUpdateOptions(&picInfo))
{
case oleupdate_always:
LoadString(hINSTANCE, IDSTRAuto, szType, sizeof(szType));
if (bSelected)
switch (idButton) {
case 0: idButton = IDD_AUTO; break;
case IDD_MANUAL: idButton = -1; break;
default: break;
}
break;
case oleupdate_oncall:
LoadString(hINSTANCE, IDSTRManual, szType, sizeof(szType));
if (bSelected)
switch (idButton) {
case 0: idButton = IDD_MANUAL; break;
case IDD_AUTO: idButton = -1; break;
default: break;
}
break;
default:
LoadString(hINSTANCE, IDSTRFrozen, szType, sizeof(szType));
if (bSelected)
idButton = -1;
/* Disable the change link button, can't change frozen link */
aCurName = -1;
}
/* Retrieve the server name */
olestat = ObjGetData(lpOBJ_QUERY_INFO(&picInfo), vcfLink, &hData);
if ((olestat != OLE_WARN_DELETE_DATA) && (olestat != OLE_OK))
return TRUE;
lpstrData = MAKELP(hData,0);
/* The link format is: "szClass0szDocument0szItem00" */
/* Retrieve the server's class ID */
RegGetClassId(szFull, lpstrData);
lstrcat(szFull, "\t");
/* Display the Document and Item names */
while (*lpstrData++);
/* Get this document name */
aDocName = AddAtom(lpstrData);
/* Make sure only one document selected for Change Link */
if (bSelected)
switch (aCurName) {
case 0:
aCurName = aDocName;
break;
case -1:
break;
default:
if (aCurName != aDocName)
aCurName = -1;
break;
}
DeleteAtom(aDocName);
/* Strip off the path name and drive letter */
lpstrTemp = lpstrData;
while (*lpstrTemp)
{
if (*lpstrTemp == '\\' || *lpstrTemp == ':')
lpstrData = lpstrTemp + 1;
#ifdef DBCS //T-HIROYN 1992.07.13
lpstrTemp = AnsiNext(lpstrTemp);
#else
lpstrTemp++;
#endif
}
/* Append the file name */
lstrcat(szFull, lpstrData);
lstrcat(szFull, "\t");
/* Append the item name */
while (*lpstrData++);
lstrcat(szFull, lpstrData);
lstrcat(szFull, "\t");
if (olestat == OLE_WARN_DELETE_DATA)
GlobalFree(hData);
/* Append the type of link */
lstrcat(szFull, szType);
switch (msg)
{
case WM_UPDATELB:
SendMessage(vhwndObjListBox, LB_DELETESTRING, iListItem, 0L);
// fall through...
case WM_INITDIALOG:
SendMessage(vhwndObjListBox, LB_INSERTSTRING, iListItem, (DWORD)(LPSTR)szFull);
SendMessage(vhwndObjListBox, LB_SETSEL, bSelected, (DWORD)iListItem);
break;
}
if (bSelected)
cSelected++;
iListItem++;
}
/* Uncheck those buttons that shouldn't be checked */
CheckDlgButton(hDlg, IDD_AUTO, idButton == IDD_AUTO);
CheckDlgButton(hDlg, IDD_MANUAL, idButton == IDD_MANUAL);
/* Gray the Change Link... button, as appropriate */
EnableWindow(GetDlgItem(hDlg, IDD_CHANGE), (aCurName && aCurName != -1));
EnableWindow(GetDlgItem(hDlg, IDD_EDIT), cSelected);
EnableWindow(GetDlgItem(hDlg, IDD_PLAY), cSelected);
EnableWindow(GetDlgItem(hDlg, IDD_UPDATE), cSelected);
EnableWindow(GetDlgItem(hDlg, IDD_FREEZE), cSelected);
EnableWindow(GetDlgItem(hDlg, IDD_AUTO), cSelected);
EnableWindow(GetDlgItem(hDlg, IDD_MANUAL), cSelected);
if (msg == WM_UPDATELB)
{
/* WM_UPDATELB case: Redraw the list box */
InvalidateRect(vhwndObjListBox, NULL, TRUE);
SendMessage(vhwndObjListBox, WM_SETREDRAW, 1, 0L);
}
return TRUE;
}
case WM_SYSCOMMAND:
switch(wParam & 0xFFF0)
{
case SC_CLOSE:
goto onOut;
break;
}
break;
case WM_DOLINKSCOMMAND:
{
BOOL bError;
bDidSomething |= DoLinksCommand(wParam,lParam,hDlg,&bError);
switch (wParam)
{
case IDD_PLAY:
case IDD_EDIT:
InvalidateRect(hDOCWINDOW, NULL, TRUE);
if (!bError) // don't leave if there was an error
goto onOut;
}
}
break;
case WM_COMMAND:
switch (wParam)
{
case IDCANCEL:
if (bDidSomething)
{
SendMessage(hDlg,WM_DOLINKSCOMMAND,IDD_UNDO,0L);
InvalidateRect(hDOCWINDOW, NULL, TRUE);
bDidSomething = FALSE; // cause its undone now
}
// fall through...
case IDOK:
onOut:
if (bDidSomething)
{
ObjEnumInDoc(docCur,ObjClearCloneInDoc);
}
NoUndo();
bLinkProps = FALSE;
//ObjWriteFixup(docCur,FALSE,cp0);
OurEndDialog(hDlg, TRUE);
UpdateWindow(hDOCWINDOW); // cause we may have lost activation
return TRUE;
default:
/** posting message avoids some weird asynchronicities when
waiting for objects before returning after pressing a
button **/
PostMessage(hDlg,WM_DOLINKSCOMMAND,wParam,lParam);
break;
}
break;
}
return FALSE;
}
static BOOL DoLinksCommand(WORD wParam, DWORD lParam, HWND hDlg, BOOL *bError)
{
int cItems;
int i;
HANDLE hSelected=NULL;
int far *lpSelected;
typeCP cpSuccess;
typeCP cpPicInfo;
BOOL bFirst=TRUE;
OBJPICINFO picInfo;
BOOL bDidSomething=FALSE;
HWND vhwndObjListBox = GetDlgItem(hDlg, IDD_LISTBOX);
StartLongOp();
*bError = FALSE;
switch (wParam)
{
case IDD_REFRESH:
/** update a link if its been set to AUTOMATIC update */
{
OLEOPT_UPDATE UpdateOpt;
if (!ObjError(OleGetLinkUpdateOptions(((LPOBJINFO)lParam)->lpobject,&UpdateOpt)))
if (UpdateOpt == oleupdate_always)
fnObjUpdate((LPOBJINFO)lParam);
goto SkipIt;
}
break;
case IDD_LISTBOX:
switch (HIWORD(lParam))
{
case LBN_SELCHANGE:
PostMessage(hDlg, WM_UPDATEBN, 0, 0L); // fall through
default:
goto SkipIt;
}
break;
case IDD_CHANGE:
aNewName = aOldName = 0;
// fall through...
case IDD_UPDATE:
ObjEnumInDoc(docCur,ObjSetNoUpdate);
break;
case IDD_AUTO:
case IDD_MANUAL:
if (IsDlgButtonChecked(hDlg,wParam))
goto SkipIt;
/* work around for bug #8280 */
CheckDlgButton(hDlg,wParam,TRUE);
break;
}
/**
Everything after here is done for each item selected in
links list box *
**/
/* If nothing is selected, quit! */
if (wParam != IDD_UNDO)
{
if ((cItems = SendMessage(vhwndObjListBox, LB_GETSELCOUNT, 0, 0L)) <= 0)
goto SkipIt;
if ((hSelected = GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT,
cItems * sizeof(int))) == NULL)
{
Error(IDPMTNoMemory);
goto SkipIt;
}
if ((lpSelected = (int far *)GlobalLock(hSelected)) == NULL)
{
Error(IDPMTNoMemory);
goto SkipIt;
}
/* Retrieve the selected items (in sorted order) */
SendMessage(vhwndObjListBox, LB_GETSELITEMS,
cItems, (DWORD)lpSelected);
}
for (i = 0, cpPicInfo = cpNil;
ObjPicEnumInRange(&picInfo,docCur,cp0,CpMacText(docCur),&cpPicInfo);)
{
/**
For IDD_UNDO we do all. Dirty flag will filter in the ones
we've operated on. Assumes Saved before calling (see
fnObjProperties())
**/
if (fOBJ_QUERY_IN_PROP_LIST(&picInfo)) // is or was in list
{
if (wParam == IDD_UNDO)
{
cpSuccess = ObjUseCloneInDoc(&picInfo,docCur,cpPicInfo);
if ((cpSuccess == cp0) || ferror || fPropsError)
break; // there was an error
}
else if (fOBJ_QUERY_IN_PROP_LIST(&picInfo) == IN)
{
/** We're enumerating all objects, not just
ones in list box **/
if (*lpSelected == i) // selected item
{
ObjCachePara(docCur,cpPicInfo);
switch(wParam)
{
case IDD_AUTO: /* Change the (link) update options */
case IDD_MANUAL:
if (!fOBJ_BADLINK(&picInfo))
{
cpSuccess = ObjBackupInDoc(&picInfo,docCur,cpPicInfo);
if (cpSuccess)
cpSuccess = (typeCP)ObjSetUpdateOptions(&picInfo, wParam, docCur, cpPicInfo);
}
break;
case IDD_CHANGE:
if (bFirst)
{
if (!ObjQueryNewLinkName(&picInfo,docCur,cpPicInfo))
// then didn't get new link name
goto SkipIt;
bFirst=FALSE;
}
cpSuccess = ObjBackupInDoc(&picInfo,docCur,cpPicInfo);
if (cpSuccess)
cpSuccess = ObjChangeLinkInDoc(&picInfo,docCur,cpPicInfo);
/* must do this because we don't want to put up
ChangeOtherLinks dialog until we know the first
change was a success */
if (cpSuccess)
{
lpOBJ_QUERY_INFO(&picInfo)->fCompleteAsync = TRUE;
if (ObjWaitForObject(lpOBJ_QUERY_INFO(&picInfo),TRUE))
cpSuccess = cp0;
else if (ferror || fPropsError)
cpSuccess = cp0;
}
break;
case IDD_PLAY:
cpSuccess = ObjPlayObjectInDoc(&picInfo,docCur,cpPicInfo);
break;
case IDD_EDIT:
cpSuccess = ObjEditObjectInDoc(&picInfo,docCur,cpPicInfo);
break;
case IDD_UPDATE:
cpSuccess = ObjBackupInDoc(&picInfo,docCur,cpPicInfo);
if (cpSuccess)
cpSuccess = ObjUpdateObjectInDoc(&picInfo,docCur,cpPicInfo);
/* must do this because we don't want to put up
ChangeOtherLinks dialog until we know the first
change was a success */
if (cpSuccess)
{
lpOBJ_QUERY_INFO(&picInfo)->fCompleteAsync = TRUE;
if (ObjWaitForObject(lpOBJ_QUERY_INFO(&picInfo),TRUE))
cpSuccess = cp0;
else if (ferror || fPropsError)
cpSuccess = cp0;
}
break;
case IDD_UPDATEOTHER:
aOldName = aOBJ_QUERY_DOCUMENT_LINK(&picInfo);
if (cpSuccess)
ChangeOtherLinks(docCur,FALSE,TRUE);
aOldName=0;
break;
case IDD_FREEZE:
cpSuccess = ObjBackupInDoc(&picInfo,docCur,cpPicInfo);
if (cpSuccess)
cpSuccess = ObjFreezeObjectInDoc(&picInfo,docCur,cpPicInfo);
break;
}
if ((cpSuccess == cp0) || ferror || fPropsError)
break; // there was an error
lpSelected++;
}
i++; // counting all objects in list box
} // end if IN
}
}
/*** Handle error conditions ***/
if ((cpSuccess == cp0) || ferror || fPropsError)
{
*bError = TRUE;
if (!ferror) // issue error message
{
switch (wParam)
{
case IDD_UPDATE:
case IDD_CHANGE:
Error(IDPMTLinkUnavailable);
break;
default:
Error(IDPMTOLEError);
break;
}
}
if (wParam != IDD_UNDO)
{
/** so we can continue calling Replace(), etc */
ferror = FALSE;
/* undo whatever we tried to do that failed */
ObjCachePara(docCur,cpPicInfo); // for use clone
ObjUseCloneInDoc(&picInfo,docCur,cpPicInfo);
lpOBJ_QUERY_INFO(&picInfo)->fCompleteAsync = TRUE;
ObjWaitForObject(lpOBJ_QUERY_INFO(&picInfo),TRUE);
ObjInvalidatePict(&picInfo,cpPicInfo);
PostMessage(hDlg,WM_UPDATELB,0,0L);
ferror = FALSE; // again
}
fPropsError = FALSE;
}
switch (wParam)
{
/* Dismiss the dialog on Open */
case IDD_UPDATEOTHER:
UPDATE_INVALID();
break;
case IDD_PLAY:
case IDD_EDIT:
case IDD_UNDO:
break;
case IDD_UPDATE:
if (cpSuccess)
SendMessage(hDlg,WM_COMMAND,IDD_UPDATEOTHER,0L);
bDidSomething = TRUE;
break;
case IDD_CHANGE:
if (cpSuccess)
{
/** aOldName and aNewName are now set, change other links having
aOldName */
/** if first change is bad, don't change others */
ChangeOtherLinks(docCur,TRUE,TRUE);
UPDATE_INVALID();
}
aOldName=0;
aNewName=0;
// fall through....
case IDD_FREEZE:
case IDD_AUTO:
case IDD_MANUAL:
PostMessage(hDlg,WM_UPDATELB,0,0L);
bDidSomething = TRUE;
break;
}
SkipIt:
if (hSelected)
GlobalFree(hSelected);
EndLongOp(vhcArrow);
return bDidSomething;
}
#else
// cause I don't wanna change def file yet...
BOOL FAR PASCAL fnProperties(HWND hDlg, unsigned msg, WORD wParam, LONG lParam)
{
hDlg;
}
#endif
/* Invalid Link dialog */
int FAR PASCAL fnInvalidLink(HWND hDlg, unsigned msg, WORD wParam, LONG lParam)
{
switch (msg) {
case WM_INITDIALOG:
#if 0
{
char lpString[120];
LoadString(hINSTANCE, (WORD)lParam, lpString, sizeof(lpString));
SetDlgItemText(hDlg,IDD_MESSAGE,lpString);
}
#endif
break;
case WM_SYSCOMMAND:
switch(wParam & 0xFFF0)
{
case SC_CLOSE:
EndDialog(hDlg, IDOK);
break;
}
break;
case WM_COMMAND:
switch (wParam) {
case IDOK:
case IDD_CHANGE:
EndDialog(hDlg, wParam);
}
}
return FALSE;
}
/* Insert New... dialog */
int FAR PASCAL fnInsertNew(HWND hDlg, unsigned msg, WORD wParam, LONG lParam)
{
HWND hwndList = GetDlgItem(hDlg, IDD_LISTBOX);
switch (msg) {
case WM_INITDIALOG:
if (!RegGetClassNames(hwndList))
OurEndDialog(hDlg, IDCANCEL);
EnableOtherModeless(FALSE);
SendMessage(hwndList, LB_SETCURSEL, 0, 0L);
break;
case WM_ACTIVATE:
if (wParam)
vhWndMsgBoxParent = hDlg;
break;
case WM_SYSCOMMAND:
switch(wParam & 0xFFF0)
{
case SC_CLOSE:
OurEndDialog(hDlg, IDCANCEL);
break;
}
break;
case WM_COMMAND:
switch (wParam) {
case IDD_LISTBOX:
if (HIWORD(lParam) != LBN_DBLCLK)
break;
case IDOK:
StartLongOp();
if (!RegCopyClassName(hwndList, (LPSTR)szClassName))
wParam = IDCANCEL;
// fall through ...
case IDCANCEL:
OurEndDialog(hDlg, wParam);
break;
}
break;
}
return FALSE;
}
BOOL vbCancelOK=FALSE;
/* Waiting for object dialog */
BOOL FAR PASCAL fnObjWait(HWND hDlg, unsigned msg, WORD wParam, LONG lParam)
{
static LPOLEOBJECT lpObject;
static LPOBJINFO lpOInfo;
static BOOL bCanCancel;
extern HWND hwndWait;
extern int vfDeactByOtherApp;
extern int flashID;
switch (msg) {
case WM_INITDIALOG:
{
/**
NOTE: the key idea in setting these options is that the cancel
button must cancel what the user thinks is the current operation.
vbCancelOK == TRUE,
cancel button may be enabled, depending on other flags
vbCancelOK is set in WMsgLoop.
lpOInfo->fCancelAsync == TRUE,
Cancel is enabled if vbCancelOK
Cancel button cancels dialog without regard to pending async.
Pending async is killed quietly in CallBack if possible.
Generally use if the pending async is not part of the operation
being cancelled, and:
1) You're about to make a very important call which justifies
silently killing any pending operation.
Note: this one is weird if you're trying to release or delete, because
the pending async could itself be a release or delete.
lpOInfo->fCompleteAsync == TRUE,
Cancel is enabled only if pending async can be cancelled.
Cancel button cancels pending async.
Generally use if the pending async *is* part of the operation
being cancelled, and:
1) You're in a sequence of async calls and cancelling
would require cancelling the previous async in the
sequence, or
2) You have just made an async call which you want to make
synchronous but don't mind if the user cancels it.
lpOInfo->fCanKillAsync == TRUE,
Use with lpOInfo->fCompleteAsync.
Indicates that we already know that the async can be cancelled,
so Cancel button can be enabled immediately.
**/
hwndWait = hDlg;
lpObject = (LPOLEOBJECT)lParam;
Assert (lpObject != NULL);
lpOInfo = GetObjInfo(lpObject);
Assert(lpOInfo != NULL);
bCanCancel=FALSE;
if (vbCancelOK && (!lpOInfo->fCompleteAsync || lpOInfo->fCanKillAsync))
SendMessage(hDlg,WM_UKANKANCEL,0,0L);
if (lpOInfo->fCancelAsync)
/* we'll cancel async in CallBack if get a QUERY_RETRY */
lpOInfo->fKillMe = TRUE;
SetTimer(hDlg, 1234, 250, (FARPROC)NULL);
return TRUE;
}
break;
case WM_ACTIVATE:
if (wParam)
vhWndMsgBoxParent = hDlg;
break;
case WM_RUTHRUYET:
case WM_TIMER:
/* this is a lot easier than making this modeless */
/* we gotta check this because if server dies we don't get
an OLE_RELEASE (the 'normal way this dialog is knocked off),
rather OleQueryReleaseStatus will return OLE_OK */
if (OleQueryReleaseStatus(lpObject) != OLE_BUSY)
PostMessage(hDlg,WM_DIESCUMSUCKINGPIG,0,0L);
break;
case WM_UKANKANCEL:
/* we got a QUERY_RETRY or are initing */
if (!bCanCancel && vbCancelOK)
{
char szMsg[20];
LoadString(hINSTANCE, IDSTRCancel, szMsg, sizeof(szMsg));
SetDlgItemText(hDlg,IDOK,szMsg);
bCanCancel=TRUE;
}
break;
case WM_DIESCUMSUCKINGPIG:
hwndWait = NULL;
KillTimer(hDlg, 1234);
/* clear flags */
if (CheckPointer(lpOInfo,1))
{
lpOInfo->fCompleteAsync =
lpOInfo->fCancelAsync =
lpOInfo->fCanKillAsync = FALSE;
}
/* wParam is TRUE if error */
OurEndDialog(hDlg,wParam);
break;
case WM_COMMAND:
switch (wParam) {
case IDOK:
if (bCanCancel) // pressed cancel button
{
if (lpOInfo->fCompleteAsync)
lpOInfo->fKillMe = TRUE; // cancel async asynchronously
else if (lpOInfo->fCancelAsync)
lpOInfo->fKillMe = FALSE; // had a chance to kill, user doesn't care anymore
PostMessage(hDlg,WM_DIESCUMSUCKINGPIG,1,0L);
}
else
{
/* retry */
if (OleQueryReleaseStatus(lpObject) != OLE_BUSY)
PostMessage(hDlg,WM_DIESCUMSUCKINGPIG,0,0L);
}
break;
case IDD_SWITCH:
/* bring up task list */
DefWindowProc(hDlg,WM_SYSCOMMAND,SC_TASKLIST,0L);
break;
}
break;
default:
break;
}
return FALSE;
}
/****************************************************************/
/*********************** VARIOUS OLE FUNCTIONS ******************/
/****************************************************************/
void fnObjInsertNew(void)
{
OBJPICINFO picInfo;
typeCP cpNext=selCur.cpFirst;
if (!FWriteOk( fwcInsert ))
return;
/* this'll set global szClassName */
if (OurDialogBox(hINSTANCE, "DTCREATE" ,hMAINWINDOW, lpfnInsertNew) == IDCANCEL)
return;
StartLongOp();
ObjCachePara( docCur, cpNext);
if (!ObjCreateObjectInDoc(docCur, cpNext))
{
ClearInsertLine();
fnClearEdit(OBJ_INSERTING);
NoUndo();
}
EndLongOp(vhcIBeam);
}
BOOL ObjCreateObjectInDoc(int doc,typeCP cpParaStart)
/* assumes szClassName is set to server class */
/* called only for InsertObject */
/* return whether error */
{
szOBJNAME szObjName;
LPOBJINFO lpObjInfo=NULL;
if ((lpObjInfo = ObjGetObjInfo(szObjName)) == NULL)
goto err;
if (ObjError(OleCreate(PROTOCOL, (LPOLECLIENT)lpObjInfo,
(LPSTR)szClassName,
lhClientDoc, szObjName, &(lpObjInfo->lpobject), olerender_draw, 0)))
{
/* will free memory later */
lpObjInfo->lpobject = NULL;
goto err;
}
/* normally set in ObjAllocObjInfo, but for unfinished objects we need it now! */
lpObjInfo->cpWhere = cpParaStart;
lpObjInfo->objectType = NONE;
//lpObjInfo->aName = AddAtom(szClassName);
if (ObjInitServerInfo(lpObjInfo))
goto err;
return FALSE;
err:
if (lpObjInfo)
ObjDeleteObject(lpObjInfo,TRUE);
Error(IDPMTFailedToCreateObject);
return TRUE;
}
#define DRAG_EMBED 0 /* nothing */
#define DRAG_LINK 6 /* Ctrl + Shift + Drag */
#define DRAG_MULTIPLE 4 /* Shift + Drag */
void ObjGetDrop(HANDLE hDrop, BOOL bOpenFile)
{
int nNumFiles,count;
char szFileName[cchMaxFile];
extern struct CHP vchpSel;
struct CHP chpT;
BYTE bKeyState = 0;
typeCP cpFirst=selCur.cpFirst, dcp = 0;
int cchAddedEol=0;
typeCP cpNext=selCur.cpFirst,cpPrev=selCur.cpFirst,cpSel;
OBJPICINFO picInfo;
BOOL bError=FALSE;
static char szPackage[] = "Package";
MSG msg;
if (!FWriteOk( fwcInsert ))
return;
/* get number of files dropped */
nNumFiles = DragQueryFile(hDrop,0xFFFF,NULL,0);
/* See what the user wants us to do */
PeekMessage(&msg, (HWND)NULL, NULL, NULL, PM_NOREMOVE);
bKeyState = ((((GetKeyState(VK_SHIFT) < 0) << 2)
| ((GetKeyState(VK_CONTROL) < 0) << 1)));
if ((nNumFiles == 0) ||
((bKeyState != DRAG_EMBED) && (bKeyState != DRAG_LINK) && (bKeyState != DRAG_MULTIPLE)) ||
(bOpenFile && (bKeyState != DRAG_EMBED) && (bKeyState != DRAG_MULTIPLE)))
{
DragFinish(hDrop);
return;
}
if (bOpenFile)
{
DragQueryFile(hDrop,0,szFileName,sizeof(szFileName));
fnOpenFile((LPSTR)szFileName);
DragFinish(hDrop);
return;
}
ClearInsertLine();
if (fnClearEdit(OBJ_INSERTING))
return;
StartLongOp();
chpT = vchpSel;
(**hpdocdod)[docCur].fFormatted = fTrue;
if (cpFirst > cp0)
{
ObjCachePara(docCur, cpFirst - 1);
if (vcpLimParaCache != cpFirst)
{
cchAddedEol = ccpEol;
InsertEolPap(docCur, selCur.cpFirst, &vpapAbs);
cpNext += (typeCP)ccpEol;
}
}
ObjCachePara( docCur, cpNext );
/* create object for each file dropped */
for (count=0; count < nNumFiles; ++count)
{
szOBJNAME szObjName;
typeCP cpTmp;
/* get the filename */
DragQueryFile(hDrop,count,szFileName,sizeof(szFileName));
if (ObjAllocObjInfo(&picInfo,cpNext,EMBEDDED,TRUE,szObjName))
{
bError=TRUE;
goto end;
}
if ((bKeyState == DRAG_LINK))
{
if (ObjError(OleCreateLinkFromFile(PROTOCOL, (LPOLECLIENT)lpOBJ_QUERY_INFO(&picInfo),
szPackage,
szFileName, NULL,
lhClientDoc, szObjName,
&lpOBJ_QUERY_OBJECT(&picInfo), olerender_draw, 0)))
{
bError=TRUE;
lpOBJ_QUERY_OBJECT(&picInfo) = NULL;
goto end;
}
}
else // if ((bKeyState == DRAG_EMBED))
{
if (ObjError(OleCreateFromFile(PROTOCOL, (LPOLECLIENT)lpOBJ_QUERY_INFO(&picInfo),
szPackage,
szFileName,
lhClientDoc, szObjName,
&lpOBJ_QUERY_OBJECT(&picInfo), olerender_draw, 0)))
{
bError=TRUE;
lpOBJ_QUERY_OBJECT(&picInfo) = NULL;
goto end;
}
}
if (ObjInitServerInfo(lpOBJ_QUERY_INFO(&picInfo)))
{
bError=TRUE;
goto end;
}
if (!FComputePictSize(&picInfo, &(picInfo.dxaSize),
&(picInfo.dyaSize)))
{
bError=TRUE;
goto end;
}
ObjCachePara(docCur,cpNext);
if ((cpTmp = ObjSaveObjectToDoc(&picInfo,docCur,cpNext)) == cp0)
{
bError=TRUE;
goto end;
}
cpNext = cpTmp;
}
end:
dcp = cpNext-cpFirst;
if (dcp)
{
cpSel=CpFirstSty(cpFirst + dcp, styChar );
SetUndo( uacInsert, docCur, cpFirst, dcp, docNil, cpNil, cp0, 0 );
SetUndoMenuStr(IDSTRUndoEdit);
if (vuab.uac == uacReplNS)
/* Special UNDO code for picture paste */
vuab.uac = uacReplPic;
Select(cpSel, cpSel);
vchpSel = chpT; /* Preserve insert point props across this operation */
if (wwdCurrentDoc.fEditHeader || wwdCurrentDoc.fEditFooter)
{ /* If running head/foot, remove chSects & set para props */
MakeRunningCps( docCur, cpFirst, dcp );
}
if (ferror)
NoUndo();
}
if (bError)
{
Error(IDPMTFailedToCreateObject);
ObjDeleteObject(lpOBJ_QUERY_INFO(&picInfo),TRUE);
}
EndLongOp(vhcIBeam);
DragFinish(hDrop);
}
int vcVerbs;
void fnObjDoVerbs(WORD wVerb)
{
NoUndo();
if ((wVerb == imiVerb) // more than one object selected
|| (vcVerbs == 1)) // one verb
OBJ_PLAYEDIT = OLEVERB_PRIMARY;
else
OBJ_PLAYEDIT = (int)(wVerb - imiVerb - 1);
ObjEnumInRange(docCur,selCur.cpFirst,selCur.cpLim,ObjPlayObjectInDoc);
OBJ_PLAYEDIT = OLEVERB_PRIMARY;
}
void fnObjProperties(void)
{
int nRetval;
if (nRetval != -1)
OurDialogBox(hINSTANCE, "DTPROP", hMAINWINDOW, lpfnLinkProps);
}
BOOL fnObjUpdate(LPOBJINFO lpObjInfo)
{
BOOL bRetval;
#ifdef DEBUG
OutputDebugString( (LPSTR) "Updating object\n\r");
#endif
if (ObjWaitForObject(lpObjInfo,TRUE))
return TRUE;
StartLongOp();
if ((bRetval = ObjError(OleUpdate(lpObjInfo->lpobject))))
Error(IDPMTFailedToUpdate);
EndLongOp(vhcArrow);
return bRetval;
}
BOOL ObjDeleteObject(LPOBJINFO lpObjInfo, BOOL bDelete)
/** Delete object as well as objinfo. Note this must be synchronous.
Return whether an error.
**/
{
LPOLEOBJECT lpObject;
Assert(lpObjInfo != NULL);
if (!CheckPointer((LPSTR)lpObjInfo,1))
return FALSE; // already deleted
lpObject = lpObjInfo->lpobject;
if (lpObject == NULL)
{
ObjDeleteObjInfo(lpObjInfo);
return FALSE;
}
/* make sure not already deleted */
if (!ObjIsValid(lpObject))
{
ObjDeleteObjInfo(lpObjInfo);
return FALSE;
}
/** asynchronous deletion **/
if (OleQueryReleaseStatus(lpObject) != OLE_BUSY)
{
OLESTATUS olestat;
if (bDelete)
olestat = OleDelete(lpObject);
else
olestat = OleRelease(lpObject);
switch (olestat)
{
case OLE_OK:
ObjDeleteObjInfo(lpObjInfo);
break;
case OLE_WAIT_FOR_RELEASE:
lpObjInfo->fFreeMe = TRUE;
break;
}
}
else if (bDelete)
lpObjInfo->fDeleteMe = TRUE; // delete on OLE_RELEASE
else
lpObjInfo->fReleaseMe = TRUE; // release on OLE_RELEASE
return FALSE;
}
#include <print.h>
HANDLE hStdTargetDevice=NULL;
void ObjSetTargetDevice(BOOL bSetObjects)
{
extern PRINTDLG PD; /* Common print dlg structure, initialized in the init code */
extern CHAR (**hszPrinter)[];
extern CHAR (**hszPrDriver)[];
extern CHAR (**hszPrPort)[];
LPSTDTARGETDEVICE lpStdTargetDevice;
WORD nCount;
DEVMODE FAR *lpDevmodeData;
char FAR *lpData;
LPOLEOBJECT lpObject;
STDTARGETDEVICE stdT;
if (!PD.hDevMode)
/* then get for default printer */
{
if (hszPrinter == NULL || hszPrDriver == NULL || hszPrPort == NULL)
return;
if (**hszPrinter == '\0' || **hszPrDriver == '\0' || **hszPrPort == '\0')
return;
if (fnPrGetDevmode())
return;
}
lpDevmodeData = MAKELP(PD.hDevMode,0);
/* get the offsets */
stdT.deviceNameOffset = 0;
nCount = CchSz(*hszPrinter);
stdT.driverNameOffset = nCount;
nCount += CchSz(*hszPrDriver);
stdT.portNameOffset = nCount;
nCount += CchSz(*hszPrPort);
stdT.extDevmodeOffset = nCount;
nCount += (stdT.extDevmodeSize = lpDevmodeData->dmSize);
stdT.environmentOffset = nCount;
nCount += (stdT.environmentSize = lpDevmodeData->dmSize);
/* alloc the buffer */
if (hStdTargetDevice == NULL)
{
if ((hStdTargetDevice = GlobalAlloc(GMEM_MOVEABLE|GMEM_ZEROINIT,nCount+sizeof(STDTARGETDEVICE))) == NULL)
return;
}
else
{
if ((hStdTargetDevice =
GlobalReAlloc(hStdTargetDevice,
nCount+sizeof(STDTARGETDEVICE),GMEM_MOVEABLE|GMEM_ZEROINIT)) == NULL)
{
return;
}
}
lpStdTargetDevice = (LPSTDTARGETDEVICE)GlobalLock(hStdTargetDevice);
GlobalUnlock(hStdTargetDevice);
/* copy stdT into lpStdTargetDevice */
bltbx((LPSTR)&stdT, lpStdTargetDevice, sizeof(STDTARGETDEVICE));
/* get temporary pointer to the end of StdTargetDevice (the data buffer) */
lpData = ((LPSTR)lpStdTargetDevice) + sizeof(STDTARGETDEVICE);
/* now fill the buffer */
nCount = lpStdTargetDevice->driverNameOffset;
bltbx((LPSTR)*hszPrinter, lpData, nCount);
lpData += nCount;
nCount = lpStdTargetDevice->portNameOffset -
lpStdTargetDevice->driverNameOffset;
bltbx((LPSTR)*hszPrDriver, lpData, nCount);
lpData += nCount;
nCount = lpStdTargetDevice->extDevmodeOffset -
lpStdTargetDevice->portNameOffset;
bltbx((LPSTR)*hszPrPort, lpData, nCount);
lpData += nCount;
nCount = lpStdTargetDevice->extDevmodeSize;
bltbx(lpDevmodeData, (LPSTR)lpData, nCount);
lpData += nCount;
/* environment info is the same as the devmode info */
bltbx(lpDevmodeData, (LPSTR)lpData, nCount);
/* now set all the objects to this printer */
if (bSetObjects)
{
lpObject=NULL;
do
{
OleEnumObjects(lhClientDoc,&lpObject);
if (lpObject)
{
#ifdef DEBUG
OutputDebugString("Setting Target Device\n\r");
#endif
OleSetTargetDevice(lpObject,hStdTargetDevice);
}
}
while (lpObject);
}
}
BOOL ObjSetTargetDeviceForObject(LPOBJINFO lpObjInfo)
/* return whether error */
/* we assume object ain't busy!! */
{
extern CHAR (**hszPrinter)[];
extern CHAR (**hszPrDriver)[];
extern CHAR (**hszPrPort)[];
if (lpObjInfo == NULL)
{
Assert(0);
return TRUE;
}
if (lpObjInfo->lpobject == NULL)
{
Assert(0);
return TRUE;
}
if (lpObjInfo->objectType == STATIC)
return FALSE;
if (hszPrinter == NULL || hszPrDriver == NULL || hszPrPort == NULL)
return FALSE;
if (**hszPrinter == '\0' || **hszPrDriver == '\0' || **hszPrPort == '\0')
return FALSE;
if (PD.hDevMode == NULL)
ObjSetTargetDevice(FALSE);
if (PD.hDevMode == NULL)
{
return FALSE; // punt, couldn't get extdevmode structure.
// device doesn't support it
}
#ifdef DEBUG
OutputDebugString("Setting Target Device\n\r");
#endif
return (ObjError(OleSetTargetDevice(lpObjInfo->lpobject,hStdTargetDevice)));
}
#if 0
BOOL ObjContainsUnfinished(int doc, typeCP cpFirst, typeCP cpLim)
{
OBJPICINFO picInfo;
typeCP cpPicInfo;
BOOL bRetval=FALSE;
StartLongOp();
for (cpPicInfo = cpNil;
ObjPicEnumInRange(&picInfo,doc,cpFirst,cpLim,&cpPicInfo);
)
{
if (lpOBJ_QUERY_INFO(&picInfo) == NULL)
continue;
if (otOBJ_QUERY_TYPE(&picInfo) == NONE)
{
bRetval = TRUE;
break;
}
}
EndLongOp(vhcArrow);
return bRetval;
}
#endif
BOOL ObjContainsOpenEmb(int doc, typeCP cpFirst, typeCP cpLim, BOOL bLookForUnfinished)
{
OBJPICINFO picInfo;
typeCP cpPicInfo;
BOOL bRetval=FALSE;
LPLPOBJINFO lplpObjTmp;
StartLongOp();
for (cpPicInfo = cpNil;
ObjPicEnumInRange(&picInfo,doc,cpFirst,cpLim,&cpPicInfo);
)
{
if (lpOBJ_QUERY_INFO(&picInfo) == NULL)
continue;
if (lpOBJ_QUERY_OBJECT(&picInfo) == NULL)
continue;
#if 0 // see new check below (NONEs are no longer saved to doc)
if (otOBJ_QUERY_TYPE(&picInfo) == NONE)
{
bRetval = TRUE;
break;
}
#endif
if ((otOBJ_QUERY_TYPE(&picInfo) == EMBEDDED) &&
OleQueryOpen(lpOBJ_QUERY_OBJECT(&picInfo)) == OLE_OK)
{
bRetval = TRUE;
break;
}
}
if (bLookForUnfinished)
for (lplpObjTmp = NULL; lplpObjTmp = EnumObjInfos(lplpObjTmp) ;)
{
if (((*lplpObjTmp)->objectType == NONE) &&
((*lplpObjTmp)->cpWhere >= cpFirst) &&
((*lplpObjTmp)->cpWhere <= cpLim))
{
bRetval = TRUE;
break;
}
}
EndLongOp(vhcArrow);
return bRetval;
}
BOOL ObjDeletionOK(int nMode)
/**
Return whether OK to delete objects in current selection.
We don't worry about unfinished objects because they are just floating around in space
(ie, no picinfo has been yet saved to the doc),
and we don't allow the user to delete them until they are finished or the
document is abandonded.
**/
{
if (ObjContainsOpenEmb(docCur, selCur.cpFirst, selCur.cpLim,FALSE))
{
switch (nMode)
{
case OBJ_INSERTING:
Error(IDPMTInsertOpenEmb);
return FALSE;
break;
case OBJ_CUTTING:
case OBJ_DELETING:
{
char szMsg[cchMaxSz];
LoadString(hINSTANCE,
nMode == OBJ_DELETING ? IDPMTDeleteOpenEmb : IDPMTCutOpenEmb,
szMsg, sizeof(szMsg));
if (MessageBox(hPARENTWINDOW, (LPSTR)szMsg, (LPSTR)szAppName, MB_OKCANCEL) == IDCANCEL)
return FALSE;
if (ObjEnumInRange(docCur,selCur.cpFirst,selCur.cpLim,ObjCloseObjectInDoc) < 0)
return FALSE;
/* handle any unfinished objects in selection region */
ObjAdjustCpsForDeletion(docCur);
return TRUE;
}
break;
}
}
else
{
/* handle any unfinished objects in selection region */
ObjAdjustCpsForDeletion(docCur);
return TRUE;
}
}
void ObjAdjustCps(int doc,typeCP cpLim, typeCP dcpAdj)
/* for every picinfo after cpLim, adjust the cp value in its objinfo */
{
LPLPOBJINFO lplpObjTmp;
typeCP cpMac = CpMacText(doc);
if (dcpAdj == cp0)
return;
if (doc != docCur)
return;
for (lplpObjTmp = NULL; lplpObjTmp = EnumObjInfos(lplpObjTmp) ;)
{
if (((*lplpObjTmp)->objectType == NONE) &&
((*lplpObjTmp)->cpWhere >= cpLim))
{
typeCP cpNew = (*lplpObjTmp)->cpWhere + dcpAdj;
if (cpNew > cpMac)
cpNew = cpMac;
else if (cpNew < cp0)
cpNew = cp0;
(*lplpObjTmp)->cpWhere = cpNew;
}
}
}
void ObjAdjustCpsForDeletion(int doc)
/* for every picinfo in selCur, set cpWhere to selCur.cpFirst (presumably
selCur is about to be deleted) */
{
LPLPOBJINFO lplpObjTmp;
if (selCur.cpFirst == selCur.cpLim)
return;
if (doc != docCur)
return;
for (lplpObjTmp = NULL; lplpObjTmp = EnumObjInfos(lplpObjTmp) ;)
{
if (((*lplpObjTmp)->objectType == NONE) &&
((*lplpObjTmp)->cpWhere >= selCur.cpFirst) &&
((*lplpObjTmp)->cpWhere <= selCur.cpLim))
(*lplpObjTmp)->cpWhere = selCur.cpFirst;
}
}
#include <stdlib.h>
BOOL GimmeNewPicinfo(OBJPICINFO *pPicInfo, LPOBJINFO lpObjInfo)
/* assume lpObjInfo already is filled out */
/* return whether error */
{
szOBJNAME szObjName;
char *pdumb;
if (lpObjInfo == NULL)
return TRUE;
bltbc( pPicInfo, 0, cchPICINFOX );
/* objinfo */
lpOBJ_QUERY_INFO(pPicInfo) = lpObjInfo;
/* so Save'll save */
fOBJ_QUERY_DIRTY_OBJECT(pPicInfo) = TRUE;
/* only save picinfo until File.Save */
bOBJ_QUERY_DONT_SAVE_DATA(pPicInfo) = TRUE;
ObjUpdateFromObjInfo(pPicInfo);
/* data size */
dwOBJ_QUERY_DATA_SIZE(pPicInfo) = 0xFFFFFFFF; // to indicate brand new object
pPicInfo->mx = mxMultByOne;
pPicInfo->my = myMultByOne;
pPicInfo->cbHeader = cchPICINFOX;
pPicInfo->dxaOffset = 0;
pPicInfo->mm = MM_OLE;
pPicInfo->dxaSize = nOBJ_BLANKOBJECT_X;
pPicInfo->dyaSize = nOBJ_BLANKOBJECT_Y;
return FALSE;
}
BOOL ObjInitServerInfo(LPOBJINFO lpObjInfo)
/* this is called right after creating an object */
/* return whether error */
{
lpObjInfo->fCompleteAsync = TRUE; // kill prev async (OleCreate...)
if (ObjWaitForObject(lpObjInfo,TRUE))
return TRUE;
/* make sure Create succeeded */
if (lpObjInfo->fDeleteMe)
/* this is how we know it failed asynchronously */
return TRUE;
if ((lpObjInfo->objectType == EMBEDDED) ||
(lpObjInfo->objectType == NONE))
{
if (ObjSetHostName(lpObjInfo,docCur))
return TRUE;
lpObjInfo->fCompleteAsync = TRUE; // kill SetHostName if Cancel
if (ObjWaitForObject(lpObjInfo,TRUE))
return TRUE;
}
if (ObjSetTargetDeviceForObject(lpObjInfo))
return TRUE;
if (lpObjInfo->aName == NULL)
if (lpObjInfo->objectType == LINK)
{
lpObjInfo->fCompleteAsync = TRUE; // kill SetTarget if Cancel
if (ObjWaitForObject(lpObjInfo,TRUE))
return TRUE;
if ((lpObjInfo->aName = MakeLinkAtom(lpObjInfo)) == NULL)
return TRUE;
}
/* note: Caller needs to handle getting the size of object. */
return FALSE;
}