diff options
Diffstat (limited to 'private/mvdm/wow16/write/obj3.c')
-rw-r--r-- | private/mvdm/wow16/write/obj3.c | 1972 |
1 files changed, 1972 insertions, 0 deletions
diff --git a/private/mvdm/wow16/write/obj3.c b/private/mvdm/wow16/write/obj3.c new file mode 100644 index 000000000..91de04f37 --- /dev/null +++ b/private/mvdm/wow16/write/obj3.c @@ -0,0 +1,1972 @@ +/************************************************************/ +/* 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); + + if (lpOBJ_QUERY_INFO(lpPicInfo)->fCantDisplay) + return(FALSE); + + 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 + + bSuccess = !ObjError(OleDraw(lpOBJ_QUERY_OBJECT(lpPicInfo),hDC,lpBounds,NULL,NULL)); + if (!bSuccess) + lpOBJ_QUERY_INFO(lpPicInfo)->fCantDisplay = TRUE; + 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; + lpstrTemp++; + } + + /* 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; +} |