Annotation of mstools/ole20/samples/outline/outldoc.c, revision 1.1

1.1     ! root        1: /*************************************************************************
        !             2: **
        !             3: **    OLE 2 Sample Code
        !             4: **
        !             5: **    outldoc.c
        !             6: **
        !             7: **    This file contains OutlineDoc functions.
        !             8: **
        !             9: **    (c) Copyright Microsoft Corp. 1992 - 1993 All Rights Reserved
        !            10: **
        !            11: *************************************************************************/
        !            12: 
        !            13: #include "outline.h"
        !            14: #include <ole2ui.h>
        !            15: 
        !            16: #if !defined( OLE_VERSION )
        !            17: #include <commdlg.h>
        !            18: #endif
        !            19: 
        !            20: 
        !            21: OLEDBGDATA
        !            22: 
        !            23: extern LPOUTLINEAPP g_lpApp;
        !            24: 
        !            25: // REVIEW: should use string resource for messages
        !            26: char ErrMsgDocWnd[] = "Can't create Document Window!";
        !            27: char ErrMsgFormatNotSupported[] = "Clipboard format not supported!";
        !            28: char MsgSaveFile[] = "Save existing file ?";
        !            29: char ErrMsgSaving[] = "Error in saving file!";
        !            30: char ErrMsgOpening[] = "Error in opening file!";
        !            31: char ErrMsgFormat[] = "Improper file format!";
        !            32: char ErrOutOfMemory[] = "Error: out of memory!";
        !            33: static char ErrMsgPrint[] = "Printing Error!";
        !            34: 
        !            35: static BOOL fCancelPrint;    // TRUE if the user has canceled the print job
        !            36: static HWND hWndPDlg;       // Handle to the cancel print dialog
        !            37: 
        !            38: 
        !            39: /* OutlineDoc_Init
        !            40:  * ---------------
        !            41:  *
        !            42:  *  Initialize the fields of a new OutlineDoc object. The object is initially
        !            43:  *  not associated with a file or an (Untitled) document. This function sets
        !            44:  *  the docInitType to DOCTYPE_UNKNOWN. After calling this function the
        !            45:  *  caller should call:
        !            46:  *      1. OutlineDoc_InitNewFile to set the OutlineDoc to (Untitled)
        !            47:  *      2. OutlineDoc_LoadFromFile to associate the OutlineDoc with a file.
        !            48:  *  This function creates a new window for the document.
        !            49:  *
        !            50:  *  NOTE: the window is initially created with a NIL size. it must be
        !            51:  *        sized and positioned by the caller. also the document is initially
        !            52:  *        created invisible. the caller must call OutlineDoc_ShowWindow
        !            53:  *        after sizing it to make the document window visible.
        !            54:  */
        !            55: BOOL OutlineDoc_Init(LPOUTLINEDOC lpOutlineDoc, BOOL fDataTransferDoc)
        !            56: {
        !            57:     LPOUTLINEAPP lpOutlineApp = (LPOUTLINEAPP)g_lpApp;
        !            58: 
        !            59: #if defined( INPLACE_CNTR )
        !            60:     lpOutlineDoc->m_hWndDoc = CreateWindow(
        !            61:                     DOCWNDCLASS,            // Window class name
        !            62:                     NULL,                   // Window's title
        !            63: 
        !            64:                     /* OLE2NOTE: an in-place contanier MUST use
        !            65:                     **    WS_CLIPCHILDREN window style for the window
        !            66:                     **    that it uses as the parent for the server's
        !            67:                     **    in-place active window so that its
        !            68:                     **    painting does NOT interfere with the painting
        !            69:                     **    of the server's in-place active child window.
        !            70:                     */
        !            71: 
        !            72:                     WS_CLIPCHILDREN |
        !            73:                     WS_CHILDWINDOW, 
        !            74:                     0, 0,
        !            75:                     0, 0,
        !            76:                     lpOutlineApp->m_hWndApp,// Parent window's handle
        !            77:                     (HMENU)1,               // child window id 
        !            78:                     lpOutlineApp->m_hInst,  // Instance of window
        !            79:                     NULL);                  // Create struct for WM_CREATE
        !            80: 
        !            81: #else                    
        !            82: 
        !            83:     lpOutlineDoc->m_hWndDoc = CreateWindow(
        !            84:                     DOCWNDCLASS,            // Window class name
        !            85:                     NULL,                   // Window's title
        !            86:                     WS_CHILDWINDOW, 
        !            87:                     0, 0,
        !            88:                     0, 0,
        !            89:                     lpOutlineApp->m_hWndApp,// Parent window's handle
        !            90:                     (HMENU)1,               // child window id 
        !            91:                     lpOutlineApp->m_hInst,  // Instance of window
        !            92:                     NULL);                  // Create struct for WM_CREATE
        !            93: #endif    
        !            94: 
        !            95:     if(! lpOutlineDoc->m_hWndDoc) {
        !            96:         OutlineApp_ErrorMessage(lpOutlineApp, ErrMsgDocWnd);
        !            97:         return FALSE;
        !            98:     }
        !            99: 
        !           100:     SetWindowLong(lpOutlineDoc->m_hWndDoc, 0, (LONG) lpOutlineDoc);
        !           101: 
        !           102:     if (! LineList_Init(&lpOutlineDoc->m_LineList, lpOutlineDoc))
        !           103:         return FALSE;
        !           104: 
        !           105:     lpOutlineDoc->m_lpNameTable = OutlineDoc_CreateNameTable(lpOutlineDoc);
        !           106:     if (! lpOutlineDoc->m_lpNameTable )
        !           107:         return FALSE;
        !           108: 
        !           109:     lpOutlineDoc->m_docInitType = DOCTYPE_UNKNOWN;
        !           110:     lpOutlineDoc->m_cfSaveFormat = lpOutlineApp->m_cfOutline;
        !           111:     lpOutlineDoc->m_szFileName[0] = '\0';
        !           112:     lpOutlineDoc->m_lpszDocTitle = lpOutlineDoc->m_szFileName;
        !           113:     lpOutlineDoc->m_fDataTransferDoc = fDataTransferDoc;
        !           114:     lpOutlineDoc->m_uCurrentZoom = IDM_V_ZOOM_100;
        !           115:     lpOutlineDoc->m_scale.dwSxN  = (DWORD) 1;
        !           116:     lpOutlineDoc->m_scale.dwSxD  = (DWORD) 1;
        !           117:     lpOutlineDoc->m_scale.dwSyN  = (DWORD) 1;
        !           118:     lpOutlineDoc->m_scale.dwSyD  = (DWORD) 1;
        !           119:     lpOutlineDoc->m_uCurrentMargin = IDM_V_SETMARGIN_0;
        !           120:     lpOutlineDoc->m_nLeftMargin  = 0;
        !           121:     lpOutlineDoc->m_nRightMargin = 0;
        !           122:     lpOutlineDoc->m_nDisableDraw = 0;
        !           123:     OutlineDoc_SetModified(lpOutlineDoc, FALSE, FALSE, FALSE);
        !           124: 
        !           125: #if defined( USE_HEADING )
        !           126:     if (! fDataTransferDoc) {
        !           127:         if (!Heading_Create((LPHEADING)&lpOutlineDoc->m_heading, 
        !           128:                 lpOutlineDoc->m_hWndDoc, lpOutlineApp->m_hInst)) {
        !           129:             return FALSE;
        !           130:         
        !           131:         }
        !           132:     }
        !           133: #endif  // USE_HEADING
        !           134: 
        !           135: #if defined( USE_FRAMETOOLS )
        !           136:     if (! fDataTransferDoc) {
        !           137:         lpOutlineDoc->m_lpFrameTools = OutlineApp_GetFrameTools(lpOutlineApp);
        !           138:         FrameTools_AssociateDoc(
        !           139:                 lpOutlineDoc->m_lpFrameTools, 
        !           140:                 lpOutlineDoc
        !           141:         );
        !           142:     }
        !           143: #endif  // USE_FRAMETOOLS
        !           144: 
        !           145: #if defined( OLE_VERSION )
        !           146:     /* OLE2NOTE: perform initialization required for OLE */
        !           147:     if (! OleDoc_Init((LPOLEDOC)lpOutlineDoc, fDataTransferDoc))
        !           148:         return FALSE;
        !           149: #endif  // OLE_VERSION
        !           150: 
        !           151:     return TRUE;
        !           152: }
        !           153: 
        !           154: 
        !           155: /* OutlineDoc_InitNewFile
        !           156:  * ----------------------
        !           157:  *
        !           158:  *  Initialize the OutlineDoc object to be a new (Untitled) document.
        !           159:  *  This function sets the docInitType to DOCTYPE_NEW.
        !           160:  */
        !           161: BOOL OutlineDoc_InitNewFile(LPOUTLINEDOC lpOutlineDoc)
        !           162: {
        !           163: #if defined( OLE_VERSION )
        !           164:     // OLE2NOTE: call OLE version of this function instead
        !           165:     return OleDoc_InitNewFile((LPOLEDOC)lpOutlineDoc);
        !           166: 
        !           167: #else
        !           168: 
        !           169:     OleDbgAssert(lpOutlineDoc->m_docInitType == DOCTYPE_UNKNOWN);
        !           170: 
        !           171:     // set file name to untitled
        !           172:     // REVIEW: should load from string resource
        !           173:     lstrcpy(lpOutlineDoc->m_szFileName, UNTITLED);
        !           174:     lpOutlineDoc->m_lpszDocTitle = lpOutlineDoc->m_szFileName;
        !           175:     lpOutlineDoc->m_docInitType = DOCTYPE_NEW;
        !           176: 
        !           177:     if (! lpOutlineDoc->m_fDataTransferDoc)
        !           178:         OutlineDoc_SetTitle(lpOutlineDoc);
        !           179: 
        !           180:     return TRUE;
        !           181: 
        !           182: #endif      // BASE OUTLINE VERSION
        !           183: }
        !           184: 
        !           185: 
        !           186: /* OutlineDoc_CreateNameTable
        !           187:  * --------------------------
        !           188:  *
        !           189:  * Allocate a new NameTable of the appropriate type. Each document has
        !           190:  * a NameTable and a LineList.
        !           191:  *  OutlineDoc --> creates standard OutlineNameTable type name tables.
        !           192:  *  ServerDoc  --> creates enhanced SeverNameTable type name tables.
        !           193:  *
        !           194:  *      Returns lpNameTable for successful, NULL if error.
        !           195:  */
        !           196: LPOUTLINENAMETABLE OutlineDoc_CreateNameTable(LPOUTLINEDOC lpOutlineDoc)
        !           197: {
        !           198:     LPOUTLINENAMETABLE lpOutlineNameTable;
        !           199: 
        !           200:     lpOutlineNameTable = (LPOUTLINENAMETABLE)New(
        !           201:             (DWORD)sizeof(OUTLINENAMETABLE)
        !           202:     );
        !           203: 
        !           204:     if (! OleDbgVerifySz(lpOutlineNameTable != NULL, 
        !           205:                                                 "Error allocating NameTable"))
        !           206:         return NULL;
        !           207: 
        !           208:     // initialize new NameTable
        !           209:     if (! OutlineNameTable_Init(lpOutlineNameTable, lpOutlineDoc) )
        !           210:         goto error;
        !           211: 
        !           212:     return lpOutlineNameTable;
        !           213: 
        !           214: error:
        !           215:     if (lpOutlineNameTable)
        !           216:         Delete(lpOutlineNameTable);
        !           217:     return NULL;
        !           218: }
        !           219: 
        !           220: 
        !           221: /* OutlineDoc_ClearCommand
        !           222:  * -----------------------
        !           223:  *
        !           224:  *      Delete selection in list box by calling OutlineDoc_Delete
        !           225:  */
        !           226: void OutlineDoc_ClearCommand(LPOUTLINEDOC lpOutlineDoc)
        !           227: {
        !           228:     LPLINELIST lpLL = &lpOutlineDoc->m_LineList;
        !           229:     int i;
        !           230:     int nNumSel;
        !           231:     LINERANGE lrSel;
        !           232: 
        !           233:     nNumSel=LineList_GetSel(lpLL, (LPLINERANGE)&lrSel);
        !           234: 
        !           235:     OutlineDoc_SetRedraw ( lpOutlineDoc, FALSE );
        !           236:     for(i = 0; i < nNumSel; i++)
        !           237:         OutlineDoc_DeleteLine(lpOutlineDoc, lrSel.m_nStartLine);
        !           238:     OutlineDoc_SetRedraw ( lpOutlineDoc, TRUE );
        !           239: 
        !           240:     LineList_RecalcMaxLineWidthInHimetric(lpLL, 0);
        !           241: }
        !           242: 
        !           243: 
        !           244: /* OutlineDoc_CutCommand
        !           245:  * ---------------------
        !           246:  *
        !           247:  * Cut selection to clipboard
        !           248:  */
        !           249: void OutlineDoc_CutCommand(LPOUTLINEDOC lpOutlineDoc)
        !           250: {
        !           251:     OutlineDoc_CopyCommand(lpOutlineDoc);
        !           252:     OutlineDoc_ClearCommand(lpOutlineDoc);
        !           253: }
        !           254: 
        !           255: 
        !           256: /* OutlineDoc_CopyCommand
        !           257:  * ----------------------
        !           258:  *  Copy selection to clipboard.
        !           259:  *  Post to the clipboard the formats that the app can render.
        !           260:  *  the actual data is not rendered at this time. using the
        !           261:  *  delayed rendering technique, Windows will send the clipboard
        !           262:  *  owner window either a WM_RENDERALLFORMATS or a WM_RENDERFORMAT
        !           263:  *  message when the actual data is requested.
        !           264:  *
        !           265:  *    OLE2NOTE: the normal delayed rendering technique where Windows
        !           266:  *    sends the clipboard owner window either a WM_RENDERALLFORMATS or
        !           267:  *    a WM_RENDERFORMAT message when the actual data is requested is
        !           268:  *    NOT exposed to the app calling OleSetClipboard. OLE internally
        !           269:  *    creates its own window as the clipboard owner and thus our app
        !           270:  *    will NOT get these WM_RENDER messages.
        !           271:  */
        !           272: void OutlineDoc_CopyCommand(LPOUTLINEDOC lpSrcOutlineDoc)
        !           273: {
        !           274:     LPOUTLINEAPP lpOutlineApp = (LPOUTLINEAPP)g_lpApp;
        !           275:     LPOUTLINEDOC lpClipboardDoc;
        !           276: 
        !           277: #if defined( OLE_VERSION )
        !           278: 
        !           279:     /* squirrel away a copy of the current selection to the ClipboardDoc */
        !           280:     lpClipboardDoc = OutlineDoc_CreateDataTransferDoc(lpSrcOutlineDoc);
        !           281: 
        !           282:     if (! lpClipboardDoc)
        !           283:         return;     // Error: could not create DataTransferDoc
        !           284: 
        !           285:     lpOutlineApp->m_lpClipboardDoc = (LPOUTLINEDOC)lpClipboardDoc;
        !           286: 
        !           287:     /* OLE2NOTE: initially the Doc object is created with a 0 ref
        !           288:     **    count. in order to have a stable Doc object during the
        !           289:     **    process of initializing the Doc instance and transfering it
        !           290:     **    to the clipboard, we intially AddRef the Doc ref cnt and later
        !           291:     **    Release it. This initial AddRef is artificial; it is simply
        !           292:     **    done to guarantee that a harmless QueryInterface followed by
        !           293:     **    a Release does not inadvertantly force our object to destroy
        !           294:     **    itself prematurely.
        !           295:     */
        !           296:     OleDoc_AddRef((LPOLEDOC)lpClipboardDoc);
        !           297: 
        !           298:     /* OLE2NOTE: the OLE 2.0 style to put data onto the clipboard is to
        !           299:     **    give the clipboard a pointer to an IDataObject interface that
        !           300:     **    is able to statisfy IDataObject::GetData calls to render
        !           301:     **    data. in our case we give the pointer to the ClipboardDoc
        !           302:     **    which holds a cloned copy of the current user's selection.
        !           303:     */
        !           304:     OLEDBG_BEGIN2("OleSetClipboard called\r\n")
        !           305:     OleSetClipboard((LPDATAOBJECT)&((LPOLEDOC)lpClipboardDoc)->m_DataObject);
        !           306:     OLEDBG_END2
        !           307: 
        !           308:     OleDoc_Release((LPOLEDOC)lpClipboardDoc);   // rel artificial AddRef above
        !           309: 
        !           310: #else
        !           311: 
        !           312:     OpenClipboard(lpSrcOutlineDoc->m_hWndDoc);
        !           313:     EmptyClipboard();
        !           314: 
        !           315:     /* squirrel away a copy of the current selection to the ClipboardDoc */
        !           316:     lpClipboardDoc = OutlineDoc_CreateDataTransferDoc(lpSrcOutlineDoc);
        !           317: 
        !           318:     if (! lpClipboardDoc)
        !           319:         return;     // Error: could not create DataTransferDoc
        !           320: 
        !           321:     lpOutlineApp->m_lpClipboardDoc = (LPOUTLINEDOC)lpClipboardDoc;
        !           322: 
        !           323:     SetClipboardData(lpOutlineApp->m_cfOutline, NULL);
        !           324:     SetClipboardData(CF_TEXT, NULL);
        !           325: 
        !           326:     CloseClipboard();
        !           327: 
        !           328: #endif
        !           329: }
        !           330: 
        !           331: 
        !           332: /* OutlineDoc_ClearAllLines
        !           333:  * ------------------------
        !           334:  *
        !           335:  *      Delete all lines in the document.
        !           336:  */
        !           337: void OutlineDoc_ClearAllLines(LPOUTLINEDOC lpOutlineDoc)
        !           338: {
        !           339:     LPLINELIST lpLL = &lpOutlineDoc->m_LineList;
        !           340:     int i;
        !           341: 
        !           342:     for(i = 0; i < lpLL->m_nNumLines; i++)
        !           343:         OutlineDoc_DeleteLine(lpOutlineDoc, 0);
        !           344: 
        !           345:     LineList_RecalcMaxLineWidthInHimetric(lpLL, 0);
        !           346: }
        !           347: 
        !           348: 
        !           349: /* OutlineDoc_CreateDataTransferDoc
        !           350:  * --------------------------------
        !           351:  *
        !           352:  *      Create a document to be use to transfer data (either via a
        !           353:  *  drag/drop operation of the clipboard). Copy the selection of the
        !           354:  *  source doc to the data transfer document. A data transfer document is
        !           355:  *  the same as a document that is created by the user except that it is
        !           356:  *  NOT made visible to the user. it is specially used to hold a copy of
        !           357:  *  data that the user should not be able to change.
        !           358:  *
        !           359:  *  OLE2NOTE: in the OLE version the data transfer document is used
        !           360:  *      specifically to provide an IDataObject* that renders the data copied.
        !           361:  */
        !           362: LPOUTLINEDOC OutlineDoc_CreateDataTransferDoc(LPOUTLINEDOC lpSrcOutlineDoc)
        !           363: {
        !           364:     LPOUTLINEAPP lpOutlineApp = (LPOUTLINEAPP)g_lpApp;
        !           365:     LPOUTLINEDOC lpDestOutlineDoc;
        !           366:     LPLINELIST lpSrcLL = &lpSrcOutlineDoc->m_LineList;
        !           367:     LINERANGE lrSel;
        !           368:     int nCopied;
        !           369: 
        !           370:     lpDestOutlineDoc = OutlineApp_CreateDoc(lpOutlineApp, TRUE);
        !           371:     if (! lpDestOutlineDoc) return NULL;
        !           372: 
        !           373:     // set the ClipboardDoc to an (Untitled) doc.
        !           374:     if (! OutlineDoc_InitNewFile(lpDestOutlineDoc))
        !           375:         goto error;
        !           376: 
        !           377:     LineList_GetSel(lpSrcLL, (LPLINERANGE)&lrSel);
        !           378:     nCopied = LineList_CopySelToDoc(
        !           379:             lpSrcLL,
        !           380:             (LPLINERANGE)&lrSel,
        !           381:             lpDestOutlineDoc
        !           382:     );
        !           383: 
        !           384: #if defined( OLE_SERVER )
        !           385:     {
        !           386:         LPOLEDOC lpSrcOleDoc = (LPOLEDOC)lpSrcOutlineDoc;
        !           387:         LPOLEDOC lpDestOleDoc = (LPOLEDOC)lpDestOutlineDoc;
        !           388:         LPSERVERDOC lpDestServerDoc = (LPSERVERDOC)lpDestOutlineDoc;
        !           389:         LPMONIKER lpmkDoc = NULL;
        !           390:         LPMONIKER lpmkItem = NULL;
        !           391: 
        !           392:         /* If source document is able to provide a moniker, then the
        !           393:         **    destination document (lpDestOutlineDoc) should offer
        !           394:         **    CF_LINKSOURCE via its IDataObject interface that it gives
        !           395:         **    to the clipboard or the drag/drop operation.
        !           396:         **
        !           397:         **    OLE2NOTE: we want to ask the source document if it can
        !           398:         **    produce a moniker, but we do NOT want to FORCE moniker
        !           399:         **    assignment at this point. we only want to FORCE moniker
        !           400:         **    assignment later if a Paste Link occurs (ie. GetData for
        !           401:         **    CF_LINKSOURCE). if the source document is able to give
        !           402:         **    a moniker, then we store a pointer to the source document
        !           403:         **    so we can ask it at a later time to get the moniker. we
        !           404:         **    also save the range of the current selection so we can
        !           405:         **    generate a proper item name later when Paste Link occurs.
        !           406:         **    Also we need to give a string which identifies the source
        !           407:         **    of the copy in the CF_OBJECTDESCRIPTOR format. this
        !           408:         **    string is used to display in the PasteSpecial dialog. we
        !           409:         **    get and store a TEMPFORUSER moniker which identifies the
        !           410:         **    source of copy.
        !           411:         */
        !           412:         lpDestOleDoc->m_lpSrcDocOfCopy = lpSrcOleDoc;
        !           413:         lpmkDoc = OleDoc_GetFullMoniker(lpSrcOleDoc, GETMONIKER_TEMPFORUSER);
        !           414:         if (lpmkDoc != NULL) {
        !           415:             lpDestOleDoc->m_fLinkSourceAvail = TRUE;
        !           416:             lpDestServerDoc->m_lrSrcSelOfCopy = lrSel;
        !           417:             OleStdRelease((LPUNKNOWN)lpmkDoc);
        !           418:         }
        !           419:     }
        !           420: 
        !           421: #elif defined( OLE_CNTR )
        !           422:     {
        !           423:         LPOLEDOC lpSrcOleDoc = (LPOLEDOC)lpSrcOutlineDoc;
        !           424:         LPOLEDOC lpDestOleDoc = (LPOLEDOC)lpDestOutlineDoc;
        !           425:         LPCONTAINERDOC lpDestContainerDoc = (LPCONTAINERDOC)lpDestOutlineDoc;
        !           426: 
        !           427:         /* If one line was copied from the source document, and it was a
        !           428:         **    single OLE object, then the destination document should
        !           429:         **    offer additional data formats to allow the transfer of
        !           430:         **    the OLE object via IDataObject::GetData. Specifically, the
        !           431:         **    following additional data formats are offered if a single
        !           432:         **    OLE object is copied:
        !           433:         **          CF_EMBEDDEDOBJECT
        !           434:         **          CF_OBJECTDESCRIPTOR     (should be given even w/o object)
        !           435:         **          CF_METAFILEPICT         (note: dwAspect depends on object)
        !           436:         **          CF_LINKSOURCE           -- if linking is possible
        !           437:         **          CF_LINKSOURCEDESCRIPTOR -- if linking is possible
        !           438:         **    
        !           439:         **    optionally the container may give
        !           440:         **          <data format available in OLE object's cache>
        !           441:         */
        !           442: 
        !           443:         if (nCopied == 1) {
        !           444:             LPOLEOBJECT lpSrcOleObj;
        !           445:             LPCONTAINERLINE lpSrcContainerLine;
        !           446:             DWORD dwStatus;
        !           447: 
        !           448:             lpSrcContainerLine = (LPCONTAINERLINE)LineList_GetLine(
        !           449:                     lpSrcLL, 
        !           450:                     lrSel.m_nStartLine
        !           451:             );
        !           452: 
        !           453:             lpDestOleDoc->m_lpSrcDocOfCopy = lpSrcOleDoc;
        !           454: 
        !           455:             if ((((LPLINE)lpSrcContainerLine)->m_lineType==CONTAINERLINETYPE)
        !           456:                     && ((lpSrcOleObj=lpSrcContainerLine->m_lpOleObj)!=NULL)) {
        !           457: 
        !           458:                 lpDestContainerDoc->m_fEmbeddedObjectAvail = TRUE;
        !           459:                 lpSrcOleObj->lpVtbl->GetUserClassID(
        !           460:                         lpSrcOleObj,
        !           461:                         &lpDestContainerDoc->m_clsidOleObjCopied
        !           462:                 );
        !           463:                 lpDestContainerDoc->m_dwAspectOleObjCopied = 
        !           464:                             lpSrcContainerLine->m_dwDrawAspect;
        !           465: 
        !           466:                 /* OLE2NOTE: if the object is allowed to be linked
        !           467:                 **    to from the inside (ie. we are allowed to
        !           468:                 **    give out a moniker which binds to the running
        !           469:                 **    OLE object), then we want to offer
        !           470:                 **    CF_LINKSOURCE format. if the object is an OLE
        !           471:                 **    2.0 embedded object then it is allowed to be
        !           472:                 **    linked to from the inside. if the object is
        !           473:                 **    either an OleLink or an OLE 1.0 embedding
        !           474:                 **    then it can not be linked to from the inside.
        !           475:                 **    if we were a container/server app then we
        !           476:                 **    could offer linking to the outside of the
        !           477:                 **    object (ie. a pseudo object within our
        !           478:                 **    document). we are a container only app that
        !           479:                 **    does not support linking to ranges of its data.
        !           480:                 */
        !           481: 
        !           482:                 lpSrcOleObj->lpVtbl->GetMiscStatus(
        !           483:                         lpSrcOleObj, 
        !           484:                         DVASPECT_CONTENT, /* aspect is not important */
        !           485:                         (LPDWORD)&dwStatus
        !           486:                 );
        !           487:                 if (! (dwStatus & OLEMISC_CANTLINKINSIDE)) {
        !           488:                     /* Our container supports linking to an embedded
        !           489:                     **    object. We want the lpDestContainerDoc to
        !           490:                     **    offer CF_LINKSOURCE via the IDataObject
        !           491:                     **    interface that it gives to the clipboard or
        !           492:                     **    the drag/drop operation. The link source will
        !           493:                     **    be identified by a composite moniker
        !           494:                     **    comprised of the FileMoniker of the source
        !           495:                     **    document and an ItemMoniker which identifies
        !           496:                     **    the OLE object inside the container. we do
        !           497:                     **    NOT want to force moniker assignment to the
        !           498:                     **    OLE object now (at copy time); we only want
        !           499:                     **    to FORCE moniker assignment later if a Paste
        !           500:                     **    Link occurs (ie. GetData for CF_LINKSOURCE).
        !           501:                     **    thus we store a pointer to the source document
        !           502:                     **    and the source ContainerLine so we can
        !           503:                     **    generate a proper ItemMoniker later when
        !           504:                     **    Paste Link occurs. 
        !           505:                     */
        !           506:                     lpDestOleDoc->m_fLinkSourceAvail = TRUE;
        !           507:                     lpDestContainerDoc->m_lpSrcContainerLine =
        !           508:                             lpSrcContainerLine;
        !           509:                 }
        !           510:             }
        !           511:         }
        !           512:     }
        !           513: 
        !           514: #endif
        !           515: 
        !           516:     return lpDestOutlineDoc;
        !           517: 
        !           518: error:
        !           519:     if (lpDestOutlineDoc)
        !           520:         OutlineDoc_Destroy(lpDestOutlineDoc);
        !           521: 
        !           522:     return NULL;
        !           523: }
        !           524: 
        !           525: 
        !           526: /* OutlineDoc_PasteCommand
        !           527:  * -----------------------
        !           528:  *
        !           529:  * Paste lines from clipboard
        !           530:  */
        !           531: void OutlineDoc_PasteCommand(LPOUTLINEDOC lpOutlineDoc)
        !           532: {
        !           533: #if defined( OLE_VERSION )
        !           534:     // Call OLE version of this function instead
        !           535:     OleDoc_PasteCommand((LPOLEDOC)lpOutlineDoc);
        !           536: 
        !           537: #else
        !           538: 
        !           539:     LPOUTLINEAPP lpOutlineApp = (LPOUTLINEAPP)g_lpApp;
        !           540:     LPLINELIST lpLL = (LPLINELIST)&lpOutlineDoc->m_LineList;
        !           541:     int nIndex;
        !           542:     int nCount;
        !           543:     HGLOBAL hData;
        !           544:     LINERANGE lrSel;
        !           545:     UINT uFormat;
        !           546: 
        !           547:     if (LineList_GetCount(lpLL) == 0)
        !           548:         nIndex = -1;    // pasting to empty list
        !           549:     else
        !           550:         nIndex=LineList_GetFocusLineIndex(lpLL);
        !           551: 
        !           552:     OutlineDoc_SetRedraw ( lpOutlineDoc, FALSE );
        !           553: 
        !           554:     OpenClipboard(lpOutlineDoc->m_hWndDoc);
        !           555: 
        !           556:     uFormat = 0;
        !           557:     while(uFormat = EnumClipboardFormats(uFormat)) {
        !           558:         if(uFormat == lpOutlineApp->m_cfOutline) {
        !           559:             hData = GetClipboardData(lpOutlineApp->m_cfOutline);
        !           560:             nCount = OutlineDoc_PasteOutlineData(lpOutlineDoc, hData, nIndex);
        !           561:             break;
        !           562:         }
        !           563:         if(uFormat == CF_TEXT) {
        !           564:             hData = GetClipboardData(CF_TEXT);
        !           565:             nCount = OutlineDoc_PasteTextData(lpOutlineDoc, hData, nIndex);
        !           566:             break;
        !           567:         }
        !           568:     }
        !           569: 
        !           570:     lrSel.m_nStartLine = nIndex + nCount;
        !           571:     lrSel.m_nEndLine = nIndex + 1;
        !           572:     LineList_SetSel(lpLL, &lrSel);
        !           573:     OutlineDoc_SetRedraw ( lpOutlineDoc, TRUE );
        !           574: 
        !           575:     CloseClipboard();
        !           576: 
        !           577: #endif      // ! OLE_VERSION
        !           578: }
        !           579: 
        !           580: 
        !           581: /* OutlineDoc_PasteOutlineData
        !           582:  * ---------------------------
        !           583:  *
        !           584:  *      Put an array of Line Objects (stored in hOutline) into the document
        !           585:  *
        !           586:  * Return the number of items added
        !           587:  */
        !           588: int OutlineDoc_PasteOutlineData(LPOUTLINEDOC lpOutlineDoc, HGLOBAL hOutline, int nStartIndex)
        !           589: {
        !           590:     int nCount;
        !           591:     int i;
        !           592:     LPTEXTLINE arrLine;
        !           593: 
        !           594:     nCount = (int) GlobalSize(hOutline) / sizeof(TEXTLINE);
        !           595:     arrLine = (LPTEXTLINE)GlobalLock(hOutline);
        !           596:     if (!arrLine)
        !           597:         return 0;
        !           598: 
        !           599:     for(i = 0; i < nCount; i++)
        !           600:         Line_CopyToDoc((LPLINE)&arrLine[i], lpOutlineDoc, nStartIndex+i);
        !           601: 
        !           602:     GlobalUnlock(hOutline);
        !           603: 
        !           604:     return nCount;
        !           605: }
        !           606: 
        !           607: 
        !           608: /* OutlineDoc_PasteTextData
        !           609:  * ------------------------
        !           610:  *
        !           611:  *      Build Line Objects from the strings (separated by '\n') in hText
        !           612:  * and put them into the document
        !           613:  */
        !           614: int OutlineDoc_PasteTextData(LPOUTLINEDOC lpOutlineDoc, HGLOBAL hText, int nStartIndex)
        !           615: {
        !           616:     LPLINELIST  lpLL = (LPLINELIST)&lpOutlineDoc->m_LineList;
        !           617:     HDC         hDC;
        !           618:     LPSTR       lpszText;
        !           619:     LPSTR       lpszEnd;
        !           620:     LPTEXTLINE  lpLine;
        !           621:     int         nLineCount;
        !           622:     int         i;
        !           623:     UINT        nTab;
        !           624:     char        szBuf[MAXSTRLEN+1];
        !           625: 
        !           626:     lpszText=(LPSTR)GlobalLock(hText);
        !           627:     if(!lpszText)
        !           628:         return 0;
        !           629: 
        !           630:     lpszEnd = lpszText + lstrlen(lpszText);
        !           631:     nLineCount=0;
        !           632: 
        !           633:     while(*lpszText && (lpszText<lpszEnd)) {
        !           634: 
        !           635:         // count the tab level
        !           636:         nTab = 0;
        !           637:         while((*lpszText == '\t') && (lpszText<lpszEnd)) {
        !           638:             nTab++;
        !           639:             lpszText++;
        !           640:         }
        !           641: 
        !           642:         // collect the text string character by character
        !           643:         for(i=0; (i<MAXSTRLEN) && (lpszText<lpszEnd); i++) {
        !           644:             if ((! *lpszText) || (*lpszText == '\n'))
        !           645:                 break;
        !           646:             szBuf[i] = *lpszText++;
        !           647:         }
        !           648:         szBuf[i] = 0;
        !           649:         lpszText++;
        !           650:         if ((i > 0) && (szBuf[i-1] == '\r'))
        !           651:             szBuf[i-1] = 0;     // remove carriage return at the end
        !           652: 
        !           653:         hDC = LineList_GetDC(lpLL);
        !           654:         lpLine = TextLine_Create(hDC, nTab, szBuf);
        !           655:         LineList_ReleaseDC(lpLL, hDC);
        !           656: 
        !           657:         OutlineDoc_AddLine(
        !           658:                 lpOutlineDoc,
        !           659:                 (LPLINE)lpLine,
        !           660:                 nStartIndex + nLineCount
        !           661:         );
        !           662:         nLineCount++;
        !           663: 
        !           664:     }
        !           665: 
        !           666:     GlobalUnlock(hText);
        !           667: 
        !           668:     return nLineCount;
        !           669: }
        !           670: 
        !           671: 
        !           672: /* OutlineDoc_AddTextLineCommand
        !           673:  * -----------------------------
        !           674:  *
        !           675:  *      Add a new text line following the current focus line.
        !           676:  */
        !           677: void OutlineDoc_AddTextLineCommand(LPOUTLINEDOC lpOutlineDoc)
        !           678: {
        !           679:     LPOUTLINEAPP lpOutlineApp = (LPOUTLINEAPP)g_lpApp;
        !           680:     LPLINELIST lpLL = &lpOutlineDoc->m_LineList;
        !           681:     HDC hDC;
        !           682:     int nIndex = LineList_GetFocusLineIndex(lpLL);
        !           683:     char szBuf[MAXSTRLEN+1];
        !           684:     UINT nTab = 0;
        !           685:     LPLINE lpLine;
        !           686:     LPTEXTLINE lpTextLine;
        !           687: 
        !           688:     szBuf[0] = '\0';
        !           689: 
        !           690: #if defined( USE_FRAMETOOLS )
        !           691:     FrameTools_FB_GetEditText(
        !           692:             lpOutlineDoc->m_lpFrameTools, szBuf, sizeof(szBuf));
        !           693: #else 
        !           694:     if (! InputTextDlg(lpOutlineDoc->m_hWndDoc, szBuf, "Add Line")) 
        !           695:         return;
        !           696: #endif 
        !           697:     
        !           698:     hDC = LineList_GetDC(lpLL);
        !           699:     lpLine = LineList_GetLine(lpLL, nIndex);
        !           700:     if (lpLine)
        !           701:         nTab = Line_GetTabLevel(lpLine);
        !           702: 
        !           703:     lpTextLine=TextLine_Create(hDC, nTab, szBuf);
        !           704:     LineList_ReleaseDC(lpLL, hDC);
        !           705: 
        !           706:     if (! lpTextLine) {
        !           707:         OutlineApp_ErrorMessage(lpOutlineApp, ErrOutOfMemory);
        !           708:         return;
        !           709:     }
        !           710:     OutlineDoc_AddLine(lpOutlineDoc, (LPLINE)lpTextLine, nIndex);
        !           711: }
        !           712: 
        !           713: 
        !           714: /* OutlineDoc_AddTopLineCommand
        !           715:  * ----------------------------
        !           716:  *
        !           717:  *      Add a top (margin) line as the first line in the LineList.
        !           718:  *      (do not change the current selection)
        !           719:  */
        !           720: void OutlineDoc_AddTopLineCommand(
        !           721:         LPOUTLINEDOC        lpOutlineDoc, 
        !           722:         UINT                nHeightInHimetric
        !           723: )
        !           724: {
        !           725:     LPOUTLINEAPP lpOutlineApp = (LPOUTLINEAPP)g_lpApp;
        !           726:     LPLINELIST  lpLL = &lpOutlineDoc->m_LineList;
        !           727:     HDC         hDC = LineList_GetDC(lpLL);
        !           728:     LPTEXTLINE  lpTextLine = TextLine_Create(hDC, 0, NULL);
        !           729:     LPLINE      lpLine = (LPLINE)lpTextLine;
        !           730:     LINERANGE   lrSel;
        !           731:     int         nNumSel;
        !           732: 
        !           733:     LineList_ReleaseDC(lpLL, hDC);
        !           734: 
        !           735:     if (! lpTextLine) {
        !           736:         OutlineApp_ErrorMessage(lpOutlineApp, ErrOutOfMemory);
        !           737:         return;
        !           738:     }
        !           739: 
        !           740:     Line_SetHeightInHimetric(lpLine, nHeightInHimetric);
        !           741:                     
        !           742:     nNumSel=LineList_GetSel(lpLL, (LPLINERANGE)&lrSel);
        !           743:     if (nNumSel > 0) {
        !           744:         // adjust current selection to keep equivalent selection
        !           745:         lrSel.m_nStartLine += 1;
        !           746:         lrSel.m_nEndLine += 1;
        !           747:     }
        !           748:     OutlineDoc_AddLine(lpOutlineDoc, lpLine, -1);
        !           749:     if (nNumSel > 0) 
        !           750:         LineList_SetSel(lpLL, (LPLINERANGE)&lrSel);
        !           751:     else 
        !           752:         LineList_RemoveSel(lpLL);
        !           753: }
        !           754: 
        !           755: 
        !           756: #if defined( USE_FRAMETOOLS )
        !           757: 
        !           758: 
        !           759: /* OutlineDoc_SetFormulaBarEditText
        !           760:  * --------------------------------
        !           761:  *
        !           762:  *      Fill the edit control in the formula with the text string from a 
        !           763:  * TextLine in focus.
        !           764:  */
        !           765: void OutlineDoc_SetFormulaBarEditText(
        !           766:         LPOUTLINEDOC            lpOutlineDoc, 
        !           767:         LPLINE                  lpLine
        !           768: )
        !           769: {
        !           770:     LPLINELIST lpLL = &lpOutlineDoc->m_LineList;
        !           771:     char cBuf[MAXSTRLEN+1];
        !           772: 
        !           773:     if (! lpOutlineDoc || ! lpOutlineDoc->m_lpFrameTools)
        !           774:         return;
        !           775: 
        !           776:     if (Line_GetLineType(lpLine) != TEXTLINETYPE) {
        !           777:         FrameTools_FB_SetEditText(lpOutlineDoc->m_lpFrameTools, NULL);
        !           778:     } else {
        !           779:         TextLine_GetTextData((LPTEXTLINE)lpLine, (LPSTR)cBuf);
        !           780:         FrameTools_FB_SetEditText(lpOutlineDoc->m_lpFrameTools, (LPSTR)cBuf);
        !           781:     }
        !           782: }
        !           783: 
        !           784: 
        !           785: /* OutlineDoc_SetFormulaBarEditFocus
        !           786:  * ---------------------------------
        !           787:  *
        !           788:  *  Setup for formula bar to gain or loose edit focus. 
        !           789:  *  if gaining focus, setup up special accelerator table and scroll line
        !           790:  *      into view.
        !           791:  *  else restore normal accelerator table.
        !           792:  */
        !           793: void OutlineDoc_SetFormulaBarEditFocus(
        !           794:         LPOUTLINEDOC            lpOutlineDoc, 
        !           795:         BOOL                    fEditFocus
        !           796: )
        !           797: {
        !           798:     LPLINELIST lpLL;
        !           799:     int nFocusIndex;
        !           800:     
        !           801:     if (! lpOutlineDoc || ! lpOutlineDoc->m_lpFrameTools)
        !           802:         return;
        !           803:     
        !           804:     lpOutlineDoc->m_lpFrameTools->m_fInFormulaBar = fEditFocus;
        !           805: 
        !           806:     if (fEditFocus && lpOutlineDoc->m_lpFrameTools) {
        !           807:         lpLL = OutlineDoc_GetLineList(lpOutlineDoc);
        !           808: 
        !           809:         nFocusIndex = LineList_GetFocusLineIndex(lpLL);
        !           810:         LineList_ScrollLineIntoView(lpLL, nFocusIndex);
        !           811:         FrameTools_FB_FocusEdit(lpOutlineDoc->m_lpFrameTools);
        !           812:     }
        !           813:     
        !           814:     OutlineApp_SetFormulaBarAccel((LPOUTLINEAPP)g_lpApp, fEditFocus);
        !           815: }
        !           816: 
        !           817: 
        !           818: /* OutlineDoc_IsEditFocusInFormulaBar
        !           819: ** ----------------------------------
        !           820: **    Returns TRUE if edit focus is currently in the formula bar
        !           821: **    else FALSE if not.
        !           822: */
        !           823: BOOL OutlineDoc_IsEditFocusInFormulaBar(LPOUTLINEDOC lpOutlineDoc)
        !           824: {
        !           825:     if (! lpOutlineDoc || ! lpOutlineDoc->m_lpFrameTools)
        !           826:         return FALSE;
        !           827:     
        !           828:     return lpOutlineDoc->m_lpFrameTools->m_fInFormulaBar;
        !           829: }
        !           830: 
        !           831: 
        !           832: /* OutlineDoc_UpdateFrameToolButtons
        !           833: ** ---------------------------------
        !           834: **    Update the Enable/Disable states of the buttons in the formula
        !           835: **    bar and button bar.
        !           836: */
        !           837: void OutlineDoc_UpdateFrameToolButtons(LPOUTLINEDOC lpOutlineDoc)
        !           838: {
        !           839:     if (! lpOutlineDoc || ! lpOutlineDoc->m_lpFrameTools)
        !           840:         return;
        !           841:     FrameTools_UpdateButtons(lpOutlineDoc->m_lpFrameTools, lpOutlineDoc);
        !           842: }
        !           843: #endif  // USE_FRAMETOOLS
        !           844: 
        !           845: 
        !           846: /* OutlineDoc_EditLineCommand
        !           847:  * --------------------------
        !           848:  *
        !           849:  *      Edit the current focus line.
        !           850:  */
        !           851: void OutlineDoc_EditLineCommand(LPOUTLINEDOC lpOutlineDoc)
        !           852: {
        !           853:     LPLINELIST lpLL = &lpOutlineDoc->m_LineList;
        !           854:     HDC hDC = LineList_GetDC(lpLL);
        !           855:     int nIndex = LineList_GetFocusLineIndex(lpLL);
        !           856:     LPLINE lpLine = LineList_GetLine(lpLL, nIndex);
        !           857:     int nOrgLineWidthInHimetric = Line_GetTotalWidthInHimetric(lpLine);
        !           858:     int nNewLineWidthInHimetric;
        !           859:     BOOL fSizeChanged;
        !           860: 
        !           861:     if (Line_Edit(lpLine, lpOutlineDoc->m_hWndDoc, hDC)) {
        !           862:         nNewLineWidthInHimetric = Line_GetTotalWidthInHimetric(lpLine);
        !           863: 
        !           864:         if (nNewLineWidthInHimetric > nOrgLineWidthInHimetric) {
        !           865:             fSizeChanged = LineList_SetMaxLineWidthInHimetric(
        !           866:                     lpLL,
        !           867:                     nNewLineWidthInHimetric
        !           868:                 );
        !           869:         } else {
        !           870:             fSizeChanged = LineList_RecalcMaxLineWidthInHimetric(
        !           871:                     lpLL,
        !           872:                     nOrgLineWidthInHimetric
        !           873:                 );
        !           874:         }
        !           875: 
        !           876: #if defined( OLE_SERVER )
        !           877:         /* Update Name Table */
        !           878:         ServerNameTable_EditLineUpdate(
        !           879:                 (LPSERVERNAMETABLE)lpOutlineDoc->m_lpNameTable,
        !           880:                 nIndex
        !           881:         );
        !           882: #endif
        !           883: 
        !           884:         OutlineDoc_SetModified(lpOutlineDoc, TRUE, TRUE, fSizeChanged);
        !           885: 
        !           886:         LineList_ForceLineRedraw(lpLL, nIndex, TRUE);
        !           887:     }
        !           888:     LineList_ReleaseDC(lpLL, hDC);
        !           889: }
        !           890: 
        !           891: 
        !           892: /* OutlineDoc_IndentCommand
        !           893:  * ------------------------
        !           894:  *
        !           895:  *      Indent selection of lines
        !           896:  */
        !           897: void OutlineDoc_IndentCommand(LPOUTLINEDOC lpOutlineDoc)
        !           898: {
        !           899:     LPLINELIST  lpLL = &lpOutlineDoc->m_LineList;
        !           900:     LPLINE      lpLine;
        !           901:     HDC         hDC = LineList_GetDC(lpLL);
        !           902:     int         i;
        !           903:     int         nIndex;
        !           904:     int         nNumSel;
        !           905:     LINERANGE   lrSel;
        !           906:     BOOL        fSizeChanged = FALSE;
        !           907: 
        !           908:     nNumSel=LineList_GetSel(lpLL, (LPLINERANGE)&lrSel);
        !           909: 
        !           910:     OutlineDoc_SetRedraw ( lpOutlineDoc, FALSE );
        !           911: 
        !           912:     for(i = 0; i < nNumSel; i++) {
        !           913:         nIndex = lrSel.m_nStartLine + i;
        !           914:         lpLine=LineList_GetLine(lpLL, nIndex);
        !           915:         lpLine=LineList_GetLine(lpLL, lrSel.m_nStartLine + i);
        !           916:         Line_Indent(lpLine, hDC);
        !           917:         if (LineList_SetMaxLineWidthInHimetric(lpLL,
        !           918:             Line_GetTotalWidthInHimetric(lpLine))) {
        !           919:             fSizeChanged = TRUE;
        !           920:         }
        !           921:         LineList_ForceLineRedraw(lpLL, nIndex, TRUE);
        !           922: 
        !           923: #if defined( OLE_SERVER )
        !           924:         /* Update Name Table */
        !           925:         ServerNameTable_EditLineUpdate(
        !           926:                 (LPSERVERNAMETABLE)lpOutlineDoc->m_lpNameTable,
        !           927:                 nIndex
        !           928:         );
        !           929: #endif
        !           930: 
        !           931:     }
        !           932: 
        !           933:     LineList_ReleaseDC(lpLL, hDC);
        !           934: 
        !           935:     OutlineDoc_SetModified(lpOutlineDoc, TRUE, TRUE, fSizeChanged);
        !           936:     OutlineDoc_SetRedraw ( lpOutlineDoc, TRUE );
        !           937: }
        !           938: 
        !           939: 
        !           940: /* OutlineDoc_UnindentCommand
        !           941:  * --------------------------
        !           942:  *
        !           943:  *      Unindent selection of lines
        !           944:  */
        !           945: void OutlineDoc_UnindentCommand(LPOUTLINEDOC lpOutlineDoc)
        !           946: {
        !           947:     LPLINELIST  lpLL = &lpOutlineDoc->m_LineList;
        !           948:     LPLINE      lpLine;
        !           949:     HDC         hDC = LineList_GetDC(lpLL);
        !           950:     int         nOrgLineWidthInHimetric;
        !           951:     int         nOrgMaxLineWidthInHimetric = 0;
        !           952:     int         i;
        !           953:     int         nIndex;
        !           954:     int         nNumSel;
        !           955:     LINERANGE   lrSel;
        !           956:     BOOL        fSizeChanged;
        !           957: 
        !           958:     nNumSel=LineList_GetSel(lpLL, (LPLINERANGE)&lrSel);
        !           959: 
        !           960:     OutlineDoc_SetRedraw ( lpOutlineDoc, FALSE );
        !           961: 
        !           962:     for(i = 0; i < nNumSel; i++) {
        !           963:         nIndex = lrSel.m_nStartLine + i;
        !           964:         lpLine=LineList_GetLine(lpLL, nIndex);
        !           965:         nOrgLineWidthInHimetric = Line_GetTotalWidthInHimetric(lpLine);
        !           966:         nOrgMaxLineWidthInHimetric =
        !           967:                 (nOrgLineWidthInHimetric > nOrgMaxLineWidthInHimetric ?
        !           968:                     nOrgLineWidthInHimetric : nOrgMaxLineWidthInHimetric);
        !           969:         Line_Unindent(lpLine, hDC);
        !           970:         LineList_ForceLineRedraw(lpLL, nIndex, TRUE);
        !           971: 
        !           972: #if defined( OLE_SERVER )
        !           973:         /* Update Name Table */
        !           974:         ServerNameTable_EditLineUpdate(
        !           975:                 (LPSERVERNAMETABLE)lpOutlineDoc->m_lpNameTable,
        !           976:                 nIndex
        !           977:         );
        !           978: #endif
        !           979: 
        !           980:     }
        !           981: 
        !           982:     LineList_ReleaseDC(lpLL, hDC);
        !           983: 
        !           984:     fSizeChanged = LineList_RecalcMaxLineWidthInHimetric(
        !           985:             lpLL,
        !           986:             nOrgMaxLineWidthInHimetric
        !           987:         );
        !           988: 
        !           989:     OutlineDoc_SetModified(lpOutlineDoc, TRUE, TRUE, fSizeChanged);
        !           990:     OutlineDoc_SetRedraw ( lpOutlineDoc, TRUE );
        !           991: }
        !           992: 
        !           993: 
        !           994: /* OutlineDoc_SetLineHeightCommand
        !           995:  * -------------------------------
        !           996:  *
        !           997:  *      Set height of the selection of lines
        !           998:  */
        !           999: void OutlineDoc_SetLineHeightCommand(LPOUTLINEDOC lpOutlineDoc)
        !          1000: {
        !          1001:     LPOUTLINEAPP lpOutlineApp = (LPOUTLINEAPP)g_lpApp;
        !          1002:     LPLINELIST  lpLL;
        !          1003:     HDC         hDC;
        !          1004:     LPLINE      lpLine;
        !          1005:     int         nNewHeight;
        !          1006:     int         i;
        !          1007:     int         nIndex;
        !          1008:     int         nNumSel;
        !          1009:     LINERANGE   lrSel;
        !          1010:     BOOL        fSizeChanged;
        !          1011:     
        !          1012: 
        !          1013:     if (!lpOutlineDoc)
        !          1014:         return;
        !          1015:     
        !          1016:     lpLL = &lpOutlineDoc->m_LineList;
        !          1017:     nNumSel=LineList_GetSel(lpLL, (LPLINERANGE)&lrSel);
        !          1018:     lpLine = LineList_GetLine(lpLL, lrSel.m_nStartLine);
        !          1019:     nNewHeight = Line_GetHeightInHimetric(lpLine);
        !          1020:     
        !          1021:     
        !          1022:     DialogBoxParam(
        !          1023:             lpOutlineApp->m_hInst, 
        !          1024:             (LPSTR)"SetLineHeight", 
        !          1025:             lpOutlineDoc->m_hWndDoc, 
        !          1026:             (DLGPROC)SetLineHeightDlgProc, 
        !          1027:             (LPARAM)(LPINT)&nNewHeight
        !          1028:     );
        !          1029:             
        !          1030:     if (nNewHeight == 0)
        !          1031:         return;     /* user hit cancel */
        !          1032: 
        !          1033:     hDC = LineList_GetDC(lpLL);
        !          1034: 
        !          1035:     for (i = 0; i < nNumSel; i++) {
        !          1036:         nIndex = lrSel.m_nStartLine + i;
        !          1037:         lpLine=LineList_GetLine(lpLL, nIndex);
        !          1038:         if (nNewHeight == -1) {
        !          1039:             switch (Line_GetLineType(lpLine)) {
        !          1040:                 
        !          1041:                 case TEXTLINETYPE:
        !          1042:                     
        !          1043:                     TextLine_CalcExtents((LPTEXTLINE)lpLine, hDC);
        !          1044:                     break;
        !          1045: 
        !          1046: #if defined( OLE_CNTR )
        !          1047:                 case CONTAINERLINETYPE:
        !          1048: 
        !          1049:                     Line_SetHeightInHimetric(lpLine, -1);
        !          1050:                     break;
        !          1051: #endif 
        !          1052: 
        !          1053:             }
        !          1054:         }
        !          1055:         else
        !          1056:             Line_SetHeightInHimetric(lpLine, nNewHeight);
        !          1057: 
        !          1058: 
        !          1059:         LineList_SetLineHeight(lpLL, nIndex,
        !          1060:                 Line_GetHeightInHimetric(lpLine));
        !          1061:     }
        !          1062: 
        !          1063:     LineList_ReleaseDC(lpLL, hDC);
        !          1064:     fSizeChanged = LineList_RecalcMaxLineWidthInHimetric(lpLL, 0);
        !          1065: 
        !          1066:     OutlineDoc_SetModified(lpOutlineDoc, TRUE, TRUE, fSizeChanged);
        !          1067:     LineList_ForceRedraw(lpLL, TRUE);
        !          1068: }
        !          1069: 
        !          1070: 
        !          1071: 
        !          1072: /* OutlineDoc_SelectAllCommand
        !          1073:  * ---------------------------
        !          1074:  *
        !          1075:  *      Select all the lines in the document.
        !          1076:  */
        !          1077: void OutlineDoc_SelectAllCommand(LPOUTLINEDOC lpOutlineDoc)
        !          1078: {
        !          1079:     LPLINELIST lpLL = &lpOutlineDoc->m_LineList;
        !          1080:     LINERANGE lrSel;
        !          1081: 
        !          1082:     lrSel.m_nStartLine = 0;
        !          1083:     lrSel.m_nEndLine = LineList_GetCount(lpLL) - 1;
        !          1084:     LineList_SetSel(lpLL, &lrSel);
        !          1085: }
        !          1086: 
        !          1087: 
        !          1088: /* OutlineDoc_DefineNameCommand
        !          1089:  * ----------------------------
        !          1090:  *
        !          1091:  *      Define a name in the document
        !          1092:  */
        !          1093: void OutlineDoc_DefineNameCommand(LPOUTLINEDOC lpOutlineDoc)
        !          1094: {
        !          1095:     LPOUTLINEAPP lpOutlineApp = (LPOUTLINEAPP)g_lpApp;
        !          1096: 
        !          1097:     DialogBoxParam(
        !          1098:             lpOutlineApp->m_hInst, 
        !          1099:             (LPSTR)"DefineName", 
        !          1100:             lpOutlineDoc->m_hWndDoc, 
        !          1101:             (DLGPROC)DefineNameDlgProc, 
        !          1102:             (LPARAM) lpOutlineDoc
        !          1103:     );
        !          1104: }
        !          1105: 
        !          1106: 
        !          1107: /* OutlineDoc_GotoNameCommand
        !          1108:  * --------------------------
        !          1109:  *
        !          1110:  *      Goto a predefined name in the document
        !          1111:  */
        !          1112: void OutlineDoc_GotoNameCommand(LPOUTLINEDOC lpOutlineDoc)
        !          1113: {
        !          1114:     LPOUTLINEAPP lpOutlineApp = (LPOUTLINEAPP)g_lpApp;
        !          1115: 
        !          1116:     DialogBoxParam(
        !          1117:             lpOutlineApp->m_hInst, 
        !          1118:             (LPSTR)"GotoName", 
        !          1119:             lpOutlineDoc->m_hWndDoc,
        !          1120:             (DLGPROC)GotoNameDlgProc, 
        !          1121:             (LPARAM)lpOutlineDoc
        !          1122:     );
        !          1123: }
        !          1124: 
        !          1125: 
        !          1126: /* OutlineDoc_ShowWindow
        !          1127:  * ---------------------
        !          1128:  *
        !          1129:  *      Show the window of the document to the user.
        !          1130:  */
        !          1131: void OutlineDoc_ShowWindow(LPOUTLINEDOC lpOutlineDoc)
        !          1132: {
        !          1133:     if (! OleDbgVerifySz(lpOutlineDoc->m_docInitType != DOCTYPE_UNKNOWN, 
        !          1134:         "OutlineDoc_ShowWindow: can't show unitialized document\r\n")) {
        !          1135:         return;
        !          1136:     }
        !          1137: 
        !          1138: #if defined( OLE_VERSION )
        !          1139:     // Call OLE version of this function instead
        !          1140:     OleDoc_ShowWindow((LPOLEDOC)lpOutlineDoc);
        !          1141: #else
        !          1142:     ShowWindow(lpOutlineDoc->m_hWndDoc, SW_SHOWNORMAL);
        !          1143:     SetFocus(lpOutlineDoc->m_hWndDoc);
        !          1144: #endif
        !          1145: }
        !          1146: 
        !          1147: 
        !          1148: #if defined( USE_FRAMETOOLS )
        !          1149: 
        !          1150: void OutlineDoc_AddFrameLevelTools(LPOUTLINEDOC lpOutlineDoc)
        !          1151: {
        !          1152: #if defined( INPLACE_CNTR )
        !          1153:     // Call OLE In-Place Container version of this function instead
        !          1154:     ContainerDoc_AddFrameLevelTools((LPCONTAINERDOC)lpOutlineDoc);
        !          1155: 
        !          1156: #else   // ! INPLACE_CNTR
        !          1157:     RECT rcFrameRect;
        !          1158:     BORDERWIDTHS frameToolWidths;
        !          1159: 
        !          1160: #if defined( INPLACE_SVR )
        !          1161:     LPSERVERDOC lpServerDoc = (LPSERVERDOC)lpOutlineDoc;
        !          1162:     LPOLEINPLACEFRAME lpTopIPFrame=ServerDoc_GetTopInPlaceFrame(lpServerDoc);
        !          1163: 
        !          1164:     // if in-place active, add our tools to our in-place container's frame.
        !          1165:     if (lpTopIPFrame) {
        !          1166:         ServerDoc_AddFrameLevelTools(lpServerDoc);
        !          1167:         return;
        !          1168:     }
        !          1169: #endif  // INPLACE_SVR
        !          1170: 
        !          1171:     OutlineApp_GetFrameRect(g_lpApp, (LPRECT)&rcFrameRect);
        !          1172:     FrameTools_GetRequiredBorderSpace(
        !          1173:             lpOutlineDoc->m_lpFrameTools, 
        !          1174:             (LPBORDERWIDTHS)&frameToolWidths
        !          1175:     );
        !          1176:     OutlineApp_SetBorderSpace(g_lpApp, (LPBORDERWIDTHS)&frameToolWidths);
        !          1177:     FrameTools_AttachToFrame(
        !          1178:             lpOutlineDoc->m_lpFrameTools, OutlineApp_GetWindow(g_lpApp));
        !          1179:     FrameTools_Move(lpOutlineDoc->m_lpFrameTools, (LPRECT)&rcFrameRect);
        !          1180: #endif  // ! INPLACE_CNTR
        !          1181:     
        !          1182: }
        !          1183: 
        !          1184: #endif  // USE_FRAMETOOLS
        !          1185: 
        !          1186: 
        !          1187: /* OutlineDoc_GetWindow
        !          1188:  * --------------------
        !          1189:  *
        !          1190:  *      Get the window handle of the document.
        !          1191:  */
        !          1192: HWND OutlineDoc_GetWindow(LPOUTLINEDOC lpOutlineDoc)
        !          1193: {
        !          1194:     if(! lpOutlineDoc) return NULL;
        !          1195:     return lpOutlineDoc->m_hWndDoc;
        !          1196: }
        !          1197: 
        !          1198: 
        !          1199: /* OutlineDoc_AddLine
        !          1200:  * ------------------
        !          1201:  *
        !          1202:  *      Add one line to the Document's LineList
        !          1203:  */
        !          1204: void OutlineDoc_AddLine(LPOUTLINEDOC lpOutlineDoc, LPLINE lpLine, int nIndex)
        !          1205: {
        !          1206:     LPLINELIST lpLL = &lpOutlineDoc->m_LineList;
        !          1207: 
        !          1208:     LineList_AddLine(lpLL, lpLine, nIndex);
        !          1209: 
        !          1210:     /* Update Name Table */
        !          1211:     OutlineNameTable_AddLineUpdate(lpOutlineDoc->m_lpNameTable, nIndex);
        !          1212: 
        !          1213: #if defined( INPLACE_CNTR )
        !          1214:     {
        !          1215:         LPCONTAINERDOC lpContainerDoc = (LPCONTAINERDOC)lpOutlineDoc;
        !          1216:         /* OLE2NOTE: after adding a line we need to
        !          1217:         **    update the PosRect of the In-Place active
        !          1218:         **    objects (if any) that follow the added line.
        !          1219:         **    NOTE: nIndex is index of line before new line.
        !          1220:         **          nIndex+1 is index of new line
        !          1221:         **          nIndex+2 is index of line after new line.
        !          1222:         */
        !          1223:         ContainerDoc_UpdateInPlaceObjectRects(lpContainerDoc, nIndex+2);
        !          1224:     }
        !          1225: #endif
        !          1226: 
        !          1227:     OutlineDoc_SetModified(lpOutlineDoc, TRUE, TRUE, TRUE);
        !          1228: }
        !          1229: 
        !          1230: 
        !          1231: /* OutlineDoc_DeleteLine
        !          1232:  * ---------------------
        !          1233:  *
        !          1234:  *
        !          1235:  *      Delete one line from the document's LineList
        !          1236:  */
        !          1237: void OutlineDoc_DeleteLine(LPOUTLINEDOC lpOutlineDoc, int nIndex)
        !          1238: {
        !          1239:     LPLINELIST lpLL = &lpOutlineDoc->m_LineList;
        !          1240: 
        !          1241:     LineList_DeleteLine(lpLL, nIndex);
        !          1242: 
        !          1243:     /* Update Name Table */
        !          1244:     OutlineNameTable_DeleteLineUpdate(lpOutlineDoc->m_lpNameTable, nIndex);
        !          1245: 
        !          1246: #if defined( INPLACE_CNTR )
        !          1247:     {
        !          1248:         LPCONTAINERDOC lpContainerDoc = (LPCONTAINERDOC)lpOutlineDoc;
        !          1249:         /* OLE2NOTE: after deleting a line we need to
        !          1250:         **    update the PosRect of the In-Place active
        !          1251:         **    objects (if any).
        !          1252:         */
        !          1253:         ContainerDoc_UpdateInPlaceObjectRects(lpContainerDoc, nIndex);
        !          1254:     }
        !          1255: #endif
        !          1256: 
        !          1257:     OutlineDoc_SetModified(lpOutlineDoc, TRUE, TRUE, TRUE);
        !          1258: }
        !          1259: 
        !          1260: 
        !          1261: /* OutlineDoc_AddName
        !          1262:  * ------------------
        !          1263:  *
        !          1264:  *      Add a Name to the Document's NameTable
        !          1265:  */
        !          1266: void OutlineDoc_AddName(LPOUTLINEDOC lpOutlineDoc, LPOUTLINENAME lpOutlineName)
        !          1267: {
        !          1268:     LPOUTLINENAMETABLE lpOutlineNameTable = lpOutlineDoc->m_lpNameTable;
        !          1269: 
        !          1270:     OutlineNameTable_AddName(lpOutlineNameTable, lpOutlineName);
        !          1271: 
        !          1272:     OutlineDoc_SetModified(lpOutlineDoc, TRUE, FALSE, FALSE);
        !          1273: }
        !          1274: 
        !          1275: 
        !          1276: /* OutlineDoc_DeleteName
        !          1277:  * ---------------------
        !          1278:  *
        !          1279:  *
        !          1280:  *      Delete Name from the document's NameTable
        !          1281:  */
        !          1282: void OutlineDoc_DeleteName(LPOUTLINEDOC lpOutlineDoc, int nIndex)
        !          1283: {
        !          1284:     LPOUTLINENAMETABLE lpOutlineNameTable = lpOutlineDoc->m_lpNameTable;
        !          1285: 
        !          1286:     OutlineNameTable_DeleteName(lpOutlineNameTable, nIndex);
        !          1287: 
        !          1288:     OutlineDoc_SetModified(lpOutlineDoc, TRUE, FALSE, FALSE);
        !          1289: }
        !          1290: 
        !          1291: 
        !          1292: /* OutlineDoc_Destroy
        !          1293:  * ------------------
        !          1294:  *
        !          1295:  *  Free all memory that had been allocated for a document.
        !          1296:  *      this destroys the LineList & NameTable of the document.
        !          1297:  */
        !          1298: void OutlineDoc_Destroy(LPOUTLINEDOC lpOutlineDoc)
        !          1299: {
        !          1300:     LPLINELIST lpLL = &lpOutlineDoc->m_LineList;
        !          1301: #if defined( OLE_VERSION )
        !          1302:     LPOLEAPP lpOleApp = (LPOLEAPP)g_lpApp;
        !          1303:     LPOLEDOC lpOleDoc = (LPOLEDOC)lpOutlineDoc;
        !          1304: 
        !          1305:     if (lpOleDoc->m_fObjIsDestroying) 
        !          1306:         return;     // doc destruction is in progress
        !          1307: #endif  // OLE_VERSION
        !          1308: 
        !          1309:     OLEDBG_BEGIN3("OutlineDoc_Destroy\r\n");
        !          1310: 
        !          1311: #if defined( OLE_VERSION )
        !          1312: 
        !          1313:     /* OLE2NOTE: in order to guarantee that the application does not
        !          1314:     **    prematurely exit before the destruction of the document is
        !          1315:     **    complete, we intially AddRef the App refcnt later Release it.
        !          1316:     **    This initial AddRef is artificial; it simply guarantees that
        !          1317:     **    the app object does not get destroyed until the end of this
        !          1318:     **    routine. 
        !          1319:     */
        !          1320:     OleApp_AddRef(lpOleApp);
        !          1321: 
        !          1322:     /* OLE2NOTE: perform processing required for OLE */
        !          1323:     OleDoc_Destroy(lpOleDoc);
        !          1324: #endif
        !          1325: 
        !          1326:     LineList_Destroy(lpLL);
        !          1327:     OutlineNameTable_Destroy(lpOutlineDoc->m_lpNameTable);
        !          1328: 
        !          1329: #if defined( USE_HEADING )
        !          1330:     if (! lpOutlineDoc->m_fDataTransferDoc)
        !          1331:         Heading_Destroy((LPHEADING)&lpOutlineDoc->m_heading);
        !          1332: #endif
        !          1333: 
        !          1334: #if defined( USE_FRAMETOOLS )
        !          1335:     if (! lpOutlineDoc->m_fDataTransferDoc) 
        !          1336:         FrameTools_AssociateDoc(lpOutlineDoc->m_lpFrameTools, NULL);
        !          1337: #endif  // USE_FRAMETOOLS
        !          1338: 
        !          1339:     DestroyWindow(lpOutlineDoc->m_hWndDoc);
        !          1340:     Delete(lpOutlineDoc);   // free memory for doc itself
        !          1341: 
        !          1342:     OleDbgOut1("@@@@ DOC DESTROYED\r\n");
        !          1343: 
        !          1344: #if defined( OLE_VERSION )
        !          1345:     OleApp_Release(lpOleApp);       // release artificial AddRef above
        !          1346: #endif
        !          1347:     
        !          1348:     OLEDBG_END3
        !          1349: }
        !          1350: 
        !          1351: 
        !          1352: /* OutlineDoc_ReSize
        !          1353:  * -----------------
        !          1354:  *
        !          1355:  *  Resize the document and its components
        !          1356:  *
        !          1357:  * Parameter:
        !          1358:  *      lpRect  the new size of the document. Use current size if NULL
        !          1359:  */
        !          1360: void OutlineDoc_Resize(LPOUTLINEDOC lpOutlineDoc, LPRECT lpRect)
        !          1361: {
        !          1362:     RECT            rect;
        !          1363:     LPLINELIST      lpLL;
        !          1364:     
        !          1365: #if defined( USE_HEADING )
        !          1366:     LPHEADING       lphead;
        !          1367: #endif  // USE_HEADING
        !          1368: 
        !          1369:     LPSCALEFACTOR   lpscale;
        !          1370:     HWND            hWndLL;
        !          1371:     
        !          1372:     if (!lpOutlineDoc) 
        !          1373:         return;
        !          1374: 
        !          1375:     lpLL = (LPLINELIST)&lpOutlineDoc->m_LineList;
        !          1376:     lpscale = (LPSCALEFACTOR)&lpOutlineDoc->m_scale;
        !          1377:     hWndLL = LineList_GetWindow(lpLL);
        !          1378: 
        !          1379:     if (lpRect) {
        !          1380:         CopyRect((LPRECT)&rect, lpRect);
        !          1381:         MoveWindow(lpOutlineDoc->m_hWndDoc, rect.left, rect.top, 
        !          1382:                 rect.right-rect.left, rect.bottom-rect.top, TRUE);
        !          1383:     }
        !          1384: 
        !          1385:     GetClientRect(lpOutlineDoc->m_hWndDoc, (LPRECT)&rect);
        !          1386: 
        !          1387: #if defined( USE_HEADING )
        !          1388:     lphead = OutlineDoc_GetHeading(lpOutlineDoc);
        !          1389:     rect.left += Heading_RH_GetWidth(lphead, lpscale);
        !          1390:     rect.top += Heading_CH_GetHeight(lphead, lpscale);
        !          1391: #endif  // USE_HEADING
        !          1392:             
        !          1393:     if (lpLL) {
        !          1394:         MoveWindow(hWndLL, rect.left, rect.top,
        !          1395:                 rect.right-rect.left, rect.bottom-rect.top, TRUE);
        !          1396:     }
        !          1397: 
        !          1398: #if defined( USE_HEADING )
        !          1399:     if (lphead) 
        !          1400:         Heading_Move(lphead, lpOutlineDoc->m_hWndDoc, lpscale);
        !          1401: #endif  // USE_HEADING
        !          1402: 
        !          1403: #if defined( INPLACE_CNTR )
        !          1404:     ContainerDoc_UpdateInPlaceObjectRects((LPCONTAINERDOC)lpOutlineDoc, 0);
        !          1405: #endif
        !          1406: }           
        !          1407: 
        !          1408: 
        !          1409: /* OutlineDoc_GetNameTable
        !          1410:  * -----------------------
        !          1411:  *
        !          1412:  *      Get nametable associated with the line list
        !          1413:  */
        !          1414: LPOUTLINENAMETABLE OutlineDoc_GetNameTable(LPOUTLINEDOC lpOutlineDoc)
        !          1415: {
        !          1416:     if (!lpOutlineDoc)
        !          1417:         return NULL;
        !          1418:     else
        !          1419:         return lpOutlineDoc->m_lpNameTable;
        !          1420: }
        !          1421: 
        !          1422: 
        !          1423: /* OutlineDoc_GetLineList
        !          1424:  * ----------------------
        !          1425:  *
        !          1426:  *      Get listlist associated with the OutlineDoc
        !          1427:  */
        !          1428: LPLINELIST OutlineDoc_GetLineList(LPOUTLINEDOC lpOutlineDoc)
        !          1429: {
        !          1430:     if (!lpOutlineDoc)
        !          1431:         return NULL;
        !          1432:     else 
        !          1433:         return (LPLINELIST)&lpOutlineDoc->m_LineList;
        !          1434: }
        !          1435: 
        !          1436: 
        !          1437: /* OutlineDoc_GetNameCount
        !          1438:  * -----------------------
        !          1439:  *
        !          1440:  * Return number of names in table
        !          1441:  */
        !          1442: int OutlineDoc_GetNameCount(LPOUTLINEDOC lpOutlineDoc)
        !          1443: {
        !          1444:     return OutlineNameTable_GetCount(lpOutlineDoc->m_lpNameTable);
        !          1445: }
        !          1446: 
        !          1447: 
        !          1448: /* OutlineDoc_GetLineCount
        !          1449:  * -----------------------
        !          1450:  *
        !          1451:  * Return number of lines in the LineList
        !          1452:  */
        !          1453: int OutlineDoc_GetLineCount(LPOUTLINEDOC lpOutlineDoc)
        !          1454: {
        !          1455:     return LineList_GetCount(&lpOutlineDoc->m_LineList);
        !          1456: }
        !          1457: 
        !          1458: 
        !          1459: /* OutlineDoc_SetFileName
        !          1460:  * ----------------------
        !          1461:  *
        !          1462:  *      Set the filename of a document.
        !          1463:  *
        !          1464:  *  OLE2NOTE: If the ServerDoc has a valid filename then, the object is
        !          1465:  *  registered in the running object table (ROT). if the name of the doc
        !          1466:  *  changes (eg. via SaveAs) then the previous registration must be revoked
        !          1467:  *  and the document re-registered under the new name.
        !          1468:  */
        !          1469: BOOL OutlineDoc_SetFileName(LPOUTLINEDOC lpOutlineDoc, LPSTR lpszNewFileName, LPSTORAGE lpNewStg)
        !          1470: {
        !          1471:     if (! OleDbgVerifySz(lpszNewFileName != NULL, 
        !          1472:                                             "Can't reset doc to Untitled!"))
        !          1473:         return FALSE;
        !          1474: 
        !          1475: #if defined( OLE_CNTR )
        !          1476:     {
        !          1477:         LPCONTAINERDOC lpContainerDoc = (LPCONTAINERDOC)lpOutlineDoc;
        !          1478: 
        !          1479:         /* OLE2NOTE: the container version of the application keeps its
        !          1480:         **    storage open at all times. if the document's storage is not
        !          1481:         **    open, then open it.
        !          1482:         */
        !          1483: 
        !          1484:         if (lpNewStg) {
        !          1485: 
        !          1486:             /* CASE 1 -- document is being loaded from a file. lpNewStg is
        !          1487:             **    still open from the OutlineDoc_LoadFromFile function.
        !          1488:             */
        !          1489: 
        !          1490:             lpOutlineDoc->m_docInitType = DOCTYPE_FROMFILE;
        !          1491: 
        !          1492:         } else {
        !          1493: 
        !          1494:             /* CASE 2 -- document is being associated with a valid file
        !          1495:             **    that is not yet open. thus we must now open the file.
        !          1496:             */
        !          1497: 
        !          1498:             if (lpOutlineDoc->m_docInitType == DOCTYPE_FROMFILE &&
        !          1499:                     lstrcmp(lpOutlineDoc->m_szFileName,lpszNewFileName)==0) {
        !          1500: 
        !          1501:                 /* CASE 2a -- new filename is same as current file. if the
        !          1502:                 **    stg is already open, then the lpStg is still valid.
        !          1503:                 **    if it is not open, then open it.
        !          1504:                 */
        !          1505:                 if (! lpContainerDoc->m_lpStg) {
        !          1506:                     lpContainerDoc->m_lpStg = OleStdOpenRootStorage(
        !          1507:                             lpszNewFileName,
        !          1508:                             STGM_READWRITE | STGM_SHARE_DENY_WRITE
        !          1509:                     );
        !          1510:                     if (! lpContainerDoc->m_lpStg) return FALSE;
        !          1511:                 }
        !          1512: 
        !          1513:             } else {
        !          1514: 
        !          1515:                 /* CASE 2b -- new filename is NOT same as current file.
        !          1516:                 **    a SaveAs operation is pending. open the new file and
        !          1517:                 **    hold the storage pointer in m_lpNewStg. the
        !          1518:                 **    subsequent call to Doc_SaveToFile will save the
        !          1519:                 **    document into the new storage pointer and release the
        !          1520:                 **    old storage pointer.
        !          1521:                 */
        !          1522: 
        !          1523:                 lpOutlineDoc->m_docInitType = DOCTYPE_FROMFILE;
        !          1524: 
        !          1525:                 lpContainerDoc->m_lpNewStg = OleStdCreateRootStorage(
        !          1526:                         lpszNewFileName,
        !          1527:                         STGM_READWRITE | STGM_SHARE_DENY_WRITE | STGM_CREATE
        !          1528:                 );
        !          1529:                 if (! lpContainerDoc->m_lpNewStg) return FALSE;
        !          1530:             }
        !          1531:         }
        !          1532:     }
        !          1533: #endif      // OLE_CNTR
        !          1534: 
        !          1535:     if (lpOutlineDoc->m_docInitType != DOCTYPE_FROMFILE ||
        !          1536:         lstrcmp(lpOutlineDoc->m_szFileName, lpszNewFileName) != 0) {
        !          1537: 
        !          1538:         /* A new valid file name is being associated with the document */
        !          1539: 
        !          1540:         lstrcpy(lpOutlineDoc->m_szFileName, lpszNewFileName);
        !          1541:         lpOutlineDoc->m_docInitType = DOCTYPE_FROMFILE;
        !          1542: 
        !          1543:         // set lpszDocTitle to point to filename without path
        !          1544:         lpOutlineDoc->m_lpszDocTitle = lpOutlineDoc->m_szFileName +
        !          1545:             lstrlen(lpOutlineDoc->m_szFileName) - 1;
        !          1546:         while (lpOutlineDoc->m_lpszDocTitle > lpOutlineDoc->m_szFileName
        !          1547:             && ! IS_FILENAME_DELIM(lpOutlineDoc->m_lpszDocTitle[-1])) {
        !          1548:             lpOutlineDoc->m_lpszDocTitle--;
        !          1549:         }
        !          1550: 
        !          1551:         OutlineDoc_SetTitle(lpOutlineDoc);
        !          1552: 
        !          1553: #if defined( OLE_VERSION )
        !          1554:         {
        !          1555:             /* OLE2NOTE: both containers and servers must properly
        !          1556:             **    register in the RunningObjectTable. if the document
        !          1557:             **    is performing a SaveAs operation, then it must
        !          1558:             **    re-register in the ROT with the new moniker. in
        !          1559:             **    addition any embedded object, pseudo objects, and/or
        !          1560:             **    linking clients must be informed that the document's
        !          1561:             **    moniker has changed.
        !          1562:             */
        !          1563: 
        !          1564:             LPOLEDOC lpOleDoc = (LPOLEDOC)lpOutlineDoc;
        !          1565: 
        !          1566:             if (lpOleDoc->m_lpFileMoniker) {
        !          1567:                 OleStdRelease((LPUNKNOWN)lpOleDoc->m_lpFileMoniker);
        !          1568:                 lpOleDoc->m_lpFileMoniker = NULL;
        !          1569:             }
        !          1570: 
        !          1571:             CreateFileMoniker(lpszNewFileName,&lpOleDoc->m_lpFileMoniker);
        !          1572:             OleDoc_DocRenamedUpdate(lpOleDoc, lpOleDoc->m_lpFileMoniker);
        !          1573:         }
        !          1574: #endif      // OLE_VERSION
        !          1575: 
        !          1576:     }
        !          1577: 
        !          1578:     return TRUE;
        !          1579: }
        !          1580: 
        !          1581: 
        !          1582: /* OutlineDoc_SetTitle
        !          1583:  * -------------------
        !          1584:  *
        !          1585:  * Set window text to be current filename.
        !          1586:  * The following window hierarchy exits:
        !          1587:  *      hWndApp
        !          1588:  *          hWndDoc
        !          1589:  *              hWndListBox
        !          1590:  *  The frame window is the window which gets the title.
        !          1591:  */
        !          1592: void OutlineDoc_SetTitle(LPOUTLINEDOC lpOutlineDoc)
        !          1593: {
        !          1594:     HWND hWnd;
        !          1595:     char szText[256];
        !          1596: 
        !          1597:     if (!lpOutlineDoc->m_hWndDoc) return;
        !          1598:     if ((hWnd = GetParent(lpOutlineDoc->m_hWndDoc)) == NULL) return;
        !          1599: 
        !          1600:     lstrcpy(szText, APPNAME);
        !          1601:     lstrcat(szText," - ");
        !          1602:     lstrcat(szText, (LPSTR)lpOutlineDoc->m_lpszDocTitle);
        !          1603: 
        !          1604:     SetWindowText(hWnd,szText);
        !          1605: }
        !          1606: 
        !          1607: 
        !          1608: /* OutlineDoc_Close
        !          1609:  * ----------------
        !          1610:  *
        !          1611:  * Close active document. If modified, prompt the user if
        !          1612:  * he wants to save.
        !          1613:  *
        !          1614:  *  Returns:
        !          1615:  *      FALSE -- user canceled the closing of the doc.
        !          1616:  *      TRUE -- the doc was successfully closed
        !          1617:  */
        !          1618: BOOL OutlineDoc_Close(LPOUTLINEDOC lpOutlineDoc, DWORD dwSaveOption)
        !          1619: {
        !          1620:     LPOUTLINEAPP lpOutlineApp = (LPOUTLINEAPP)g_lpApp;
        !          1621: 
        !          1622: #if defined( OLE_VERSION )
        !          1623:     /* OLE2NOTE: call OLE specific function instead */
        !          1624:     return OleDoc_Close((LPOLEDOC)lpOutlineDoc, dwSaveOption);
        !          1625: 
        !          1626: #else
        !          1627: 
        !          1628:     if (! lpOutlineDoc)
        !          1629:         return TRUE;            // active doc's are already destroyed
        !          1630: 
        !          1631:     if (! OutlineDoc_CheckSaveChanges(lpOutlineDoc, dwSaveOption))
        !          1632:         return FALSE;           // abort closing the doc
        !          1633: 
        !          1634:     OutlineDoc_Destroy(lpOutlineDoc);
        !          1635: 
        !          1636:     OutlineApp_DocUnlockApp(lpOutlineApp, lpOutlineDoc);
        !          1637: 
        !          1638:     return TRUE;
        !          1639: 
        !          1640: #endif      // ! OLE_VERSION
        !          1641: }
        !          1642: 
        !          1643: 
        !          1644: /* OutlineDoc_CheckSaveChanges
        !          1645:  * ---------------------------
        !          1646:  *
        !          1647:  * Check if the document has been modified. if so, prompt the user if
        !          1648:  *      the changes should be saved. if yes save them.
        !          1649:  * Returns TRUE if the doc is safe to close (user answered Yes or No)
        !          1650:  *         FALSE if the user canceled the save changes option.
        !          1651:  */
        !          1652: BOOL OutlineDoc_CheckSaveChanges(LPOUTLINEDOC lpOutlineDoc, DWORD dwSaveOption)
        !          1653: {
        !          1654:     int nResponse;
        !          1655:     
        !          1656:     if (dwSaveOption == OLECLOSE_NOSAVE) {
        !          1657:         return TRUE;
        !          1658:     }
        !          1659: 
        !          1660:     if(! OutlineDoc_IsModified(lpOutlineDoc))
        !          1661:         return TRUE;    // saving is not necessary
        !          1662: 
        !          1663:     /* OLE2NOTE: our document is dirty so it needs to be saved. if 
        !          1664:     **    OLECLOSE_PROMPTSAVE the user should be prompted to see if the
        !          1665:     **    document should be saved. is specified but the document is NOT
        !          1666:     **    visible to the user, then the user can NOT be prompted. in
        !          1667:     **    the situation the document should be saved without prompting.
        !          1668:     **    if OLECLOSE_SAVEIFDIRTY is specified then, the document
        !          1669:     **    should also be saved without prompting.
        !          1670:     */
        !          1671:     if (dwSaveOption == OLECLOSE_PROMPTSAVE && 
        !          1672:             IsWindowVisible(lpOutlineDoc->m_hWndDoc)) {
        !          1673: 
        !          1674:         // prompt the user to see if changes should be saved.
        !          1675:         nResponse = MessageBox(
        !          1676:                 g_lpApp->m_hWndApp,
        !          1677:                 MsgSaveFile,
        !          1678:                 APPNAME,
        !          1679:                 MB_ICONQUESTION | MB_YESNOCANCEL
        !          1680:         );
        !          1681:         if(nResponse==IDCANCEL)
        !          1682:             return FALSE;   // close is canceled
        !          1683:         if(nResponse==IDNO)
        !          1684:             return TRUE;    // don't save, but is ok to close
        !          1685:     } else if (dwSaveOption != OLECLOSE_SAVEIFDIRTY) {
        !          1686:         return TRUE;        // unknown dwSaveOption; close w/o saving
        !          1687:     }
        !          1688: 
        !          1689: #if defined( OLE_SERVER )
        !          1690: 
        !          1691:     if (lpOutlineDoc->m_docInitType == DOCTYPE_EMBEDDED) {
        !          1692:         LPSERVERDOC lpServerDoc = (LPSERVERDOC)lpOutlineDoc;
        !          1693:         HRESULT hrErr;
        !          1694: 
        !          1695:         /* OLE2NOTE: Update the container before closing without prompting
        !          1696:         **    the user. To update the container, we must ask our container
        !          1697:         **    to save us.
        !          1698:         */
        !          1699:         OleDbgAssert(lpServerDoc->m_lpOleClientSite != NULL);
        !          1700:         OLEDBG_BEGIN2("IOleClientSite::SaveObject called\r\n")
        !          1701:         hrErr = lpServerDoc->m_lpOleClientSite->lpVtbl->SaveObject(
        !          1702:                 lpServerDoc->m_lpOleClientSite
        !          1703:         );
        !          1704:         OLEDBG_END2
        !          1705: 
        !          1706:         if (hrErr != NOERROR) {
        !          1707:             OleDbgOutHResult("IOleClientSite::SaveObject returned", hrErr);
        !          1708:             return FALSE;
        !          1709:         }
        !          1710: 
        !          1711:         return TRUE;    // doc is safe to be closed
        !          1712: 
        !          1713:     } else
        !          1714:         
        !          1715: #endif      // OLE_SERVER
        !          1716: 
        !          1717:     {
        !          1718:         return OutlineApp_SaveCommand(g_lpApp);
        !          1719:     }
        !          1720: }
        !          1721: 
        !          1722: 
        !          1723: /* OutlineDoc_IsModified
        !          1724:  * ---------------------
        !          1725:  *
        !          1726:  * Return modify flag of OUTLINEDOC
        !          1727:  */
        !          1728: BOOL OutlineDoc_IsModified(LPOUTLINEDOC lpOutlineDoc)
        !          1729: {
        !          1730:     if (lpOutlineDoc->m_fModified)
        !          1731:         return lpOutlineDoc->m_fModified;
        !          1732: 
        !          1733: #if defined( OLE_CNTR )
        !          1734:     {
        !          1735:         /* OLE2NOTE: if there are OLE objects, then we must ask if any of
        !          1736:         **    them are dirty. if so we must consider our document
        !          1737:         **    as modified.
        !          1738:         */
        !          1739:         LPCONTAINERDOC lpContainerDoc = (LPCONTAINERDOC)lpOutlineDoc;
        !          1740:         LPLINELIST     lpLL;
        !          1741:         int                    nLines;
        !          1742:         int                    nIndex;
        !          1743:         LPLINE         lpLine;
        !          1744:         HRESULT     hrErr;
        !          1745: 
        !          1746:         lpLL = (LPLINELIST)&((LPOUTLINEDOC)lpContainerDoc)->m_LineList;
        !          1747:         nLines = LineList_GetCount(lpLL);
        !          1748: 
        !          1749:         for (nIndex = 0; nIndex < nLines; nIndex++) {
        !          1750:             lpLine = LineList_GetLine(lpLL, nIndex);
        !          1751:             if (!lpLine)
        !          1752:                 break;
        !          1753:             if (Line_GetLineType(lpLine) == CONTAINERLINETYPE) {
        !          1754:                 LPCONTAINERLINE lpContainerLine = (LPCONTAINERLINE)lpLine;
        !          1755:                 if (lpContainerLine->m_lpPersistStg) {
        !          1756:                     hrErr = lpContainerLine->m_lpPersistStg->lpVtbl->IsDirty(
        !          1757:                             lpContainerLine->m_lpPersistStg);
        !          1758:                     if (hrErr == NOERROR) {
        !          1759:                         return TRUE;
        !          1760:                     }
        !          1761:                 }
        !          1762:             }
        !          1763:         }
        !          1764:     }        
        !          1765: #endif    
        !          1766:     return FALSE;
        !          1767: }
        !          1768: 
        !          1769: 
        !          1770: /* OutlineDoc_SetModified
        !          1771:  * ----------------------
        !          1772:  *
        !          1773:  *  Set the modified flag of the document
        !          1774:  *
        !          1775:  */
        !          1776: void OutlineDoc_SetModified(LPOUTLINEDOC lpOutlineDoc, BOOL fModified, BOOL fDataChanged, BOOL fSizeChanged)
        !          1777: {
        !          1778:     lpOutlineDoc->m_fModified = fModified;
        !          1779: 
        !          1780: #if defined( OLE_VERSION )
        !          1781:     if (! lpOutlineDoc->m_fDataTransferDoc) {
        !          1782:         LPOLEDOC    lpOleDoc = (LPOLEDOC)lpOutlineDoc;
        !          1783:         LPOUTLINEAPP lpOutlineApp = (LPOUTLINEAPP)g_lpApp;
        !          1784:         LPOLEDOC    lpClipboardDoc = (LPOLEDOC)lpOutlineApp->m_lpClipboardDoc;
        !          1785: #if defined( OLE_SERVER )
        !          1786:         LPSERVERDOC lpServerDoc = (LPSERVERDOC)lpOutlineDoc;
        !          1787: 
        !          1788:         /* OLE2NOTE: if the document has changed, then broadcast the change
        !          1789:         **    to all clients who have set up Advise connections. notify
        !          1790:         **    them that our data (and possibly also our extents) have
        !          1791:         **    changed.
        !          1792:         */
        !          1793:         if (fDataChanged) {
        !          1794:             lpServerDoc->m_fDataChanged     = TRUE;
        !          1795:             lpServerDoc->m_fSizeChanged     = fSizeChanged;
        !          1796:             lpServerDoc->m_fSendDataOnStop  = TRUE;
        !          1797: 
        !          1798:             ServerDoc_SendAdvise(
        !          1799:                     lpServerDoc, 
        !          1800:                     OLE_ONDATACHANGE, 
        !          1801:                     NULL,   /* lpmkDoc -- not relevant here */
        !          1802:                     0       /* advf -- no flags necessary */
        !          1803:             );
        !          1804:         }
        !          1805: #endif  // OLE_SERVER
        !          1806: 
        !          1807:         /* OLE2NOTE: if the document that is the source of data on the
        !          1808:         **    clipborad has been edited, then the copied data is no
        !          1809:         **    longer considered a valid potential link source. disable
        !          1810:         **    the offering of CF_LINKSOURCE from the clipboard
        !          1811:         **    document. this avoids problems that arise when the
        !          1812:         **    editing operation changes or deletes the original data
        !          1813:         **    copied. 
        !          1814:         */
        !          1815:         if (lpClipboardDoc 
        !          1816:             && fDataChanged     // line data has changed
        !          1817:             && lpClipboardDoc->m_lpSrcDocOfCopy == (LPOLEDOC)lpOutlineDoc) {
        !          1818:             lpClipboardDoc->m_fLinkSourceAvail = FALSE;
        !          1819: 
        !          1820:             /* OLE2NOTE: since we are changing the list of formats on
        !          1821:             **    the clipboard (ie. removing CF_LINKSOURCE), we must
        !          1822:             **    call OleSetClipboard again. to be sure that the
        !          1823:             **    clipboard datatransfer document object does not get
        !          1824:             **    destroyed we will guard the call to OleSetClipboard
        !          1825:             **    within a pair of AddRef/Release.
        !          1826:             */
        !          1827:             OleDoc_AddRef((LPOLEDOC)lpClipboardDoc);    // guard obj life-time
        !          1828: 
        !          1829:             OLEDBG_BEGIN2("OleSetClipboard called\r\n")
        !          1830:             OleSetClipboard(
        !          1831:                     (LPDATAOBJECT)&((LPOLEDOC)lpClipboardDoc)->m_DataObject);
        !          1832:             OLEDBG_END2
        !          1833: 
        !          1834:             OleDoc_Release((LPOLEDOC)lpClipboardDoc);    // rel. AddRef above
        !          1835:         }
        !          1836:     }
        !          1837: #endif  // OLE_VERSION
        !          1838: }
        !          1839: 
        !          1840: 
        !          1841: /* OutlineDoc_SetRedraw
        !          1842:  * --------------------
        !          1843:  *
        !          1844:  *  Enable/Disable the redraw of the document on screen.
        !          1845:  *  The calls to SetRedraw counted so that nested calls can be handled 
        !          1846:  *  properly. calls to SetRedraw must be balanced.
        !          1847:  *
        !          1848:  *  fEnbaleDraw = TRUE      - enable redraw
        !          1849:  *                FALSE     - disable redraw
        !          1850:  */
        !          1851: void OutlineDoc_SetRedraw(LPOUTLINEDOC lpOutlineDoc, BOOL fEnableDraw)
        !          1852: {
        !          1853:     static HCURSOR hPrevCursor = NULL;
        !          1854: 
        !          1855:     if (fEnableDraw) {
        !          1856:         if (lpOutlineDoc->m_nDisableDraw == 0)
        !          1857:             return;     // already enabled; no state transition
        !          1858: 
        !          1859:         if (--lpOutlineDoc->m_nDisableDraw > 0) 
        !          1860:             return;     // drawing should still be disabled
        !          1861:     } else {
        !          1862:         if (lpOutlineDoc->m_nDisableDraw++ > 0)
        !          1863:             return;     // already disabled; no state transition
        !          1864:     }
        !          1865: 
        !          1866:     if (lpOutlineDoc->m_nDisableDraw > 0) {
        !          1867:         // this may take a while, put up hourglass cursor
        !          1868:         hPrevCursor = SetCursor(LoadCursor(NULL, IDC_WAIT));
        !          1869:     } else {
        !          1870:         if (hPrevCursor) {
        !          1871:             SetCursor(hPrevCursor);     // restore original cursor
        !          1872:             hPrevCursor = NULL;
        !          1873:         }
        !          1874:     }
        !          1875: 
        !          1876: #if defined( OLE_SERVER )
        !          1877:     /* OLE2NOTE: for the Server version, while Redraw is disabled
        !          1878:     **    postpone sending advise notifications until Redraw is re-enabled.
        !          1879:     */
        !          1880:     {
        !          1881:         LPSERVERDOC lpServerDoc = (LPSERVERDOC)lpOutlineDoc;
        !          1882:         LPSERVERNAMETABLE lpServerNameTable =
        !          1883:                 (LPSERVERNAMETABLE)lpOutlineDoc->m_lpNameTable;
        !          1884: 
        !          1885:         if (lpOutlineDoc->m_nDisableDraw == 0) {
        !          1886:             /* drawing is being Enabled. if changes occurred while drawing
        !          1887:             **    was disabled, then notify clients now.
        !          1888:             */
        !          1889:             if (lpServerDoc->m_fDataChanged)
        !          1890:                 ServerDoc_SendAdvise(
        !          1891:                         lpServerDoc, 
        !          1892:                         OLE_ONDATACHANGE, 
        !          1893:                         NULL,   /* lpmkDoc -- not relevant here */
        !          1894:                         0       /* advf -- no flags necessary */
        !          1895:                 );
        !          1896: 
        !          1897:             /* OLE2NOTE: send pending change notifications for pseudo objs. */
        !          1898:             ServerNameTable_SendPendingAdvises(lpServerNameTable);
        !          1899: 
        !          1900:         } 
        !          1901:     }
        !          1902: #endif      // OLE_SERVER
        !          1903: 
        !          1904: #if defined( OLE_CNTR )
        !          1905:     /* OLE2NOTE: for the Container version, while Redraw is disabled
        !          1906:     **    postpone updating the extents of OLE objects until Redraw is
        !          1907:     **    re-enabled. 
        !          1908:     */
        !          1909:     {
        !          1910:         LPCONTAINERDOC lpContainerDoc = (LPCONTAINERDOC)lpOutlineDoc;
        !          1911: 
        !          1912:         /* Update the extents of any OLE object that is marked that
        !          1913:         **    its size may  have changed. when an
        !          1914:         **    IAdviseSink::OnViewChange notification is received,
        !          1915:         **    the corresponding ContainerLine is marked
        !          1916:         **    (m_fDoGetExtent==TRUE) and a message
        !          1917:         **    (WM_U_UPDATEOBJECTEXTENT) is posted to the document
        !          1918:         **    indicating that there are dirty objects.  
        !          1919:         */
        !          1920:         if (lpOutlineDoc->m_nDisableDraw == 0) 
        !          1921:             ContainerDoc_UpdateExtentOfAllOleObjects(lpContainerDoc);
        !          1922:     }
        !          1923: #endif      // OLE_CNTR
        !          1924: 
        !          1925:     // enable/disable redraw of the LineList listbox
        !          1926:     LineList_SetRedraw(&lpOutlineDoc->m_LineList, fEnableDraw);
        !          1927: }
        !          1928: 
        !          1929: 
        !          1930: /* OutlineDoc_SetSel
        !          1931:  * -----------------
        !          1932:  *
        !          1933:  *      Set the selection in the documents's LineList
        !          1934:  */
        !          1935: void OutlineDoc_SetSel(LPOUTLINEDOC lpOutlineDoc, LPLINERANGE lplrSel)
        !          1936: {
        !          1937:     LineList_SetSel(&lpOutlineDoc->m_LineList, lplrSel);
        !          1938: }
        !          1939: 
        !          1940: 
        !          1941: /* OutlineDoc_GetSel
        !          1942:  * -----------------
        !          1943:  *
        !          1944:  *      Get the selection in the documents's LineList.
        !          1945:  *
        !          1946:  *      Returns the count of items selected
        !          1947:  */
        !          1948: int OutlineDoc_GetSel(LPOUTLINEDOC lpOutlineDoc, LPLINERANGE lplrSel)
        !          1949: {
        !          1950:     return LineList_GetSel(&lpOutlineDoc->m_LineList, lplrSel);
        !          1951: }
        !          1952: 
        !          1953: 
        !          1954: /* OutlineDoc_ForceRedraw
        !          1955:  * ----------------------
        !          1956:  *
        !          1957:  *      Force the document window to repaint.
        !          1958:  */
        !          1959: void OutlineDoc_ForceRedraw(LPOUTLINEDOC lpOutlineDoc, BOOL fErase)
        !          1960: {
        !          1961:     if (!lpOutlineDoc)
        !          1962:         return;
        !          1963: 
        !          1964:     LineList_ForceRedraw(&lpOutlineDoc->m_LineList, fErase);
        !          1965:     Heading_CH_ForceRedraw(&lpOutlineDoc->m_heading, fErase);
        !          1966:     Heading_RH_ForceRedraw(&lpOutlineDoc->m_heading, fErase);
        !          1967: }
        !          1968: 
        !          1969: 
        !          1970: /* OutlineDoc_RenderFormat
        !          1971:  * -----------------------
        !          1972:  *
        !          1973:  *      Render a clipboard format supported by ClipboardDoc
        !          1974:  */
        !          1975: void OutlineDoc_RenderFormat(LPOUTLINEDOC lpOutlineDoc, UINT uFormat)
        !          1976: {
        !          1977:     HGLOBAL      hData = NULL;
        !          1978: 
        !          1979:     if (uFormat == g_lpApp->m_cfOutline) 
        !          1980:         hData = OutlineDoc_GetOutlineData(lpOutlineDoc, NULL);
        !          1981: 
        !          1982:     else if (uFormat == CF_TEXT)
        !          1983:         hData = OutlineDoc_GetTextData(lpOutlineDoc, NULL);
        !          1984: 
        !          1985:     else {
        !          1986:         OutlineApp_ErrorMessage(g_lpApp, ErrMsgFormatNotSupported);
        !          1987:         return;
        !          1988:     }
        !          1989: 
        !          1990:     SetClipboardData(uFormat, hData);
        !          1991: }
        !          1992: 
        !          1993: 
        !          1994: /* OutlineDoc_RenderAllFormats
        !          1995:  * ---------------------------
        !          1996:  *
        !          1997:  *      Render all formats supported by ClipboardDoc
        !          1998:  */
        !          1999: void OutlineDoc_RenderAllFormats(LPOUTLINEDOC lpOutlineDoc)
        !          2000: {
        !          2001:     HGLOBAL      hData = NULL;
        !          2002: 
        !          2003:     OpenClipboard(lpOutlineDoc->m_hWndDoc);
        !          2004: 
        !          2005:     hData = OutlineDoc_GetOutlineData(lpOutlineDoc, NULL);
        !          2006:     SetClipboardData(g_lpApp->m_cfOutline, hData);
        !          2007: 
        !          2008:     hData = OutlineDoc_GetTextData(lpOutlineDoc, NULL);
        !          2009:     SetClipboardData(CF_TEXT, hData);
        !          2010: 
        !          2011:     CloseClipboard();
        !          2012: }
        !          2013: 
        !          2014: 
        !          2015: 
        !          2016: /* OutlineDoc_GetOutlineData
        !          2017:  * -------------------------
        !          2018:  *
        !          2019:  * Return a handle to an array of TextLine objects for the desired line
        !          2020:  *      range.
        !          2021:  *  NOTE: if lplrSel == NULL, then all lines are returned
        !          2022:  *
        !          2023:  */
        !          2024: HGLOBAL OutlineDoc_GetOutlineData(LPOUTLINEDOC lpOutlineDoc, LPLINERANGE lplrSel)
        !          2025: {
        !          2026:     HGLOBAL     hOutline  = NULL;
        !          2027:     LPLINELIST  lpLL=(LPLINELIST)&lpOutlineDoc->m_LineList;
        !          2028:     LPLINE      lpLine;
        !          2029:     LPTEXTLINE  arrLine;
        !          2030:     int     i;
        !          2031:     int     nStart = (lplrSel ? lplrSel->m_nStartLine : 0);
        !          2032:     int     nEnd =(lplrSel ? lplrSel->m_nEndLine : LineList_GetCount(lpLL)-1);
        !          2033:     int     nLines = nEnd - nStart + 1;
        !          2034:     int     nCopied = 0;
        !          2035: 
        !          2036:     hOutline=GlobalAlloc(GMEM_SHARE | GMEM_ZEROINIT,sizeof(TEXTLINE)*nLines);
        !          2037: 
        !          2038:     if (! hOutline) return NULL;
        !          2039: 
        !          2040:     arrLine=(LPTEXTLINE)GlobalLock(hOutline);
        !          2041: 
        !          2042:     for (i = nStart; i <= nEnd; i++) {
        !          2043:         lpLine=LineList_GetLine(lpLL, i);
        !          2044:         if (Line_GetOutlineData(lpLine, &arrLine[nCopied]))
        !          2045:             nCopied++;
        !          2046:     }
        !          2047: 
        !          2048:     GlobalUnlock(hOutline);
        !          2049: 
        !          2050:     return hOutline;
        !          2051: }
        !          2052: 
        !          2053: 
        !          2054: 
        !          2055: /* OutlineDoc_GetTextData
        !          2056:  * ----------------------
        !          2057:  *
        !          2058:  * Return a handle to an object's data in text form for the desired line
        !          2059:  *      range.
        !          2060:  *  NOTE: if lplrSel == NULL, then all lines are returned
        !          2061:  *
        !          2062:  */
        !          2063: HGLOBAL OutlineDoc_GetTextData(LPOUTLINEDOC lpOutlineDoc, LPLINERANGE lplrSel)
        !          2064: {
        !          2065:     LPLINELIST  lpLL=(LPLINELIST)&lpOutlineDoc->m_LineList;
        !          2066:     LPLINE  lpLine;
        !          2067:     HGLOBAL hText = NULL;
        !          2068:     LPSTR   lpszText = NULL;
        !          2069:     DWORD   dwMemSize=0;
        !          2070:     int     i,j;
        !          2071:     int     nStart = (lplrSel ? lplrSel->m_nStartLine : 0);
        !          2072:     int     nEnd =(lplrSel ? lplrSel->m_nEndLine : LineList_GetCount(lpLL)-1);
        !          2073:     int     nTabLevel;
        !          2074: 
        !          2075:     // calculate memory size required
        !          2076:     for(i = nStart; i <= nEnd; i++) {
        !          2077:         lpLine=LineList_GetLine(lpLL, i);
        !          2078: 
        !          2079:         dwMemSize += Line_GetTabLevel(lpLine);
        !          2080:         dwMemSize += Line_GetTextLen(lpLine);
        !          2081: 
        !          2082:         dwMemSize += 2; // add 1 for '\r\n' at the end of each line
        !          2083:     }
        !          2084:     dwMemSize++;        // add 1 for '\0' at the end of string
        !          2085: 
        !          2086:     if(!(hText = GlobalAlloc(GMEM_SHARE | GMEM_ZEROINIT, dwMemSize)))
        !          2087:         return NULL;
        !          2088: 
        !          2089:     if(!(lpszText = (LPSTR)GlobalLock(hText)))
        !          2090:         return NULL;
        !          2091: 
        !          2092:     // put line text to memory
        !          2093:     for(i = nStart; i <= nEnd; i++) {
        !          2094:         lpLine=LineList_GetLine(lpLL, i);
        !          2095: 
        !          2096:         nTabLevel=Line_GetTabLevel(lpLine);
        !          2097:         for(j = 0; j < nTabLevel; j++)
        !          2098:             *lpszText++='\t';
        !          2099: 
        !          2100:         Line_GetTextData(lpLine, lpszText);
        !          2101:         while(*lpszText)
        !          2102:             lpszText++;     // advance to end of string
        !          2103: 
        !          2104:         *lpszText++ = '\r';
        !          2105:         *lpszText++ = '\n';
        !          2106:     }
        !          2107: 
        !          2108:     GlobalUnlock (hText);
        !          2109: 
        !          2110:     return hText;
        !          2111: }
        !          2112: 
        !          2113: 
        !          2114: /* OutlineDoc_SaveToFile
        !          2115:  * ---------------------
        !          2116:  *
        !          2117:  *      Save the document to a file with the same name as stored in the
        !          2118:  * document
        !          2119:  */
        !          2120: BOOL OutlineDoc_SaveToFile(LPOUTLINEDOC lpOutlineDoc, LPCSTR lpszFileName, UINT uFormat, BOOL fRemember)
        !          2121: {
        !          2122: #if defined( OLE_CNTR )
        !          2123:     // Call OLE container specific function instead
        !          2124:     return ContainerDoc_SaveToFile(
        !          2125:             (LPCONTAINERDOC)lpOutlineDoc,
        !          2126:             lpszFileName,
        !          2127:             uFormat,
        !          2128:             fRemember
        !          2129:     );
        !          2130: 
        !          2131: #else
        !          2132: 
        !          2133:     LPSTORAGE lpDestStg = NULL;
        !          2134:     HRESULT hrErr;
        !          2135:     BOOL fStatus;
        !          2136: 
        !          2137:     if (fRemember) {
        !          2138:         if (lpszFileName) {
        !          2139:             fStatus = OutlineDoc_SetFileName(
        !          2140:                     lpOutlineDoc,
        !          2141:                     (LPSTR)lpszFileName,
        !          2142:                     NULL
        !          2143:             );
        !          2144:             if (! fStatus) goto error;
        !          2145:         } else 
        !          2146:             lpszFileName = lpOutlineDoc->m_szFileName; // use cur. file name
        !          2147:     } else if (! lpszFileName) {
        !          2148:         goto error;
        !          2149:     }
        !          2150:                                    
        !          2151:     hrErr = StgCreateDocfile(
        !          2152:             lpszFileName,
        !          2153:             STGM_READWRITE|STGM_DIRECT|STGM_SHARE_EXCLUSIVE|STGM_CREATE,
        !          2154:             0,
        !          2155:             &lpDestStg
        !          2156:     );
        !          2157:                          
        !          2158:     if (! OleDbgVerifySz(hrErr == NOERROR, "Could not create Docfile")) 
        !          2159:         goto error;
        !          2160: 
        !          2161: #if defined( OLE_SERVER )
        !          2162: 
        !          2163:     /*  OLE2NOTE: we must be sure to write our class ID into our
        !          2164:     **    storage. this information is used by OLE to determine the
        !          2165:     **    class of the data stored in our storage. Even for top
        !          2166:     **    "file-level" objects this information should be written to
        !          2167:     **    the file.  
        !          2168:     */
        !          2169:     if(WriteClassStg(lpDestStg, &CLSID_APP) != NOERROR) 
        !          2170:         goto error;
        !          2171: #endif 
        !          2172: 
        !          2173:     fStatus = OutlineDoc_SaveSelToStg(
        !          2174:             lpOutlineDoc,
        !          2175:             NULL,
        !          2176:             uFormat,
        !          2177:             lpDestStg,
        !          2178:             fRemember
        !          2179:     );
        !          2180:     if (! fStatus) goto error;
        !          2181: 
        !          2182:     OleStdRelease((LPUNKNOWN)lpDestStg);
        !          2183: 
        !          2184:     if (fRemember)
        !          2185:         OutlineDoc_SetModified(lpOutlineDoc, FALSE, FALSE, FALSE);
        !          2186: 
        !          2187: #if defined( OLE_SERVER )
        !          2188: 
        !          2189:     /* OLE2NOTE: (SERVER-ONLY) inform any linking clients that the
        !          2190:     **    document has been saved. in addition, any currently active
        !          2191:     **    pseudo objects should also inform their clients.
        !          2192:     */
        !          2193:     ServerDoc_SendAdvise (
        !          2194:             (LPSERVERDOC)lpOutlineDoc, 
        !          2195:             OLE_ONSAVE, 
        !          2196:             NULL,   /* lpmkDoc -- not relevant here */
        !          2197:             0       /* advf -- not relevant here */
        !          2198:     );
        !          2199: 
        !          2200: #endif 
        !          2201: 
        !          2202:     return TRUE;
        !          2203: 
        !          2204: error:
        !          2205:     if (lpDestStg)
        !          2206:         OleStdRelease((LPUNKNOWN)lpDestStg);
        !          2207: 
        !          2208:     OutlineApp_ErrorMessage(g_lpApp, ErrMsgSaving);
        !          2209:     return FALSE;
        !          2210: 
        !          2211: #endif  // ! OLE_CNTR
        !          2212: }
        !          2213: 
        !          2214: 
        !          2215: /* OutlineDoc_LoadFromFile
        !          2216:  * -----------------------
        !          2217:  *
        !          2218:  *      Load a document from a file
        !          2219:  */
        !          2220: BOOL OutlineDoc_LoadFromFile(LPOUTLINEDOC lpOutlineDoc, LPSTR lpszFileName)
        !          2221: {
        !          2222:     LPOUTLINEAPP    lpOutlineApp = (LPOUTLINEAPP)g_lpApp;
        !          2223:     LPLINELIST      lpLL = &lpOutlineDoc->m_LineList;
        !          2224:     HRESULT         hrErr;
        !          2225:     SCODE           sc;
        !          2226:     LPSTORAGE       lpSrcStg;
        !          2227:     BOOL            fStatus;
        !          2228: 
        !          2229:     hrErr = StgOpenStorage(lpszFileName,
        !          2230:             NULL,
        !          2231: #if defined( OLE_CNTR )
        !          2232:             STGM_READWRITE | STGM_TRANSACTED | STGM_SHARE_DENY_WRITE,
        !          2233: #else
        !          2234:             STGM_READ | STGM_SHARE_DENY_WRITE,
        !          2235: #endif
        !          2236:             NULL,
        !          2237:             0,
        !          2238:             &lpSrcStg
        !          2239:     );
        !          2240: 
        !          2241:     if ((sc = GetScode(hrErr)) == STG_E_FILENOTFOUND) {
        !          2242:         OutlineApp_ErrorMessage(lpOutlineApp, "File not found");
        !          2243:         return FALSE;
        !          2244:     } else if (sc == STG_E_FILEALREADYEXISTS) {
        !          2245:         OutlineApp_ErrorMessage(lpOutlineApp, ErrMsgFormat);
        !          2246:         return FALSE;
        !          2247:     } else if (sc != S_OK) {
        !          2248:         OleDbgOutScode("StgOpenStorage returned", sc);
        !          2249:         OutlineApp_ErrorMessage(
        !          2250:                 lpOutlineApp, 
        !          2251:                 "File already in use--could not be opened"
        !          2252:         );
        !          2253:         return FALSE;
        !          2254:     }
        !          2255: 
        !          2256:     if(! OutlineDoc_LoadFromStg(lpOutlineDoc, lpSrcStg)) goto error;
        !          2257: 
        !          2258:     fStatus = OutlineDoc_SetFileName(lpOutlineDoc, lpszFileName, lpSrcStg);
        !          2259:     if (! fStatus) goto error;
        !          2260: 
        !          2261:     OutlineDoc_ForceRedraw(lpOutlineDoc, TRUE);
        !          2262: 
        !          2263:     OleStdRelease((LPUNKNOWN)lpSrcStg);
        !          2264:        
        !          2265:        
        !          2266:     return TRUE;
        !          2267: 
        !          2268: error:
        !          2269:     OleStdRelease((LPUNKNOWN)lpSrcStg);
        !          2270:     OutlineApp_ErrorMessage(lpOutlineApp, ErrMsgOpening);
        !          2271:     // REVIEW: is this the proper error handling here?
        !          2272:     return FALSE;
        !          2273: }
        !          2274: 
        !          2275: 
        !          2276: 
        !          2277: /* OutlineDoc_LoadFromStg
        !          2278:  * ----------------------
        !          2279:  *
        !          2280:  *  Load entire document from an open IStorage pointer (lpSrcStg)
        !          2281:  *      Return TRUE if ok, FALSE if error.
        !          2282:  */
        !          2283: BOOL OutlineDoc_LoadFromStg(LPOUTLINEDOC lpOutlineDoc, LPSTORAGE lpSrcStg)
        !          2284: {
        !          2285:     HRESULT hrErr;
        !          2286:     BOOL fStatus;
        !          2287:     ULONG nRead;
        !          2288:     LINERANGE lrSel = { 0, 0 };
        !          2289:     LPSTREAM lpLLStm;
        !          2290:     OUTLINEDOCHEADER docRecord;
        !          2291: 
        !          2292:     hrErr = lpSrcStg->lpVtbl->OpenStream(
        !          2293:             lpSrcStg,
        !          2294:             "LineList",
        !          2295:             NULL,
        !          2296:             STGM_READ | STGM_SHARE_EXCLUSIVE,
        !          2297:             0,
        !          2298:             &lpLLStm
        !          2299:     );
        !          2300: 
        !          2301:     if (! OleDbgVerifySz(hrErr == NOERROR,"Could not open LineList stream")) {
        !          2302:         OleDbgOutHResult("Open LineList Stream returned", hrErr);
        !          2303:         goto error;
        !          2304:     }
        !          2305: 
        !          2306:     /* read OutlineDoc header record */
        !          2307:     hrErr = lpLLStm->lpVtbl->Read(
        !          2308:             lpLLStm,
        !          2309:             (LPVOID)&docRecord,
        !          2310:             sizeof(OUTLINEDOCHEADER),
        !          2311:             &nRead
        !          2312:     );
        !          2313:     
        !          2314:     if (! OleDbgVerifySz(hrErr == NOERROR, 
        !          2315:                     "Could not read LineList header from LineList stream")) 
        !          2316:         goto error;
        !          2317: 
        !          2318:     fStatus = OutlineApp_VersionNoCheck(
        !          2319:             g_lpApp,
        !          2320:             docRecord.m_szFormatName,
        !          2321:             docRecord.m_narrAppVersionNo
        !          2322:     );
        !          2323: 
        !          2324:     /* storage is an incompatible version; file can not be read */
        !          2325:     if (! fStatus) 
        !          2326:         goto error;
        !          2327: 
        !          2328:     lpOutlineDoc->m_heading.m_fShow = docRecord.m_fShowHeading;
        !          2329: 
        !          2330: #if defined( OLE_SERVER )
        !          2331:     {
        !          2332:         // Load ServerDoc specific data
        !          2333:         LPSERVERDOC lpServerDoc = (LPSERVERDOC)lpOutlineDoc;
        !          2334: #if defined( SVR_TREATAS )
        !          2335:         LPOUTLINEAPP lpOutlineApp = (LPOUTLINEAPP)g_lpApp;
        !          2336:         CLSID       clsid;
        !          2337:         CLIPFORMAT  cfFmt;
        !          2338:         LPSTR       lpszType;
        !          2339: #endif  // SVR_TREATAS
        !          2340: 
        !          2341:         lpServerDoc->m_nNextRangeNo = (ULONG)docRecord.m_reserved1;
        !          2342: 
        !          2343: #if defined( SVR_TREATAS )
        !          2344:         /* OLE2NOTE: if the Server is capable of supporting "TreatAs"
        !          2345:         **    (aka. ActivateAs), it must read the class that is written
        !          2346:         **    into the storage. if this class is NOT the app's own
        !          2347:         **    class ID, then this is a TreatAs operation. the server
        !          2348:         **    then must faithfully pretend to be the class that is
        !          2349:         **    written into the storage. it must also faithfully write
        !          2350:         **    the data back to the storage in the SAME format as is
        !          2351:         **    written in the storage.
        !          2352:         **    
        !          2353:         **    SVROUTL and ISVROTL can emulate each other. they have the
        !          2354:         **    simplification that they both read/write the identical
        !          2355:         **    format. thus for these apps no actual conversion of the
        !          2356:         **    native bits is actually required.
        !          2357:         */
        !          2358:         lpServerDoc->m_clsidTreatAs = CLSID_NULL;
        !          2359:         if (OleStdGetTreatAsFmtUserType(&CLSID_APP, lpSrcStg, &clsid,
        !          2360:                             (CLIPFORMAT FAR*)&cfFmt, (LPSTR FAR*)&lpszType)) {
        !          2361:                             
        !          2362:             if (cfFmt == lpOutlineApp->m_cfOutline) {
        !          2363:                 // We should perform TreatAs operation
        !          2364:                 if (lpServerDoc->m_lpszTreatAsType) 
        !          2365:                     OleStdFreeString(lpServerDoc->m_lpszTreatAsType, NULL);
        !          2366: 
        !          2367:                 lpServerDoc->m_clsidTreatAs = clsid;
        !          2368:                 ((LPOUTLINEDOC)lpServerDoc)->m_cfSaveFormat = cfFmt; 
        !          2369:                 lpServerDoc->m_lpszTreatAsType = lpszType;
        !          2370: 
        !          2371:                 OleDbgOut3("OutlineDoc_LoadFromStg: TreateAs ==> '");
        !          2372:                 OleDbgOutNoPrefix3(lpServerDoc->m_lpszTreatAsType);
        !          2373:                 OleDbgOutNoPrefix3("'\r\n");
        !          2374:             } else {
        !          2375:                 // ERROR: we ONLY support TreatAs for CF_OUTLINE format
        !          2376:                 OleDbgOut("SvrDoc_PStg_InitNew: INVALID TreatAs Format\r\n");
        !          2377:                 OleStdFreeString(lpszType, NULL);
        !          2378:             }
        !          2379:         }
        !          2380: #endif  // SVR_TREATAS
        !          2381:     }
        !          2382: #elif defined( OLE_CNTR )
        !          2383:     {
        !          2384:         // Load ContainerDoc specific data
        !          2385:         LPCONTAINERDOC lpContainerDoc = (LPCONTAINERDOC)lpOutlineDoc;
        !          2386: 
        !          2387:         lpContainerDoc->m_nNextObjNo = (ULONG)docRecord.m_reserved2;
        !          2388:     }
        !          2389: #endif
        !          2390: 
        !          2391:     OutlineDoc_SetRedraw ( lpOutlineDoc, FALSE );
        !          2392: 
        !          2393:     if(! LineList_LoadFromStg(&lpOutlineDoc->m_LineList, lpSrcStg, lpLLStm))
        !          2394:         goto error;
        !          2395:     if(! OutlineNameTable_LoadFromStg(lpOutlineDoc->m_lpNameTable, lpSrcStg))
        !          2396:         goto error;
        !          2397: 
        !          2398:     OutlineDoc_SetModified(lpOutlineDoc, FALSE, FALSE, FALSE);
        !          2399:     OutlineDoc_SetSel(lpOutlineDoc, &lrSel);
        !          2400: 
        !          2401:     OutlineDoc_SetRedraw ( lpOutlineDoc, TRUE );
        !          2402: 
        !          2403:     OleStdRelease((LPUNKNOWN)lpLLStm);
        !          2404: 
        !          2405: #if defined( OLE_CNTR )
        !          2406:     {
        !          2407:         LPCONTAINERDOC lpContainerDoc = (LPCONTAINERDOC)lpOutlineDoc;
        !          2408: 
        !          2409:         /* A ContainerDoc keeps its storage open at all times. it is necessary
        !          2410:         *   to AddRef the lpSrcStg in order to hang on to it.
        !          2411:         */
        !          2412:         if (lpContainerDoc->m_lpStg) {
        !          2413:             OleStdVerifyRelease((LPUNKNOWN)lpContainerDoc->m_lpStg,
        !          2414:                     "Doc Storage not released properly");
        !          2415:         }
        !          2416:         lpSrcStg->lpVtbl->AddRef(lpSrcStg);
        !          2417:         lpContainerDoc->m_lpStg = lpSrcStg;
        !          2418:     }
        !          2419: #endif      // OLE_CNTR
        !          2420: 
        !          2421:     return TRUE;
        !          2422: 
        !          2423: error:
        !          2424:     OutlineDoc_SetRedraw ( lpOutlineDoc, TRUE );
        !          2425:     if (lpLLStm)
        !          2426:         OleStdRelease((LPUNKNOWN)lpLLStm);
        !          2427:     return FALSE;
        !          2428: }
        !          2429: 
        !          2430: 
        !          2431: /* OutlineDoc_SaveSelToStg
        !          2432:  * -----------------------
        !          2433:  *
        !          2434:  *      Save the specified selection of document into file. All lines
        !          2435:  * within the selection along with any names completely contained within the
        !          2436:  * selection will be written
        !          2437:  *
        !          2438:  *      Return TRUE if ok, FALSE if error
        !          2439:  */
        !          2440: BOOL OutlineDoc_SaveSelToStg(LPOUTLINEDOC lpOutlineDoc, LPLINERANGE lplrSel, UINT uFormat, LPSTORAGE lpDestStg, BOOL fRemember)
        !          2441: {
        !          2442:     HRESULT hrErr = NOERROR;
        !          2443:     LPSTREAM lpLLStm = NULL;
        !          2444:     ULONG nWritten;
        !          2445:     BOOL fStatus;
        !          2446:     OUTLINEDOCHEADER docRecord;
        !          2447:     HCURSOR  hPrevCursor;      
        !          2448: 
        !          2449: #if defined( OLE_VERSION )
        !          2450:     LPSTR lpszUserType;
        !          2451: 
        !          2452:     /*  OLE2NOTE: we must be sure to write the information required for
        !          2453:     **    OLE into our docfile. this includes user type
        !          2454:     **    name, data format, etc. Even for top "file-level" objects
        !          2455:     **    this information should be written to the file. Both
        !          2456:     **    containters and servers should write this information.
        !          2457:     */
        !          2458: 
        !          2459: #if defined( OLE_SERVER ) && defined( SVR_TREATAS )
        !          2460:     LPSERVERDOC lpServerDoc = (LPSERVERDOC)lpOutlineDoc;
        !          2461: 
        !          2462:     /* OLE2NOTE: if the Server is emulating another class (ie.
        !          2463:     **    "TreatAs" aka. ActivateAs), it must write the same user type
        !          2464:     **    name and format that was was originally written into the
        !          2465:     **    storage rather than its own user type name.
        !          2466:     **    
        !          2467:     **    SVROUTL and ISVROTL can emulate each other. they have the
        !          2468:     **    simplification that they both read/write the identical
        !          2469:     **    format. thus for these apps no actual conversion of the
        !          2470:     **    native bits is actually required.
        !          2471:     */
        !          2472:     if (! IsEqualCLSID(&lpServerDoc->m_clsidTreatAs, &CLSID_NULL))
        !          2473:         lpszUserType = lpServerDoc->m_lpszTreatAsType;
        !          2474:     else
        !          2475: #endif
        !          2476:         lpszUserType = (LPSTR)FULLUSERTYPENAME;
        !          2477:     
        !          2478: 
        !          2479:     hrErr = WriteFmtUserTypeStg(
        !          2480:             lpDestStg, 
        !          2481:             uFormat,
        !          2482:             lpszUserType
        !          2483:     );
        !          2484:     if(hrErr != NOERROR) goto error;
        !          2485: #endif  // OLE_VERSION
        !          2486: 
        !          2487:     // this may take a while, put up hourglass cursor
        !          2488:     hPrevCursor = SetCursor(LoadCursor(NULL, IDC_WAIT));
        !          2489:     
        !          2490:     hrErr = lpDestStg->lpVtbl->CreateStream(
        !          2491:             lpDestStg,
        !          2492:             "LineList",
        !          2493:             STGM_WRITE | STGM_SHARE_EXCLUSIVE | STGM_CREATE,
        !          2494:             0,
        !          2495:             0,
        !          2496:             &lpLLStm
        !          2497:     );
        !          2498:     if (! OleDbgVerifySz(hrErr==NOERROR,"Could not create LineList stream")) 
        !          2499:         goto error;
        !          2500: 
        !          2501:     _fmemset((LPOUTLINEDOCHEADER)&docRecord,0,sizeof(OUTLINEDOCHEADER));
        !          2502:     GetClipboardFormatName(
        !          2503:             uFormat,
        !          2504:             docRecord.m_szFormatName,
        !          2505:             sizeof(docRecord.m_szFormatName)
        !          2506:     );
        !          2507:     OutlineApp_GetAppVersionNo(g_lpApp, docRecord.m_narrAppVersionNo);
        !          2508: 
        !          2509:     docRecord.m_fShowHeading = lpOutlineDoc->m_heading.m_fShow;
        !          2510: 
        !          2511: #if defined( OLE_SERVER )
        !          2512:     {
        !          2513:         // Store ServerDoc specific data
        !          2514:         LPSERVERDOC lpServerDoc = (LPSERVERDOC)lpOutlineDoc;
        !          2515: 
        !          2516:         docRecord.m_reserved1 = (DWORD)lpServerDoc->m_nNextRangeNo;
        !          2517:     }
        !          2518: #elif defined( OLE_CNTR )
        !          2519:     {
        !          2520:         // Store ContainerDoc specific data
        !          2521:         LPCONTAINERDOC lpContainerDoc = (LPCONTAINERDOC)lpOutlineDoc;
        !          2522: 
        !          2523:         docRecord.m_reserved2 = (DWORD)lpContainerDoc->m_nNextObjNo;
        !          2524:     }
        !          2525: #endif
        !          2526: 
        !          2527:     /* write OutlineDoc header record */
        !          2528:     hrErr = lpLLStm->lpVtbl->Write(
        !          2529:             lpLLStm,
        !          2530:             (LPVOID)&docRecord,
        !          2531:             sizeof(OUTLINEDOCHEADER),
        !          2532:             &nWritten
        !          2533:         );
        !          2534:     if (! OleDbgVerifySz(hrErr == NOERROR, 
        !          2535:                     "Could not write OutlineDoc header to LineList stream")) 
        !          2536:         goto error;
        !          2537: 
        !          2538:     // Save LineList
        !          2539:     /* OLE2NOTE: A ContainerDoc keeps its storage open at all times. It is
        !          2540:     **    necessary to pass the current open storage (lpContainerDoc->m_lpStg)
        !          2541:     **    to the LineList_SaveSelToStg method so that currently written data
        !          2542:     **    for any embeddings is also saved to the new destination
        !          2543:     **    storage. The data required by a contained object is both the
        !          2544:     **    ContainerLine information and the associated sub-storage that is
        !          2545:     **    written directly by the embedded object.
        !          2546:     */
        !          2547:     fStatus = LineList_SaveSelToStg(
        !          2548:         &lpOutlineDoc->m_LineList,
        !          2549:             lplrSel,
        !          2550:             uFormat,
        !          2551: #if defined( OLE_CNTR )
        !          2552:             ((LPCONTAINERDOC)lpOutlineDoc)->m_lpStg,
        !          2553: #else
        !          2554:             NULL,
        !          2555: #endif
        !          2556:             lpDestStg,
        !          2557:             lpLLStm,
        !          2558:             fRemember
        !          2559:     );
        !          2560:     if (! fStatus) goto error;
        !          2561: 
        !          2562:     // Save associated NameTable
        !          2563:     fStatus = OutlineNameTable_SaveSelToStg(
        !          2564:             lpOutlineDoc->m_lpNameTable,
        !          2565:             lplrSel,
        !          2566:             uFormat,
        !          2567:             lpDestStg
        !          2568:     );
        !          2569: 
        !          2570:     if (! fStatus) goto error;
        !          2571: 
        !          2572:     OleStdRelease((LPUNKNOWN)lpLLStm);
        !          2573:     lpOutlineDoc->m_cfSaveFormat = uFormat;  // remember format used to save
        !          2574: 
        !          2575:     SetCursor(hPrevCursor);     // restore original cursor
        !          2576:     return TRUE;
        !          2577: 
        !          2578: error:
        !          2579:     if (lpLLStm)
        !          2580:         OleStdRelease((LPUNKNOWN)lpLLStm);
        !          2581: 
        !          2582:     SetCursor(hPrevCursor);     // restore original cursor
        !          2583:     return FALSE;
        !          2584: }
        !          2585: 
        !          2586: 
        !          2587: /* OutlineDoc_Print
        !          2588:  * ----------------
        !          2589:  *  Prints the contents of the list box in HIMETRIC mapping mode. Origin
        !          2590:  *  remains to be the upper left corner and the print proceeds down the 
        !          2591:  *  page using a negative y-cordinate.
        !          2592:  *
        !          2593:  */
        !          2594: void OutlineDoc_Print(LPOUTLINEDOC lpOutlineDoc, HDC hDC)
        !          2595: {
        !          2596:     LPLINELIST lpLL = &lpOutlineDoc->m_LineList;
        !          2597:     LPOUTLINEAPP lpOutlineApp = (LPOUTLINEAPP)g_lpApp;
        !          2598:     WORD    nIndex;
        !          2599:     WORD    nTotal;
        !          2600:     int     dy;
        !          2601:     BOOL    fError = FALSE;
        !          2602:     LPLINE  lpLine;
        !          2603:     RECT    rcLine;
        !          2604:     RECT    rcPix;
        !          2605:     RECT    rcHim;
        !          2606:     RECT    rcWindowOld;
        !          2607:     RECT    rcViewportOld;
        !          2608:     HFONT   hOldFont;
        !          2609:     DOCINFO di;         /* Document information for StartDoc function */
        !          2610: 
        !          2611:     /* Get dimension of page */
        !          2612:     rcPix.left = 0;
        !          2613:     rcPix.top = 0;
        !          2614:     rcPix.right = GetDeviceCaps(hDC, HORZRES);
        !          2615:     rcPix.bottom = GetDeviceCaps(hDC, VERTRES);
        !          2616: 
        !          2617:     SetDCToDrawInHimetricRect(hDC, (LPRECT)&rcPix, (LPRECT)&rcHim,
        !          2618:             (LPRECT)&rcWindowOld, (LPRECT)&rcViewportOld);
        !          2619:     
        !          2620:     // Set the default font size, and font face name
        !          2621:     hOldFont = SelectObject(hDC, lpOutlineApp->m_hStdFont);
        !          2622: 
        !          2623:     /* Get the lines in document */
        !          2624:     nIndex     = 0;
        !          2625:     nTotal  = LineList_GetCount(lpLL);
        !          2626: 
        !          2627:     /* Create the Cancel dialog */
        !          2628:     // REVIEW: should load dialog title from string resource file
        !          2629:     hWndPDlg = CreateDialog (
        !          2630:             lpOutlineApp->m_hInst,
        !          2631:             "Print",
        !          2632:             lpOutlineApp->m_hWndApp,
        !          2633:             (DLGPROC)PrintDlgProc
        !          2634:     );
        !          2635:     
        !          2636:     if(!hWndPDlg)
        !          2637:         goto getout;
        !          2638: 
        !          2639:     /* Allow the app. to inform GDI of the abort function to call */
        !          2640:     if(SetAbortProc(hDC, (ABORTPROC)AbortProc) < 0) {
        !          2641:         fError = TRUE;
        !          2642:         goto getout3;
        !          2643:     }
        !          2644: 
        !          2645:     /* Disable the main application window */
        !          2646:     EnableWindow (lpOutlineApp->m_hWndApp, FALSE);
        !          2647:     
        !          2648:     // initialize the rectangle for the first line
        !          2649:     rcLine.left = rcHim.left;
        !          2650:     rcLine.bottom = rcHim.top;
        !          2651: 
        !          2652:     /* Initialize the document */
        !          2653:     fCancelPrint = FALSE;
        !          2654: 
        !          2655:     di.cbSize = sizeof(di);
        !          2656:     di.lpszDocName = lpOutlineDoc->m_lpszDocTitle;
        !          2657:     di.lpszOutput = NULL;
        !          2658:     
        !          2659:     if(StartDoc(hDC, (DOCINFO FAR*)&di) <= 0) {
        !          2660:         fError = TRUE;
        !          2661:         OleDbgOut2("StartDoc error\n");          
        !          2662:         goto getout5;
        !          2663:     }
        !          2664: 
        !          2665:     if(StartPage(hDC) <= 0) {       // start first page
        !          2666:         fError = TRUE;
        !          2667:         OleDbgOut2("StartPage error\n");          
        !          2668:         goto getout2;
        !          2669:     }
        !          2670: 
        !          2671:     /* While more lines print out the text */
        !          2672:     while(nIndex < nTotal) {
        !          2673:         lpLine = LineList_GetLine(lpLL, nIndex);
        !          2674:         dy = Line_GetHeightInHimetric(lpLine);
        !          2675: 
        !          2676:         /* Reached end of page. Tell the device driver to eject a page */
        !          2677:         if(rcLine.bottom - dy < rcHim.bottom) {
        !          2678:             if (EndPage(hDC) < 0) {
        !          2679:                 fError=TRUE;
        !          2680:                 OleDbgOut2("EndPage error\n");          
        !          2681:                 goto getout2;
        !          2682:             }
        !          2683:             
        !          2684:             // NOTE: Reset the Mapping mode of DC
        !          2685:             SetDCToDrawInHimetricRect(hDC, (LPRECT)&rcPix, (LPRECT)&rcHim,
        !          2686:                     (LPRECT)&rcWindowOld, (LPRECT)&rcViewportOld);
        !          2687:                     
        !          2688:             // Set the default font size, and font face name
        !          2689:             SelectObject(hDC, lpOutlineApp->m_hStdFont);
        !          2690: 
        !          2691:             if (StartPage(hDC) <= 0) {
        !          2692:                 fError=TRUE;
        !          2693:                 OleDbgOut2("StartPage error\n");          
        !          2694:                 goto getout2;
        !          2695:             }
        !          2696:                 
        !          2697:             rcLine.bottom = rcHim.top;
        !          2698:         }
        !          2699: 
        !          2700:         rcLine.top = rcLine.bottom;
        !          2701:         rcLine.bottom -= dy;
        !          2702:         rcLine.right = rcLine.left + Line_GetWidthInHimetric(lpLine);
        !          2703: 
        !          2704:         /* Print the line */
        !          2705:         Line_Draw(lpLine, hDC, &rcLine);
        !          2706: 
        !          2707:         OleDbgOut2("a line is drawn\n");
        !          2708: 
        !          2709:         /* Test and see if the Abort flag has been set. If yes, exit. */
        !          2710:         if (fCancelPrint)
        !          2711:             goto getout2;
        !          2712: 
        !          2713:         /* Move down the page */
        !          2714:         nIndex++;
        !          2715:     }
        !          2716: 
        !          2717:     {
        !          2718:         char szBuf[255];
        !          2719:         int nCode;
        !          2720: 
        !          2721:         /* Eject the last page. */
        !          2722:         if((nCode = EndPage(hDC)) < 0) {
        !          2723:             wsprintf(szBuf, "EndPage error code is %d\n", nCode);
        !          2724:             OleDbgOut2(szBuf);
        !          2725:             fError=TRUE;
        !          2726:             goto getout2;
        !          2727:         }
        !          2728:     }
        !          2729: 
        !          2730:     
        !          2731:     /* Complete the document. */
        !          2732:     if(EndDoc(hDC) < 0) {
        !          2733:         fError=TRUE;
        !          2734:         OleDbgOut2("EndDoc error\n");          
        !          2735: 
        !          2736: getout2:
        !          2737:         /* Ran into a problem before NEWFRAME? Abort the document */
        !          2738:         AbortDoc(hDC);
        !          2739:     }
        !          2740: 
        !          2741: getout5:    
        !          2742:     /* Re-enable main app. window */
        !          2743:     EnableWindow (lpOutlineApp->m_hWndApp, TRUE);
        !          2744: 
        !          2745: getout3:
        !          2746:     /* Close the cancel dialog */
        !          2747:     DestroyWindow (hWndPDlg);
        !          2748: 
        !          2749: getout:
        !          2750: 
        !          2751:     /* Error? make sure the user knows... */
        !          2752:     if(fError || CommDlgExtendedError())
        !          2753:         OutlineApp_ErrorMessage(lpOutlineApp, ErrMsgPrint);
        !          2754: 
        !          2755:     SelectObject(hDC, hOldFont);
        !          2756: }
        !          2757: 
        !          2758: 
        !          2759: 
        !          2760: 
        !          2761: 
        !          2762: /* OutlineDoc_DialogHelp
        !          2763:  * ---------------------
        !          2764:  *
        !          2765:  *  Show help message for ole2ui dialogs.
        !          2766:  *
        !          2767:  * Parameters:
        !          2768:  *
        !          2769:  *   hDlg      HWND to the dialog the help message came from - use
        !          2770:  *             this in the call to WinHelp/MessageBox so that 
        !          2771:  *             activation/focus goes back to the dialog, and not the
        !          2772:  *             main window.
        !          2773:  *
        !          2774:  *   wParam    ID of the dialog (so we know what type of dialog it is).
        !          2775:  */
        !          2776: void OutlineDoc_DialogHelp(HWND hDlg, 
        !          2777:                            WPARAM wDlgID)
        !          2778: {
        !          2779: 
        !          2780:    char szMessageBoxText[64];
        !          2781: 
        !          2782:    if (!IsWindow(hDlg))  // don't do anything if we've got a bogus hDlg.
        !          2783:      return;
        !          2784: 
        !          2785:    lstrcpy(szMessageBoxText, "Help Message for ");
        !          2786: 
        !          2787:    switch (wDlgID)
        !          2788:    {
        !          2789: 
        !          2790:     case IDD_CONVERT:
        !          2791:        lstrcat(szMessageBoxText, "Convert");
        !          2792:        break;
        !          2793: 
        !          2794:     case IDD_CHANGEICON:
        !          2795:        lstrcat(szMessageBoxText, "Change Icon");
        !          2796:        break;
        !          2797: 
        !          2798:     case IDD_INSERTOBJECT:
        !          2799:        lstrcat(szMessageBoxText, "Insert Object");
        !          2800:        break;
        !          2801: 
        !          2802:     case IDD_PASTESPECIAL:
        !          2803:        lstrcat(szMessageBoxText, "Paste Special");
        !          2804:        break;
        !          2805: 
        !          2806:     case IDD_EDITLINKS:
        !          2807:        lstrcat(szMessageBoxText, "Edit Links");
        !          2808:        break;
        !          2809: 
        !          2810:     default:
        !          2811:        lstrcat(szMessageBoxText, "Unknown");
        !          2812:        break;
        !          2813:     }
        !          2814: 
        !          2815:     lstrcat(szMessageBoxText, " Dialog.");
        !          2816: 
        !          2817:     // You'd probably really a call to WinHelp here.
        !          2818:     MessageBox(hDlg, szMessageBoxText, "Help", MB_OK);
        !          2819: 
        !          2820:     return;
        !          2821: }
        !          2822: 
        !          2823: 
        !          2824: /* OutlineDoc_SetCurrentZoomCommand
        !          2825:  * --------------------------------
        !          2826:  *
        !          2827:  *  Set current zoom level to be checked in the menu. 
        !          2828:  *  Set the corresponding scalefactor for the document.
        !          2829:  */
        !          2830: void OutlineDoc_SetCurrentZoomCommand(
        !          2831:         LPOUTLINEDOC        lpOutlineDoc, 
        !          2832:         UINT                uCurrentZoom
        !          2833: )
        !          2834: {
        !          2835:     SCALEFACTOR scale;
        !          2836: 
        !          2837:     if (!lpOutlineDoc)
        !          2838:         return;
        !          2839: 
        !          2840:     lpOutlineDoc->m_uCurrentZoom = uCurrentZoom;
        !          2841: 
        !          2842:     switch (uCurrentZoom) {
        !          2843: 
        !          2844: #if !defined( OLE_CNTR )
        !          2845:             case IDM_V_ZOOM_400:                                               
        !          2846:                 scale.dwSxN = (DWORD) 4;
        !          2847:                 scale.dwSxD = (DWORD) 1;
        !          2848:                 scale.dwSyN = (DWORD) 4;
        !          2849:                 scale.dwSyD = (DWORD) 1;
        !          2850:                 break;
        !          2851: 
        !          2852:             case IDM_V_ZOOM_300:                                               
        !          2853:                 scale.dwSxN = (DWORD) 3;
        !          2854:                 scale.dwSxD = (DWORD) 1;
        !          2855:                 scale.dwSyN = (DWORD) 3;
        !          2856:                 scale.dwSyD = (DWORD) 1;
        !          2857:                 break;
        !          2858: 
        !          2859:             case IDM_V_ZOOM_200:                                               
        !          2860:                 scale.dwSxN = (DWORD) 2;
        !          2861:                 scale.dwSxD = (DWORD) 1;
        !          2862:                 scale.dwSyN = (DWORD) 2;
        !          2863:                 scale.dwSyD = (DWORD) 1;
        !          2864:                 break;
        !          2865: #endif         // !OLE_CNTR
        !          2866: 
        !          2867:             case IDM_V_ZOOM_100:                                               
        !          2868:                 scale.dwSxN = (DWORD) 1;
        !          2869:                 scale.dwSxD = (DWORD) 1;
        !          2870:                 scale.dwSyN = (DWORD) 1;
        !          2871:                 scale.dwSyD = (DWORD) 1;
        !          2872:                 break;
        !          2873: 
        !          2874:             case IDM_V_ZOOM_75:                                                
        !          2875:                 scale.dwSxN = (DWORD) 3;
        !          2876:                 scale.dwSxD = (DWORD) 4;
        !          2877:                 scale.dwSyN = (DWORD) 3;
        !          2878:                 scale.dwSyD = (DWORD) 4;
        !          2879:                 break;
        !          2880: 
        !          2881:             case IDM_V_ZOOM_50:
        !          2882:                 scale.dwSxN = (DWORD) 1;
        !          2883:                 scale.dwSxD = (DWORD) 2;
        !          2884:                 scale.dwSyN = (DWORD) 1;
        !          2885:                 scale.dwSyD = (DWORD) 2;
        !          2886:                 break;
        !          2887: 
        !          2888:             case IDM_V_ZOOM_25:
        !          2889:                 scale.dwSxN = (DWORD) 1;
        !          2890:                 scale.dwSxD = (DWORD) 4;
        !          2891:                 scale.dwSyN = (DWORD) 1;
        !          2892:                 scale.dwSyD = (DWORD) 4;
        !          2893:                 break;
        !          2894:     }
        !          2895: 
        !          2896:     OutlineDoc_SetScaleFactor(lpOutlineDoc, (LPSCALEFACTOR)&scale, NULL);
        !          2897: }
        !          2898: 
        !          2899: 
        !          2900: /* OutlineDoc_GetCurrentZoomMenuCheck
        !          2901:  * ----------------------------------
        !          2902:  *
        !          2903:  *  Get current zoom level to be checked in the menu.
        !          2904:  */
        !          2905: UINT OutlineDoc_GetCurrentZoomMenuCheck(LPOUTLINEDOC lpOutlineDoc) 
        !          2906: {
        !          2907:     return lpOutlineDoc->m_uCurrentZoom;
        !          2908: }
        !          2909: 
        !          2910: 
        !          2911: /* OutlineDoc_SetScaleFactor
        !          2912:  * -------------------------
        !          2913:  *
        !          2914:  *  Set the scale factor of the document which will affect the 
        !          2915:  *      size of the document on the screen
        !          2916:  *
        !          2917:  * Parameters:
        !          2918:  *
        !          2919:  *   scale      structure containing x and y scales
        !          2920:  */
        !          2921: void OutlineDoc_SetScaleFactor(
        !          2922:         LPOUTLINEDOC        lpOutlineDoc, 
        !          2923:         LPSCALEFACTOR       lpscale, 
        !          2924:         LPRECT              lprcDoc
        !          2925: )
        !          2926: {
        !          2927:     LPLINELIST         lpLL = OutlineDoc_GetLineList(lpOutlineDoc);
        !          2928:     HWND            hWndLL = LineList_GetWindow(lpLL);
        !          2929: 
        !          2930:     if (!lpOutlineDoc || !lpscale)
        !          2931:         return;
        !          2932: 
        !          2933:     InvalidateRect(hWndLL, NULL, TRUE);
        !          2934: 
        !          2935:     lpOutlineDoc->m_scale = *lpscale;
        !          2936:     LineList_ReScale((LPLINELIST)&lpOutlineDoc->m_LineList, lpscale);
        !          2937: 
        !          2938: #if defined( USE_HEADING )
        !          2939:     Heading_ReScale((LPHEADING)&lpOutlineDoc->m_heading, lpscale);
        !          2940: #endif
        !          2941: 
        !          2942:     OutlineDoc_Resize(lpOutlineDoc, lprcDoc);
        !          2943: }
        !          2944: 
        !          2945: 
        !          2946: /* OutlineDoc_GetScaleFactor
        !          2947:  * -------------------------
        !          2948:  *
        !          2949:  *  Retrieve the scale factor of the document
        !          2950:  *
        !          2951:  * Parameters:
        !          2952:  *  
        !          2953:  */
        !          2954: LPSCALEFACTOR OutlineDoc_GetScaleFactor(LPOUTLINEDOC lpOutlineDoc)
        !          2955: {
        !          2956:     if (!lpOutlineDoc)
        !          2957:         return NULL;
        !          2958:     
        !          2959:     return (LPSCALEFACTOR)&lpOutlineDoc->m_scale;
        !          2960: }
        !          2961: 
        !          2962: 
        !          2963: /* OutlineDoc_SetCurrentMarginCommand
        !          2964:  * ----------------------------------
        !          2965:  *
        !          2966:  *  Set current Margin level to be checked in the menu.
        !          2967:  */
        !          2968: void OutlineDoc_SetCurrentMarginCommand(
        !          2969:         LPOUTLINEDOC        lpOutlineDoc, 
        !          2970:         UINT                uCurrentMargin
        !          2971: )
        !          2972: {
        !          2973:     if (!lpOutlineDoc)
        !          2974:         return;
        !          2975: 
        !          2976:     lpOutlineDoc->m_uCurrentMargin = uCurrentMargin;
        !          2977: 
        !          2978:     switch (uCurrentMargin) {
        !          2979:         case IDM_V_SETMARGIN_0:
        !          2980:             OutlineDoc_SetMargin(lpOutlineDoc, 0, 0);
        !          2981:             break;
        !          2982: 
        !          2983:         case IDM_V_SETMARGIN_1:
        !          2984:             OutlineDoc_SetMargin(lpOutlineDoc, 1000, 1000);
        !          2985:             break;
        !          2986: 
        !          2987:         case IDM_V_SETMARGIN_2:
        !          2988:             OutlineDoc_SetMargin(lpOutlineDoc, 2000, 2000);
        !          2989:             break;
        !          2990: 
        !          2991:         case IDM_V_SETMARGIN_3:                                                        
        !          2992:             OutlineDoc_SetMargin(lpOutlineDoc, 3000, 3000);
        !          2993:             break;
        !          2994: 
        !          2995:         case IDM_V_SETMARGIN_4:
        !          2996:             OutlineDoc_SetMargin(lpOutlineDoc, 4000, 4000);
        !          2997:             break;
        !          2998:     }
        !          2999: }
        !          3000: 
        !          3001: 
        !          3002: /* OutlineDoc_GetCurrentMarginMenuCheck
        !          3003:  * ------------------------------------
        !          3004:  *
        !          3005:  *  Get current Margin level to be checked in the menu.
        !          3006:  */
        !          3007: UINT OutlineDoc_GetCurrentMarginMenuCheck(LPOUTLINEDOC lpOutlineDoc)
        !          3008: {
        !          3009:     return lpOutlineDoc->m_uCurrentMargin;
        !          3010: }
        !          3011: 
        !          3012: 
        !          3013: /* OutlineDoc_SetMargin
        !          3014:  * --------------------
        !          3015:  *
        !          3016:  *  Set the left and right margin of the document
        !          3017:  *
        !          3018:  * Parameters:
        !          3019:  *      nLeftMargin  - left margin in Himetric values
        !          3020:  *      nRightMargin - right margin in Himetric values
        !          3021:  */
        !          3022: void OutlineDoc_SetMargin(LPOUTLINEDOC lpOutlineDoc, int nLeftMargin, int nRightMargin)
        !          3023: {
        !          3024:     LPLINELIST lpLL;
        !          3025:     int        nMaxWidthInHim;
        !          3026: 
        !          3027:     if (!lpOutlineDoc)
        !          3028:         return;
        !          3029: 
        !          3030:     lpOutlineDoc->m_nLeftMargin = nLeftMargin;
        !          3031:     lpOutlineDoc->m_nRightMargin = nRightMargin;
        !          3032:     lpLL = OutlineDoc_GetLineList(lpOutlineDoc);
        !          3033: 
        !          3034:     // Force recalculation of Horizontal extent
        !          3035:     nMaxWidthInHim = LineList_GetMaxLineWidthInHimetric(lpLL);
        !          3036:     LineList_SetMaxLineWidthInHimetric(lpLL, -nMaxWidthInHim);
        !          3037: 
        !          3038: #if defined( INPLACE_CNTR )
        !          3039:     ContainerDoc_UpdateInPlaceObjectRects((LPCONTAINERDOC)lpOutlineDoc, 0);
        !          3040: #endif
        !          3041:     
        !          3042:     OutlineDoc_ForceRedraw(lpOutlineDoc, TRUE);
        !          3043: }
        !          3044: 
        !          3045: 
        !          3046: /* OutlineDoc_GetMargin
        !          3047:  * --------------------
        !          3048:  *
        !          3049:  *  Get the left and right margin of the document
        !          3050:  *
        !          3051:  *  Parameters:
        !          3052:  *      nLeftMargin  - left margin in Himetric values
        !          3053:  *      nRightMargin - right margin in Himetric values
        !          3054:  *
        !          3055:  *  Returns:
        !          3056:  *      low order word  - left margin
        !          3057:  *      high order word - right margin
        !          3058:  */
        !          3059: LONG OutlineDoc_GetMargin(LPOUTLINEDOC lpOutlineDoc)
        !          3060: {
        !          3061:     if (!lpOutlineDoc)
        !          3062:         return 0;
        !          3063:     
        !          3064:     return MAKELONG(lpOutlineDoc->m_nLeftMargin, lpOutlineDoc->m_nRightMargin);
        !          3065: }
        !          3066: 
        !          3067: #if defined( USE_HEADING )
        !          3068: 
        !          3069: /* OutlineDoc_GetHeading
        !          3070:  * ---------------------
        !          3071:  *
        !          3072:  *      Get Heading Object in OutlineDoc
        !          3073:  */
        !          3074: LPHEADING OutlineDoc_GetHeading(LPOUTLINEDOC lpOutlineDoc)
        !          3075: {
        !          3076:     if (!lpOutlineDoc || lpOutlineDoc->m_fDataTransferDoc)
        !          3077:         return NULL;
        !          3078:     else
        !          3079:         return (LPHEADING)&lpOutlineDoc->m_heading;
        !          3080: }
        !          3081: 
        !          3082: 
        !          3083: /* OutlineDoc_ShowHeading
        !          3084:  * ----------------------
        !          3085:  *
        !          3086:  *  Show/Hide document row/column headings.
        !          3087:  */
        !          3088: void OutlineDoc_ShowHeading(LPOUTLINEDOC lpOutlineDoc, BOOL fShow)
        !          3089: {
        !          3090:     LPHEADING   lphead = OutlineDoc_GetHeading(lpOutlineDoc);
        !          3091: #if defined( INPLACE_SVR )
        !          3092:     LPSERVERDOC lpServerDoc = (LPSERVERDOC)lpOutlineDoc;
        !          3093: #endif 
        !          3094: 
        !          3095:     if (! lphead) 
        !          3096:         return;
        !          3097: 
        !          3098:     Heading_Show(lphead, fShow);
        !          3099: 
        !          3100: #if defined( INPLACE_SVR )
        !          3101:     if (lpServerDoc->m_fUIActive) {
        !          3102:         LPINPLACEDATA lpIPData = lpServerDoc->m_lpIPData;
        !          3103: 
        !          3104:         /* OLE2NOTE: our extents have NOT changed; only our the size of
        !          3105:         **    our object-frame adornments is changing. we can use the
        !          3106:         **    current PosRect and ClipRect and simply resize our
        !          3107:         **    windows WITHOUT informing our in-place container.
        !          3108:         */
        !          3109:         ServerDoc_ResizeInPlaceWindow(
        !          3110:                 lpServerDoc, 
        !          3111:                 (LPRECT)&(lpIPData->rcPosRect),
        !          3112:                 (LPRECT)&(lpIPData->rcClipRect)
        !          3113:         );
        !          3114:     } else 
        !          3115: #else   // !INPLACE_SVR
        !          3116: 
        !          3117:     OutlineDoc_Resize(lpOutlineDoc, NULL);
        !          3118: 
        !          3119: #if defined( INPLACE_CNTR )
        !          3120:     ContainerDoc_UpdateInPlaceObjectRects((LPCONTAINERDOC)lpOutlineDoc, 0);
        !          3121: #endif  // INPLACE_CNTR
        !          3122: 
        !          3123: #endif  // INPLACE_SVR
        !          3124: 
        !          3125:     OutlineDoc_ForceRedraw(lpOutlineDoc, TRUE);                         
        !          3126: }
        !          3127: 
        !          3128: #endif  // USE_HEADING
        !          3129:     
        !          3130: 
        !          3131: /* AbortProc
        !          3132:  * ---------
        !          3133:  *  AborProc is called by GDI print code to check for user abort.
        !          3134:  */
        !          3135: BOOL FAR PASCAL EXPORT AbortProc (HDC hdc, WORD reserved)
        !          3136: {
        !          3137:     MSG msg;
        !          3138: 
        !          3139:     /* Allow other apps to run, or get abort messages */
        !          3140:     while(! fCancelPrint && PeekMessage (&msg, NULL, 0, 0, PM_REMOVE)) {
        !          3141:         if(!hWndPDlg || !IsDialogMessage (hWndPDlg, &msg)) {
        !          3142:             TranslateMessage (&msg);
        !          3143:             DispatchMessage  (&msg);
        !          3144:         }
        !          3145:     }
        !          3146:     return !fCancelPrint;
        !          3147: }
        !          3148: 
        !          3149: 
        !          3150: /* PrintDlgProc
        !          3151:  * ------------
        !          3152:  *  Dialog function for the print cancel dialog box.
        !          3153:  *
        !          3154:  *  RETURNS    : TRUE  - OK to abort/ not OK to abort
        !          3155:  *               FALSE - otherwise.
        !          3156:  */
        !          3157: BOOL FAR PASCAL EXPORT PrintDlgProc(
        !          3158:         HWND hwnd, 
        !          3159:         WORD msg, 
        !          3160:         WORD wParam, 
        !          3161:         LONG lParam
        !          3162: )
        !          3163: {
        !          3164:     switch (msg) {
        !          3165:         case WM_COMMAND:
        !          3166:         /* abort printing if the only button gets hit */
        !          3167:             fCancelPrint = TRUE;
        !          3168:             return TRUE;
        !          3169:     }
        !          3170: 
        !          3171:     return FALSE;
        !          3172: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.