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