|
|
1.1 root 1: /*************************************************************************
2: **
3: ** OLE 2 Sample Code
4: **
5: ** outlline.c
6: **
7: ** This file contains Line functions.
8: **
9: ** (c) Copyright Microsoft Corp. 1992 - 1993 All Rights Reserved
10: **
11: *************************************************************************/
12:
13:
14: #include "outline.h"
15:
16:
17: OLEDBGDATA
18:
19: extern LPOUTLINEAPP g_lpApp;
20:
21:
22: /* Line_Init
23: * ---------
24: *
25: * Init the calculated data of a line object
26: */
27: void Line_Init(LPLINE lpLine, int nTab, HDC hDC)
28: {
29: lpLine->m_lineType = UNKNOWNLINETYPE;
30: lpLine->m_nTabLevel = nTab;
31: lpLine->m_nTabWidthInHimetric = Line_CalcTabWidthInHimetric(lpLine,hDC);
32: lpLine->m_nWidthInHimetric = 0;
33: lpLine->m_nHeightInHimetric = 0;
34: lpLine->m_fSelected = FALSE;
35:
36: #if defined( USE_DRAGDROP )
37: lpLine->m_fDragOverLine = FALSE;
38: #endif
39: }
40:
41:
42: /* Line_Edit
43: * ---------
44: *
45: * Edit the line object.
46: *
47: * Returns TRUE if line was changed
48: * FALSE if the line was NOT changed
49: */
50: BOOL Line_Edit(LPLINE lpLine, HWND hWndDoc, HDC hDC)
51: {
52: switch (lpLine->m_lineType) {
53: case TEXTLINETYPE:
54: return TextLine_Edit((LPTEXTLINE)lpLine, hWndDoc, hDC);
55:
56: #if defined( OLE_CNTR )
57: case CONTAINERLINETYPE:
58: ContainerLine_Edit((LPCONTAINERLINE)lpLine, hWndDoc, hDC);
59: break;
60: #endif
61:
62: default:
63: return FALSE; // unknown line type
64: }
65: }
66:
67:
68: /* Line_GetLineType
69: * ----------------
70: *
71: * Return type of the line
72: */
73: LINETYPE Line_GetLineType(LPLINE lpLine)
74: {
75: if (! lpLine) return 0;
76:
77: return lpLine->m_lineType;
78: }
79:
80:
81: /* Line_GetTextLen
82: * ---------------
83: *
84: * Return length of string representation of the Line
85: * (not considering the tab level).
86: */
87: int Line_GetTextLen(LPLINE lpLine)
88: {
89: switch (lpLine->m_lineType) {
90: case TEXTLINETYPE:
91: return TextLine_GetTextLen((LPTEXTLINE)lpLine);
92:
93: #if defined( OLE_CNTR )
94: case CONTAINERLINETYPE:
95: return ContainerLine_GetTextLen((LPCONTAINERLINE)lpLine);
96: #endif
97:
98: default:
99: return 0; // unknown line type
100: }
101: }
102:
103:
104: /* Line_GetTextData
105: * ----------------
106: *
107: * Return the string representation of the Line.
108: * (not considering the tab level).
109: */
110: void Line_GetTextData(LPLINE lpLine, LPSTR lpszBuf)
111: {
112: switch (lpLine->m_lineType) {
113: case TEXTLINETYPE:
114: TextLine_GetTextData((LPTEXTLINE)lpLine, lpszBuf);
115: break;
116:
117: #if defined( OLE_CNTR )
118: case CONTAINERLINETYPE:
119: ContainerLine_GetTextData((LPCONTAINERLINE)lpLine, lpszBuf);
120: break;
121: #endif
122:
123: default:
124: *lpszBuf = '\0';
125: return; // unknown line type
126: }
127: }
128:
129:
130: /* Line_GetOutlineData
131: * -------------------
132: *
133: * Return the CF_OUTLINE format representation of the Line.
134: */
135: BOOL Line_GetOutlineData(LPLINE lpLine, LPTEXTLINE lpBuf)
136: {
137: switch (lpLine->m_lineType) {
138: case TEXTLINETYPE:
139: return TextLine_GetOutlineData((LPTEXTLINE)lpLine, lpBuf);
140:
141: #if defined( OLE_CNTR )
142: case CONTAINERLINETYPE:
143: return ContainerLine_GetOutlineData(
144: (LPCONTAINERLINE)lpLine,
145: lpBuf
146: );
147: #endif
148:
149: default:
150: return FALSE; // unknown line type
151: }
152: }
153:
154:
155: /* Line_CalcTabWidthInHimetric
156: * ---------------------------
157: *
158: * Recalculate the width for the line's current tab level
159: */
160: static int Line_CalcTabWidthInHimetric(LPLINE lpLine, HDC hDC)
161: {
162: int nTabWidthInHimetric;
163:
164: nTabWidthInHimetric=lpLine->m_nTabLevel * TABWIDTH;
165: return nTabWidthInHimetric;
166: }
167:
168:
169: /* Line_Indent
170: * -----------
171: *
172: * Increment the tab level for the line
173: */
174: void Line_Indent(LPLINE lpLine, HDC hDC)
175: {
176: lpLine->m_nTabLevel++;
177: lpLine->m_nTabWidthInHimetric = Line_CalcTabWidthInHimetric(lpLine, hDC);
178:
179: #if defined( INPLACE_CNTR )
180: if (Line_GetLineType(lpLine) == CONTAINERLINETYPE)
181: ContainerLine_UpdateInPlaceObjectRects((LPCONTAINERLINE)lpLine, NULL);
182: #endif
183: }
184:
185:
186: /* Line_Unindent
187: * -------------
188: *
189: * Decrement the tab level for the line
190: */
191: void Line_Unindent(LPLINE lpLine, HDC hDC)
192: {
193: if(lpLine->m_nTabLevel > 0) {
194: lpLine->m_nTabLevel--;
195: lpLine->m_nTabWidthInHimetric = Line_CalcTabWidthInHimetric(lpLine, hDC);
196: }
197:
198: #if defined( INPLACE_CNTR )
199: if (Line_GetLineType(lpLine) == CONTAINERLINETYPE)
200: ContainerLine_UpdateInPlaceObjectRects((LPCONTAINERLINE)lpLine, NULL);
201: #endif
202: }
203:
204:
205: /* Line_GetTotalWidthInHimetric
206: * ----------------------------
207: *
208: * Calculate the total width of the line
209: */
210: UINT Line_GetTotalWidthInHimetric(LPLINE lpLine)
211: {
212: return lpLine->m_nWidthInHimetric + lpLine->m_nTabWidthInHimetric;
213: }
214:
215:
216: /* Line_SetWidthInHimetric
217: * -----------------------
218: *
219: * Set the width of the line
220: */
221: void Line_SetWidthInHimetric(LPLINE lpLine, int nWidth)
222: {
223: if (!lpLine)
224: return;
225:
226: lpLine->m_nWidthInHimetric = nWidth;
227: }
228:
229:
230: /* Line_GetWidthInHimetric
231: * -----------------------
232: *
233: * Return the width of the line
234: */
235: UINT Line_GetWidthInHimetric(LPLINE lpLine)
236: {
237: if (!lpLine)
238: return 0;
239:
240: return lpLine->m_nWidthInHimetric;
241: }
242:
243:
244:
245:
246:
247: /* Line_GetTabLevel
248: * ----------------
249: *
250: * Return the tab level of a line object.
251: */
252: UINT Line_GetTabLevel(LPLINE lpLine)
253: {
254: return lpLine->m_nTabLevel;
255: }
256:
257:
258: /* Line_DrawToScreen
259: * -----------------
260: *
261: * Draw the item in the owner-draw listbox
262: */
263: void Line_DrawToScreen(
264: LPLINE lpLine,
265: HDC hDC,
266: LPRECT lprcPix,
267: UINT itemAction,
268: UINT itemState,
269: LPRECT lprcDevice
270: )
271: {
272: if (!lpLine || !hDC || !lprcPix || !lprcDevice)
273: return;
274:
275: /* Draw a list box item in its normal drawing action.
276: * Then check if it is selected or has the focus state, and call
277: * functions to handle drawing for these states if necessary.
278: */
279: if(itemAction == ODA_DRAWENTIRE) {
280: HFONT hfontOld;
281: int nMapModeOld;
282: RECT rcWindowOld;
283: RECT rcViewportOld;
284: RECT rcLogical;
285:
286: // NOTE: we have to set the device context to HIMETRIC in order
287: // draw the line; however, we have to restore the HDC before
288: // we draw focus or dragfeedback...
289:
290: rcLogical.left = 0;
291: rcLogical.bottom = 0;
292: rcLogical.right = lpLine->m_nWidthInHimetric;
293: rcLogical.top = lpLine->m_nHeightInHimetric;
294:
295: nMapModeOld=SetDCToAnisotropic(hDC, lprcDevice, &rcLogical,
296: (LPRECT)&rcWindowOld, (LPRECT)&rcViewportOld);
297:
298: // Set the default font size, and font face name
299: hfontOld = SelectObject(hDC, OutlineApp_GetActiveFont(g_lpApp));
300:
301: InflateRect(
302: &rcLogical,
303: -XformWidthInPixelsToHimetric(hDC, LINE_BOUNDARY_WIDTH),
304: XformHeightInPixelsToHimetric(hDC, LINE_BOUNDARY_WIDTH)
305: );
306:
307: Line_Draw(lpLine, hDC, &rcLogical);
308:
309: SelectObject(hDC, hfontOld);
310:
311: ResetOrigDC(hDC, nMapModeOld, (LPRECT)&rcWindowOld,
312: (LPRECT)&rcViewportOld);
313:
314:
315: // If item selected, do additional drawing -- invert rectangle
316: if (itemState & ODS_SELECTED)
317: Line_DrawSelHilight(lpLine, hDC, lprcPix, itemAction, itemState);
318: else
319: lpLine->m_fSelected = FALSE;
320:
321:
322: // if item has focus, do additional drawing -- dashed border
323: #if defined( USE_DRAGDROP )
324: if (lpLine->m_fDragOverLine)
325: Line_DrawDragFeedback(lpLine, hDC, lprcPix, itemState );
326: else if (itemState & ODS_FOCUS)
327: Line_DrawFocusRect(lpLine, hDC, lprcPix, itemAction, itemState);
328: else
329: Line_DrawDragFeedback(lpLine, hDC, lprcPix, itemState );
330: #else
331: if (itemState & ODS_FOCUS)
332: Line_DrawFocusRect(lpLine, hDC, lprcPix, itemAction, itemState);
333: #endif
334:
335:
336: }
337:
338: /* If a list box item was just selected or unselected,
339: * call function (which could check if ODS_SELECTED bit is set)
340: * and draws item in selected or unselected state.
341: */
342: if(itemAction == ODA_SELECT )
343: Line_DrawSelHilight(lpLine, hDC, lprcPix, itemAction, itemState);
344:
345:
346:
347: /* If a list box item just gained or lost the focus,
348: * call function (which could check if ODS_FOCUS bit is set)
349: * and draws item in focus or non-focus state.
350: */
351: if(itemAction == ODA_FOCUS )
352: Line_DrawFocusRect(lpLine, hDC, lprcPix, itemAction, itemState);
353:
354:
355:
356: #if defined( OLE_CNTR )
357: if (Line_GetLineType(lpLine) == CONTAINERLINETYPE) {
358: LPCONTAINERLINE lpContainerLine = (LPCONTAINERLINE)lpLine;
359: LPCONTAINERDOC lpDoc = lpContainerLine->m_lpDoc;
360: BOOL fIsLink;
361: RECT rcObj;
362:
363: if (ContainerDoc_GetShowObjectFlag(lpDoc)) {
364: ContainerLine_GetOleObjectRectInPixels(lpContainerLine, &rcObj);
365: fIsLink = ContainerLine_IsOleLink(lpContainerLine);
366: InflateRect(&rcObj, 1, 1);
367: OleUIShowObject(&rcObj, hDC, fIsLink);
368: }
369: }
370: #endif
371:
372:
373: }
374:
375:
376: /* Line_Draw
377: * ---------
378: *
379: * Draw a line on a DC.
380: *
381: * Parameters:
382: * hDC - DC to which the line will be drawn
383: * lpRect - the object rect in logical coordinates
384: */
385: void Line_Draw(LPLINE lpLine, HDC hDC, LPRECT lpRect)
386: {
387: switch (lpLine->m_lineType) {
388: case TEXTLINETYPE:
389: TextLine_Draw((LPTEXTLINE)lpLine, hDC, lpRect);
390: break;
391:
392: #if defined( OLE_CNTR )
393: case CONTAINERLINETYPE:
394: ContainerLine_Draw((LPCONTAINERLINE)lpLine, hDC, lpRect);
395: break;
396: #endif
397:
398: default:
399: return; // unknown line type
400: }
401: return;
402: }
403:
404:
405: /* Line_DrawSelHilight
406: * -------------------
407: *
408: * Handles selection of list box item
409: */
410: void Line_DrawSelHilight(LPLINE lpLine, HDC hDC, LPRECT lpRect, UINT itemAction, UINT itemState)
411: {
412: switch (lpLine->m_lineType) {
413: case TEXTLINETYPE:
414: TextLine_DrawSelHilight((LPTEXTLINE)lpLine, hDC, lpRect,
415: itemAction, itemState);
416: break;
417:
418: #if defined( OLE_CNTR )
419: case CONTAINERLINETYPE:
420: ContainerLine_DrawSelHilight((LPCONTAINERLINE)lpLine, hDC, lpRect,
421: itemAction, itemState);
422: break;
423: #endif
424:
425: default:
426: return; // unknown line type
427: }
428: return;
429:
430: }
431:
432: /* Line_DrawFocusRect
433: * ------------------
434: *
435: * Handles focus state of list box item
436: */
437: void Line_DrawFocusRect(LPLINE lpLine, HDC hDC, LPRECT lpRect, UINT itemAction, UINT itemState)
438: {
439: HBRUSH hbr;
440:
441: // if (lpdis->itemID >= 0 && lpdis->itemID < nNumLine)
442: if(lpLine) {
443: if (itemState & ODS_FOCUS) {
444: /* Draw focus rect */
445: hbr = GetStockObject(LTGRAY_BRUSH);
446: FrameRect(hDC, lpRect, hbr);
447: } else {
448: /* Remove focus rect */
449: if (itemState & ODS_SELECTED)
450: hbr = GetStockObject(BLACK_BRUSH);
451: else
452: hbr = GetStockObject(WHITE_BRUSH);
453: FrameRect(hDC, lpRect, hbr);
454: }
455: }
456: }
457:
458: #if defined( USE_DRAGDROP )
459:
460: /* Line_DrawDragFeedback
461: * ---------------------
462: *
463: * Handles focus state of list box item
464: */
465: void Line_DrawDragFeedback(LPLINE lpLine, HDC hDC, LPRECT lpRect, UINT itemState )
466: {
467: HBRUSH hbr;
468:
469: if(lpLine) {
470:
471: if (!lpLine->m_fDragOverLine) {
472:
473: if (itemState & ODS_SELECTED)
474: hbr = GetStockObject(BLACK_BRUSH);
475: else
476: hbr = GetStockObject(WHITE_BRUSH);
477:
478: }
479: else {
480:
481: hbr = GetStockObject(LTGRAY_BRUSH);
482:
483: }
484: FrameRect(hDC, lpRect, hbr);
485: }
486:
487: }
488:
489: #endif
490:
491:
492: /* Line_GetHeightInHimetric
493: * ------------------------
494: *
495: * Return the height of the item in HIMETRIC units
496: */
497: UINT Line_GetHeightInHimetric(LPLINE lpLine)
498: {
499: if (!lpLine)
500: return 0;
501:
502: return (UINT)lpLine->m_nHeightInHimetric;
503: }
504:
505:
506: /* Line_SetHeightInHimetric
507: * ------------------------
508: *
509: * Set the height of the item in HIMETRIC units.
510: */
511: void Line_SetHeightInHimetric(LPLINE lpLine, int nHeight)
512: {
513: if (!lpLine)
514: return;
515:
516: switch (lpLine->m_lineType) {
517: case TEXTLINETYPE:
518: TextLine_SetHeightInHimetric((LPTEXTLINE)lpLine, nHeight);
519: break;
520:
521: #if defined( OLE_CNTR )
522: case CONTAINERLINETYPE:
523: ContainerLine_SetHeightInHimetric((LPCONTAINERLINE)lpLine,
524: nHeight);
525: break;
526: #endif
527:
528: }
529: }
530:
531:
532: /* Line_Delete
533: * -----------
534: *
535: * Delete the Line structure
536: */
537: void Line_Delete(LPLINE lpLine)
538: {
539: switch (lpLine->m_lineType) {
540: case TEXTLINETYPE:
541: TextLine_Delete((LPTEXTLINE)lpLine);
542: break;
543:
544: #if defined( OLE_CNTR )
545: case CONTAINERLINETYPE:
546: ContainerLine_Delete((LPCONTAINERLINE)lpLine);
547: break;
548: #endif
549:
550: default:
551: break; // unknown line type
552: }
553: }
554:
555:
556: /* Line_CopyToDoc
557: * --------------
558: *
559: * Copy a line to another Document (usually ClipboardDoc)
560: */
561: BOOL Line_CopyToDoc(LPLINE lpSrcLine, LPOUTLINEDOC lpDestDoc, int nIndex)
562: {
563: switch (lpSrcLine->m_lineType) {
564: case TEXTLINETYPE:
565: return TextLine_CopyToDoc((LPTEXTLINE)lpSrcLine,lpDestDoc,nIndex);
566: break;
567:
568: #if defined( OLE_CNTR )
569: case CONTAINERLINETYPE:
570: return ContainerLine_CopyToDoc(
571: (LPCONTAINERLINE)lpSrcLine,
572: lpDestDoc,
573: nIndex
574: );
575: break;
576: #endif
577:
578: default:
579: return FALSE; // unknown line type
580: }
581: }
582:
583:
584: /* Line_SaveToStg
585: * --------------
586: *
587: * Save a single line object to a storage
588: *
589: * Return TRUE if successful, FALSE otherwise
590: */
591: BOOL Line_SaveToStg(LPLINE lpLine, UINT uFormat, LPSTORAGE lpSrcStg, LPSTORAGE lpDestStg, LPSTREAM lpLLStm, BOOL fRemember)
592: {
593: LINERECORD lineRecord;
594: ULONG nWritten;
595: HRESULT hrErr;
596:
597: lineRecord.m_lineType = lpLine->m_lineType;
598: lineRecord.m_nTabLevel = lpLine->m_nTabLevel;
599: lineRecord.m_nTabWidthInHimetric = lpLine->m_nTabWidthInHimetric;
600: lineRecord.m_nWidthInHimetric = lpLine->m_nWidthInHimetric;
601: lineRecord.m_nHeightInHimetric = lpLine->m_nHeightInHimetric;
602: lineRecord.m_reserved = 0;
603:
604: /* write line record header */
605: hrErr = lpLLStm->lpVtbl->Write(
606: lpLLStm,
607: (LPVOID)&lineRecord,
608: sizeof(LINERECORD),
609: &nWritten
610: );
611:
612: if (! OleDbgVerifySz(hrErr == NOERROR,
613: "Could not write Line header to LineList stream"))
614: return FALSE;
615:
616: switch (lpLine->m_lineType) {
617: case TEXTLINETYPE:
618: return TextLine_SaveToStg(
619: (LPTEXTLINE)lpLine,
620: uFormat,
621: lpSrcStg,
622: lpDestStg,
623: lpLLStm,
624: fRemember
625: );
626:
627: #if defined( OLE_CNTR )
628: case CONTAINERLINETYPE:
629: return ContainerLine_SaveToStg(
630: (LPCONTAINERLINE)lpLine,
631: uFormat,
632: lpSrcStg,
633: lpDestStg,
634: lpLLStm,
635: fRemember
636: );
637: #endif
638:
639: default:
640: return FALSE; // unknown line type
641: }
642: }
643:
644:
645: /* Line_LoadFromStg
646: * ----------------
647: *
648: * Load a single line object from storage
649: */
650: LPLINE Line_LoadFromStg(LPSTORAGE lpSrcStg, LPSTREAM lpLLStm, LPOUTLINEDOC lpDestDoc)
651: {
652: LINERECORD lineRecord;
653: LPLINE lpLine = NULL;
654: ULONG nRead;
655: HRESULT hrErr;
656:
657: /* read line record header */
658: hrErr = lpLLStm->lpVtbl->Read(
659: lpLLStm,
660: (LPVOID)&lineRecord,
661: sizeof(LINERECORD),
662: &nRead
663: );
664:
665: if (! OleDbgVerifySz(hrErr == NOERROR,
666: "Could not read Line header from LineList stream"))
667: return NULL;
668:
669: switch (lineRecord.m_lineType) {
670: case TEXTLINETYPE:
671: lpLine = TextLine_LoadFromStg(lpSrcStg, lpLLStm, lpDestDoc);
672: break;
673:
674: #if defined( OLE_CNTR )
675: case CONTAINERLINETYPE:
676: lpLine = ContainerLine_LoadFromStg(lpSrcStg, lpLLStm, lpDestDoc);
677: break;
678: #endif
679:
680: default:
681: return NULL; // unknown line type
682: }
683:
684: lpLine->m_lineType = lineRecord.m_lineType;
685: lpLine->m_nTabLevel = lineRecord.m_nTabLevel;
686: lpLine->m_nTabWidthInHimetric = lineRecord.m_nTabWidthInHimetric;
687: lpLine->m_nWidthInHimetric = lineRecord.m_nWidthInHimetric;
688: lpLine->m_nHeightInHimetric = lineRecord.m_nHeightInHimetric;
689:
690: return lpLine;
691: }
692:
693:
694: /* Line_IsSelected
695: * ---------------
696: *
697: * Return the selection state of the line
698: */
699: BOOL Line_IsSelected(LPLINE lpLine)
700: {
701: if (!lpLine)
702: return FALSE;
703:
704: return lpLine->m_fSelected;
705: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.