|
|
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.