Annotation of mstools/ole20/samples/outline/outllist.c, revision 1.1.1.1

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  

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.