summaryrefslogtreecommitdiffstats
path: root/private/mvdm/wow16/write/obj3.c
diff options
context:
space:
mode:
Diffstat (limited to 'private/mvdm/wow16/write/obj3.c')
-rw-r--r--private/mvdm/wow16/write/obj3.c1972
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;
+}