Annotation of mstools/ole20/samples/ole2ui/links.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * links.c
                      3:  * 
                      4:  * Implements the OleUIEditLinks function which invokes the complete
                      5:  * Edit Links dialog.
                      6:  *
                      7:  * Copyright (c)1992 Microsoft Corporation, All Right Reserved
                      8:  */
                      9: 
                     10: #define STRICT  1
                     11: #include "ole2ui.h"
                     12: #include "common.h"
                     13: #include "edlinks.h"
                     14: #include "utility.h"
                     15: #include <commdlg.h>
                     16: #include <dlgs.h>
                     17: #include <stdlib.h>
                     18: 
                     19: OLEDBGDATA
                     20: 
                     21: /*
                     22: * OleUIEditLinks
                     23: *
                     24: * Purpose:
                     25: *  Invokes the standard OLE Edit Links dialog box allowing the user
                     26: *  to manipulate ole links (delete, update, change source, etc).
                     27: *
                     28: * Parameters:
                     29: *  lpEL            LPOLEUIEditLinks pointing to the in-out structure
                     30: *                  for this dialog.
                     31: *
                     32: * Return Value:
                     33: *  UINT            One of the following codes, indicating success or error:
                     34: *                      OLEUI_SUCCESS           Success
                     35: *                      OLEUI_ERR_STRUCTSIZE    The dwStructSize value is wrong
                     36: */
                     37: 
                     38: STDAPI_(UINT) OleUIEditLinks(LPOLEUIEDITLINKS lpEL)
                     39: {
                     40:     UINT        uRet;
                     41:     HGLOBAL     hMemDlg=NULL;
                     42: 
                     43:     uRet=UStandardValidation((LPOLEUISTANDARD)lpEL, sizeof(OLEUIEDITLINKS)
                     44:         , &hMemDlg);
                     45: 
                     46:     if (OLEUI_SUCCESS!=uRet)
                     47:         return uRet;
                     48: 
                     49:     /*
                     50:     * PERFORM ANY STRUCTURE-SPECIFIC VALIDATION HERE!
                     51:     * ON FAILURE:
                     52:     *  {
                     53:     *  if (NULL!=hMemDlg)
                     54:     *      FreeResource(hMemDlg)
                     55:     *
                     56:     *  return OLEUI_<ABBREV>ERR_<ERROR>
                     57:     *  }
                     58:     */
                     59: 
                     60:     //Now that we've validated everything, we can invoke the dialog.
                     61:     uRet=UStandardInvocation(EditLinksDialogProc, (LPOLEUISTANDARD)lpEL,
                     62:     hMemDlg, MAKEINTRESOURCE(IDD_EDITLINKS));
                     63: 
                     64:     /*
                     65:     * IF YOU ARE CREATING ANYTHING BASED ON THE RESULTS, DO IT HERE.
                     66:     */
                     67: 
                     68: 
                     69:     return uRet;
                     70: }
                     71: 
                     72: 
                     73: 
                     74: /*
                     75: * EditLinksDialogProc
                     76: *
                     77: * Purpose:
                     78: *  Implements the OLE Edit Links dialog as invoked through the
                     79: *  OleUIEditLinks function.
                     80: *
                     81: * Parameters:
                     82: *  Standard
                     83: *
                     84: * Return Value:
                     85: *  Standard
                     86: */
                     87: 
                     88: BOOL CALLBACK EXPORT EditLinksDialogProc(HWND hDlg, UINT iMsg, WPARAM wParam, LPARAM lParam)
                     89: {
                     90:     LPEDITLINKS           lpEL;
                     91:     BOOL                  fHook=FALSE;
                     92:     UINT                  uRet=0;
                     93:     HRESULT               hErr;
                     94:     static int            nColPos[3];
                     95: 
                     96:     //Declare Win16/Win32 compatible WM_COMMAND parameters.
                     97:     COMMANDPARAMS(wID, wCode, hWndMsg);
                     98: 
                     99:     //This will fail under WM_INITDIALOG, where we allocate it.
                    100:     lpEL=(LPEDITLINKS)LpvStandardEntry(hDlg, iMsg, wParam, lParam, &uRet);
                    101: 
                    102:     //If the hook processed the message, we're done.
                    103:     if (0!=uRet)
                    104:         return (BOOL)uRet;
                    105: 
                    106:         // Process help message from secondary dialog
                    107:     if (iMsg == uMsgHelp) {
                    108: 
                    109:         PostMessage(lpEL->lpOEL->hWndOwner, uMsgHelp, wParam, lParam);
                    110:         return FALSE;
                    111: 
                    112:     }
                    113: 
                    114: 
                    115:     //Process the temination message
                    116:     if (iMsg==uMsgEndDialog) {
                    117:         
                    118:         //Free any specific allocations before calling StandardCleanup
                    119: 
                    120:         StandardCleanup(lpEL, hDlg);
                    121: 
                    122:         EndDialog(hDlg, wParam);
                    123:         return TRUE;
                    124:    }
                    125: 
                    126:     switch (iMsg) {
                    127:         static int    nHeightLine = -1;
                    128:         static int    nMaxCharWidth = -1;
                    129:             
                    130:         case WM_INITDIALOG:
                    131:         {
                    132:             RECT rc;
                    133:             int  nStart;
                    134:             
                    135:             /* calculate the column positions relative to the listbox */
                    136:             GetWindowRect(GetDlgItem(hDlg, ID_EL_LINKSLISTBOX), (LPRECT)&rc);
                    137:             nStart = rc.left;
                    138:             GetWindowRect(GetDlgItem(hDlg, ID_EL_COL1), (LPRECT)&rc);
                    139:             nColPos[0] = rc.left - nStart;
                    140:             GetWindowRect(GetDlgItem(hDlg, ID_EL_COL2), (LPRECT)&rc);
                    141:             nColPos[1] = rc.left - nStart;
                    142:             GetWindowRect(GetDlgItem(hDlg, ID_EL_COL3), (LPRECT)&rc);
                    143:             nColPos[2] = rc.left - nStart;
                    144:             
                    145:             return FEditLinksInit(hDlg, wParam, lParam);
                    146:         }
                    147:         break;
                    148: 
                    149:         case WM_MEASUREITEM:
                    150:         {
                    151:             LPMEASUREITEMSTRUCT   lpMIS;
                    152: 
                    153:             lpMIS = (LPMEASUREITEMSTRUCT)lParam;
                    154: 
                    155:             if (nHeightLine == -1) {
                    156:                 HFONT hFont;
                    157:                 HDC   hDC;
                    158:                 TEXTMETRIC  tm;
                    159: 
                    160:                 /*  Attempt to get font dialog.  If that fails,
                    161:                 use system font
                    162:                 */
                    163: 
                    164:                 hFont = (HANDLE)(UINT)SendMessage(hDlg, WM_GETFONT, 0, 0L);
                    165: 
                    166:                 if (hFont == NULL)
                    167:                     hFont = GetStockObject(SYSTEM_FONT);
                    168: 
                    169:                 hDC = GetDC(hDlg);
                    170:                 hFont = SelectObject(hDC, hFont);
                    171: 
                    172:                 GetTextMetrics(hDC, &tm);
                    173:                 nHeightLine = tm.tmHeight;
                    174:                 nMaxCharWidth = tm.tmMaxCharWidth;
                    175: 
                    176:                 ReleaseDC(hDlg, hDC);
                    177:             }
                    178: 
                    179:             lpMIS->itemHeight = nHeightLine;
                    180:         }
                    181:         break;
                    182: 
                    183:         case WM_DRAWITEM:
                    184:         {
                    185:             LPDRAWITEMSTRUCT    lpDIS;
                    186:             COLORREF            crText;
                    187:             LPLINKINFO          lpLI;
                    188:             HBRUSH              hbr;
                    189:             int                 nOldBkMode;
                    190:             char                sz[OLEUI_CCHPATHMAX];
                    191:             LPSTR               lpsz;
                    192:             RECT                rcClip;
                    193:                 
                    194:             lpDIS = (LPDRAWITEMSTRUCT)lParam;
                    195:             lpLI = (LPLINKINFO)lpDIS->itemData;
                    196: 
                    197:             if ((int)lpDIS->itemID < 0)
                    198:                 break;
                    199: 
                    200:             if ((ODA_DRAWENTIRE | ODA_SELECT) & lpDIS->itemAction) {
                    201: 
                    202:                 if (ODS_SELECTED & lpDIS->itemState) {
                    203:                     /*Get proper txt colors */
                    204:                     crText = SetTextColor(lpDIS->hDC,
                    205:                             GetSysColor(COLOR_HIGHLIGHTTEXT));
                    206:                     hbr = CreateSolidBrush(GetSysColor(COLOR_HIGHLIGHT));
                    207:                     lpLI->fIsSelected = TRUE;
                    208:                 }
                    209:                 else {
                    210:                     hbr = CreateSolidBrush(GetSysColor(COLOR_WINDOW));
                    211:                     lpLI->fIsSelected = FALSE;                  
                    212:                 }
                    213: 
                    214:                 FillRect(lpDIS->hDC, &lpDIS->rcItem, hbr);
                    215:                 DeleteObject(hbr);
                    216: 
                    217:                 nOldBkMode = SetBkMode(lpDIS->hDC, TRANSPARENT);
                    218:                 
                    219:                 if (lpLI->lpszDisplayName) {
                    220:                     lstrcpy((LPSTR)sz, lpLI->lpszDisplayName);
                    221:                     lpsz = ChopText(
                    222:                             lpDIS->hwndItem, 
                    223:                             nColPos[1] - nColPos[0] 
                    224:                                   - (nMaxCharWidth > 0 ? nMaxCharWidth : 5), 
                    225:                             sz
                    226:                     );
                    227:                     rcClip.left = lpDIS->rcItem.left + nColPos[0];
                    228:                     rcClip.top = lpDIS->rcItem.top;
                    229:                     rcClip.right = lpDIS->rcItem.left + nColPos[1] 
                    230:                                     - (nMaxCharWidth > 0 ? nMaxCharWidth : 5);
                    231:                     rcClip.bottom = lpDIS->rcItem.bottom;
                    232:                     ExtTextOut(
                    233:                             lpDIS->hDC, 
                    234:                             rcClip.left, 
                    235:                             rcClip.top,
                    236:                             ETO_CLIPPED,
                    237:                             (LPRECT)&rcClip,
                    238:                             lpsz,
                    239:                             lstrlen(lpsz),
                    240:                             NULL
                    241:                     );
                    242:                 }
                    243:                 if (lpLI->lpszShortLinkType) {
                    244:                     rcClip.left = lpDIS->rcItem.left + nColPos[1];
                    245:                     rcClip.top = lpDIS->rcItem.top;
                    246:                     rcClip.right = lpDIS->rcItem.left + nColPos[2]
                    247:                                     - (nMaxCharWidth > 0 ? nMaxCharWidth : 5);
                    248:                         
                    249:                     rcClip.bottom = lpDIS->rcItem.bottom;
                    250:                     ExtTextOut(
                    251:                             lpDIS->hDC, 
                    252:                             rcClip.left, 
                    253:                             rcClip.top,
                    254:                             ETO_CLIPPED,
                    255:                             (LPRECT)&rcClip,
                    256:                             lpLI->lpszShortLinkType,
                    257:                             lstrlen(lpLI->lpszShortLinkType),
                    258:                             NULL
                    259:                     );
                    260:                 }
                    261:                 if (lpLI->lpszAMX) {
                    262:                     rcClip.left = lpDIS->rcItem.left + nColPos[2];
                    263:                     rcClip.top = lpDIS->rcItem.top;
                    264:                     rcClip.right = lpDIS->rcItem.right;
                    265:                     rcClip.bottom = lpDIS->rcItem.bottom;
                    266:                     ExtTextOut(
                    267:                             lpDIS->hDC, 
                    268:                             rcClip.left, 
                    269:                             rcClip.top,
                    270:                             ETO_CLIPPED,
                    271:                             (LPRECT)&rcClip,
                    272:                             lpLI->lpszAMX,
                    273:                             lstrlen(lpLI->lpszAMX),
                    274:                             NULL
                    275:                     );
                    276:                 }
                    277:                 
                    278:                 SetBkMode(lpDIS->hDC, nOldBkMode);
                    279: 
                    280:                 // restore orig colors if we changed them
                    281:                 if (ODS_SELECTED & lpDIS->itemState)
                    282:                     SetTextColor(lpDIS->hDC, crText);
                    283:                 
                    284:             }
                    285:             
                    286:             InitControls(hDlg);
                    287:                     
                    288:             if (ODA_FOCUS & lpDIS->itemAction)
                    289:                 DrawFocusRect(lpDIS->hDC, &lpDIS->rcItem);
                    290:                 
                    291:         }
                    292:         return TRUE;
                    293: 
                    294: 
                    295:         case WM_DELETEITEM:
                    296:         {
                    297:             UINT  idCtl;
                    298:             LPDELETEITEMSTRUCT  lpDIS;
                    299:             LPLINKINFO  lpLI;
                    300: 
                    301:             lpDIS = (LPDELETEITEMSTRUCT)lParam;
                    302:             idCtl = wParam;
                    303:             lpLI = (LPLINKINFO)lpDIS->itemData;
                    304: 
                    305:             if (lpLI->lpszDisplayName)
                    306:                 OleStdFree((LPVOID)lpLI->lpszDisplayName);
                    307:             if (lpLI->lpszShortLinkType)
                    308:                 OleStdFree((LPVOID)lpLI->lpszShortLinkType);
                    309:             if (lpLI->lpszFullLinkType)
                    310:                 OleStdFree((LPVOID)lpLI->lpszFullLinkType);
                    311: 
                    312:             /* The ChangeSource processing reuses allocated space for
                    313:             **    links that have been modified. 
                    314:             */
                    315:             // Don't free the LINKINFO for the changed links
                    316:             if (lpLI->fDontFree)
                    317:                 lpLI->fDontFree = FALSE;
                    318:             else {
                    319:                 if (lpLI->lpszAMX)
                    320:                     OleStdFree((LPVOID)lpLI->lpszAMX);
                    321:                 OleStdFree((LPVOID)lpLI);               
                    322:             }
                    323:             
                    324:             return TRUE;
                    325:         }
                    326: 
                    327:         case WM_COMPAREITEM:
                    328:         {
                    329:             LPCOMPAREITEMSTRUCT lpCIS = (LPCOMPAREITEMSTRUCT)lParam;
                    330:             LPLINKINFO lpLI1 = (LPLINKINFO)lpCIS->itemData1;
                    331:             LPLINKINFO lpLI2 = (LPLINKINFO)lpCIS->itemData2;
                    332: 
                    333:             // Sort list entries by DisplayName
                    334:             return lstrcmp(lpLI1->lpszDisplayName,lpLI2->lpszDisplayName);
                    335:         }
                    336: 
                    337:         case WM_COMMAND:
                    338:             switch (wID) {
                    339: 
                    340:             case ID_EL_CHANGESOURCE:
                    341:             {
                    342:                 BOOL fRet = FALSE;
                    343: 
                    344:                 /* This will bring up the file open dlg with one
                    345:                 edit field containing the whole link name.  The file part
                    346:                 will (eventually) be highlighted to indicate where the
                    347:                 file part is.  We need to hook on OK here to be able to
                    348:                 send the changed string to the Parse function */
                    349: 
                    350: #if !defined( PUBLISHER )
                    351:                 // PUBLISHER ONLY The Break Link button is hidden all the time
                    352:                 fRet = Container_ChangeSource(hDlg, lpEL);
                    353:                 if (!fRet)
                    354:                     PopupMessage(hDlg, IDS_LINKS, IDS_FAILED, 
                    355:                              MB_ICONEXCLAMATION | MB_OK);
                    356:                 InitControls(hDlg);                         
                    357:                 // END OF PUBLISHER ONLY
                    358: #endif                
                    359:             }
                    360:             break;
                    361:             
                    362:             case ID_EL_AUTOMATIC:
                    363:             {
                    364:                 /*  This is available for single or multi-select.  There is
                    365:                 a flag in the structure that is set initially indicating
                    366:                 whether the link is auto or manual so that we need not
                    367:                 query the link each time we want to find out.
                    368: 
                    369:                 This command will make the link automatic if not already.
                    370:                 It will have no effect on links already set to auto.
                    371:                 */
                    372:                 // turn the button ON
                    373: 
                    374:                 CheckDlgButton(hDlg, ID_EL_AUTOMATIC, 1);
                    375:                 CheckDlgButton(hDlg, ID_EL_MANUAL, 0);              
                    376: 
                    377:                 hErr = Container_AutomaticManual(hDlg, TRUE, lpEL);
                    378:                 if (hErr != NOERROR)
                    379:                     PopupMessage(hDlg, IDS_LINKS, IDS_FAILED,
                    380:                             MB_ICONEXCLAMATION | MB_OK);
                    381: 
                    382:                 InitControls(hDlg);
                    383:             }
                    384:             break;
                    385: 
                    386:             case ID_EL_MANUAL:
                    387:             {
                    388:                 /* Same rules apply here as they do to auto link.
                    389:                 Additional note - just because something is changed does
                    390:                 not mean that it updates at the moment.  It simply
                    391:                 reflects what kind of updating it does while it lives in
                    392:                 the document.
                    393:                 */
                    394:                 // turn the button ON
                    395: 
                    396:                 CheckDlgButton(hDlg, ID_EL_MANUAL, 1);
                    397:                 CheckDlgButton(hDlg, ID_EL_AUTOMATIC, 0);
                    398:                 
                    399:                 hErr = Container_AutomaticManual(hDlg, FALSE, lpEL);
                    400:                 if (hErr != NOERROR)
                    401:                     PopupMessage(hDlg, IDS_LINKS, IDS_FAILED,
                    402:                             MB_ICONEXCLAMATION | MB_OK);
                    403: 
                    404:                 InitControls(hDlg);                         
                    405:             }
                    406:             break;
                    407: 
                    408:             case ID_EL_CANCELLINK:
                    409:             {
                    410:                 /*  This is Break Link now in the dlg.  This sets the
                    411:                 moniker to null, thereby effectively breaking the link.
                    412:                 The object still has its data effective at the time of
                    413:                 breaking, but becomes a static object.
                    414:                 *****It will need to be deleted from the listbox
                    415:                 */
                    416: 
                    417: #if !defined( PUBLISHER )
                    418:                 // PUBLISHER ONLY The Break Link button is hidden all the time
                    419:                 CancelLink(hDlg,lpEL);
                    420:                 InitControls(hDlg);                         
                    421:                 // END OF PUBLISHER ONLY
                    422: #endif 
                    423:             }
                    424:             break;
                    425: 
                    426:             case ID_EL_UPDATENOW:
                    427:             {
                    428:                 /*  This forces an immediate update of the selected
                    429:                 links.  This will start the server etc, so this is a very
                    430:                 expensive operation.
                    431:                 */
                    432:                 hErr = Container_UpdateNow(hDlg, lpEL);
                    433:                 InitControls(hDlg);                         
                    434:             }
                    435:             break;
                    436: 
                    437:             case ID_EL_OPENSOURCE:
                    438:             {   
                    439:                 /*  This will only work on single selection.  It makes no
                    440:                 sense to open multiple sources at the same time, since
                    441:                 the one opened will try to show itself and become the
                    442:                 primary operating target, so to speak.  Button is greyed
                    443:                 if multi select.
                    444: 
                    445:                 Here we do not add the break because we want to exit the
                    446:                 dlg in this case.
                    447:                 */
                    448: #if !defined( PUBLISHER )
                    449:                 // PUBLISHER ONLY The Open Source button is hidden all the time
                    450:                 hErr = Container_OpenSource(hDlg, lpEL);
                    451:                 if (hErr != NOERROR) {
                    452:                     InitControls(hDlg);
                    453:                     break;      // don't close dialog
                    454:                 }
                    455:                 // END OF PUBLISHER ONLY
                    456: #endif 
                    457:             }       // fall through
                    458: 
                    459:             case ID_EL_CLOSE:
                    460:             {
                    461:                 /* The user is finished with their editing - they now
                    462:                 return to their container document.
                    463: 
                    464:                 */
                    465:                 SendMessage(hDlg, uMsgEndDialog, OLEUI_OK, 0L);
                    466:             }
                    467:             break;
                    468: 
                    469:             case IDCANCEL:
                    470:             {
                    471:                 /*  This changes to CLOSE after the user does even ONE
                    472:                 thing in the dlg.  Nothing can really effectively be undone.
                    473:                 */
                    474:                 SendMessage(hDlg, uMsgEndDialog, OLEUI_CANCEL, 0L);
                    475:             }
                    476:             break;
                    477: 
                    478:             case ID_EL_HELP:
                    479:             {
                    480:                 PostMessage(lpEL->lpOEL->hWndOwner, uMsgHelp
                    481:                     , (WPARAM)hDlg, MAKELPARAM(IDD_EDITLINKS, 0));
                    482:                 break;
                    483:             }
                    484:             break;
                    485:         }
                    486:         break;
                    487:     }
                    488: 
                    489:     return FALSE;
                    490: }
                    491: 
                    492: 
                    493: /*
                    494:  * FEditLinksInit
                    495:  *
                    496:  * Purpose:
                    497:  *  WM_INITIDIALOG handler for the Edit Links dialog box.
                    498:  *
                    499:  *
                    500:  * Parameters:
                    501:  *  hDlg            HWND of the dialog
                    502:  *  wParam          WPARAM of the message
                    503:  *  lParam          LPARAM of the message
                    504:  *
                    505:  * Return Value:
                    506:  *  BOOL            Value to return for WM_INITDIALOG.
                    507:  */
                    508: 
                    509: BOOL FEditLinksInit(HWND hDlg, WPARAM wParam, LPARAM lParam)
                    510: {
                    511:     LPEDITLINKS             lpEL;
                    512:     LPOLEUIEDITLINKS        lpOEL;
                    513:     HFONT                   hFont;
                    514:     BOOL                    fDlgItem = FALSE;
                    515:     DWORD                   dwLink = 0;
                    516:     ULONG                   cLinks;
                    517:     LPOLEUILINKCONTAINER    lpOleUILinkCntr;
                    518:     HWND                    hListBox = GetDlgItem(hDlg, ID_EL_LINKSLISTBOX);
                    519:     
                    520: 
                    521: 
                    522:     //1.  Copy the structure at lParam into our instance memory.
                    523:     lpEL = (LPEDITLINKS)LpvStandardInit(hDlg, sizeof(OLEUIEDITLINKS), TRUE, 
                    524:             &hFont);
                    525: 
                    526:     //PvStandardInit send a termination to us already.
                    527:     if (NULL==lpEL)
                    528:         return FALSE;
                    529: 
                    530:     lpOEL=(LPOLEUIEDITLINKS)lParam;
                    531: 
                    532:     lpEL->lpOEL=lpOEL;
                    533: 
                    534:     lpOleUILinkCntr = lpEL->lpOEL->lpOleUILinkContainer;
                    535: 
                    536:     cLinks = LoadLinkLB(hListBox, lpOleUILinkCntr);
                    537:     if (cLinks < 0)
                    538:         return FALSE;
                    539:     
                    540:     fDlgItem = (BOOL)cLinks;
                    541:     lpEL->fItemsExist = (BOOL)cLinks;
                    542: 
                    543: 
                    544:     InitControls(hDlg);
                    545: 
                    546:     //Copy other information from lpOEL that we might modify.
                    547: 
                    548:     //2.  If we got a font, send it to the necessary controls.
                    549:     if (NULL != hFont) {
                    550:         // Do this for as many controls as you need it for.
                    551:         // SendDlgItemMessage(hDlg, ID_<UFILL>, WM_SETFONT, (WPARAM)hFont, 0L);
                    552:     }
                    553:  
                    554: 
                    555:     //3.  Show or hide the help button
                    556:     if (!(lpEL->lpOEL->dwFlags & ELF_SHOWHELP))
                    557:         StandardShowDlgItem(hDlg, ID_EL_HELP, SW_HIDE);
                    558: 
                    559:     /*
                    560:      * PERFORM OTHER INITIALIZATION HERE.  ON ANY LoadString
                    561:      * FAILURE POST OLEUI_MSG_ENDDIALOG WITH OLEUI_ERR_LOADSTRING.
                    562:      */
                    563: 
                    564:      //n.  Call the hook with lCustData in lParam
                    565:     UStandardHook(lpEL, hDlg, WM_INITDIALOG, wParam, lpOEL->lCustData);
                    566:     
                    567:     return TRUE;
                    568: }
                    569: 
                    570: 
                    571: 
                    572: /*
                    573:  * ChangeSourceHook
                    574:  *
                    575:  * Purpose:
                    576:  *  Hooks the ChangeSource dialog to attempt to validate link source changes
                    577:  *  specified by the user.
                    578:  *
                    579:  * Parameters:
                    580:  *  hDlg            HWND of the dialog
                    581:  *  uMsg            UINT Message
                    582:  *  wParam          WPARAM of the message
                    583:  *  lParam          LPARAM of the message
                    584:  *
                    585:  * Return Value:
                    586:  *  UNIT            Zero = Do default processing; 
                    587:  *                  Non Zero = Don't do default processing.
                    588:  */
                    589: 
                    590: UINT CALLBACK EXPORT ChangeSourceHook(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
                    591: {
                    592:     static LPOPENFILENAME lpOfn;
                    593:     static LPCHANGESOURCEHOOKDATA lpCshData;
                    594:     static int  nFileLength;
                    595:     static char szFileName[OLEUI_CCHPATHMAX];
                    596:     static char szItemName[OLEUI_CCHPATHMAX];
                    597:     static BOOL bFileNameStored;
                    598:     static BOOL bItemNameStored;
                    599:     static char szEdit[OLEUI_CCHPATHMAX];
                    600:     static int  nEditLength;
                    601:     static LPLINKINFO lpLI;
                    602:     LPEDITLINKS lpEL;
                    603:     LPOLEUILINKCONTAINER lpOleUILinkCntr;
                    604:     HRESULT hErr;
                    605:     UINT uRet;
                    606:     ULONG ulChEaten;
                    607: 
                    608:     // User pressed the OK button
                    609:     if (uMsg == uMsgFileOKString) {
                    610:         
                    611:         lpEL = lpCshData->lpEL;
                    612:         lpOleUILinkCntr = lpEL->lpOEL->lpOleUILinkContainer;
                    613: 
                    614:                /* NOTE: trigger the focus lost of the edit control. This is
                    615:                **    not necessary if the user click OK with the mouse but is
                    616:                **    needed when the user just press <Enter>. If the mouse was
                    617:                **    used, no extra is done as the MODIFY flag of the edit control
                    618:                **    has been cleared.
                    619:                */
                    620:                SendMessage(hDlg, WM_COMMAND, edt1, 
                    621:                                MAKELPARAM(GetDlgItem(hDlg, edt1), EN_KILLFOCUS));
                    622:         if (bItemNameStored) {
                    623:             nFileLength = lstrlen((LPSTR)szEdit) - lstrlen((LPSTR)szItemName);
                    624:         }
                    625:         else {
                    626:             nFileLength = lstrlen((LPSTR)szEdit);
                    627:         }
                    628: 
                    629:         // Try to validate link source change
                    630:         OLEDBG_BEGIN2("IOleUILinkContainer::SetLinkSource called\r\n");
                    631:         hErr = lpOleUILinkCntr->lpVtbl->SetLinkSource(
                    632:                 lpOleUILinkCntr,
                    633:                 lpLI->dwLink,
                    634:                 (LPSTR)szEdit,
                    635:                 (ULONG)nFileLength,
                    636:                 &ulChEaten,
                    637:                 TRUE
                    638:         );
                    639:         OLEDBG_END2
                    640: 
                    641:         // Link source change  not validated
                    642:         if (hErr != NOERROR) {
                    643:             uRet =PopupMessage(hDlg, IDS_CHANGESOURCE, IDS_INVALIDSOURCE, 
                    644:                     MB_ICONQUESTION | MB_YESNO);
                    645: 
                    646:             if (uRet == IDYES) {
                    647:                 /* User wants to correct invalid link. Set the edit
                    648:                 **    control selection to the invalid part of the contents.
                    649:                 */
                    650:                 SetFocus(GetDlgItem(hDlg, edt1));
                    651:                 SendDlgItemMessage(hDlg, edt1, EM_SETSEL, 0, 
                    652:                         MAKELPARAM(ulChEaten, -1));
                    653:                 return 1; // Don't close ChangeSource dialog
                    654:             }
                    655:             else {
                    656:                 /* User does not want to correct invalid link. So set
                    657:                 **    the link source but don't validate the link.
                    658:                 */
                    659:                 OLEDBG_BEGIN2("IOleUILinkContainer::SetLinkSource called\r\n");
                    660:                 hErr = lpOleUILinkCntr->lpVtbl->SetLinkSource(
                    661:                         lpOleUILinkCntr,
                    662:                         lpLI->dwLink,
                    663:                         (LPSTR)szEdit,
                    664:                         (ULONG)nFileLength,                     
                    665:                         &ulChEaten,
                    666:                         FALSE
                    667:                 );
                    668:                 OLEDBG_END2
                    669:                 lpCshData->fValidLink = FALSE;
                    670:             }
                    671:         }
                    672:         else {     // Link source change validated
                    673:             lpCshData->fValidLink = TRUE;
                    674:         }
                    675:         
                    676:         if (bItemNameStored && bFileNameStored) {
                    677:             HWND  hListBox = GetDlgItem(lpOfn->hwndOwner, ID_EL_LINKSLISTBOX);
                    678:             
                    679:             DiffPrefix(
                    680:                     lpLI->lpszDisplayName, 
                    681:                     (LPSTR)szEdit, 
                    682:                     (char FAR* FAR*)&lpCshData->lpszFrom,
                    683:                     (char FAR* FAR*)&lpCshData->lpszTo
                    684:             );
                    685:             
                    686:             /* we keep the strings if there is a difference between the
                    687:             **    lpszFrom and lpszTo strings AND if the change is only
                    688:             **    in the file portion otherwise free them and other
                    689:             **    links won't be compared.
                    690:             */
                    691:             if ( (lstrcmp(lpCshData->lpszTo, lpCshData->lpszFrom)==0)
                    692:                     || (lstrlen(lpCshData->lpszTo) > nFileLength) ) {
                    693:                 if (lpCshData->lpszFrom) {
                    694:                     OleStdFree(lpCshData->lpszFrom);
                    695:                     lpCshData->lpszFrom = NULL;
                    696:                 }
                    697:                 if (lpCshData->lpszTo) {
                    698:                     OleStdFree(lpCshData->lpszTo);
                    699:                     lpCshData->lpszTo = NULL;
                    700:                 }
                    701:             }
                    702:         }
                    703:         
                    704:         return 0;       // Close ChangeSource dialog
                    705:     }   
                    706: 
                    707:     switch (uMsg) {
                    708:         case WM_INITDIALOG:
                    709:             lpOfn = (LPOPENFILENAME)lParam;
                    710:             lpCshData = (LPCHANGESOURCEHOOKDATA)lpOfn->lCustData;
                    711:             lpLI = lpCshData->lpLI;
                    712:             
                    713:             bFileNameStored = TRUE;
                    714:             bItemNameStored = TRUE;
                    715:             nFileLength = (int)lpLI->clenFileName;
                    716:             if (lpLI->lpszDisplayName) {
                    717:                 lstrcpyn((LPSTR)szFileName, lpLI->lpszDisplayName,
                    718:                         nFileLength + 1);
                    719:                 lstrcpy((LPSTR)szEdit, lpLI->lpszDisplayName);
                    720:             } else {
                    721:                 szFileName[0] = '\0';
                    722:                 szEdit[0] = '\0';
                    723:             }
                    724:             if (lpLI->lpszItemName) 
                    725:                 lstrcpy((LPSTR)szItemName, lpLI->lpszItemName);
                    726:             else 
                    727:                 szItemName[0] = '\0';
                    728: 
                    729:             return 0;
                    730: 
                    731:         case WM_COMMAND:
                    732:             if ((wParam == lst1) && 
                    733:                 (HIWORD(lParam) == LBN_SELCHANGE)) {
                    734:                 
                    735:                 int     nIndex;
                    736:                 HWND    hListBox = (HWND)LOWORD(lParam);
                    737: 
                    738:                 nIndex = (int)SendMessage(hListBox, LB_GETCURSEL, 0, 0L);
                    739:                 SendMessage(hListBox, LB_GETTEXT, 
                    740:                         (WPARAM)nIndex, (LPARAM)(LPSTR)szFileName);
                    741: 
                    742:                                /* need to build the full path filename for the moniker */
                    743:                                AnsiToOem(szFileName, szFileName);
                    744:                                _fullpath(szEdit, szFileName, sizeof(szEdit));
                    745:                                OemToAnsi(szEdit, szEdit);
                    746:                                
                    747:                 /* convert filename to lower case as it appears in the
                    748:                 **    listbox 
                    749:                 */
                    750:                 AnsiLower((LPSTR)szEdit);
                    751:                                lstrcpy((LPSTR)szFileName, (LPSTR)szEdit);
                    752:                                nFileLength = lstrlen((LPSTR)szEdit);
                    753:                 if (bItemNameStored)
                    754:                     lstrcat((LPSTR)szEdit, szItemName);
                    755: 
                    756:                 SetDlgItemText(hDlg, edt1, (LPSTR)szEdit);
                    757:                 nEditLength = lstrlen((LPSTR)szEdit);
                    758:                 bFileNameStored = TRUE;
                    759:                 
                    760:                 return 1;
                    761:             }
                    762:             
                    763:             if ((wParam == lst2) && 
                    764:                 (HIWORD(lParam) == LBN_SELCHANGE)) {
                    765:                 
                    766:                 if (bItemNameStored)
                    767:                     SetDlgItemText(hDlg, edt1, (LPSTR)szItemName);
                    768: 
                    769:                 return 1;
                    770:             }
                    771:             
                    772:             if ((wParam == cmb2) && 
                    773:                 (HIWORD(lParam) == CBN_SELCHANGE)) {
                    774:                 
                    775:                 if (bItemNameStored)
                    776:                     SetDlgItemText(hDlg, edt1, (LPSTR)szItemName);
                    777: 
                    778:                 return 1;
                    779:             }
                    780:             
                    781:             if (wParam == edt1) {
                    782:                 HWND hEdit = (HWND)LOWORD(lParam);
                    783:                 
                    784:                 switch (HIWORD(lParam)) {
                    785:                     case EN_SETFOCUS:
                    786:                         SendMessage(hEdit, EM_SETSEL, 0, 
                    787:                                 MAKELPARAM(0, nFileLength));
                    788:                         return 1;
                    789:                         
                    790:                     case EN_KILLFOCUS:
                    791:                         if (SendMessage(hEdit, EM_GETMODIFY, 0, 0L)) {
                    792:                             char szTmp[OLEUI_CCHPATHMAX];
                    793:                             
                    794:                             *(LPWORD)szEdit = sizeof(szEdit) - 1;
                    795:                             nEditLength = (int)SendMessage(hEdit, 
                    796:                                     EM_GETLINE, 0, (LPARAM)(LPSTR)szEdit);
                    797:                             szEdit[nEditLength] = '\0';
                    798:                             lstrcpyn((LPSTR)szTmp, (LPSTR)szEdit, 
                    799:                                     nFileLength + 1);
                    800:                                     
                    801:                             if (bFileNameStored && 
                    802:                                 !lstrcmp((LPSTR)szFileName, (LPSTR)szTmp)) {
                    803:                                     lstrcpy((LPSTR)szItemName, 
                    804:                                             (LPSTR)szEdit + nFileLength);
                    805:                                     bItemNameStored = TRUE;
                    806:                             }
                    807:                             else if (bItemNameStored && 
                    808:                                     !lstrcmp((LPSTR)szItemName, 
                    809:                                             (LPSTR)szEdit + nEditLength - 
                    810:                                             lstrlen((LPSTR)szItemName))) {
                    811:                                     lstrcpyn((LPSTR)szFileName, 
                    812:                                             (LPSTR)szEdit,
                    813:                                             nEditLength - 
                    814:                                             lstrlen((LPSTR)szItemName) + 1);
                    815:                                     bFileNameStored = TRUE;
                    816:                             }
                    817:                             else {
                    818:                                 bItemNameStored = FALSE;
                    819:                                 bFileNameStored = FALSE;
                    820:                             }
                    821:                             
                    822:                             SendMessage(hEdit, EM_SETMODIFY, FALSE, 0L);
                    823:                         }
                    824:                         return 0;
                    825:                 }
                    826:             }
                    827:             
                    828: 
                    829:             return 0;
                    830:             
                    831:         default:
                    832:             return 0;
                    833:     }
                    834: }
                    835: 
                    836: 
                    837: /*
                    838: * ChangeSource
                    839: *
                    840: * Purpose:
                    841: *  Displays the standard GetOpenFileName dialog with a customized template and
                    842: *  hook.
                    843: *
                    844: * Parameters:
                    845: *  hWndOwner       HWND owning the dialog
                    846: *  lpszFile        LPSTR specifying the initial file.  If there is no
                    847: *                  initial file the first character of this string should
                    848: *                  be a null.
                    849: *  cchFile         UINT length of pszFile
                    850: *  iFilterString   UINT index into the stringtable for the filter string.
                    851: *  lpfnBrowseHook  COMMDLGHOOKPROC hook to process link source information when user
                    852: *                                  presses OK
                    853: *  lpCshData       LPCHANGESOURCEHOOKDATA custom data that is accessible to the hook
                    854: *
                    855: * Return Value:
                    856: *  BOOL            TRUE if the user selected a file and pressed OK.
                    857: *                  FALSE otherwise, such as on pressing Cancel.
                    858: */
                    859: 
                    860: BOOL WINAPI ChangeSource(
                    861:         HWND hWndOwner,
                    862:         LPSTR lpszFile,
                    863:         UINT cchFile,
                    864:         UINT iFilterString,
                    865:         COMMDLGHOOKPROC lpfnBrowseHook,
                    866:         LPCHANGESOURCEHOOKDATA lpCshData
                    867: )
                    868: {
                    869:     UINT            cch;
                    870:     char            szFilters[OLEUI_CCHPATHMAX];
                    871:     char            szDir[OLEUI_CCHPATHMAX];    
                    872:     char            szTitle[OLEUI_CCHPATHMAX];
                    873:     OPENFILENAME    ofn;
                    874:     BOOL            fStatus;
                    875:     LPSTR           lpszFileBuffer;
                    876: 
                    877:     if (NULL==lpszFile || 0==cchFile)
                    878:         return FALSE;
                    879: 
                    880:     lpszFileBuffer = (LPSTR)OleStdMalloc(cchFile * sizeof(char));
                    881:     if (!lpszFileBuffer)
                    882:         return FALSE;
                    883: 
                    884:     lstrcpy(lpszFileBuffer, lpszFile);
                    885:     
                    886:     // Get filters
                    887:     if (0!=iFilterString)
                    888:         cch = LoadString(ghInst, iFilterString, (LPSTR)szFilters, 
                    889:                 sizeof(szFilters));
                    890:     else
                    891:     {
                    892:         szFilters[0]=0;
                    893:         cch=1;
                    894:     }
                    895:     if (0==cch) {
                    896:         fStatus = FALSE;
                    897:         goto cleanup;
                    898:     }
                    899:     
                    900:     ReplaceCharWithNull(szFilters, szFilters[cch-1]);
                    901: 
                    902:     lstrcpy((LPSTR)szDir, lpszFile);
                    903:     for (cch = lstrlen((LPSTR)szDir) - 1; cch >= 0; cch--)
                    904:         if ((szDir[cch]=='\\') || (szDir[cch]==':') || (szDir[cch]=='/')) {
                    905:             szDir[cch] = '\0';
                    906:             break;
                    907:         }
                    908: 
                    909:     LoadString(ghInst, IDS_CHANGESOURCE, (LPSTR)szTitle, sizeof(szTitle));
                    910:     _fmemset((LPOPENFILENAME)&ofn, 0, sizeof(ofn));
                    911:     ofn.lStructSize     = sizeof(ofn);
                    912:     ofn.hwndOwner       = hWndOwner;
                    913:     ofn.lpstrFile       = lpszFileBuffer;
                    914:     ofn.nMaxFile        = cchFile;
                    915:     ofn.lpstrFilter     = (LPSTR)szFilters;
                    916:     ofn.nFilterIndex    = 1;
                    917:     ofn.lpstrTitle      = (LPSTR)szTitle;
                    918:     ofn.lpstrInitialDir = (LPSTR)szDir;
                    919:     ofn.lpTemplateName  = MAKEINTRESOURCE(IDD_FILEOPEN);
                    920:     ofn.lpfnHook        = lpfnBrowseHook;
                    921:     ofn.hInstance       = ghInst;
                    922:     ofn.lCustData       = (LPARAM)lpCshData;
                    923:     ofn.Flags           = OFN_NOVALIDATE | OFN_HIDEREADONLY | 
                    924:                             OFN_ENABLETEMPLATE | OFN_ENABLEHOOK;
                    925: 
                    926:    // Only show help button if edit links dialog shows it.
                    927:    if (lpCshData->lpEL->lpOEL->dwFlags & ELF_SHOWHELP)
                    928:      ofn.Flags |= OFN_SHOWHELP;
                    929: 
                    930:     fStatus = GetOpenFileName((LPOPENFILENAME)&ofn);
                    931:     
                    932: cleanup:
                    933:     OleStdFree((LPVOID)lpszFileBuffer);
                    934:     return fStatus;
                    935: 
                    936: }
                    937: 
                    938: /*
                    939: * Container_ChangeSource
                    940: *
                    941: * Purpose:
                    942: *  Tunnel to File Open type dlg and allow user to select new file
                    943: *  for file based monikers, OR to change the whole moniker to what
                    944: *  the user types into the editable field.
                    945: *
                    946: * Parameters:
                    947: *  hDlg            HWND of the dialog
                    948: *  LPEDITLINKS     Pointer to EditLinks structure (contains all nec.
                    949: *              info)
                    950: *
                    951: * Return Value:
                    952: *  BOOL          for now, because we are not using any ole functions
                    953: *                to return an HRESULT.
                    954: *  HRESULT       HRESULT value indicating success or failure of
                    955: *              changing the moniker value
                    956: */
                    957: 
                    958: BOOL Container_ChangeSource(HWND hDlg, LPEDITLINKS lpEL)
                    959: {
                    960:     UINT        uRet;
                    961:     int         cSelItems;
                    962:     int FAR*    rgIndex;
                    963:     int         i = 0;
                    964:     LPLINKINFO  lpLI;
                    965:     HWND        hListBox = GetDlgItem(hDlg, ID_EL_LINKSLISTBOX);
                    966:     LPOLEUILINKCONTAINER lpOleUILinkCntr = lpEL->lpOEL->lpOleUILinkContainer;
                    967:     CHANGESOURCEHOOKDATA  cshData;     // Data that needs to be accessed by the ChangeSource dialog hook
                    968: 
                    969: 
                    970:     cSelItems = GetSelectedItems(hListBox, &rgIndex);
                    971: 
                    972:     if (cSelItems < 0) 
                    973:         return FALSE;
                    974:     
                    975:     if (!cSelItems) 
                    976:         return TRUE;
                    977:     
                    978:     if (!lpEL->fClose) {
                    979:         SetWindowText(GetDlgItem(hDlg, IDCANCEL), (LPSTR)szCLOSE);
                    980:         lpEL->fClose = TRUE;
                    981:     }
                    982: 
                    983:     cshData.lpEL = (LPEDITLINKS)lpEL;
                    984:     cshData.lpszFrom = NULL;
                    985:     cshData.lpszTo = NULL;
                    986:     
                    987:     for (i = cSelItems-1; i >=0; i--) {
                    988:         SendMessage(hListBox, LB_GETTEXT, rgIndex[i], 
                    989:                 (LPARAM) (LPLINKINFO FAR*) &lpLI);
                    990: 
                    991:         uRet = UStandardHook(lpEL, hDlg, uMsgBrowse, 
                    992:                 OLEUI_CCHPATHMAX, (LONG)(LPSTR)lpLI->lpszDisplayName);
                    993: 
                    994:         if (!uRet) {
                    995:             cshData.lpLI = lpLI;
                    996:             /* Bring up the ChangeSource dialog after hooking it so
                    997:             **    that the user specified link source is verified
                    998:             **    when OK is pressed.
                    999:             */
                   1000:             uRet = (UINT)ChangeSource(hDlg, lpLI->lpszDisplayName,
                   1001:                     OLEUI_CCHPATHMAX, IDS_FILTERS, ChangeSourceHook,
                   1002:                     &cshData);
                   1003:         }
                   1004: 
                   1005:         /* If Cancel is pressed in any ChangeSource dialog, stop
                   1006:         **    the ChangeSource processing for all links.
                   1007:         */
                   1008:         if (!uRet) {
                   1009:             if (rgIndex)
                   1010:                 OleStdFree(rgIndex);
                   1011:             return TRUE;
                   1012:         }
                   1013:         
                   1014:         UpdateLinkLBItem(hListBox, rgIndex[i], lpEL, TRUE);
                   1015:         
                   1016:         if (cshData.lpszFrom && cshData.lpszTo) {
                   1017:             ChangeAllLinks(hListBox, lpOleUILinkCntr, cshData.lpszFrom, 
                   1018:                     cshData.lpszTo);
                   1019:             OleStdFree(cshData.lpszFrom);
                   1020:             OleStdFree(cshData.lpszTo);
                   1021:         }
                   1022: 
                   1023:     } // end FOR
                   1024: 
                   1025:     
                   1026:     if (rgIndex)
                   1027:         OleStdFree(rgIndex);
                   1028:     
                   1029:     return TRUE;
                   1030: 
                   1031: }
                   1032: 
                   1033: 
                   1034: /*
                   1035: * Container_AutomaticManual
                   1036: *
                   1037: * Purpose:
                   1038: *   To change the selected moniker to manual or automatic update.
                   1039: *
                   1040: * Parameters:
                   1041: *  hDlg            HWND of the dialog
                   1042: *  FAutoMan        Flag indicating AUTO (TRUE/1) or MANUAL(FALSE/0)
                   1043: *  LPEDITLINKS     Pointer to EditLinks structure (contains all nec.
                   1044: *              info)
                   1045: *            * this may change - don't know how the linked list
                   1046: *            * of multi-selected items will work.
                   1047: * Return Value:
                   1048: *  HRESULT       HRESULT value indicating success or failure of
                   1049: *              changing the moniker value
                   1050: */
                   1051: 
                   1052: HRESULT Container_AutomaticManual(HWND hDlg, BOOL fAutoMan, LPEDITLINKS lpEL)
                   1053: {
                   1054: 
                   1055:     HRESULT hErr = NOERROR;
                   1056:     int cSelItems;
                   1057:     int FAR* rgIndex;
                   1058:     int i = 0;
                   1059:     LPLINKINFO  lpLI;
                   1060:     LPOLEUILINKCONTAINER lpOleUILinkCntr = lpEL->lpOEL->lpOleUILinkContainer;
                   1061:     HWND        hListBox = GetDlgItem(hDlg, ID_EL_LINKSLISTBOX);
                   1062:     BOOL        bUpdate = FALSE;
                   1063: 
                   1064:     OleDbgAssert(lpOleUILinkCntr);
                   1065: 
                   1066:     /* Change so looks at flag in structure.  Only update those that
                   1067:     need to be updated.  Make sure to change flag if status changes.
                   1068:     */
                   1069: 
                   1070:     cSelItems = GetSelectedItems(hListBox, &rgIndex);
                   1071: 
                   1072:     if (cSelItems < 0)
                   1073:         return ResultFromScode(E_FAIL);
                   1074:     
                   1075:     if (!cSelItems)
                   1076:         return NOERROR;
                   1077: 
                   1078:     if (!lpEL->fClose)
                   1079:         SetDlgItemText(hDlg, IDCANCEL, (LPSTR) szCLOSE);
                   1080: 
                   1081:     for (i = 0; i < cSelItems; i++) {
                   1082:         SendMessage(hListBox, LB_GETTEXT, (WPARAM)rgIndex[i], 
                   1083:                 (LPARAM) (LPLINKINFO FAR*) &lpLI);
                   1084: 
                   1085:         if (fAutoMan) {   // If switching to AUTOMATIC
                   1086:             if (!lpLI->fIsAuto) {   // Only change MANUAL links
                   1087:                 OLEDBG_BEGIN2("IOleUILinkContainer::SetLinkUpdateOptions called\r\n");
                   1088:                 hErr=lpOleUILinkCntr->lpVtbl->SetLinkUpdateOptions(
                   1089:                         lpOleUILinkCntr,
                   1090:                         lpLI->dwLink,
                   1091:                         OLEUPDATE_ALWAYS
                   1092:                 );
                   1093:                 OLEDBG_END2
                   1094: 
                   1095:                 lpLI->fIsAuto=TRUE;
                   1096:                 lpLI->fIsMarked = TRUE;
                   1097:                 bUpdate = TRUE;
                   1098:             }
                   1099:         }
                   1100:         else {   // If switching to MANUAL
                   1101:             if (lpLI->fIsAuto) {  // Only do AUTOMATIC Links
                   1102:                 OLEDBG_BEGIN2("IOleUILinkContainer::SetLinkUpdateOptions called\r\n");
                   1103:                 hErr=lpOleUILinkCntr->lpVtbl->SetLinkUpdateOptions(
                   1104:                         lpOleUILinkCntr,
                   1105:                         lpLI->dwLink,
                   1106:                         OLEUPDATE_ONCALL
                   1107:                 );  
                   1108:                 OLEDBG_END2
                   1109: 
                   1110:                 lpLI->fIsAuto = FALSE;
                   1111:                 lpLI->fIsMarked = TRUE;             
                   1112:                 bUpdate = TRUE;
                   1113:             }
                   1114:         }
                   1115:         
                   1116:         if (hErr != NOERROR) {
                   1117:             OleDbgOutHResult("WARNING: IOleUILinkContainer::SetLinkUpdateOptions returned",hErr);
                   1118:             break;
                   1119:         }
                   1120: 
                   1121:     }
                   1122:     
                   1123:     if (bUpdate)
                   1124:         RefreshLinkLB(hListBox, lpOleUILinkCntr);
                   1125:     
                   1126:     if (rgIndex)
                   1127:         OleStdFree((LPVOID)rgIndex);
                   1128: 
                   1129:     return hErr;
                   1130: }
                   1131: 
                   1132: 
                   1133: HRESULT CancelLink(HWND hDlg, LPEDITLINKS lpEL)
                   1134: {
                   1135:     HRESULT hErr;
                   1136:     LPMONIKER lpmk;
                   1137:     int cSelItems;
                   1138:     int FAR* rgIndex;
                   1139:     int i = 0;
                   1140:     LPLINKINFO  lpLI;
                   1141:     LPOLEUILINKCONTAINER lpOleUILinkCntr = lpEL->lpOEL->lpOleUILinkContainer;
                   1142:     HWND        hListBox = GetDlgItem(hDlg, ID_EL_LINKSLISTBOX);
                   1143:     BOOL        bUpdate = FALSE;
                   1144:     
                   1145:     OleDbgAssert(lpOleUILinkCntr);
                   1146: 
                   1147:     lpmk = NULL;
                   1148: 
                   1149:     cSelItems = GetSelectedItems(hListBox, &rgIndex);
                   1150: 
                   1151:     if (cSelItems < 0)
                   1152:         return ResultFromScode(E_FAIL);
                   1153:     
                   1154:     if (!cSelItems)
                   1155:         return NOERROR;
                   1156:     
                   1157:     if (!lpEL->fClose) {
                   1158:         SetWindowText(GetDlgItem(hDlg, IDCANCEL), (LPSTR) szCLOSE);
                   1159:         lpEL->fClose = TRUE;
                   1160:     }
                   1161: 
                   1162:     for (i = 0; i < cSelItems; i++) {
                   1163:         SendMessage(hListBox, LB_GETTEXT, (WPARAM)rgIndex[i], 
                   1164:                 (LPARAM)(LPLINKINFO FAR*) &lpLI);
                   1165: 
                   1166:         OLEDBG_BEGIN2("IOleUILinkContainer::CancelLink called\r\n");
                   1167:         hErr = lpOleUILinkCntr->lpVtbl->CancelLink(
                   1168:                 lpOleUILinkCntr,
                   1169:                 lpLI->dwLink
                   1170:         );
                   1171:         OLEDBG_END2
                   1172: 
                   1173:         if (hErr != NOERROR) {
                   1174:             OleDbgOutHResult("WARNING: IOleUILinkContainer::CancelLink returned",hErr);
                   1175:             lpLI->fIsMarked = TRUE;
                   1176:             bUpdate = TRUE;
                   1177:         }
                   1178:         else 
                   1179:             // Delete links that we make null from listbox
                   1180:             SendMessage(hListBox, LB_DELETESTRING, (WPARAM) rgIndex[i], 0L);
                   1181: 
                   1182:     }
                   1183: 
                   1184:     if (bUpdate)
                   1185:         RefreshLinkLB(hListBox, lpOleUILinkCntr);
                   1186:     
                   1187:     if (rgIndex)
                   1188:         OleStdFree((LPVOID)rgIndex);
                   1189:     
                   1190:     return hErr;
                   1191: 
                   1192: }
                   1193: 
                   1194: 
                   1195: /*
                   1196:  * Container_UpdateNow
                   1197:  *
                   1198:  * Purpose:
                   1199:  *   Immediately force an update for all (manual) links
                   1200:  * 
                   1201:  * Parameters:
                   1202:  *  hDlg            HWND of the dialog
                   1203:  *  LPEDITLINKS     Pointer to EditLinks structure (contains all nec. info)
                   1204:  *            * this may change - don't know how the linked list
                   1205:  *            * of multi-selected items will work.
                   1206:  * Return Value:
                   1207:  *  HRESULT       HRESULT value indicating success or failure of
                   1208:  *              changing the moniker value
                   1209:  */
                   1210: 
                   1211: HRESULT Container_UpdateNow(HWND hDlg, LPEDITLINKS lpEL)
                   1212: {
                   1213:     HRESULT         hErr;
                   1214:     LPLINKINFO      lpLI;
                   1215:     int cSelItems;
                   1216:     int FAR* rgIndex;
                   1217:     int i = 0;
                   1218:     LPOLEUILINKCONTAINER lpOleUILinkCntr = lpEL->lpOEL->lpOleUILinkContainer;
                   1219:     HWND        hListBox = GetDlgItem(hDlg, ID_EL_LINKSLISTBOX);
                   1220:     BOOL        bUpdate = FALSE;
                   1221:     
                   1222:     OleDbgAssert(lpOleUILinkCntr);
                   1223: 
                   1224:     cSelItems = GetSelectedItems(hListBox, &rgIndex);
                   1225: 
                   1226:     if (cSelItems < 0)
                   1227:         return ResultFromScode(E_FAIL);
                   1228:     
                   1229:     if (!cSelItems)
                   1230:         return NOERROR;
                   1231: 
                   1232:     if (!lpEL->fClose) {
                   1233:         SetWindowText(GetDlgItem(hDlg, IDCANCEL), (LPSTR) szCLOSE);
                   1234:         lpEL->fClose = TRUE;
                   1235:     }
                   1236: 
                   1237:     for (i = 0; i < cSelItems; i++) {
                   1238:         SendMessage(hListBox, LB_GETTEXT,
                   1239:                 (WPARAM)rgIndex[i], (LPARAM)(LPLINKINFO FAR*)&lpLI);
                   1240: 
                   1241:         OLEDBG_BEGIN2("IOleUILinkContainer::UpdateLink called\r\n");
                   1242:         hErr = lpOleUILinkCntr->lpVtbl->UpdateLink(
                   1243:                 lpOleUILinkCntr,
                   1244:                 lpLI->dwLink,
                   1245:                 TRUE,
                   1246:                 FALSE
                   1247:         );
                   1248:         OLEDBG_END2
                   1249:         bUpdate = TRUE;
                   1250:     
                   1251:         if (hErr != NOERROR) {
                   1252:             OleDbgOutHResult("WARNING: IOleUILinkContainer::UpdateLink returned",hErr);
                   1253:             break;
                   1254:         }
                   1255: 
                   1256:     }
                   1257: 
                   1258:     if (bUpdate)
                   1259:         RefreshLinkLB(hListBox, lpOleUILinkCntr);
                   1260:     
                   1261:     if (rgIndex)
                   1262:         OleStdFree((LPVOID)rgIndex);
                   1263:     
                   1264:     return hErr;
                   1265: 
                   1266: }
                   1267: 
                   1268: /*
                   1269:  * Container_OpenSource
                   1270:  *
                   1271:  * Purpose:
                   1272:  *   Immediately force an update for all (manual) links
                   1273:  *
                   1274:  * Parameters:
                   1275:  *  hDlg            HWND of the dialog
                   1276:  *  LPEDITLINKS     Pointer to EditLinks structure (contains all nec.
                   1277:  *              info)
                   1278:  *
                   1279:  * Return Value:
                   1280:  *  HRESULT       HRESULT value indicating success or failure of
                   1281:  *              changing the moniker value
                   1282:  */
                   1283: 
                   1284: HRESULT Container_OpenSource(HWND hDlg, LPEDITLINKS lpEL)
                   1285: {
                   1286:     HRESULT         hErr;
                   1287:     int             cSelItems;
                   1288:     int FAR*        rgIndex;
                   1289:     LPLINKINFO      lpLI;
                   1290:     RECT            rcPosRect;
                   1291:     LPOLEUILINKCONTAINER lpOleUILinkCntr = lpEL->lpOEL->lpOleUILinkContainer;
                   1292:     HWND            hListBox = GetDlgItem(hDlg, ID_EL_LINKSLISTBOX);
                   1293:     
                   1294:     OleDbgAssert(lpOleUILinkCntr);
                   1295: 
                   1296:     rcPosRect.top = 0;
                   1297:     rcPosRect.left = 0;
                   1298:     rcPosRect.right = 0;
                   1299:     rcPosRect.bottom = 0;
                   1300: 
                   1301:     cSelItems = GetSelectedItems(hListBox, &rgIndex);
                   1302: 
                   1303:     if (cSelItems < 0)
                   1304:         return ResultFromScode(E_FAIL);
                   1305:     
                   1306:     if (cSelItems != 1)     // can't open source for multiple items
                   1307:         return NOERROR;     
                   1308: 
                   1309:     if (!lpEL->fClose) {
                   1310:         SetWindowText(GetDlgItem(hDlg, IDCANCEL), (LPSTR) szCLOSE);
                   1311:         lpEL->fClose = TRUE;
                   1312:     }
                   1313:     
                   1314:     SendMessage(hListBox, LB_GETTEXT, (WPARAM)rgIndex[0], 
                   1315:             (LPARAM)(LPLINKINFO FAR*)&lpLI);
                   1316: 
                   1317:     OLEDBG_BEGIN2("IOleUILinkContainer::OpenLinkSource called\r\n");
                   1318:     hErr = lpOleUILinkCntr->lpVtbl->OpenLinkSource(
                   1319:             lpOleUILinkCntr,
                   1320:             lpLI->dwLink
                   1321:     );
                   1322:     OLEDBG_END2
                   1323: 
                   1324:     UpdateLinkLBItem(hListBox, rgIndex[0], lpEL, TRUE);
                   1325:     if (hErr != NOERROR)
                   1326:         OleDbgOutHResult("WARNING: IOleUILinkContainer::OpenLinkSource returned",hErr);
                   1327:     
                   1328:     if (rgIndex)
                   1329:         OleStdFree((LPVOID)rgIndex);
                   1330:     
                   1331:     return hErr;
                   1332: }
                   1333: 
                   1334: 
                   1335: 
                   1336: /* AddLinkLBItem
                   1337: ** -------------
                   1338: **    
                   1339: **    Add the item pointed to by lpLI to the Link ListBox and return
                   1340: **    the index of it in the ListBox
                   1341: */
                   1342: int AddLinkLBItem(HWND hListBox, LPOLEUILINKCONTAINER lpOleUILinkCntr, LPLINKINFO lpLI, BOOL fGetSelected)
                   1343: {
                   1344:     HRESULT hErr;
                   1345:     DWORD dwUpdateOpt;
                   1346:     int nIndex;
                   1347: 
                   1348:     OleDbgAssert(lpOleUILinkCntr && hListBox && lpLI);
                   1349: 
                   1350:     lpLI->fDontFree = FALSE;
                   1351:     
                   1352:     OLEDBG_BEGIN2("IOleUILinkContainer::GetLinkSource called\r\n");
                   1353:     hErr = lpOleUILinkCntr->lpVtbl->GetLinkSource(
                   1354:             lpOleUILinkCntr,
                   1355:             lpLI->dwLink,
                   1356:             (LPSTR FAR*)&lpLI->lpszDisplayName,
                   1357:             (ULONG FAR*)&lpLI->clenFileName,
                   1358:             (LPSTR FAR*)&lpLI->lpszFullLinkType,
                   1359:             (LPSTR FAR*)&lpLI->lpszShortLinkType,
                   1360:             (BOOL FAR*)&lpLI->fSourceAvailable,
                   1361:             fGetSelected ? (BOOL FAR*)&lpLI->fIsSelected : NULL
                   1362:     );
                   1363:     OLEDBG_END2
                   1364: 
                   1365:     if (hErr != NOERROR) {
                   1366:         OleDbgOutHResult("WARNING: IOleUILinkContainer::GetLinkSource returned",hErr);
                   1367:         PopupMessage(hListBox, IDS_LINKS, IDS_ERR_GETLINKSOURCE, 
                   1368:                 MB_ICONEXCLAMATION | MB_OK);
                   1369:                     
                   1370:         goto cleanup;
                   1371:     }
                   1372: 
                   1373:     OLEDBG_BEGIN2("IOleUILinkContainer::GetLinkUpdateOptions called\r\n");
                   1374:     hErr=lpOleUILinkCntr->lpVtbl->GetLinkUpdateOptions(
                   1375:             lpOleUILinkCntr,
                   1376:             lpLI->dwLink,
                   1377:             (LPDWORD)&dwUpdateOpt
                   1378:     );
                   1379:     OLEDBG_END2
                   1380: 
                   1381: 
                   1382:     if (hErr != NOERROR) {
                   1383:         OleDbgOutHResult("WARNING: IOleUILinkContainer::GetLinkUpdateOptions returned",hErr);
                   1384:         PopupMessage(hListBox, IDS_LINKS, IDS_ERR_GETLINKUPDATEOPTIONS, 
                   1385:                 MB_ICONEXCLAMATION | MB_OK);
                   1386:         
                   1387:         goto cleanup;
                   1388:     }
                   1389: 
                   1390:     if (lpLI->fSourceAvailable) {
                   1391:         if (dwUpdateOpt == OLEUPDATE_ALWAYS) {
                   1392:             lpLI->fIsAuto = TRUE;
                   1393:             LoadString(ghInst, IDS_LINK_AUTO, lpLI->lpszAMX, 
                   1394:                     (int)OleStdGetSize((LPVOID)lpLI->lpszAMX));
                   1395:         }
                   1396:         else {
                   1397:             lpLI->fIsAuto = FALSE;
                   1398:             LoadString(ghInst, IDS_LINK_MANUAL, lpLI->lpszAMX,
                   1399:                     (int)OleStdGetSize((LPVOID)lpLI->lpszAMX));
                   1400:         }
                   1401:     }
                   1402:     else
                   1403:         LoadString(ghInst, IDS_LINK_UNKNOWN, lpLI->lpszAMX, 
                   1404:                 (int)OleStdGetSize((LPVOID)lpLI->lpszAMX));
                   1405:                 
                   1406:     BreakString(lpLI);
                   1407: 
                   1408:     nIndex = (int)SendMessage(hListBox, LB_ADDSTRING, (WPARAM)0, 
                   1409:             (LPARAM)(DWORD)lpLI);
                   1410: 
                   1411:     if (nIndex == LB_ERR) {
                   1412:         PopupMessage(hListBox, IDS_LINKS, IDS_ERR_ADDSTRING, 
                   1413:                 MB_ICONEXCLAMATION | MB_OK);
                   1414: 
                   1415:         goto cleanup;
                   1416:     }
                   1417: 
                   1418:     return nIndex;
                   1419: 
                   1420: cleanup:
                   1421:     if (lpLI->lpszDisplayName)
                   1422:         OleStdFree((LPVOID)lpLI->lpszDisplayName);
                   1423: 
                   1424:     if (lpLI->lpszShortLinkType)
                   1425:         OleStdFree((LPVOID)lpLI->lpszShortLinkType);
                   1426: 
                   1427:     if (lpLI->lpszFullLinkType)
                   1428:         OleStdFree((LPVOID)lpLI->lpszFullLinkType);
                   1429: 
                   1430:     return -1;
                   1431: }
                   1432: 
                   1433: 
                   1434: /* BreakString
                   1435:  * -----------
                   1436:  *
                   1437:  *  Purpose:
                   1438:  *      Break the lpszDisplayName into various parts
                   1439:  *
                   1440:  *  Parameters:
                   1441:  *      lpLI            pointer to LINKINFO structure
                   1442:  *
                   1443:  *  Returns:
                   1444:  *
                   1445:  */
                   1446: VOID BreakString(LPLINKINFO lpLI)
                   1447: {
                   1448:     LPSTR lpsz;
                   1449:     
                   1450:     if (!lpLI->clenFileName ||
                   1451:         (lstrlen(lpLI->lpszDisplayName)==(int)lpLI->clenFileName)) {
                   1452: 
                   1453:         lpLI->lpszItemName = NULL;
                   1454:     }
                   1455:     else {
                   1456:         lpLI->lpszItemName = lpLI->lpszDisplayName + lpLI->clenFileName;
                   1457:     }
                   1458:     
                   1459:     // search from last character of filename
                   1460:     lpsz = lpLI->lpszDisplayName + lstrlen(lpLI->lpszDisplayName);
                   1461:     while (lpsz > lpLI->lpszDisplayName) {
                   1462:         lpsz = AnsiPrev(lpLI->lpszDisplayName, lpsz);
                   1463:         if ((*lpsz == '\\') || (*lpsz == '/') || (*lpsz == ':'))
                   1464:             break;
                   1465:     }
                   1466:     
                   1467:     if (lpsz == lpLI->lpszDisplayName)
                   1468:         lpLI->lpszShortFileName = lpsz;     
                   1469:     else
                   1470:         lpLI->lpszShortFileName = AnsiNext(lpsz);       
                   1471: }
                   1472: 
                   1473: 
                   1474: /* GetSelectedItems
                   1475:  * ----------------
                   1476:  *
                   1477:  *  Purpose:
                   1478:  *      Retrieve the indices of the selected items in the listbox
                   1479:  *      Note that *lprgIndex needed to be free after using the function
                   1480:  *
                   1481:  *  Parameters:
                   1482:  *      hListBox        window handle of listbox
                   1483:  *      lprgIndex       pointer to an integer array to receive the indices
                   1484:  *                      must be freed afterwards
                   1485:  *
                   1486:  *  Returns:
                   1487:  *      number of indices retrieved, -1 if error
                   1488:  */
                   1489: int GetSelectedItems(HWND hListBox, int FAR* FAR* lprgIndex)
                   1490: {
                   1491:     DWORD cSelItems;
                   1492:     DWORD cCheckItems;
                   1493: 
                   1494:     *lprgIndex = NULL;
                   1495: 
                   1496:     cSelItems = SendMessage(hListBox, LB_GETSELCOUNT, 0, 0L);
                   1497:     if (cSelItems < 0)      // error
                   1498:         return (int)cSelItems;
                   1499: 
                   1500:     if (!cSelItems)
                   1501:         return 0;
                   1502: 
                   1503:     *lprgIndex = (int FAR*)OleStdMalloc((int)cSelItems * sizeof(int));
                   1504: 
                   1505:     cCheckItems = SendMessage(hListBox, LB_GETSELITEMS,
                   1506:             (WPARAM) cSelItems, (LPARAM) (int FAR*) *lprgIndex);
                   1507: 
                   1508:     if (cCheckItems == cSelItems)
                   1509:         return (int)cSelItems;
                   1510:     else {
                   1511:         if (*lprgIndex)
                   1512:             OleStdFree((LPVOID)*lprgIndex);
                   1513:         *lprgIndex = NULL;
                   1514:         return 0;
                   1515:     }
                   1516: }
                   1517: 
                   1518: 
                   1519: /* InitControls
                   1520:  * ------------
                   1521:  *
                   1522:  *  Purpose:
                   1523:  *      Initialize the state of the Auto/Manual button, Link source/type 
                   1524:  *      static field, etc in the dialogs according to the selection in the
                   1525:  *      listbox
                   1526:  *
                   1527:  *  Parameters:
                   1528:  *      hDlg        handle to the dialog window
                   1529:  */
                   1530: VOID InitControls(HWND hDlg)
                   1531: {
                   1532:     int         cSelItems;
                   1533:     HWND        hListBox;
                   1534:     int         i;
                   1535:     int FAR*    rgIndex;
                   1536:     LPLINKINFO  lpLI;
                   1537:     LPSTR       lpszType = NULL;
                   1538:     LPSTR       lpszSource = NULL;
                   1539:     int         cAuto = 0;
                   1540:     int         cManual = 0;
                   1541:     BOOL        bSameType = TRUE;
                   1542:     BOOL        bSameSource = TRUE;
                   1543:     char        sz[OLEUI_CCHPATHMAX];
                   1544:     LPSTR       lpsz;
                   1545:     
                   1546:     
                   1547:     hListBox = GetDlgItem(hDlg, ID_EL_LINKSLISTBOX);
                   1548: 
                   1549:     cSelItems = GetSelectedItems(hListBox, &rgIndex);
                   1550:     if (cSelItems < 0)
                   1551:         return;
                   1552: 
                   1553:     EnableWindow(GetDlgItem(hDlg, ID_EL_AUTOMATIC), (BOOL)cSelItems);
                   1554:     EnableWindow(GetDlgItem(hDlg, ID_EL_MANUAL), (BOOL)cSelItems); 
                   1555: 
                   1556:     // PUBLISHER ONLY hide the buttons that don't work: "Break Link",
                   1557:     //    "Open Source", "Change Source".  We'll fix them later.
                   1558: 
                   1559: #if !defined( PUBLISHER )
                   1560:     EnableWindow(GetDlgItem(hDlg, ID_EL_CANCELLINK), (BOOL)cSelItems);
                   1561: #else 
                   1562:     EnableWindow(GetDlgItem(hDlg, ID_EL_CANCELLINK), FALSE);
                   1563:     ShowWindow(GetDlgItem(hDlg, ID_EL_CANCELLINK), SW_HIDE);
                   1564: #endif 
                   1565: 
                   1566: #if !defined( PUBLISHER )
                   1567:     EnableWindow(GetDlgItem(hDlg, ID_EL_OPENSOURCE), cSelItems == 1);       
                   1568: #else 
                   1569:     EnableWindow(GetDlgItem(hDlg, ID_EL_OPENSOURCE), FALSE);
                   1570:     ShowWindow(GetDlgItem(hDlg, ID_EL_OPENSOURCE), SW_HIDE);
                   1571: #endif 
                   1572: 
                   1573: #if !defined( PUBLISHER )
                   1574:     EnableWindow(GetDlgItem(hDlg, ID_EL_CHANGESOURCE), cSelItems == 1);
                   1575: #else 
                   1576:     EnableWindow(GetDlgItem(hDlg, ID_EL_CHANGESOURCE), FALSE);
                   1577:     ShowWindow(GetDlgItem(hDlg, ID_EL_CHANGESOURCE), SW_HIDE);
                   1578: #endif 
                   1579:     // END OF PUBLISHER ONLY
                   1580: 
                   1581:     EnableWindow(GetDlgItem(hDlg, ID_EL_UPDATENOW), (BOOL)cSelItems);
                   1582:     
                   1583:     for (i = 0; i < cSelItems; i++) {
                   1584:         SendDlgItemMessage(
                   1585:                 hDlg, 
                   1586:                 ID_EL_LINKSLISTBOX,
                   1587:                 LB_GETTEXT, 
                   1588:                 (WPARAM)rgIndex[i],
                   1589:                 (LPARAM)(LPLINKINFO FAR*)&lpLI);
                   1590: 
                   1591:         if (lpszSource && lpLI->lpszDisplayName) {
                   1592:             if (bSameSource && lstrcmp(lpszSource, lpLI->lpszDisplayName)) {
                   1593:                 bSameSource = FALSE;
                   1594:             }
                   1595:         }
                   1596:         else
                   1597:             lpszSource = lpLI->lpszDisplayName;
                   1598: 
                   1599:         if (lpszType && lpLI->lpszFullLinkType) {
                   1600:             if (bSameType && lstrcmp(lpszType, lpLI->lpszFullLinkType)) {
                   1601:                 bSameType = FALSE;
                   1602:             }
                   1603:         }
                   1604:         else
                   1605:             lpszType = lpLI->lpszFullLinkType;
                   1606:         
                   1607:         if (lpLI->fIsAuto)
                   1608:             cAuto++;
                   1609:         else
                   1610:             cManual++;
                   1611:     }
                   1612: 
                   1613:     CheckDlgButton(hDlg, ID_EL_AUTOMATIC, cAuto && !cManual);
                   1614:     CheckDlgButton(hDlg, ID_EL_MANUAL, !cAuto && cManual);
                   1615: 
                   1616:     /* fill full source in static text box
                   1617:     **    below list 
                   1618:     */
                   1619:     if (!bSameSource || !lpszSource)
                   1620:         lpszSource = szNULL;
                   1621:     lstrcpy((LPSTR)sz, lpszSource);
                   1622:     lpsz = ChopText(GetDlgItem(hDlg, ID_EL_LINKSOURCE), 0, sz);
                   1623:     SetDlgItemText(hDlg, ID_EL_LINKSOURCE, lpsz);
                   1624: 
                   1625:     /* fill full link type name in static
                   1626:     **    "type" text box
                   1627:     */
                   1628:     if (!bSameType || !lpszType)
                   1629:         lpszType = szNULL;
                   1630:     SetDlgItemText(hDlg, ID_EL_LINKTYPE, lpszType);
                   1631: 
                   1632:     if (rgIndex)
                   1633:         OleStdFree((LPVOID)rgIndex);
                   1634: }   
                   1635: 
                   1636: 
                   1637: /* UpdateLinkLBItem
                   1638:  * -----------------
                   1639:  *
                   1640:  *  Purpose:
                   1641:  *      Update the linkinfo struct in the listbox to reflect the changes
                   1642:  *      made by the last operation. It is done simply by removing the item
                   1643:  *      from the listbox and add it back. 
                   1644:  *
                   1645:  *  Parameters:
                   1646:  *      hListBox        handle of listbox
                   1647:  *      nIndex          index of listbox item
                   1648:  *      lpEL            pointer to editlinks structure
                   1649:  *      bSelect         select the item or not after update
                   1650:  */
                   1651: VOID UpdateLinkLBItem(HWND hListBox, int nIndex, LPEDITLINKS lpEL, BOOL bSelect)
                   1652: {
                   1653:     LPLINKINFO lpLI;
                   1654:     DWORD       dwErr;
                   1655:     LPOLEUILINKCONTAINER    lpOleUILinkCntr;    
                   1656:     
                   1657:     if (!hListBox || (nIndex < 0) || !lpEL)
                   1658:         return;
                   1659: 
                   1660:     lpOleUILinkCntr = lpEL->lpOEL->lpOleUILinkContainer;
                   1661:     
                   1662:     dwErr = SendMessage(hListBox, LB_GETTEXT, nIndex, 
                   1663:             (LPARAM)(LPLINKINFO FAR*) &lpLI);
                   1664:             
                   1665:     if ((dwErr == LB_ERR) || !lpLI)
                   1666:         return;
                   1667:     
                   1668:     /* Don't free the data associated with this listbox item
                   1669:     **    because we are going to reuse the allocated space for
                   1670:     **    the modified link. WM_DELETEITEM processing in the
                   1671:     **    dialog checks this flag before deleting data
                   1672:     **    associcated with list item.
                   1673:     */
                   1674:     lpLI->fDontFree = TRUE; 
                   1675:     SendMessage(hListBox, LB_DELETESTRING, nIndex, 0L);
                   1676:     
                   1677:     nIndex = AddLinkLBItem(hListBox, lpOleUILinkCntr, lpLI, FALSE);   
                   1678:     if (bSelect)
                   1679:         SendMessage(hListBox, LB_SETSEL, (WPARAM)TRUE, MAKELPARAM(nIndex, 0));
                   1680: }
                   1681: 
                   1682: 
                   1683: 
                   1684: /* DiffPrefix
                   1685:  * ----------
                   1686:  *
                   1687:  *  Purpose:
                   1688:  *      Compare (case-insensitive) two strings and return the prefixes of the
                   1689:  *      the strings formed by removing the common suffix string from them.
                   1690:  *      Integrity of tokens (directory name, filename and object names) are
                   1691:  *      preserved. Note that the prefixes are converted to upper case 
                   1692:  *      characters.
                   1693:  *
                   1694:  *  Parameters:
                   1695:  *      lpsz1           string 1
                   1696:  *      lpsz2           string 2
                   1697:  *      lplpszPrefix1   prefix of string 1
                   1698:  *      lplpszPrefix2   prefix of string 2
                   1699:  *
                   1700:  *  Returns:
                   1701:  *      
                   1702:  */
                   1703: VOID DiffPrefix(LPCSTR lpsz1, LPCSTR lpsz2, char FAR* FAR* lplpszPrefix1, char FAR* FAR* lplpszPrefix2)
                   1704: {
                   1705:     LPSTR   lpstr1;
                   1706:     LPSTR   lpstr2;
                   1707:     
                   1708:     OleDbgAssert(lpsz1 && lpsz2 && *lpsz1 && *lpsz2 && lplpszPrefix1 && 
                   1709:             lplpszPrefix2);
                   1710:     
                   1711:     *lplpszPrefix1 = NULL;
                   1712:     *lplpszPrefix2 = NULL;
                   1713:     *lplpszPrefix1 = OleStdMalloc((lstrlen(lpsz1)+1) * sizeof(BYTE));
                   1714:     if (!*lplpszPrefix1)
                   1715:         return;
                   1716: 
                   1717:     *lplpszPrefix2 = OleStdMalloc((lstrlen(lpsz2)+1) * sizeof(BYTE));
                   1718:     if (!*lplpszPrefix2) {
                   1719:         OleStdFree(*lplpszPrefix1);
                   1720:         *lplpszPrefix1 = NULL;
                   1721:         return;
                   1722:     }
                   1723:     
                   1724:     lstrcpy(*lplpszPrefix1, lpsz1);
                   1725:     lstrcpy(*lplpszPrefix2, lpsz2);
                   1726: //  AnsiLower(*lplpszPrefix1);
                   1727: //  AnsiLower(*lplpszPrefix2);
                   1728:     
                   1729:     lpstr1 = *lplpszPrefix1 + lstrlen(*lplpszPrefix1);
                   1730:     lpstr2 = *lplpszPrefix2 + lstrlen(*lplpszPrefix2);
                   1731:     
                   1732:     while ((lpstr1>*lplpszPrefix1) && (lpstr2>*lplpszPrefix2)) {
                   1733:         lpstr1 = AnsiPrev(*lplpszPrefix1, lpstr1);
                   1734:         lpstr2 = AnsiPrev(*lplpszPrefix2, lpstr2);
                   1735:         if (*lpstr1 != *lpstr2) {
                   1736:             lpstr1 = AnsiNext(lpstr1);
                   1737:             lpstr2 = AnsiNext(lpstr2);
                   1738:             break;
                   1739:         }
                   1740:     }
                   1741:     
                   1742:     for (; *lpstr1 && *lpstr1!='\\' && *lpstr1!='!'; lpstr1=AnsiNext(lpstr1));
                   1743:     for (; *lpstr2 && *lpstr2!='\\' && *lpstr2!='!'; lpstr2=AnsiNext(lpstr2));
                   1744: 
                   1745:     *lpstr1 = '\0';
                   1746:     *lpstr2 = '\0';
                   1747: }
                   1748: 
                   1749: 
                   1750: /* PopupMessage
                   1751:  * ------------
                   1752:  *
                   1753:  *  Purpose:
                   1754:  *      Popup s messagebox and get some response from the user. It is the same
                   1755:  *      as MessageBox() except that the title and message string are loaded 
                   1756:  *      from the resource file.
                   1757:  *
                   1758:  *  Parameters:
                   1759:  *      hwndParent      parent window of message box
                   1760:  *      idTitle         id of title string
                   1761:  *      idMessage       id of message string
                   1762:  *      fuStyle         style of message box
                   1763:  */
                   1764: int PopupMessage(HWND hwndParent, UINT idTitle, UINT idMessage, UINT fuStyle)
                   1765: {
                   1766:     char szTitle[256];
                   1767:     char szMsg[256];
                   1768:     
                   1769:     LoadString(ghInst, idTitle, (LPSTR)szTitle, sizeof(szTitle));
                   1770:     LoadString(ghInst, idMessage, (LPSTR)szMsg, sizeof(szMsg));
                   1771:     return MessageBox(hwndParent, szMsg, szTitle, fuStyle);
                   1772: }
                   1773: 
                   1774: 
                   1775: /* ChangeAllLinks
                   1776:  * --------------
                   1777:  *
                   1778:  *  Purpose:
                   1779:  *      Enumerate all the links in the listbox and change those starting
                   1780:  *      with lpszFrom to lpszTo.
                   1781:  *
                   1782:  *  Parameters:
                   1783:  *      hListBox        window handle of 
                   1784:  *      lpOleUILinkCntr pointer to OleUI Link Container
                   1785:  *      lpszFrom        prefix for matching
                   1786:  *      lpszTo          prefix to substitution
                   1787:  *
                   1788:  *  Returns:
                   1789:  */
                   1790: VOID ChangeAllLinks(HWND hListBox, LPOLEUILINKCONTAINER lpOleUILinkCntr, LPSTR lpszFrom, LPSTR lpszTo)
                   1791: {
                   1792:     int     cItems;
                   1793:     int     nIndex;
                   1794:     int     cFrom;
                   1795:     LPLINKINFO  lpLI;
                   1796:     LPSTR   szTmp[OLEUI_CCHPATHMAX];
                   1797:     BOOL    bFound;
                   1798:     
                   1799:     cFrom = lstrlen(lpszFrom);
                   1800: 
                   1801:     cItems = (int)SendMessage(hListBox, LB_GETCOUNT, 0, 0L);
                   1802:     OleDbgAssert(cItems >= 0);
                   1803:     
                   1804:     bFound = FALSE;
                   1805:     
                   1806:     OleDbgPrint(3, "From : ", lpszFrom, 0);
                   1807:     OleDbgPrint(3, "", "\r\n", 0);  
                   1808:     OleDbgPrint(3, "To   : ", lpszTo, 0);
                   1809:     OleDbgPrint(3, "", "\r\n", 0);  
                   1810: 
                   1811:     for (nIndex=0; nIndex<cItems; nIndex++) {
                   1812:         SendMessage(hListBox, LB_GETTEXT, nIndex, 
                   1813:                 (LPARAM)(LPLINKINFO FAR*)&lpLI);
                   1814:         
                   1815:         // unmark the item
                   1816:         lpLI->fIsMarked = FALSE;
                   1817:         
                   1818:         /* if the corresponding position for the end of lpszFrom in the 
                   1819:         **    display name is not a separator. We stop comparing this
                   1820:         **    link. 
                   1821:         */
                   1822:         if (!*(lpLI->lpszDisplayName + cFrom) || 
                   1823:             (*(lpLI->lpszDisplayName + cFrom) == '\\') ||
                   1824:             (*(lpLI->lpszDisplayName + cFrom) == '!')) {
                   1825: 
                   1826:             lstrcpyn((LPSTR)szTmp, lpLI->lpszDisplayName, cFrom + 1);
                   1827:             if (!lstrcmp((LPSTR)szTmp, lpszFrom)) {
                   1828:                 HRESULT hErr;
                   1829:                 int nFileLength;
                   1830:                 ULONG ulDummy;
                   1831:                 
                   1832:                 if (!bFound) {
                   1833:                     char szTitle[256];
                   1834:                     char szMsg[256];
                   1835:                     char szBuf[256];
                   1836:                     int uRet;
                   1837:                     
                   1838:                     LoadString(ghInst, IDS_CHANGESOURCE, (LPSTR)szTitle, 
                   1839:                             sizeof(szTitle));
                   1840:                     LoadString(ghInst, IDS_CHANGEADDITIONALLINKS, 
                   1841:                             (LPSTR)szMsg, sizeof(szMsg));
                   1842:                     wsprintf((LPSTR)szBuf, (LPSTR)szMsg, lpszFrom); 
                   1843:                     uRet = MessageBox(hListBox, (LPSTR)szBuf, (LPSTR)szTitle, 
                   1844:                             MB_ICONQUESTION | MB_YESNO);
                   1845:                     if (uRet == IDYES)
                   1846:                         bFound = TRUE;
                   1847:                     else
                   1848:                         return;         // exit function
                   1849:                 }
                   1850:                 
                   1851:                 lstrcpy((LPSTR)szTmp, lpszTo);
                   1852:                 lstrcat((LPSTR)szTmp, lpLI->lpszDisplayName + cFrom);
                   1853:                 nFileLength = lstrlen((LPSTR)szTmp) -
                   1854:                     (lpLI->lpszItemName ? lstrlen(lpLI->lpszItemName) : 0);
                   1855: 
                   1856:                 
                   1857:                 hErr = lpOleUILinkCntr->lpVtbl->SetLinkSource(
                   1858:                         lpOleUILinkCntr,
                   1859:                         lpLI->dwLink,
                   1860:                         (LPSTR)szTmp,
                   1861:                         (ULONG)nFileLength,
                   1862:                         (ULONG FAR*)&ulDummy,
                   1863:                         TRUE
                   1864:                 );
                   1865:                 if (hErr != NOERROR)
                   1866:                     lpOleUILinkCntr->lpVtbl->SetLinkSource(
                   1867:                             lpOleUILinkCntr,
                   1868:                             lpLI->dwLink,
                   1869:                             (LPSTR)szTmp,
                   1870:                             (ULONG)nFileLength,                     
                   1871:                             (ULONG FAR*)&ulDummy,
                   1872:                             FALSE
                   1873:                     );
                   1874:                 lpLI->fIsMarked = TRUE;
                   1875:             }
                   1876:         }
                   1877:     }
                   1878:     
                   1879:     /* have to do the refreshing after processing all links, otherwise
                   1880:     **    the item positions will change during the process as the
                   1881:     **    listbox stores items in order 
                   1882:     */
                   1883:     if (bFound)
                   1884:         RefreshLinkLB(hListBox, lpOleUILinkCntr);
                   1885: }
                   1886: 
                   1887: 
                   1888: 
                   1889: /* LoadLinkLB
                   1890:  * ----------
                   1891:  *
                   1892:  *  Purpose:
                   1893:  *      Enumerate all links from the Link Container and build up the Link
                   1894:  *      ListBox
                   1895:  *
                   1896:  *  Parameters:
                   1897:  *      hListBox        window handle of 
                   1898:  *      lpOleUILinkCntr pointer to OleUI Link Container
                   1899:  *      lpszFrom        prefix for matching
                   1900:  *      lpszTo          prefix to substitution
                   1901:  *
                   1902:  *  Returns:
                   1903:  *      number of link items loaded, -1 if error
                   1904:  */
                   1905: int LoadLinkLB(HWND hListBox, LPOLEUILINKCONTAINER lpOleUILinkCntr)
                   1906: {
                   1907:     DWORD       dwLink = 0;
                   1908:     LPLINKINFO  lpLI;
                   1909:     int         nIndex;
                   1910:     int         cLinks;
                   1911:     
                   1912:     cLinks = 0;
                   1913:     
                   1914:     while ((dwLink = lpOleUILinkCntr->lpVtbl->GetNextLink(lpOleUILinkCntr, 
                   1915:             dwLink)) != 0) {
                   1916:         lpLI = (LPLINKINFO)OleStdMalloc(sizeof(LINKINFO));
                   1917:         if (NULL == lpLI)
                   1918:             return -1;
                   1919:         
                   1920:         lpLI->fIsMarked = FALSE;
                   1921:         lpLI->fIsSelected = FALSE;
                   1922:         lpLI->fDontFree = FALSE;
                   1923:         lpLI->lpszAMX = (LPSTR)OleStdMalloc((LINKTYPELEN+1)*sizeof(BYTE));
                   1924: 
                   1925:         lpLI->dwLink = dwLink;
                   1926:         cLinks++;
                   1927:         if ((nIndex = AddLinkLBItem(hListBox,lpOleUILinkCntr,lpLI,TRUE)) < 0)
                   1928:             // can't load list box
                   1929:             return -1;
                   1930:         
                   1931:         if (lpLI->fIsSelected)
                   1932:             SendMessage(hListBox, LB_SETSEL, TRUE, MAKELPARAM(nIndex, 0));
                   1933:     }
                   1934: 
                   1935:     return cLinks;
                   1936: }
                   1937: 
                   1938: 
                   1939: /* RefreshLinkLB
                   1940:  * -------------
                   1941:  *
                   1942:  *  Purpose:
                   1943:  *      Enumerate all items in the links listbox and update those with
                   1944:  *      fIsMarked set.
                   1945:  *      Note that this is a time consuming routine as it keeps iterating
                   1946:  *      all items in the listbox until all of them are unmarked.
                   1947:  *
                   1948:  *  Parameters:
                   1949:  *      hListBox        window handle of listbox
                   1950:  *      lpOleUILinkCntr pointer to OleUI Link Container
                   1951:  *
                   1952:  *  Returns:
                   1953:  *
                   1954:  */
                   1955: VOID RefreshLinkLB(HWND hListBox, LPOLEUILINKCONTAINER lpOleUILinkCntr)
                   1956: {
                   1957:     int cItems;
                   1958:     int nIndex;
                   1959:     LPLINKINFO  lpLI;
                   1960:     BOOL        bStop;
                   1961:     
                   1962:     OleDbgAssert(hListBox);
                   1963: 
                   1964:     cItems = (int)SendMessage(hListBox, LB_GETCOUNT, 0, 0L);
                   1965:     OleDbgAssert(cItems >= 0);
                   1966: 
                   1967:     do {
                   1968:         bStop = TRUE;
                   1969:         for (nIndex=0; nIndex<cItems; nIndex++) {
                   1970:             SendMessage(hListBox, LB_GETTEXT, nIndex, 
                   1971:                     (LPARAM)(LPLINKINFO FAR*)&lpLI);
                   1972:             if (lpLI->fIsMarked) {
                   1973:                 lpLI->fIsMarked = FALSE;
                   1974:                 lpLI->fDontFree = TRUE; 
                   1975:                 
                   1976:                 SendMessage(hListBox, LB_DELETESTRING, nIndex, 0L);
                   1977:                 nIndex=AddLinkLBItem(hListBox, lpOleUILinkCntr, lpLI, FALSE);
                   1978:                 if (lpLI->fIsSelected)
                   1979:                     SendMessage(hListBox, LB_SETSEL, (WPARAM)TRUE, 
                   1980:                             MAKELPARAM(nIndex, 0));
                   1981:                 bStop = FALSE;
                   1982:                 break;
                   1983:             }
                   1984:         }
                   1985:     } while (!bStop);
                   1986: }
                   1987: 

unix.superglobalmegacorp.com

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