|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.