|
|
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:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.