|
|
1.1 root 1: /*************************************************************************
2: **
3: ** OLE 2 Sample Code
4: **
5: ** outldata.c
6: **
7: ** This file contains LineList and NameTable functions
8: ** and related support functions.
9: **
10: ** (c) Copyright Microsoft Corp. 1992 - 1993 All Rights Reserved
11: **
12: *************************************************************************/
13:
14:
15: #include "outline.h"
16:
17: OLEDBGDATA
18:
19: extern LPOUTLINEAPP g_lpApp;
20:
21: char ErrMsgListBox[] = "Can't create ListBox!";
22:
23: static int g_iMapMode;
24:
25: /* LineList_Init
26: * -------------
27: *
28: * Create and Initialize the LineList (owner-drawn listbox)
29: */
30: BOOL LineList_Init(LPLINELIST lpLL, LPOUTLINEDOC lpOutlineDoc)
31: {
32: LPOUTLINEAPP lpOutlineApp = (LPOUTLINEAPP)g_lpApp;
33:
34: #if defined( INPLACE_CNTR )
35: lpLL->m_hWndListBox = CreateWindow(
36: "listbox", /* Window class name */
37: NULL, /* Window's title */
38: WS_CHILDWINDOW |
39:
40: /* OLE2NOTE: an in-place contanier MUST use
41: ** WS_CLIPCHILDREN window style for the window
42: ** that it uses as the parent for the server's
43: ** in-place active window so that its
44: ** painting does NOT interfere with the painting
45: ** of the server's in-place active child window.
46: */
47:
48: WS_CLIPCHILDREN |
49: WS_VISIBLE |
50: WS_VSCROLL |
51: WS_HSCROLL |
52: LBS_EXTENDEDSEL |
53: LBS_NOTIFY |
54: LBS_OWNERDRAWVARIABLE |
55: LBS_NOINTEGRALHEIGHT |
56: LBS_USETABSTOPS,
57: 0, 0, /* Use default X, Y */
58: 0, 0, /* Use default X, Y */
59: lpOutlineDoc->m_hWndDoc,/* Parent window's handle */
60: (HMENU)IDC_LINELIST, /* Child Window ID */
61: lpOutlineApp->m_hInst, /* Instance of window */
62: NULL); /* Create struct for WM_CREATE */
63: #else
64: lpLL->m_hWndListBox = CreateWindow(
65: "listbox", /* Window class name */
66: NULL, /* Window's title */
67: WS_CHILDWINDOW |
68: WS_VISIBLE |
69: WS_VSCROLL |
70: WS_HSCROLL |
71: LBS_EXTENDEDSEL |
72: LBS_NOTIFY |
73: LBS_OWNERDRAWVARIABLE |
74: LBS_NOINTEGRALHEIGHT |
75: LBS_USETABSTOPS,
76: 0, 0, /* Use default X, Y */
77: 0, 0, /* Use default X, Y */
78: lpOutlineDoc->m_hWndDoc,/* Parent window's handle */
79: (HMENU)IDC_LINELIST, /* Child Window ID */
80: lpOutlineApp->m_hInst, /* Instance of window */
81: NULL); /* Create struct for WM_CREATE */
82:
83: #endif
84:
85:
86: if(! lpLL->m_hWndListBox) {
87: OutlineApp_ErrorMessage(g_lpApp, ErrMsgListBox);
88: return FALSE;
89: }
90:
91: lpOutlineApp->m_ListBoxWndProc =
92: (FARPROC) GetWindowLong ( lpLL->m_hWndListBox, GWL_WNDPROC );
93: SetWindowLong (lpLL->m_hWndListBox, GWL_WNDPROC, (LONG) LineListWndProc);
94:
95: #if defined ( USE_DRAGDROP )
96: /* m_iDragOverLine saves index of line that has drag/drop target
97: ** feedback. we currently use our focus rectangle feedback for
98: ** this. it would be better to have a different visual feedback
99: ** for potential target of the pending drop.
100: */
101: lpLL->m_iDragOverLine = -1;
102: #endif
103:
104: lpLL->m_nNumLines = 0;
105: lpLL->m_nMaxLineWidthInHimetric = 0;
106: lpLL->m_lpDoc = lpOutlineDoc;
107: _fmemset(&lpLL->m_lrSaveSel, 0, sizeof(LINERANGE));
108:
109: return TRUE;
110: }
111:
112:
113: /* LineList_Destroy
114: * ----------------
115: *
116: * Clear (delete) all Line objects from the list and free supporting
117: * memory (ListBox Window) used by the LineList object itself.
118: */
119: void LineList_Destroy(LPLINELIST lpLL)
120: {
121: int i;
122: int linesTotal = lpLL->m_nNumLines;
123:
124: // Delete all Line objects
125: for (i = 0; i < linesTotal; i++)
126: LineList_DeleteLine(lpLL, 0); // NOTE: always delete line 0
127:
128: // Remove all Lines from the ListBox
129: SendMessage(lpLL->m_hWndListBox,LB_RESETCONTENT,0,0L);
130:
131: lpLL->m_nNumLines=0;
132: DestroyWindow(lpLL->m_hWndListBox);
133: lpLL->m_hWndListBox = NULL;
134: }
135:
136:
137: /* LineList_AddLine
138: * ----------------
139: *
140: * Add one line to the list box. The line is added following the
141: * line with index "nIndex". If nIndex is larger than the number of lines
142: * in the ListBox, then the line is appended to the end. The selection
143: * is set to the newly added line.
144: */
145: void LineList_AddLine(LPLINELIST lpLL, LPLINE lpLine, int nIndex)
146: {
147: int nAddIndex = (lpLL->m_nNumLines == 0 ?
148: 0 :
149: (nIndex >= lpLL->m_nNumLines ? lpLL->m_nNumLines : nIndex+1));
150: LINERANGE lrSel;
151:
152: #if defined( USE_HEADING )
153: int nHeight = Line_GetHeightInHimetric(lpLine);
154:
155: nHeight = XformHeightInHimetricToPixels(NULL, nHeight);
156:
157: // Add a dummy string to the row heading
158: Heading_RH_SendMessage(OutlineDoc_GetHeading(lpLL->m_lpDoc),
159: LB_INSERTSTRING, (WPARAM)nAddIndex, MAKELPARAM(nHeight, 0));
160: #endif
161:
162:
163: lrSel.m_nStartLine = nAddIndex;
164: lrSel.m_nEndLine = nAddIndex;
165:
166: if (!lpLine) {
167: OutlineApp_ErrorMessage(g_lpApp, "Could not create line.");
168: return;
169: }
170:
171: SendMessage(lpLL->m_hWndListBox, LB_INSERTSTRING, (WPARAM)nAddIndex,
172: (DWORD)lpLine);
173:
174: LineList_SetMaxLineWidthInHimetric(
175: lpLL,
176: Line_GetTotalWidthInHimetric(lpLine)
177: );
178:
179: lpLL->m_nNumLines++;
180:
181: LineList_SetSel(lpLL, &lrSel);
182: }
183:
184:
185: /* LineList_DeleteLine
186: * -------------------
187: *
188: * Delete one line from listbox and memory
189: */
190: void LineList_DeleteLine(LPLINELIST lpLL, int nIndex)
191: {
192: LPLINE lpLine = LineList_GetLine(lpLL, nIndex);
193: BOOL fResetSel;
194:
195: fResetSel = (BOOL)SendMessage(lpLL->m_hWndListBox, LB_GETSEL, (WPARAM)nIndex, 0L);
196:
197: if (lpLine)
198: Line_Delete(lpLine); // free memory of Line
199:
200: // Remove the Line from the ListBox
201: SendMessage(lpLL->m_hWndListBox, LB_DELETESTRING, (WPARAM)nIndex, 0L);
202: lpLL->m_nNumLines--;
203:
204: if (fResetSel) {
205: if (nIndex > 0) {
206: #if defined( WIN32 )
207: SendMessage(
208: lpLL->m_hWndListBox,
209: LB_SETSEL,
210: (WPARAM)TRUE,
211: (LPARAM)nIndex-1
212: );
213: #else
214: SendMessage(
215: lpLL->m_hWndListBox,
216: LB_SETSEL,
217: (WPARAM)TRUE,
218: MAKELPARAM(nIndex-1,0)
219: );
220: #endif
221: } else {
222: if (lpLL->m_nNumLines > 0) {
223: #if defined( WIN32 )
224: SendMessage(
225: lpLL->m_hWndListBox,
226: LB_SETSEL,
227: (WPARAM)TRUE,
228: (LPARAM)0
229: );
230: #else
231: SendMessage(
232: lpLL->m_hWndListBox,
233: LB_SETSEL,
234: (WPARAM)TRUE,
235: MAKELPARAM(0,0)
236: );
237: #endif
238: }
239: }
240: }
241:
242: #if defined( USE_HEADING )
243: // Remove the dummy string from the row heading
244: Heading_RH_SendMessage(OutlineDoc_GetHeading(lpLL->m_lpDoc),
245: LB_DELETESTRING, (WPARAM)nIndex, 0L);
246: #endif
247:
248: }
249:
250:
251: /* LineList_ReplaceLine
252: * --------------------
253: *
254: * Replace the line at a given index in the list box with a new
255: * line.
256: */
257: void LineList_ReplaceLine(LPLINELIST lpLL, LPLINE lpLine, int nIndex)
258: {
259: LPLINE lpOldLine = LineList_GetLine(lpLL, nIndex);
260:
261: if (lpOldLine)
262: Line_Delete(lpOldLine); // free memory of Line
263: else
264: return; // if no previous line then invalid index
265:
266: SendMessage(
267: lpLL->m_hWndListBox,
268: LB_SETITEMDATA,
269: (WPARAM)nIndex,
270: (LPARAM)lpLine
271: );
272: }
273:
274:
275: /* LineList_GetLineIndex
276: * ---------------------
277: *
278: * Return the index of the Line given a pointer to the line.
279: * Return -1 if the line is not found.
280: */
281: int LineList_GetLineIndex(LPLINELIST lpLL, LPLINE lpLine)
282: {
283: LRESULT lReturn;
284:
285: if (! lpLine) return -1;
286:
287: lReturn = SendMessage(
288: lpLL->m_hWndListBox,
289: LB_FINDSTRING,
290: (WPARAM)-1,
291: (LPARAM)(LPCSTR)lpLine
292: );
293:
294: return ((lReturn == LB_ERR) ? -1 : (int)lReturn);
295: }
296:
297:
298: /* LineList_GetLine
299: * ----------------
300: *
301: * Retrieve the pointer to the Line given its index in the LineList
302: */
303: LPLINE LineList_GetLine(LPLINELIST lpLL, int nIndex)
304: {
305: DWORD dWord = 0;
306: LPLINE lpLine;
307:
308: if (lpLL->m_nNumLines == 0 || nIndex > lpLL->m_nNumLines || nIndex < 0)
309: return NULL;
310:
311: SendMessage(lpLL->m_hWndListBox,LB_GETTEXT,nIndex,(LPARAM)(LPCSTR)&dWord);
312: lpLine=(LPLINE)dWord;
313: return lpLine;
314: }
315:
316:
317: /* LineList_SetFocusLine
318: * ---------------------
319: *
320: */
321:
322: void LineList_SetFocusLine ( LPLINELIST lpLL, WORD wIndex )
323: {
324:
325: SendMessage(lpLL->m_hWndListBox, LB_SETCARETINDEX, (WPARAM)wIndex, 0L );
326:
327: }
328:
329:
330: /* LineList_GetLineRect
331: * --------------------
332: *
333: * Retrieve the rectangle of a Line given its index in the LineList
334: */
335: BOOL LineList_GetLineRect(LPLINELIST lpLL, int nIndex, LPRECT lpRect)
336: {
337: DWORD iReturn = (DWORD)LB_ERR;
338:
339: if ( !(lpLL->m_nNumLines == 0 || nIndex > lpLL->m_nNumLines || nIndex < 0) )
340: iReturn = SendMessage(lpLL->m_hWndListBox,LB_GETITEMRECT,nIndex,(LPARAM)lpRect);
341:
342: return (iReturn == LB_ERR ? FALSE : TRUE );
343: }
344:
345:
346: /* LineList_GetFocusLineIndex
347: * --------------------------
348: *
349: * Get the index of the line that currently has focus (the active line).
350: */
351: int LineList_GetFocusLineIndex(LPLINELIST lpLL)
352: {
353: return (int)SendMessage(lpLL->m_hWndListBox,LB_GETCARETINDEX,0,0L);
354: }
355:
356:
357: /* LineList_GetCount
358: * -----------------
359: *
360: * Return number of line objects
361: */
362: int LineList_GetCount(LPLINELIST lpLL)
363: {
364: if (lpLL)
365: return lpLL->m_nNumLines;
366: else {
367: OleDbgAssert(lpLL!=NULL);
368: return 0;
369: }
370: }
371:
372:
373: /* LineList_SetMaxLineWidthInHimetric
374: * ----------------------------------
375: *
376: * Adjust the maximum line width for the listbox. The max line width is
377: * used to determine if a horizontal scroll bar is needed.
378: *
379: * Parameters:
380: * nWidthInHimetric - if +ve, width of an additional line
381: * - if -ve, reset Max to be the value
382: *
383: * Returns:
384: * TRUE is max line width of LineList changed
385: * FALSE if no change
386: */
387: BOOL LineList_SetMaxLineWidthInHimetric(LPLINELIST lpLL, int nWidthInHimetric)
388: {
389: int nWidthInPix;
390: BOOL fSizeChanged = FALSE;
391: LPSCALEFACTOR lpscale;
392:
393: if (!lpLL)
394: return FALSE;
395:
396: lpscale = OutlineDoc_GetScaleFactor(lpLL->m_lpDoc);
397:
398: if (nWidthInHimetric < 0) {
399: lpLL->m_nMaxLineWidthInHimetric = -1;
400: nWidthInHimetric *= -1;
401: }
402:
403: if (nWidthInHimetric > lpLL->m_nMaxLineWidthInHimetric) {
404: lpLL->m_nMaxLineWidthInHimetric = nWidthInHimetric;
405: nWidthInPix = XformWidthInHimetricToPixels(NULL, nWidthInHimetric +
406: LOWORD(OutlineDoc_GetMargin(lpLL->m_lpDoc)) +
407: HIWORD(OutlineDoc_GetMargin(lpLL->m_lpDoc)));
408:
409: nWidthInPix = (int)(nWidthInPix * lpscale->dwSxN / lpscale->dwSxD);
410: SendMessage(
411: lpLL->m_hWndListBox,
412: LB_SETHORIZONTALEXTENT,
413: nWidthInPix,
414: 0L
415: );
416: fSizeChanged = TRUE;
417:
418: #if defined( USE_HEADING )
419: Heading_CH_SetHorizontalExtent(
420: OutlineDoc_GetHeading(lpLL->m_lpDoc), lpLL->m_hWndListBox);
421: #endif
422:
423: }
424: return fSizeChanged;
425: }
426:
427:
428: /* LineList_GetMaxLineWidthInHimetric
429: * ----------------------------------
430: *
431: * Return the width of the widest line
432: */
433: int LineList_GetMaxLineWidthInHimetric(LPLINELIST lpLL)
434: {
435: return lpLL->m_nMaxLineWidthInHimetric;
436: }
437:
438:
439: /* LineList_RecalcMaxLineWidthInHimetric
440: * -------------------------------------
441: *
442: * Recalculate the maximum line width in the entire list.
443: *
444: * Parameters:
445: * nWidthInHimetric should be set to the width of line being removed.
446: * nWidthInHimetric == 0 forces list to recalculate in all cases.
447: * nWidthInHimetric == current max width => forces recalc.
448: *
449: * Returns:
450: * TRUE is max line width of LineList changed
451: * FALSE if no change
452: */
453: BOOL LineList_RecalcMaxLineWidthInHimetric(
454: LPLINELIST lpLL,
455: int nWidthInHimetric
456: )
457: {
458: int i;
459: LPLINE lpLine;
460: BOOL fSizeChanged = FALSE;
461: int nOrgMaxLineWidthInHimetric = lpLL->m_nMaxLineWidthInHimetric;
462:
463: if (nWidthInHimetric == 0 ||
464: nWidthInHimetric == lpLL->m_nMaxLineWidthInHimetric) {
465:
466: lpLL->m_nMaxLineWidthInHimetric = -1;
467:
468: LineList_SetMaxLineWidthInHimetric(lpLL, 0);
469:
470: for(i = 0; i < lpLL->m_nNumLines; i++) {
471: lpLine=LineList_GetLine(lpLL, i);
472: LineList_SetMaxLineWidthInHimetric(
473: lpLL,
474: Line_GetTotalWidthInHimetric(lpLine)
475: );
476: }
477: }
478:
479: if (nOrgMaxLineWidthInHimetric != lpLL->m_nMaxLineWidthInHimetric)
480: fSizeChanged = TRUE;
481:
482: return fSizeChanged;
483: }
484:
485:
486: /* LineList_CalcSelExtentInHimetric
487: * --------------------------------
488: *
489: * Calculate the extents (widht and height) of a selection of lines.
490: *
491: * if lplrSel == NULL, calculate extent of all lines.
492: */
493: void LineList_CalcSelExtentInHimetric(
494: LPLINELIST lpLL,
495: LPLINERANGE lplrSel,
496: LPSIZEL lpsizel
497: )
498: {
499: int i;
500: int nEndLine;
501: int nStartLine;
502: LPLINE lpLine;
503: long lWidth;
504:
505: if (lplrSel) {
506: nEndLine = lplrSel->m_nEndLine;
507: nStartLine = lplrSel->m_nStartLine;
508: } else {
509: nEndLine = LineList_GetCount(lpLL) - 1;
510: nStartLine = 0;
511: }
512:
513: lpsizel->cx = 0;
514: lpsizel->cy = 0;
515:
516: for(i = nStartLine; i <= nEndLine; i++) {
517: lpLine=LineList_GetLine(lpLL,i);
518: lWidth = (long)Line_GetTotalWidthInHimetric(lpLine);
519: lpsizel->cx = max(lpsizel->cx, lWidth);
520: lpsizel->cy += lpLine->m_nHeightInHimetric;
521: }
522: }
523:
524:
525: /* LineList_GetWindow
526: * ------------------
527: *
528: * Return handle of list box
529: */
530: HWND LineList_GetWindow(LPLINELIST lpLL)
531: {
532: return lpLL->m_hWndListBox;
533: }
534:
535:
536: /* LineList_GetDC
537: * --------------
538: *
539: * Return DC handle of list box
540: */
541: HDC LineList_GetDC(LPLINELIST lpLL)
542: {
543: HFONT hfontOld;
544: HDC hDC = GetDC(lpLL->m_hWndListBox);
545: int iXppli; //* pixels per logical inch along width
546: int iYppli; //* pixels per logical inch along height
547: SIZE size;
548:
549: // Setup a mapping mode for the DC which maps physical pixel
550: // coordinates to HIMETRIC units. The standard MM_HIMETRIC mapping
551: // mode does not work correctly because it does not take into
552: // account that a logical inch on the display screen is drawn
553: // physically larger than 1 inch. We will setup an anisotropic
554: // mapping mode which will perform the transformation properly.
555:
556: g_iMapMode = SetMapMode(hDC, MM_ANISOTROPIC);
557: iXppli = GetDeviceCaps (hDC, LOGPIXELSX);
558: iYppli = GetDeviceCaps (hDC, LOGPIXELSY);
559: SetViewportExtEx(hDC, iXppli, iYppli, &size);
560: SetWindowExtEx(hDC, HIMETRIC_PER_INCH, HIMETRIC_PER_INCH, &size);
561:
562: // Set the default font size, and font face name
563: hfontOld = SelectObject(hDC, OutlineApp_GetActiveFont(g_lpApp));
564:
565: return hDC;
566: }
567:
568:
569: /* LineList_ReleaseDC
570: * ------------------
571: *
572: * Release DC of list box returned from previous LineList_GetDC call.
573: */
574: void LineList_ReleaseDC(LPLINELIST lpLL, HDC hDC)
575: {
576: SetMapMode(hDC, g_iMapMode);
577: ReleaseDC(lpLL->m_hWndListBox, hDC);
578: }
579:
580:
581: /* LineList_SetLineHeight
582: * ----------------------
583: *
584: * Set the height of a line in the LineList list box
585: */
586: void LineList_SetLineHeight(LPLINELIST lpLL,int nIndex,int nHeightInHimetric)
587: {
588: LPARAM lParam;
589: LPOUTLINEDOC lpDoc;
590: LPSCALEFACTOR lpscale;
591: UINT uHeightInPix;
592: LPHEADING lphead;
593:
594: if (!lpLL)
595: return;
596:
597: lpDoc = lpLL->m_lpDoc;
598: lphead = OutlineDoc_GetHeading(lpDoc);
599: lpscale = OutlineDoc_GetScaleFactor(lpDoc);
600:
601: uHeightInPix = XformHeightInHimetricToPixels(NULL, nHeightInHimetric);
602:
603: Heading_RH_SendMessage(lphead, LB_SETITEMDATA, (WPARAM)nIndex,
604: MAKELPARAM(uHeightInPix, 0));
605:
606: uHeightInPix = (UINT)(uHeightInPix * lpscale->dwSyN / lpscale->dwSyD);
607:
608: if (uHeightInPix > LISTBOX_HEIGHT_LIMIT)
609: uHeightInPix = LISTBOX_HEIGHT_LIMIT;
610:
611:
612: lParam = MAKELPARAM(uHeightInPix, 0);
613: SendMessage(lpLL->m_hWndListBox,LB_SETITEMHEIGHT,(WPARAM)nIndex, lParam);
614: Heading_RH_SendMessage(lphead, LB_SETITEMHEIGHT, (WPARAM)nIndex, lParam);
615: Heading_RH_ForceRedraw(lphead, TRUE);
616: }
617:
618:
619: /* LineList_ReScale
620: * ----------------
621: *
622: * Re-scale the LineList list box
623: */
624: void LineList_ReScale(LPLINELIST lpLL, LPSCALEFACTOR lpscale)
625: {
626: int nIndex;
627: LPLINE lpLine;
628: UINT uWidthInHim;
629:
630: if (!lpLL)
631: return;
632:
633: for (nIndex = 0; nIndex < lpLL->m_nNumLines; nIndex++) {
634: lpLine = LineList_GetLine(lpLL, nIndex);
635: LineList_SetLineHeight(
636: lpLL,
637: nIndex,
638: Line_GetHeightInHimetric(lpLine)
639: );
640: }
641:
642: uWidthInHim = LineList_GetMaxLineWidthInHimetric(lpLL);
643: LineList_SetMaxLineWidthInHimetric(lpLL, -(int)uWidthInHim);
644: }
645:
646: /* LineList_SetSel
647: * ---------------
648: *
649: * Set the selection in list box
650: */
651: void LineList_SetSel(LPLINELIST lpLL, LPLINERANGE lplrSel)
652: {
653: DWORD dwSel;
654:
655: if (lpLL->m_nNumLines <= 0 || lplrSel->m_nStartLine < 0)
656: return; // no lines in list; can't set a selection
657:
658: dwSel = MAKELPARAM(lplrSel->m_nStartLine, lplrSel->m_nEndLine);
659:
660: lpLL->m_lrSaveSel = *lplrSel;
661:
662: /* remove previous selection */
663: #if defined( WIN32 )
664: SendMessage(
665: lpLL->m_hWndListBox,
666: LB_SETSEL,
667: (WPARAM)FALSE,
668: (LPARAM)-1
669: );
670: #else
671: SendMessage(
672: lpLL->m_hWndListBox,
673: LB_SETSEL,
674: (WPARAM)FALSE,
675: MAKELPARAM(-1,0)
676: );
677: #endif
678:
679: /* mark selection */
680: SendMessage(lpLL->m_hWndListBox,LB_SELITEMRANGE, (WPARAM)TRUE, (LPARAM)dwSel);
681: /* set focus line (caret) */
682: LineList_SetFocusLine ( lpLL, (WORD)lplrSel->m_nStartLine );
683:
684: }
685:
686:
687: /* LineList_GetSel
688: * ---------------
689: *
690: * Get the selection in list box.
691: *
692: * Returns the count of items selected
693: */
694: int LineList_GetSel(LPLINELIST lpLL, LPLINERANGE lplrSel)
695: {
696: int nNumSel=(int)SendMessage(lpLL->m_hWndListBox,LB_GETSELCOUNT,0,0L);
697:
698: if (nNumSel) {
699: SendMessage(lpLL->m_hWndListBox,LB_GETSELITEMS,
700: (WPARAM)1,(LPARAM)(int FAR*)&(lplrSel->m_nStartLine));
701: lplrSel->m_nEndLine = lplrSel->m_nStartLine + nNumSel - 1;
702: } else {
703: _fmemset(lplrSel, 0, sizeof(LINERANGE));
704: }
705: return nNumSel;
706: }
707:
708:
709: /* LineList_RemoveSel
710: * ------------------
711: *
712: * Remove the selection in list box but save the selection state so that
713: * it can be restored by calling LineList_RestoreSel
714: * LineList_RemoveSel is called when the LineList window looses focus.
715: */
716: void LineList_RemoveSel(LPLINELIST lpLL)
717: {
718: LINERANGE lrSel;
719: if (LineList_GetSel(lpLL, &lrSel) > 0) {
720: lpLL->m_lrSaveSel = lrSel;
721: #if defined( WIN32 )
722: SendMessage(
723: lpLL->m_hWndListBox,
724: LB_SETSEL,
725: (WPARAM)FALSE,
726: (LPARAM)-1
727: );
728: #else
729: SendMessage(
730: lpLL->m_hWndListBox,
731: LB_SETSEL,
732: (WPARAM)FALSE,
733: MAKELPARAM(-1,0)
734: );
735: #endif
736: }
737: }
738:
739:
740: /* LineList_RestoreSel
741: * ------------------
742: *
743: * Restore the selection in list box that was previously saved by a call to
744: * LineList_RemoveSel.
745: * LineList_RestoreSel is called when the LineList window gains focus.
746: */
747: void LineList_RestoreSel(LPLINELIST lpLL)
748: {
749: LineList_SetSel(lpLL, &lpLL->m_lrSaveSel);
750: }
751:
752:
753: /* LineList_SetRedraw
754: * ------------------
755: *
756: * Enable/Disable the redraw of the linelist (listbox) on screen
757: *
758: * fEnbaleDraw = TRUE - enable redraw
759: * FALSE - disable redraw
760: */
761: void LineList_SetRedraw(LPLINELIST lpLL, BOOL fEnableDraw)
762: {
763: SendMessage(lpLL->m_hWndListBox,WM_SETREDRAW,(WPARAM)fEnableDraw,0L);
764: }
765:
766:
767: /* LineList_ForceRedraw
768: * --------------------
769: *
770: * Force redraw of the linelist (listbox) on screen
771: */
772: void LineList_ForceRedraw(LPLINELIST lpLL, BOOL fErase)
773: {
774: InvalidateRect(lpLL->m_hWndListBox, NULL, fErase);
775: }
776:
777:
778: /* LineList_ForceLineRedraw
779: * ------------------------
780: *
781: * Force a particular line of the linelist (listbox) to redraw.
782: */
783: void LineList_ForceLineRedraw(LPLINELIST lpLL, int nIndex, BOOL fErase)
784: {
785: RECT rect;
786:
787: LineList_GetLineRect( lpLL, nIndex, (LPRECT)&rect );
788: InvalidateRect( lpLL->m_hWndListBox, (LPRECT)&rect, fErase );
789: }
790:
791:
792: /* LineList_ScrollLineIntoView
793: * ---------------------------
794: * Make sure that the specified line is in view; if necessary scroll
795: * the listbox. if any portion of the line is visible, then no
796: * scrolling will occur.
797: */
798: void LineList_ScrollLineIntoView(LPLINELIST lpLL, int nIndex)
799: {
800: RECT rcWindow;
801: RECT rcLine;
802: RECT rcInt;
803:
804: if ( lpLL->m_nNumLines == 0 )
805: return;
806:
807: if (! LineList_GetLineRect( lpLL, nIndex, (LPRECT)&rcLine ) )
808: return;
809:
810: GetClientRect( lpLL->m_hWndListBox, (LPRECT) &rcWindow );
811:
812: if (! IntersectRect((LPRECT)&rcInt, (LPRECT)&rcWindow, (LPRECT)&rcLine))
813: SendMessage(
814: lpLL->m_hWndListBox,
815: LB_SETTOPINDEX,
816: (WPARAM)nIndex,
817: (LPARAM)NULL
818: );
819: }
820:
821:
822: /* LineList_CopySelToDoc
823: * ---------------------
824: *
825: * Copy the selection of the linelist to another document
826: *
827: * RETURNS: number of lines copied.
828: */
829: int LineList_CopySelToDoc(
830: LPLINELIST lpSrcLL,
831: LPLINERANGE lplrSel,
832: LPOUTLINEDOC lpDestDoc
833: )
834: {
835: int nEndLine;
836: int nStartLine;
837: LPLINELIST lpDestLL = &lpDestDoc->m_LineList;
838: signed short nDestIndex = LineList_GetFocusLineIndex(lpDestLL);
839: LPLINE lpSrcLine;
840: int nCopied = 0;
841: int i;
842:
843: if (lplrSel) {
844: nEndLine = lplrSel->m_nEndLine;
845: nStartLine = lplrSel->m_nStartLine;
846: } else {
847: nEndLine = LineList_GetCount(lpSrcLL) - 1;
848: nStartLine = 0;
849: }
850:
851: for(i = nStartLine; i <= nEndLine; i++) {
852: lpSrcLine = LineList_GetLine(lpSrcLL, i);
853: if (lpSrcLine && Line_CopyToDoc(lpSrcLine, lpDestDoc, nDestIndex)) {
854: nDestIndex++;
855: nCopied++;
856: }
857: }
858:
859: return nCopied;
860: }
861:
862:
863: /* LineList_SaveSelToStg
864: * ---------------------
865: *
866: * Save lines in selection into lpDestStg.
867: *
868: * Return TRUE if ok, FALSE if error
869: */
870: BOOL LineList_SaveSelToStg(
871: LPLINELIST lpLL,
872: LPLINERANGE lplrSel,
873: UINT uFormat,
874: LPSTORAGE lpSrcStg,
875: LPSTORAGE lpDestStg,
876: LPSTREAM lpLLStm,
877: BOOL fRemember
878: )
879: {
880: int nEndLine;
881: int nStartLine;
882: int nNumLinesWritten = 0;
883: HRESULT hrErr = NOERROR;
884: ULONG nWritten;
885: LPLINE lpLine;
886: LINELISTHEADER llhRecord;
887: int i;
888: LARGE_INTEGER dlibSaveHeaderPos;
889: LARGE_INTEGER dlibZeroOffset;
890: LISet32( dlibZeroOffset, 0 );
891:
892: if (lplrSel) {
893: nEndLine = lplrSel->m_nEndLine;
894: nStartLine = lplrSel->m_nStartLine;
895: } else {
896: nEndLine = LineList_GetCount(lpLL) - 1;
897: nStartLine = 0;
898: }
899:
900: _fmemset((LPLINELISTHEADER)&llhRecord,0,sizeof(LINELISTHEADER));
901:
902: /* save seek position for LineList header record */
903: hrErr = lpLLStm->lpVtbl->Seek(
904: lpLLStm,
905: dlibZeroOffset,
906: STREAM_SEEK_CUR,
907: (ULARGE_INTEGER FAR*)&dlibSaveHeaderPos
908: );
909: if (hrErr != NOERROR) goto error;
910:
911: /* write LineList header record */
912: hrErr = lpLLStm->lpVtbl->Write(
913: lpLLStm,
914: (LPVOID)&llhRecord,
915: sizeof(LINELISTHEADER),
916: &nWritten
917: );
918: if (hrErr != NOERROR) goto error;
919:
920: for(i = nStartLine; i <= nEndLine; i++) {
921: lpLine = LineList_GetLine(lpLL, i);
922: if(Line_SaveToStg(lpLine, uFormat, lpSrcStg, lpDestStg, lpLLStm,
923: fRemember))
924: llhRecord.m_nNumLines++;
925: }
926:
927: /* retore seek position for LineList header record */
928: hrErr = lpLLStm->lpVtbl->Seek(
929: lpLLStm,
930: dlibSaveHeaderPos,
931: STREAM_SEEK_SET,
932: NULL
933: );
934: if (hrErr != NOERROR) goto error;
935:
936: /* write LineList header record */
937: hrErr = lpLLStm->lpVtbl->Write(
938: lpLLStm,
939: (LPVOID)&llhRecord,
940: sizeof(LINELISTHEADER),
941: &nWritten
942: );
943: if (hrErr != NOERROR) goto error;
944:
945: /* reset seek position to end of stream */
946: hrErr = lpLLStm->lpVtbl->Seek(
947: lpLLStm,
948: dlibZeroOffset,
949: STREAM_SEEK_END,
950: NULL
951: );
952: if (hrErr != NOERROR) goto error;
953:
954: return TRUE;
955:
956: error:
957: OleDbgAssertSz(
958: hrErr == NOERROR,
959: "Could not write LineList header to LineList stream"
960: );
961: return FALSE;
962: }
963:
964:
965: /* LineList_LoadFromStg
966: * --------------------
967: *
968: * Load lines into linelist from storage.
969: *
970: * Return TRUE if ok, FALSE if error
971: */
972: BOOL LineList_LoadFromStg(
973: LPLINELIST lpLL,
974: LPSTORAGE lpSrcStg,
975: LPSTREAM lpLLStm
976: )
977: {
978: HRESULT hrErr;
979: ULONG nRead;
980: LPLINE lpLine;
981: int i;
982: int nNumLines;
983: LINELISTHEADER llineRecord;
984:
985: /* write LineList header record */
986: hrErr = lpLLStm->lpVtbl->Read(
987: lpLLStm,
988: (LPVOID)&llineRecord,
989: sizeof(LINELISTHEADER),
990: &nRead
991: );
992:
993: if (! OleDbgVerifySz(hrErr == NOERROR,
994: "Could not read LineList header from LineList stream"))
995: goto error;
996:
997: nNumLines = llineRecord.m_nNumLines;
998:
999: for(i = 0; i < nNumLines; i++) {
1000: lpLine = Line_LoadFromStg(lpSrcStg, lpLLStm, lpLL->m_lpDoc);
1001: if (! lpLine)
1002: goto error;
1003:
1004: // Directly add lines to LineList without trying to update a NameTbl
1005: LineList_AddLine(lpLL, lpLine, i-1);
1006: }
1007:
1008: return TRUE;
1009:
1010: error:
1011: // Delete any Line objects that were created
1012: if (lpLL->m_nNumLines > 0) {
1013: int nNumLines = lpLL->m_nNumLines;
1014: for (i = 0; i < nNumLines; i++)
1015: LineList_DeleteLine(lpLL, i);
1016: }
1017:
1018: return FALSE;
1019: }
1020:
1021:
1022: #if defined( USE_DRAGDROP )
1023:
1024:
1025: /* LineList_SetFocusLineFromPointl
1026: * -------------------------------
1027: *
1028: */
1029:
1030: void LineList_SetFocusLineFromPointl( LPLINELIST lpLL, POINTL pointl )
1031: {
1032: int i = LineList_GetLineIndexFromPointl( lpLL, pointl );
1033:
1034: if ( i == (int)-1)
1035: return ;
1036: else
1037: LineList_SetFocusLine( lpLL, (WORD)i );
1038: }
1039:
1040:
1041: /* LineList_SetDragOverLineFromPointl
1042: * ----------------------------------
1043: *
1044: */
1045:
1046: void LineList_SetDragOverLineFromPointl ( LPLINELIST lpLL, POINTL pointl )
1047: {
1048: int nIndex = LineList_GetLineIndexFromPointl( lpLL, pointl );
1049: LPLINE lpline = LineList_GetLine( lpLL, nIndex );
1050:
1051: if (!lpline)
1052: return;
1053:
1054: if (! lpline->m_fDragOverLine) {
1055: /* user has dragged over a new line. force new drop target line
1056: ** to repaint so that drop feedback will be drawn.
1057: */
1058: lpline->m_fDragOverLine = TRUE;
1059: LineList_ForceLineRedraw( lpLL, nIndex, TRUE );
1060:
1061: if (lpLL->m_iDragOverLine!= -1 && lpLL->m_iDragOverLine!=nIndex) {
1062:
1063: /* force previous drop target line to repaint so that drop
1064: ** feedback will be undrawn
1065: */
1066: lpline = LineList_GetLine( lpLL, lpLL->m_iDragOverLine );
1067: if (lpline)
1068: lpline->m_fDragOverLine = FALSE;
1069:
1070: LineList_ForceLineRedraw( lpLL, lpLL->m_iDragOverLine, TRUE );
1071: }
1072:
1073: lpLL->m_iDragOverLine = nIndex;
1074:
1075: // Force repaint immediately
1076: UpdateWindow(lpLL->m_hWndListBox);
1077: }
1078: }
1079:
1080:
1081: /* LineList_Scroll
1082: * ---------------
1083: *
1084: * Scroll the LineList list box in the desired direction by one line.
1085: *
1086: * this function is called during a drag operation.
1087: */
1088:
1089: void LineList_Scroll(LPLINELIST lpLL, DWORD dwScrollDir)
1090: {
1091: switch (dwScrollDir) {
1092: case SCROLLDIR_UP:
1093: SendMessage( lpLL->m_hWndListBox, WM_VSCROLL, SB_LINEUP, 0L );
1094: break;
1095:
1096: case SCROLLDIR_DOWN:
1097: SendMessage( lpLL->m_hWndListBox, WM_VSCROLL, SB_LINEDOWN, 0L );
1098: break;
1099: }
1100: }
1101:
1102:
1103: /* LineList_GetLineIndexFromPointl
1104: * -------------------------------
1105: * do hit test to get index of line corresponding to pointl
1106: */
1107: int LineList_GetLineIndexFromPointl(LPLINELIST lpLL, POINTL pointl)
1108: {
1109: RECT rect;
1110: POINT point;
1111: DWORD i;
1112:
1113: point.x = (int)pointl.x;
1114: point.y = (int)pointl.y;
1115:
1116: ScreenToClient( lpLL->m_hWndListBox, &point);
1117:
1118: if ( lpLL->m_nNumLines == 0 )
1119: return -1;
1120:
1121: GetClientRect( lpLL->m_hWndListBox, (LPRECT) &rect );
1122:
1123: i = SendMessage( lpLL->m_hWndListBox, LB_GETTOPINDEX, (WPARAM)NULL, (LPARAM)NULL );
1124:
1125: for ( ;; i++){
1126:
1127: RECT rectItem;
1128:
1129: if (!LineList_GetLineRect( lpLL, (int)i, (LPRECT)&rectItem ) )
1130: return -1;
1131:
1132: if ( rectItem.top > rect.bottom )
1133: return -1;
1134:
1135: if ( rectItem.top <= point.y && point.y <= rectItem.bottom)
1136: return (int)i;
1137:
1138: }
1139:
1140: }
1141:
1142:
1143: /* LineList_RestoreDragFeedback
1144: * ----------------------------
1145: *
1146: * Retore the index of the line that currently has focus (the active line).
1147: */
1148: void LineList_RestoreDragFeedback(LPLINELIST lpLL)
1149: {
1150: LPLINE lpLine;
1151:
1152: if (lpLL->m_iDragOverLine < 0 )
1153: return;
1154:
1155: lpLine = LineList_GetLine( lpLL, lpLL->m_iDragOverLine);
1156:
1157: if (lpLine) {
1158:
1159: lpLine->m_fDragOverLine = FALSE;
1160: LineList_ForceLineRedraw( lpLL, lpLL->m_iDragOverLine, TRUE );
1161:
1162: // Force repaint immediately
1163: UpdateWindow(lpLL->m_hWndListBox);
1164: }
1165:
1166: lpLL->m_iDragOverLine = -1;
1167:
1168: }
1169:
1170: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.