Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1544 lines
57 KiB

  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. #include "precomp.h"
  10. #include "common.h"
  11. #include "utility.h"
  12. #include <commdlg.h>
  13. #include <dlgs.h>
  14. #include <stdlib.h>
  15. #include <strsafe.h>
  16. OLEDBGDATA
  17. // INTERNAL INFORMATION STARTS HERE
  18. #define OLEUI_SZMAX 255
  19. #define LINKTYPELEN 30 // was 9, now I've more than tripled it
  20. #define szNULL TEXT("\0")
  21. typedef UINT (CALLBACK* COMMDLGHOOKPROC)(HWND, UINT, WPARAM, LPARAM);
  22. // Internally used structure
  23. typedef struct tagLINKINFO
  24. {
  25. DWORD dwLink; // app specific identifier of a link
  26. LPTSTR lpszDisplayName; // file based part of name
  27. LPTSTR lpszItemName; // object part of name
  28. LPTSTR lpszShortFileName; // filename without path
  29. LPTSTR lpszShortLinkType; // Short link type - progID
  30. LPTSTR lpszFullLinkType; // Full link type - user friendly name
  31. LPTSTR lpszAMX; // Is the link auto (A) man (M) or dead (X)
  32. ULONG clenFileName; // count of file part of mon.
  33. BOOL fSourceAvailable; // bound or not - on boot assume yes??
  34. BOOL fIsAuto; // 1 =automatic, 0=manual update
  35. BOOL fIsMarked; // 1 = marked, 0 = not
  36. BOOL fDontFree; // Don't free this data since it's being reused
  37. BOOL fIsSelected; // item selected or to be selected
  38. } LINKINFO, FAR* LPLINKINFO;
  39. typedef struct tagEDITLINKS
  40. {
  41. // Keep this item first as the Standard* functions depend on it here.
  42. LPOLEUIEDITLINKS lpOEL; // Original structure passed.
  43. UINT nIDD; // IDD of dialog (used for help info)
  44. BOOL fClose; // Does the button read cancel (0) or
  45. // close (1)?
  46. BOOL fItemsExist; // TRUE, items in lbox, FALSE, none
  47. UINT nChgSrcHelpID; // ID for Help callback from ChangeSrc dlg
  48. TCHAR szClose[50]; // Text for Close button
  49. // (when Cancel button gets renamed)
  50. int nColPos[3]; // tab positions for list box
  51. int nHeightLine; // height of each line in owner draw listbox
  52. int nMaxCharWidth; // maximim width of text in owner draw listbox
  53. } EDITLINKS, *PEDITLINKS, FAR *LPEDITLINKS;
  54. // Internal function prototypes
  55. // LINKS.CPP
  56. INT_PTR CALLBACK EditLinksDialogProc(HWND, UINT, WPARAM, LPARAM);
  57. BOOL FEditLinksInit(HWND, WPARAM, LPARAM);
  58. BOOL Container_ChangeSource(HWND, LPEDITLINKS);
  59. HRESULT Container_AutomaticManual(HWND, BOOL, LPEDITLINKS);
  60. HRESULT CancelLink(HWND, LPEDITLINKS);
  61. HRESULT Container_UpdateNow(HWND, LPEDITLINKS);
  62. HRESULT Container_OpenSource(HWND, LPEDITLINKS);
  63. int AddLinkLBItem(HWND hListBox, LPOLEUILINKCONTAINER lpOleUILinkCntr, LPLINKINFO lpLI,
  64. BOOL fGetSelected);
  65. VOID BreakString(LPLINKINFO);
  66. int GetSelectedItems(HWND, int FAR* FAR*);
  67. VOID InitControls(HWND hDlg, LPEDITLINKS lpEL);
  68. VOID UpdateLinkLBItem(HWND hListBox, int nIndex, LPEDITLINKS lpEL, BOOL bSelect);
  69. VOID ChangeAllLinks(HWND hLIstBox, LPOLEUILINKCONTAINER lpOleUILinkCntr, LPTSTR lpszFrom, LPTSTR lpszTo);
  70. int LoadLinkLB(HWND hListBox, LPOLEUILINKCONTAINER lpOleUILinkCntr);
  71. VOID RefreshLinkLB(HWND hListBox, LPOLEUILINKCONTAINER lpOleUILinkCntr);
  72. /*
  73. * OleUIEditLinks
  74. *
  75. * Purpose:
  76. * Invokes the standard OLE Edit Links dialog box allowing the user
  77. * to manipulate ole links (delete, update, change source, etc).
  78. *
  79. * Parameters:
  80. * lpEL LPOLEUIEditLinks pointing to the in-out structure
  81. * for this dialog.
  82. *
  83. * Return Value:
  84. * UINT One of the following codes, indicating success or error:
  85. * OLEUI_SUCCESS Success
  86. * OLEUI_ERR_STRUCTSIZE The dwStructSize value is wrong
  87. */
  88. STDAPI_(UINT) OleUIEditLinks(LPOLEUIEDITLINKS lpEL)
  89. {
  90. HGLOBAL hMemDlg = NULL;
  91. UINT uRet = UStandardValidation((LPOLEUISTANDARD)lpEL, sizeof(OLEUIEDITLINKS),
  92. &hMemDlg);
  93. if (OLEUI_SUCCESS != uRet)
  94. return uRet;
  95. // Validate interface.
  96. if (NULL == lpEL->lpOleUILinkContainer)
  97. {
  98. uRet = OLEUI_ELERR_LINKCNTRNULL;
  99. }
  100. else if(IsBadReadPtr(lpEL->lpOleUILinkContainer, sizeof(IOleUILinkContainer)))
  101. {
  102. uRet = OLEUI_ELERR_LINKCNTRINVALID;
  103. }
  104. if (OLEUI_SUCCESS != uRet)
  105. {
  106. return(uRet);
  107. }
  108. UINT nIDD = bWin4 ? IDD_EDITLINKS4 : IDD_EDITLINKS;
  109. // Now that we've validated everything, we can invoke the dialog.
  110. uRet = UStandardInvocation(EditLinksDialogProc, (LPOLEUISTANDARD)lpEL,
  111. hMemDlg, MAKEINTRESOURCE(nIDD));
  112. return uRet;
  113. }
  114. /*
  115. * EditLinksDialogProc
  116. *
  117. * Purpose:
  118. * Implements the OLE Edit Links dialog as invoked through the
  119. * OleUIEditLinks function.
  120. *
  121. * Parameters:
  122. * Standard
  123. *
  124. * Return Value:
  125. * Standard
  126. */
  127. INT_PTR CALLBACK EditLinksDialogProc(HWND hDlg, UINT iMsg, WPARAM wParam, LPARAM lParam)
  128. {
  129. // Declare Win16/Win32 compatible WM_COMMAND parameters.
  130. COMMANDPARAMS(wID, wCode, hWndMsg);
  131. // This will fail under WM_INITDIALOG, where we allocate it.
  132. UINT uRet = 0;
  133. LPEDITLINKS lpEL = (LPEDITLINKS)LpvStandardEntry(hDlg, iMsg, wParam, lParam, &uRet);
  134. // If the hook processed the message, we're done.
  135. if (0 != uRet)
  136. return (BOOL)uRet;
  137. //Process help message from secondary dialog
  138. if ((iMsg == uMsgHelp) && (lpEL) && (lpEL->lpOEL))
  139. {
  140. PostMessage(lpEL->lpOEL->hWndOwner, uMsgHelp, wParam, lParam);
  141. return FALSE;
  142. }
  143. // Process the temination message
  144. if (iMsg == uMsgEndDialog)
  145. {
  146. EndDialog(hDlg, wParam);
  147. return TRUE;
  148. }
  149. switch (iMsg)
  150. {
  151. case WM_DESTROY:
  152. if (lpEL)
  153. {
  154. StandardCleanup(lpEL, hDlg);
  155. }
  156. break;
  157. case WM_INITDIALOG:
  158. return FEditLinksInit(hDlg, wParam, lParam);
  159. case WM_MEASUREITEM:
  160. {
  161. LPMEASUREITEMSTRUCT lpMIS = (LPMEASUREITEMSTRUCT)lParam;
  162. int nHeightLine;
  163. if (lpEL && lpEL->nHeightLine != -1)
  164. {
  165. // use cached height
  166. nHeightLine = lpEL->nHeightLine;
  167. }
  168. else
  169. {
  170. HFONT hFont;
  171. HDC hDC;
  172. TEXTMETRIC tm;
  173. hFont = (HFONT)SendMessage(hDlg, WM_GETFONT, 0, 0L);
  174. if (hFont == NULL)
  175. hFont = (HFONT)GetStockObject(SYSTEM_FONT);
  176. hDC = GetDC(hDlg);
  177. hFont = (HFONT)SelectObject(hDC, hFont);
  178. GetTextMetrics(hDC, &tm);
  179. nHeightLine = tm.tmHeight;
  180. if (lpEL)
  181. {
  182. lpEL->nHeightLine = nHeightLine;
  183. lpEL->nMaxCharWidth = tm.tmMaxCharWidth;
  184. }
  185. ReleaseDC(hDlg, hDC);
  186. }
  187. lpMIS->itemHeight = nHeightLine;
  188. }
  189. break;
  190. case WM_DRAWITEM:
  191. {
  192. LPDRAWITEMSTRUCT lpDIS = (LPDRAWITEMSTRUCT)lParam;
  193. LPLINKINFO lpLI = (LPLINKINFO)lpDIS->itemData;
  194. if ((int)lpDIS->itemID < 0)
  195. break;
  196. if ((ODA_DRAWENTIRE | ODA_SELECT) & lpDIS->itemAction)
  197. {
  198. HBRUSH hbr;
  199. COLORREF crText;
  200. if (ODS_SELECTED & lpDIS->itemState)
  201. {
  202. /*Get proper txt colors */
  203. crText = SetTextColor(lpDIS->hDC,
  204. GetSysColor(COLOR_HIGHLIGHTTEXT));
  205. hbr = CreateSolidBrush(GetSysColor(COLOR_HIGHLIGHT));
  206. lpLI->fIsSelected = TRUE;
  207. }
  208. else
  209. {
  210. hbr = CreateSolidBrush(GetSysColor(COLOR_WINDOW));
  211. lpLI->fIsSelected = FALSE;
  212. }
  213. FillRect(lpDIS->hDC, &lpDIS->rcItem, hbr);
  214. DeleteObject(hbr);
  215. int nOldBkMode = SetBkMode(lpDIS->hDC, TRANSPARENT);
  216. RECT rcClip;
  217. if (lpLI->lpszDisplayName)
  218. {
  219. TCHAR szTemp[MAX_PATH];
  220. StringCchCopy(szTemp, sizeof(szTemp)/sizeof(szTemp[0]), lpLI->lpszDisplayName);
  221. LPTSTR lpsz = ChopText(
  222. lpDIS->hwndItem,
  223. lpEL->nColPos[1] - lpEL->nColPos[0]
  224. - (lpEL->nMaxCharWidth > 0 ?
  225. lpEL->nMaxCharWidth : 5),
  226. szTemp, 0
  227. );
  228. rcClip.left = lpDIS->rcItem.left + lpEL->nColPos[0];
  229. rcClip.top = lpDIS->rcItem.top;
  230. rcClip.right = lpDIS->rcItem.left + lpEL->nColPos[1]
  231. - (lpEL->nMaxCharWidth > 0 ?
  232. lpEL->nMaxCharWidth : 5);
  233. rcClip.bottom = lpDIS->rcItem.bottom;
  234. ExtTextOut(
  235. lpDIS->hDC,
  236. rcClip.left,
  237. rcClip.top,
  238. ETO_CLIPPED,
  239. (LPRECT)&rcClip,
  240. lpsz,
  241. lstrlen(lpsz),
  242. NULL
  243. );
  244. }
  245. if (lpLI->lpszShortLinkType)
  246. {
  247. rcClip.left = lpDIS->rcItem.left + lpEL->nColPos[1];
  248. rcClip.top = lpDIS->rcItem.top;
  249. rcClip.right = lpDIS->rcItem.left + lpEL->nColPos[2]
  250. - (lpEL->nMaxCharWidth > 0 ?
  251. lpEL->nMaxCharWidth : 5);
  252. rcClip.bottom = lpDIS->rcItem.bottom;
  253. ExtTextOut(
  254. lpDIS->hDC,
  255. rcClip.left,
  256. rcClip.top,
  257. ETO_CLIPPED,
  258. (LPRECT)&rcClip,
  259. lpLI->lpszShortLinkType,
  260. lstrlen(lpLI->lpszShortLinkType),
  261. NULL
  262. );
  263. }
  264. if (lpLI->lpszAMX)
  265. {
  266. rcClip.left = lpDIS->rcItem.left + lpEL->nColPos[2];
  267. rcClip.top = lpDIS->rcItem.top;
  268. rcClip.right = lpDIS->rcItem.right;
  269. rcClip.bottom = lpDIS->rcItem.bottom;
  270. ExtTextOut(
  271. lpDIS->hDC,
  272. rcClip.left,
  273. rcClip.top,
  274. ETO_CLIPPED,
  275. (LPRECT)&rcClip,
  276. lpLI->lpszAMX,
  277. lstrlen(lpLI->lpszAMX),
  278. NULL
  279. );
  280. }
  281. SetBkMode(lpDIS->hDC, nOldBkMode);
  282. // restore orig colors if we changed them
  283. if (ODS_SELECTED & lpDIS->itemState)
  284. SetTextColor(lpDIS->hDC, crText);
  285. }
  286. if (ODA_FOCUS & lpDIS->itemAction)
  287. DrawFocusRect(lpDIS->hDC, &lpDIS->rcItem);
  288. }
  289. return TRUE;
  290. case WM_DELETEITEM:
  291. {
  292. LPDELETEITEMSTRUCT lpDIS = (LPDELETEITEMSTRUCT)lParam;
  293. UINT idCtl = (UINT)wParam;
  294. LPLINKINFO lpLI = (LPLINKINFO)lpDIS->itemData;
  295. if (lpLI->lpszDisplayName)
  296. OleStdFree((LPVOID)lpLI->lpszDisplayName);
  297. if (lpLI->lpszShortLinkType)
  298. OleStdFree((LPVOID)lpLI->lpszShortLinkType);
  299. if (lpLI->lpszFullLinkType)
  300. OleStdFree((LPVOID)lpLI->lpszFullLinkType);
  301. /* The ChangeSource processing reuses allocated space for
  302. ** links that have been modified.
  303. */
  304. // Don't free the LINKINFO for the changed links
  305. if (lpLI->fDontFree)
  306. lpLI->fDontFree = FALSE;
  307. else
  308. {
  309. if (lpLI->lpszAMX)
  310. OleStdFree((LPVOID)lpLI->lpszAMX);
  311. OleStdFree((LPVOID)lpLI);
  312. }
  313. }
  314. return TRUE;
  315. case WM_COMPAREITEM:
  316. {
  317. LPCOMPAREITEMSTRUCT lpCIS = (LPCOMPAREITEMSTRUCT)lParam;
  318. LPLINKINFO lpLI1 = (LPLINKINFO)lpCIS->itemData1;
  319. LPLINKINFO lpLI2 = (LPLINKINFO)lpCIS->itemData2;
  320. // Sort list entries by DisplayName
  321. return lstrcmp(lpLI1->lpszDisplayName, lpLI2->lpszDisplayName);
  322. }
  323. case WM_COMMAND:
  324. switch (wID)
  325. {
  326. case IDC_EL_CHANGESOURCE:
  327. {
  328. BOOL fRet = Container_ChangeSource(hDlg, lpEL);
  329. if (!fRet)
  330. PopupMessage(hDlg, IDS_LINKS, IDS_FAILED,
  331. MB_ICONEXCLAMATION | MB_OK);
  332. InitControls(hDlg, lpEL);
  333. }
  334. break;
  335. case IDC_EL_AUTOMATIC:
  336. {
  337. CheckDlgButton(hDlg, IDC_EL_AUTOMATIC, 1);
  338. CheckDlgButton(hDlg, IDC_EL_MANUAL, 0);
  339. HRESULT hErr = Container_AutomaticManual(hDlg, TRUE, lpEL);
  340. if (hErr != NOERROR)
  341. PopupMessage(hDlg, IDS_LINKS, IDS_FAILED,
  342. MB_ICONEXCLAMATION | MB_OK);
  343. InitControls(hDlg, lpEL);
  344. }
  345. break;
  346. case IDC_EL_MANUAL:
  347. {
  348. CheckDlgButton(hDlg, IDC_EL_MANUAL, 1);
  349. CheckDlgButton(hDlg, IDC_EL_AUTOMATIC, 0);
  350. HRESULT hErr = Container_AutomaticManual(hDlg, FALSE, lpEL);
  351. if (hErr != NOERROR)
  352. PopupMessage(hDlg, IDS_LINKS, IDS_FAILED,
  353. MB_ICONEXCLAMATION | MB_OK);
  354. InitControls(hDlg, lpEL);
  355. }
  356. break;
  357. case IDC_EL_CANCELLINK:
  358. CancelLink(hDlg,lpEL);
  359. InitControls(hDlg, lpEL);
  360. break;
  361. case IDC_EL_UPDATENOW:
  362. Container_UpdateNow(hDlg, lpEL);
  363. InitControls(hDlg, lpEL);
  364. break;
  365. case IDC_EL_OPENSOURCE:
  366. {
  367. HRESULT hErr = Container_OpenSource(hDlg, lpEL);
  368. if (hErr != NOERROR)
  369. {
  370. InitControls(hDlg, lpEL);
  371. // Don't close dialog
  372. break;
  373. }
  374. SendMessage(hDlg, uMsgEndDialog, OLEUI_OK, 0L);
  375. } // fall through
  376. case IDC_EL_LINKSLISTBOX:
  377. if (wCode == LBN_SELCHANGE)
  378. InitControls(hDlg, lpEL);
  379. break;
  380. case IDCANCEL:
  381. SendMessage(hDlg, uMsgEndDialog, OLEUI_CANCEL, 0L);
  382. break;
  383. case IDC_OLEUIHELP:
  384. PostMessage(lpEL->lpOEL->hWndOwner, uMsgHelp,
  385. (WPARAM)hDlg, MAKELPARAM(IDD_EDITLINKS, 0));
  386. break;
  387. }
  388. break;
  389. default:
  390. if (lpEL != NULL && iMsg == lpEL->nChgSrcHelpID)
  391. {
  392. PostMessage(lpEL->lpOEL->hWndOwner, uMsgHelp,
  393. (WPARAM)hDlg, MAKELPARAM(IDD_CHANGESOURCE, 0));
  394. }
  395. if (iMsg == uMsgBrowseOFN &&
  396. lpEL != NULL && lpEL->lpOEL && lpEL->lpOEL->hWndOwner)
  397. {
  398. SendMessage(lpEL->lpOEL->hWndOwner, uMsgBrowseOFN, wParam, lParam);
  399. }
  400. break;
  401. }
  402. return FALSE;
  403. }
  404. /*
  405. * FEditLinksInit
  406. *
  407. * Purpose:
  408. * WM_INITIDIALOG handler for the Edit Links dialog box.
  409. *
  410. *
  411. * Parameters:
  412. * hDlg HWND of the dialog
  413. * wParam WPARAM of the message
  414. * lParam LPARAM of the message
  415. *
  416. * Return Value:
  417. * BOOL Value to return for WM_INITDIALOG.
  418. */
  419. BOOL FEditLinksInit(HWND hDlg, WPARAM wParam, LPARAM lParam)
  420. {
  421. // Copy the structure at lParam into our instance memory.
  422. HFONT hFont;
  423. LPEDITLINKS lpEL = (LPEDITLINKS)LpvStandardInit(hDlg, sizeof(EDITLINKS), &hFont);
  424. // PvStandardInit send a termination to us already.
  425. if (NULL == lpEL)
  426. return FALSE;
  427. LPOLEUIEDITLINKS lpOEL = (LPOLEUIEDITLINKS)lParam;
  428. lpEL->lpOEL = lpOEL;
  429. lpEL->nIDD = IDD_EDITLINKS;
  430. // metrics unknown so far
  431. lpEL->nHeightLine = -1;
  432. lpEL->nMaxCharWidth = -1;
  433. /* calculate the column positions relative to the listbox */
  434. HWND hListBox = GetDlgItem(hDlg, IDC_EL_LINKSLISTBOX);
  435. RECT rc;
  436. GetWindowRect(hListBox, (LPRECT)&rc);
  437. int nStart = rc.left;
  438. GetWindowRect(GetDlgItem(hDlg, IDC_EL_COL1), (LPRECT)&rc);
  439. lpEL->nColPos[0] = rc.left - nStart;
  440. GetWindowRect(GetDlgItem(hDlg, IDC_EL_COL2), (LPRECT)&rc);
  441. lpEL->nColPos[1] = rc.left - nStart;
  442. GetWindowRect(GetDlgItem(hDlg, IDC_EL_COL3), (LPRECT)&rc);
  443. lpEL->nColPos[2] = rc.left - nStart;
  444. LPOLEUILINKCONTAINER lpOleUILinkCntr = lpEL->lpOEL->lpOleUILinkContainer;
  445. ULONG cLinks = LoadLinkLB(hListBox, lpOleUILinkCntr);
  446. if ((int)cLinks < 0)
  447. return FALSE;
  448. BOOL fDlgItem = (BOOL)cLinks;
  449. lpEL->fItemsExist = (BOOL)cLinks;
  450. InitControls(hDlg, lpEL);
  451. // Copy other information from lpOEL that we might modify.
  452. // If we got a font, send it to the necessary controls.
  453. if (NULL != hFont)
  454. {
  455. // Do this for as many controls as you need it for.
  456. // SendDlgItemMessage(hDlg, ID_<UFILL>, WM_SETFONT, (WPARAM)hFont, 0L);
  457. }
  458. // Show or hide the help button
  459. if (!(lpEL->lpOEL->dwFlags & ELF_SHOWHELP))
  460. StandardShowDlgItem(hDlg, IDC_OLEUIHELP, SW_HIDE);
  461. /*
  462. * PERFORM OTHER INITIALIZATION HERE. ON ANY LoadString
  463. * FAILURE POST OLEUI_MSG_ENDDIALOG WITH OLEUI_ERR_LOADSTRING.
  464. */
  465. // If requested disable UpdateNow button
  466. if ((lpEL->lpOEL->dwFlags & ELF_DISABLEUPDATENOW))
  467. StandardShowDlgItem(hDlg, IDC_EL_UPDATENOW, SW_HIDE);
  468. // If requested disable OpenSource button
  469. if ((lpEL->lpOEL->dwFlags & ELF_DISABLEOPENSOURCE))
  470. StandardShowDlgItem(hDlg, IDC_EL_OPENSOURCE, SW_HIDE);
  471. // If requested disable UpdateNow button
  472. if ((lpEL->lpOEL->dwFlags & ELF_DISABLECHANGESOURCE))
  473. StandardShowDlgItem(hDlg, IDC_EL_CHANGESOURCE, SW_HIDE);
  474. // If requested disable CancelLink button
  475. if ((lpEL->lpOEL->dwFlags & ELF_DISABLECANCELLINK))
  476. StandardShowDlgItem(hDlg, IDC_EL_CANCELLINK, SW_HIDE);
  477. // Change the caption
  478. if (NULL!=lpOEL->lpszCaption)
  479. SetWindowText(hDlg, lpOEL->lpszCaption);
  480. // Load 'Close' string used to rename Cancel button
  481. int n = LoadString(_g_hOleStdResInst, IDS_CLOSE, lpEL->szClose, sizeof(lpEL->szClose)/sizeof(TCHAR));
  482. if (!n)
  483. {
  484. PostMessage(hDlg, uMsgEndDialog, OLEUI_ERR_LOADSTRING, 0L);
  485. return FALSE;
  486. }
  487. if (cLinks > 0)
  488. SetFocus(hListBox);
  489. else
  490. SetFocus(GetDlgItem(hDlg, IDCANCEL));
  491. lpEL->nChgSrcHelpID = RegisterWindowMessage(HELPMSGSTRING);
  492. // Call the hook with lCustData in lParam
  493. UStandardHook(lpEL, hDlg, WM_INITDIALOG, wParam, lpOEL->lCustData);
  494. return FALSE;
  495. }
  496. /*
  497. * Container_ChangeSource
  498. *
  499. * Purpose:
  500. * Tunnel to File Open type dlg and allow user to select new file
  501. * for file based monikers, OR to change the whole moniker to what
  502. * the user types into the editable field.
  503. *
  504. * Parameters:
  505. * hDlg HWND of the dialog
  506. * LPEDITLINKS Pointer to EditLinks structure (contains all nec.
  507. * info)
  508. *
  509. * Return Value:
  510. * BOOL for now, because we are not using any ole functions
  511. * to return an HRESULT.
  512. * HRESULT HRESULT value indicating success or failure of
  513. * changing the moniker value
  514. */
  515. BOOL Container_ChangeSource(HWND hDlg, LPEDITLINKS lpEL)
  516. {
  517. HWND hListBox = GetDlgItem(hDlg, IDC_EL_LINKSLISTBOX);
  518. int FAR* rgIndex;
  519. int cSelItems = GetSelectedItems(hListBox, &rgIndex);
  520. if (cSelItems < 0)
  521. return FALSE;
  522. if (!cSelItems)
  523. return TRUE;
  524. OLEUICHANGESOURCE cs; memset(&cs, 0, sizeof(cs));
  525. cs.cbStruct = sizeof(cs);
  526. cs.hWndOwner = hDlg;
  527. if (lpEL->lpOEL->dwFlags & ELF_SHOWHELP)
  528. cs.dwFlags |= CSF_SHOWHELP;
  529. LPOLEUILINKCONTAINER lpOleUILinkCntr = lpEL->lpOEL->lpOleUILinkContainer;
  530. cs.lpOleUILinkContainer = lpOleUILinkCntr;
  531. for (int i = cSelItems-1; i >= 0; i--)
  532. {
  533. // allow caller to customize the change source dialog
  534. LPLINKINFO lpLI = (LPLINKINFO)SendMessage(hListBox, LB_GETITEMDATA, rgIndex[i], 0);
  535. cs.lpszDisplayName = lpLI->lpszDisplayName;
  536. cs.dwLink = lpLI->dwLink;
  537. cs.nFileLength = lpLI->clenFileName;
  538. UINT uRet = UStandardHook(lpEL, hDlg, uMsgChangeSource, 0, (LPARAM)&cs);
  539. if (!uRet)
  540. uRet = (OLEUI_OK == OleUIChangeSource(&cs));
  541. if (!uRet)
  542. break; // dialog canceled (cancel for all)
  543. if (!lpEL->fClose)
  544. {
  545. SetDlgItemText(hDlg, IDCANCEL, lpEL->szClose);
  546. lpEL->fClose = TRUE;
  547. }
  548. // update the list box item for the new name
  549. // (note: original lpszDisplayName already freed)
  550. lpLI->fSourceAvailable = (cs.dwFlags & CSF_VALIDSOURCE);
  551. lpLI->lpszDisplayName = cs.lpszDisplayName;
  552. UpdateLinkLBItem(hListBox, rgIndex[i], lpEL, TRUE);
  553. // if differed only in file name, allow user to change all links
  554. if (cs.lpszFrom != NULL && cs.lpszTo != NULL)
  555. ChangeAllLinks(hListBox, lpOleUILinkCntr, cs.lpszFrom, cs.lpszTo);
  556. // must free and NULL out the lpszFrom and lpszTo OUT fields
  557. OleStdFree(cs.lpszFrom);
  558. cs.lpszFrom = NULL;
  559. OleStdFree(cs.lpszTo);
  560. cs.lpszTo = NULL;
  561. }
  562. if (rgIndex != NULL)
  563. OleStdFree(rgIndex);
  564. return TRUE;
  565. }
  566. /*
  567. * Container_AutomaticManual
  568. *
  569. * Purpose:
  570. * To change the selected moniker to manual or automatic update.
  571. *
  572. * Parameters:
  573. * hDlg HWND of the dialog
  574. * FAutoMan Flag indicating AUTO (TRUE/1) or MANUAL(FALSE/0)
  575. * LPEDITLINKS Pointer to EditLinks structure (contains all nec.
  576. * info)
  577. * * this may change - don't know how the linked list
  578. * * of multi-selected items will work.
  579. * Return Value:
  580. * HRESULT HRESULT value indicating success or failure of
  581. * changing the moniker value
  582. */
  583. HRESULT Container_AutomaticManual(HWND hDlg, BOOL fAutoMan, LPEDITLINKS lpEL)
  584. {
  585. HRESULT hErr = NOERROR;
  586. int cSelItems;
  587. int FAR* rgIndex;
  588. int i = 0;
  589. LPLINKINFO lpLI;
  590. LPOLEUILINKCONTAINER lpOleUILinkCntr = lpEL->lpOEL->lpOleUILinkContainer;
  591. HWND hListBox = GetDlgItem(hDlg, IDC_EL_LINKSLISTBOX);
  592. BOOL bUpdate = FALSE;
  593. OleDbgAssert(lpOleUILinkCntr);
  594. /* Change so looks at flag in structure. Only update those that
  595. need to be updated. Make sure to change flag if status changes.
  596. */
  597. cSelItems = GetSelectedItems(hListBox, &rgIndex);
  598. if (cSelItems < 0)
  599. return ResultFromScode(E_FAIL);
  600. if (!cSelItems)
  601. return NOERROR;
  602. HCURSOR hCursorOld = HourGlassOn();
  603. if (!lpEL->fClose)
  604. {
  605. SetDlgItemText(hDlg, IDCANCEL, lpEL->szClose);
  606. lpEL->fClose = TRUE;
  607. }
  608. for (i = 0; i < cSelItems; i++)
  609. {
  610. lpLI = (LPLINKINFO)SendMessage(hListBox, LB_GETITEMDATA, rgIndex[i], 0);
  611. if (fAutoMan)
  612. {
  613. // If switching to AUTOMATIC
  614. if (!lpLI->fIsAuto) // Only change MANUAL links
  615. {
  616. OLEDBG_BEGIN2(TEXT("IOleUILinkContainer::SetLinkUpdateOptions called\r\n"));
  617. hErr=lpOleUILinkCntr->SetLinkUpdateOptions(
  618. lpLI->dwLink,
  619. OLEUPDATE_ALWAYS
  620. );
  621. OLEDBG_END2
  622. lpLI->fIsAuto=TRUE;
  623. lpLI->fIsMarked = TRUE;
  624. bUpdate = TRUE;
  625. }
  626. }
  627. else // If switching to MANUAL
  628. {
  629. if (lpLI->fIsAuto) // Only do AUTOMATIC Links
  630. {
  631. OLEDBG_BEGIN2(TEXT("IOleUILinkContainer::SetLinkUpdateOptions called\r\n"));
  632. hErr=lpOleUILinkCntr->SetLinkUpdateOptions(
  633. lpLI->dwLink,
  634. OLEUPDATE_ONCALL
  635. );
  636. OLEDBG_END2
  637. lpLI->fIsAuto = FALSE;
  638. lpLI->fIsMarked = TRUE;
  639. bUpdate = TRUE;
  640. }
  641. }
  642. if (hErr != NOERROR)
  643. {
  644. OleDbgOutHResult(TEXT("WARNING: IOleUILinkContainer::SetLinkUpdateOptions returned"),hErr);
  645. break;
  646. }
  647. }
  648. if (bUpdate)
  649. RefreshLinkLB(hListBox, lpOleUILinkCntr);
  650. if (rgIndex)
  651. OleStdFree((LPVOID)rgIndex);
  652. HourGlassOff(hCursorOld);
  653. return hErr;
  654. }
  655. HRESULT CancelLink(HWND hDlg, LPEDITLINKS lpEL)
  656. {
  657. HRESULT hErr;
  658. LPMONIKER lpmk;
  659. int cSelItems;
  660. int FAR* rgIndex;
  661. int i = 0;
  662. LPLINKINFO lpLI;
  663. LPOLEUILINKCONTAINER lpOleUILinkCntr = lpEL->lpOEL->lpOleUILinkContainer;
  664. HWND hListBox = GetDlgItem(hDlg, IDC_EL_LINKSLISTBOX);
  665. BOOL bUpdate = FALSE;
  666. OleDbgAssert(lpOleUILinkCntr);
  667. lpmk = NULL;
  668. cSelItems = GetSelectedItems(hListBox, &rgIndex);
  669. if (cSelItems < 0)
  670. return ResultFromScode(E_FAIL);
  671. if (!cSelItems)
  672. return NOERROR;
  673. HCURSOR hCursorOld = HourGlassOn();
  674. for (i = 0; i < cSelItems; i++)
  675. {
  676. lpLI = (LPLINKINFO)SendMessage(hListBox, LB_GETITEMDATA, rgIndex[i], 0);
  677. UINT uRet = PopupMessage(hDlg, IDS_LINKS,
  678. IDS_CONFIRMBREAKLINK, MB_YESNO|MB_ICONQUESTION);
  679. if (uRet == IDNO)
  680. break;
  681. OLEDBG_BEGIN2(TEXT("IOleUILinkContainer::CancelLink called\r\n"));
  682. hErr = lpOleUILinkCntr->CancelLink(lpLI->dwLink);
  683. OLEDBG_END2
  684. if (!lpEL->fClose)
  685. {
  686. SetDlgItemText(hDlg, IDCANCEL, lpEL->szClose);
  687. lpEL->fClose = TRUE;
  688. }
  689. if (hErr != NOERROR)
  690. {
  691. OleDbgOutHResult(TEXT("WARNING: IOleUILinkContainer::CancelLink returned"),hErr);
  692. lpLI->fIsMarked = TRUE;
  693. bUpdate = TRUE;
  694. }
  695. else
  696. {
  697. // Delete links that we make null from listbox
  698. SendMessage(hListBox, LB_DELETESTRING, (WPARAM) rgIndex[i], 0L);
  699. int i2;
  700. for (i2 = i + 1; i2 < cSelItems; i2++)
  701. {
  702. if (rgIndex[i2] > rgIndex[i])
  703. rgIndex[i2]--;
  704. }
  705. }
  706. }
  707. if (bUpdate)
  708. RefreshLinkLB(hListBox, lpOleUILinkCntr);
  709. if (rgIndex)
  710. OleStdFree((LPVOID)rgIndex);
  711. HourGlassOff(hCursorOld);
  712. return hErr;
  713. }
  714. /*
  715. * Container_UpdateNow
  716. *
  717. * Purpose:
  718. * Immediately force an update for all (manual) links
  719. *
  720. * Parameters:
  721. * hDlg HWND of the dialog
  722. * LPEDITLINKS Pointer to EditLinks structure (contains all nec. info)
  723. * * this may change - don't know how the linked list
  724. * * of multi-selected items will work.
  725. * Return Value:
  726. * HRESULT HRESULT value indicating success or failure of
  727. * changing the moniker value
  728. */
  729. HRESULT Container_UpdateNow(HWND hDlg, LPEDITLINKS lpEL)
  730. {
  731. HRESULT hErr;
  732. LPLINKINFO lpLI;
  733. int cSelItems;
  734. int FAR* rgIndex;
  735. int i = 0;
  736. LPOLEUILINKCONTAINER lpOleUILinkCntr = lpEL->lpOEL->lpOleUILinkContainer;
  737. HWND hListBox = GetDlgItem(hDlg, IDC_EL_LINKSLISTBOX);
  738. BOOL bUpdate = FALSE;
  739. OleDbgAssert(lpOleUILinkCntr);
  740. cSelItems = GetSelectedItems(hListBox, &rgIndex);
  741. if (cSelItems < 0)
  742. return ResultFromScode(E_FAIL);
  743. if (!cSelItems)
  744. return NOERROR;
  745. HCURSOR hCursorOld = HourGlassOn();
  746. if (!lpEL->fClose)
  747. {
  748. SetDlgItemText(hDlg, IDCANCEL, lpEL->szClose);
  749. lpEL->fClose = TRUE;
  750. }
  751. for (i = 0; i < cSelItems; i++)
  752. {
  753. lpLI = (LPLINKINFO)SendMessage(hListBox, LB_GETITEMDATA, rgIndex[i], 0);
  754. OLEDBG_BEGIN2(TEXT("IOleUILinkContainer::UpdateLink called\r\n"));
  755. hErr = lpOleUILinkCntr->UpdateLink(
  756. lpLI->dwLink,
  757. TRUE,
  758. FALSE
  759. );
  760. OLEDBG_END2
  761. bUpdate = TRUE;
  762. lpLI->fIsMarked = TRUE;
  763. if (hErr != NOERROR)
  764. {
  765. OleDbgOutHResult(TEXT("WARNING: IOleUILinkContainer::UpdateLink returned"),hErr);
  766. break;
  767. }
  768. }
  769. if (bUpdate)
  770. RefreshLinkLB(hListBox, lpOleUILinkCntr);
  771. if (rgIndex)
  772. OleStdFree((LPVOID)rgIndex);
  773. HourGlassOff(hCursorOld);
  774. return hErr;
  775. }
  776. /*
  777. * Container_OpenSource
  778. *
  779. * Purpose:
  780. * Immediately force an update for all (manual) links
  781. *
  782. * Parameters:
  783. * hDlg HWND of the dialog
  784. * LPEDITLINKS Pointer to EditLinks structure (contains all nec.
  785. * info)
  786. *
  787. * Return Value:
  788. * HRESULT HRESULT value indicating success or failure of
  789. * changing the moniker value
  790. */
  791. HRESULT Container_OpenSource(HWND hDlg, LPEDITLINKS lpEL)
  792. {
  793. HRESULT hErr;
  794. int cSelItems;
  795. int FAR* rgIndex;
  796. LPLINKINFO lpLI;
  797. RECT rcPosRect;
  798. LPOLEUILINKCONTAINER lpOleUILinkCntr = lpEL->lpOEL->lpOleUILinkContainer;
  799. HWND hListBox = GetDlgItem(hDlg, IDC_EL_LINKSLISTBOX);
  800. OleDbgAssert(lpOleUILinkCntr);
  801. rcPosRect.top = 0;
  802. rcPosRect.left = 0;
  803. rcPosRect.right = 0;
  804. rcPosRect.bottom = 0;
  805. cSelItems = GetSelectedItems(hListBox, &rgIndex);
  806. if (cSelItems < 0)
  807. return ResultFromScode(E_FAIL);
  808. if (cSelItems != 1) // can't open source for multiple items
  809. return NOERROR;
  810. HCURSOR hCursorOld = HourGlassOn();
  811. if (!lpEL->fClose)
  812. {
  813. SetDlgItemText(hDlg, IDCANCEL, lpEL->szClose);
  814. lpEL->fClose = TRUE;
  815. }
  816. lpLI = (LPLINKINFO)SendMessage(hListBox, LB_GETITEMDATA, rgIndex[0], 0);
  817. OLEDBG_BEGIN2(TEXT("IOleUILinkContainer::OpenLinkSource called\r\n"));
  818. hErr = lpOleUILinkCntr->OpenLinkSource(
  819. lpLI->dwLink
  820. );
  821. OLEDBG_END2
  822. UpdateLinkLBItem(hListBox, rgIndex[0], lpEL, TRUE);
  823. if (hErr != NOERROR) {
  824. OleDbgOutHResult(TEXT("WARNING: IOleUILinkContainer::OpenLinkSource returned"),hErr);
  825. }
  826. if (rgIndex)
  827. OleStdFree((LPVOID)rgIndex);
  828. HourGlassOff(hCursorOld);
  829. return hErr;
  830. }
  831. /* AddLinkLBItem
  832. ** -------------
  833. **
  834. ** Add the item pointed to by lpLI to the Link ListBox and return
  835. ** the index of it in the ListBox
  836. */
  837. int AddLinkLBItem(HWND hListBox, LPOLEUILINKCONTAINER lpOleUILinkCntr, LPLINKINFO lpLI, BOOL fGetSelected)
  838. {
  839. HRESULT hErr;
  840. DWORD dwUpdateOpt;
  841. int nIndex;
  842. OleDbgAssert(lpOleUILinkCntr && hListBox && lpLI);
  843. lpLI->fDontFree = FALSE;
  844. OLEDBG_BEGIN2(TEXT("IOleUILinkContainer::GetLinkSource called\r\n"));
  845. hErr = lpOleUILinkCntr->GetLinkSource(
  846. lpLI->dwLink,
  847. (LPTSTR FAR*)&lpLI->lpszDisplayName,
  848. (ULONG FAR*)&lpLI->clenFileName,
  849. (LPTSTR FAR*)&lpLI->lpszFullLinkType,
  850. (LPTSTR FAR*)&lpLI->lpszShortLinkType,
  851. (BOOL FAR*)&lpLI->fSourceAvailable,
  852. fGetSelected ? (BOOL FAR*)&lpLI->fIsSelected : NULL
  853. );
  854. OLEDBG_END2
  855. if (hErr != NOERROR)
  856. {
  857. OleDbgOutHResult(TEXT("WARNING: IOleUILinkContainer::GetLinkSource returned"),hErr);
  858. PopupMessage(hListBox, IDS_LINKS, IDS_ERR_GETLINKSOURCE,
  859. MB_ICONEXCLAMATION | MB_OK);
  860. goto cleanup;
  861. }
  862. OLEDBG_BEGIN2(TEXT("IOleUILinkContainer::GetLinkUpdateOptions called\r\n"));
  863. hErr=lpOleUILinkCntr->GetLinkUpdateOptions(
  864. lpLI->dwLink,
  865. (LPDWORD)&dwUpdateOpt
  866. );
  867. OLEDBG_END2
  868. if (hErr != NOERROR)
  869. {
  870. OleDbgOutHResult(TEXT("WARNING: IOleUILinkContainer::GetLinkUpdateOptions returned"),hErr);
  871. PopupMessage(hListBox, IDS_LINKS, IDS_ERR_GETLINKUPDATEOPTIONS,
  872. MB_ICONEXCLAMATION | MB_OK);
  873. goto cleanup;
  874. }
  875. if (lpLI->fSourceAvailable)
  876. {
  877. if (dwUpdateOpt == OLEUPDATE_ALWAYS)
  878. {
  879. lpLI->fIsAuto = TRUE;
  880. LoadString(_g_hOleStdResInst, IDS_LINK_AUTO, lpLI->lpszAMX,
  881. (int)OleStdGetSize((LPVOID)lpLI->lpszAMX) / sizeof (TCHAR));
  882. }
  883. else
  884. {
  885. lpLI->fIsAuto = FALSE;
  886. LoadString(_g_hOleStdResInst, IDS_LINK_MANUAL, lpLI->lpszAMX,
  887. (int)OleStdGetSize((LPVOID)lpLI->lpszAMX) / sizeof (TCHAR));
  888. }
  889. }
  890. else
  891. LoadString(_g_hOleStdResInst, IDS_LINK_UNKNOWN, lpLI->lpszAMX,
  892. (int)OleStdGetSize((LPVOID)lpLI->lpszAMX) / sizeof (TCHAR));
  893. BreakString(lpLI);
  894. nIndex = (int)SendMessage(hListBox, LB_ADDSTRING, (WPARAM)0,
  895. (LPARAM)lpLI);
  896. if (nIndex == LB_ERR)
  897. {
  898. PopupMessage(hListBox, IDS_LINKS, IDS_ERR_ADDSTRING,
  899. MB_ICONEXCLAMATION | MB_OK);
  900. goto cleanup;
  901. }
  902. return nIndex;
  903. cleanup:
  904. if (lpLI->lpszDisplayName)
  905. OleStdFree((LPVOID)lpLI->lpszDisplayName);
  906. if (lpLI->lpszShortLinkType)
  907. OleStdFree((LPVOID)lpLI->lpszShortLinkType);
  908. if (lpLI->lpszFullLinkType)
  909. OleStdFree((LPVOID)lpLI->lpszFullLinkType);
  910. return -1;
  911. }
  912. /* BreakString
  913. * -----------
  914. *
  915. * Purpose:
  916. * Break the lpszDisplayName into various parts
  917. *
  918. * Parameters:
  919. * lpLI pointer to LINKINFO structure
  920. *
  921. * Returns:
  922. *
  923. */
  924. VOID BreakString(LPLINKINFO lpLI)
  925. {
  926. LPTSTR lpsz;
  927. if (!lpLI->clenFileName ||
  928. (lstrlen(lpLI->lpszDisplayName)==(int)lpLI->clenFileName))
  929. {
  930. lpLI->lpszItemName = NULL;
  931. }
  932. else
  933. {
  934. lpLI->lpszItemName = lpLI->lpszDisplayName + lpLI->clenFileName;
  935. }
  936. // search from last character of filename
  937. lpsz = lpLI->lpszDisplayName + lstrlen(lpLI->lpszDisplayName);
  938. while (lpsz > lpLI->lpszDisplayName)
  939. {
  940. lpsz = CharPrev(lpLI->lpszDisplayName, lpsz);
  941. if ((*lpsz == '\\') || (*lpsz == '/') || (*lpsz == ':'))
  942. break;
  943. }
  944. if (lpsz == lpLI->lpszDisplayName)
  945. lpLI->lpszShortFileName = lpsz;
  946. else
  947. lpLI->lpszShortFileName = CharNext(lpsz);
  948. }
  949. /* GetSelectedItems
  950. * ----------------
  951. *
  952. * Purpose:
  953. * Retrieve the indices of the selected items in the listbox
  954. * Note that *lprgIndex needed to be free after using the function
  955. *
  956. * Parameters:
  957. * hListBox window handle of listbox
  958. * lprgIndex pointer to an integer array to receive the indices
  959. * must be freed afterwards
  960. *
  961. * Returns:
  962. * number of indices retrieved, -1 if error
  963. */
  964. int GetSelectedItems(HWND hListBox, int FAR* FAR* lprgIndex)
  965. {
  966. DWORD cSelItems;
  967. DWORD cCheckItems;
  968. *lprgIndex = NULL;
  969. cSelItems = (DWORD)SendMessage(hListBox, LB_GETSELCOUNT, 0, 0L);
  970. if ((int)cSelItems < 0) // error
  971. return (int)cSelItems;
  972. if (!cSelItems)
  973. return 0;
  974. *lprgIndex = (int FAR*)OleStdMalloc((int)cSelItems * sizeof(int));
  975. if (!(*lprgIndex))
  976. return -1; // outofmem
  977. cCheckItems = (DWORD)SendMessage(hListBox, LB_GETSELITEMS,
  978. (WPARAM) cSelItems, (LPARAM) (int FAR *) *lprgIndex);
  979. if (cCheckItems == cSelItems)
  980. return (int)cSelItems;
  981. else
  982. {
  983. if (*lprgIndex)
  984. OleStdFree((LPVOID)*lprgIndex);
  985. *lprgIndex = NULL;
  986. return 0;
  987. }
  988. }
  989. /* InitControls
  990. * ------------
  991. *
  992. * Purpose:
  993. * Initialize the state of the Auto/Manual button, Link source/type
  994. * static field, etc in the dialogs according to the selection in the
  995. * listbox
  996. *
  997. * Parameters:
  998. * hDlg handle to the dialog window
  999. */
  1000. VOID InitControls(HWND hDlg, LPEDITLINKS lpEL)
  1001. {
  1002. int cSelItems;
  1003. HWND hListBox;
  1004. int i;
  1005. int FAR* rgIndex;
  1006. LPLINKINFO lpLI;
  1007. LPTSTR lpszType = NULL;
  1008. LPTSTR lpszSource = NULL;
  1009. int cAuto = 0;
  1010. int cManual = 0;
  1011. BOOL bSameType = TRUE;
  1012. BOOL bSameSource = TRUE;
  1013. TCHAR tsz[MAX_PATH];
  1014. LPTSTR lpsz;
  1015. hListBox = GetDlgItem(hDlg, IDC_EL_LINKSLISTBOX);
  1016. cSelItems = GetSelectedItems(hListBox, &rgIndex);
  1017. if (cSelItems < 0)
  1018. return;
  1019. if ((cSelItems > 0) && (rgIndex == NULL))
  1020. return;
  1021. StandardEnableDlgItem(hDlg, IDC_EL_AUTOMATIC, (BOOL)cSelItems);
  1022. StandardEnableDlgItem(hDlg, IDC_EL_MANUAL, (BOOL)cSelItems);
  1023. if (lpEL && !(lpEL->lpOEL->dwFlags & ELF_DISABLECANCELLINK))
  1024. StandardEnableDlgItem(hDlg, IDC_EL_CANCELLINK, (BOOL)cSelItems);
  1025. if (lpEL && !(lpEL->lpOEL->dwFlags & ELF_DISABLEOPENSOURCE))
  1026. StandardEnableDlgItem(hDlg, IDC_EL_OPENSOURCE, cSelItems == 1);
  1027. if (lpEL && !(lpEL->lpOEL->dwFlags & ELF_DISABLECHANGESOURCE))
  1028. StandardEnableDlgItem(hDlg, IDC_EL_CHANGESOURCE, cSelItems == 1);
  1029. if (lpEL && !(lpEL->lpOEL->dwFlags & ELF_DISABLEUPDATENOW))
  1030. StandardEnableDlgItem(hDlg, IDC_EL_UPDATENOW, (BOOL)cSelItems);
  1031. for (i = 0; i < cSelItems; i++)
  1032. {
  1033. lpLI = (LPLINKINFO)SendDlgItemMessage(hDlg, IDC_EL_LINKSLISTBOX,
  1034. LB_GETITEMDATA, rgIndex[i], 0);
  1035. if (lpszSource && lpLI->lpszDisplayName)
  1036. {
  1037. if (bSameSource && lstrcmp(lpszSource, lpLI->lpszDisplayName))
  1038. bSameSource = FALSE;
  1039. }
  1040. else
  1041. lpszSource = lpLI->lpszDisplayName;
  1042. if (lpszType && lpLI->lpszFullLinkType)
  1043. {
  1044. if (bSameType && lstrcmp(lpszType, lpLI->lpszFullLinkType))
  1045. bSameType = FALSE;
  1046. }
  1047. else
  1048. lpszType = lpLI->lpszFullLinkType;
  1049. if (lpLI->fIsAuto)
  1050. cAuto++;
  1051. else
  1052. cManual++;
  1053. }
  1054. CheckDlgButton(hDlg, IDC_EL_AUTOMATIC, cAuto && !cManual);
  1055. CheckDlgButton(hDlg, IDC_EL_MANUAL, !cAuto && cManual);
  1056. /* fill full source in static text box
  1057. ** below list
  1058. */
  1059. if (!bSameSource || !lpszSource)
  1060. lpszSource = szNULL;
  1061. StringCchCopy(tsz, sizeof(tsz)/sizeof(tsz[0]), lpszSource);
  1062. lpsz = ChopText(GetDlgItem(hDlg, IDC_EL_LINKSOURCE), 0, tsz, 0);
  1063. SetDlgItemText(hDlg, IDC_EL_LINKSOURCE, lpsz);
  1064. /* fill full link type name in static
  1065. ** "type" text box
  1066. */
  1067. if (!bSameType || !lpszType)
  1068. lpszType = szNULL;
  1069. SetDlgItemText(hDlg, IDC_EL_LINKTYPE, lpszType);
  1070. if (rgIndex)
  1071. OleStdFree((LPVOID)rgIndex);
  1072. }
  1073. /* UpdateLinkLBItem
  1074. * -----------------
  1075. *
  1076. * Purpose:
  1077. * Update the linkinfo struct in the listbox to reflect the changes
  1078. * made by the last operation. It is done simply by removing the item
  1079. * from the listbox and add it back.
  1080. *
  1081. * Parameters:
  1082. * hListBox handle of listbox
  1083. * nIndex index of listbox item
  1084. * lpEL pointer to editlinks structure
  1085. * bSelect select the item or not after update
  1086. */
  1087. VOID UpdateLinkLBItem(HWND hListBox, int nIndex, LPEDITLINKS lpEL, BOOL bSelect)
  1088. {
  1089. LPLINKINFO lpLI;
  1090. LPOLEUILINKCONTAINER lpOleUILinkCntr;
  1091. if (!hListBox || (nIndex < 0) || !lpEL)
  1092. return;
  1093. lpOleUILinkCntr = lpEL->lpOEL->lpOleUILinkContainer;
  1094. lpLI = (LPLINKINFO)SendMessage(hListBox, LB_GETITEMDATA, nIndex, 0);
  1095. if (lpLI == NULL)
  1096. return;
  1097. /* Don't free the data associated with this listbox item
  1098. ** because we are going to reuse the allocated space for
  1099. ** the modified link. WM_DELETEITEM processing in the
  1100. ** dialog checks this flag before deleting data
  1101. ** associcated with list item.
  1102. */
  1103. lpLI->fDontFree = TRUE;
  1104. SendMessage(hListBox, LB_DELETESTRING, nIndex, 0L);
  1105. nIndex = AddLinkLBItem(hListBox, lpOleUILinkCntr, lpLI, FALSE);
  1106. if (bSelect)
  1107. {
  1108. SendMessage(hListBox, LB_SETSEL, TRUE, MAKELPARAM(nIndex, 0));
  1109. SendMessage(hListBox, LB_SETCARETINDEX, nIndex, MAKELPARAM(TRUE, 0));
  1110. }
  1111. }
  1112. /* ChangeAllLinks
  1113. * --------------
  1114. *
  1115. * Purpose:
  1116. * Enumerate all the links in the listbox and change those starting
  1117. * with lpszFrom to lpszTo.
  1118. *
  1119. * Parameters:
  1120. * hListBox window handle of
  1121. * lpOleUILinkCntr pointer to OleUI Link Container
  1122. * lpszFrom prefix for matching
  1123. * lpszTo prefix to substitution
  1124. *
  1125. * Returns:
  1126. */
  1127. VOID ChangeAllLinks(HWND hListBox, LPOLEUILINKCONTAINER lpOleUILinkCntr, LPTSTR lpszFrom, LPTSTR lpszTo)
  1128. {
  1129. int cItems;
  1130. int nIndex;
  1131. int cFrom;
  1132. LPLINKINFO lpLI;
  1133. TCHAR szTmp[MAX_PATH];
  1134. BOOL bFound;
  1135. cFrom = lstrlen(lpszFrom);
  1136. cItems = (int)SendMessage(hListBox, LB_GETCOUNT, 0, 0L);
  1137. OleDbgAssert(cItems >= 0);
  1138. bFound = FALSE;
  1139. #ifdef _DEBUG
  1140. OleDbgPrint(3, TEXT("From : "), lpszFrom, 0);
  1141. OleDbgPrint(3, TEXT(""), TEXT("\r\n"), 0);
  1142. OleDbgPrint(3, TEXT("To : "), lpszTo, 0);
  1143. OleDbgPrint(3, TEXT(""), TEXT("\r\n"), 0);
  1144. #endif
  1145. for (nIndex = 0; nIndex < cItems; nIndex++)
  1146. {
  1147. lpLI = (LPLINKINFO)SendMessage(hListBox, LB_GETITEMDATA, nIndex, 0);
  1148. // unmark the item
  1149. lpLI->fIsMarked = FALSE;
  1150. /* if the corresponding position for the end of lpszFrom in the
  1151. ** display name is not a separator. We stop comparing this
  1152. ** link.
  1153. */
  1154. if (!*(lpLI->lpszDisplayName + cFrom) ||
  1155. (*(lpLI->lpszDisplayName + cFrom) == '\\') ||
  1156. (*(lpLI->lpszDisplayName + cFrom) == '!'))
  1157. {
  1158. lstrcpyn(szTmp, lpLI->lpszDisplayName, cFrom + 1);
  1159. if (!lstrcmp(szTmp, lpszFrom))
  1160. {
  1161. HRESULT hErr;
  1162. int nFileLength;
  1163. ULONG ulDummy;
  1164. if (!bFound)
  1165. {
  1166. TCHAR szTitle[256];
  1167. TCHAR szMsg[256];
  1168. TCHAR szBuf[256];
  1169. int uRet;
  1170. LoadString(_g_hOleStdResInst, IDS_CHANGESOURCE, szTitle,
  1171. sizeof(szTitle)/sizeof(TCHAR));
  1172. LoadString(_g_hOleStdResInst, IDS_CHANGEADDITIONALLINKS,
  1173. szMsg, sizeof(szMsg)/sizeof(TCHAR));
  1174. StringCchPrintf(szBuf, sizeof(szBuf)/sizeof(szBuf[0]), szMsg, lpszFrom);
  1175. uRet = MessageBox(hListBox, szBuf, szTitle,
  1176. MB_ICONQUESTION | MB_YESNO);
  1177. if (uRet == IDYES)
  1178. bFound = TRUE;
  1179. else
  1180. return;
  1181. }
  1182. StringCchCopy(szTmp, sizeof(szTmp)/sizeof(szTmp[0]), lpszTo);
  1183. StringCchCat(szTmp, sizeof(szTmp)/sizeof(szTmp[0]), lpLI->lpszDisplayName + cFrom);
  1184. nFileLength = lstrlen(szTmp) -
  1185. (lpLI->lpszItemName ? lstrlen(lpLI->lpszItemName) : 0);
  1186. hErr = lpOleUILinkCntr->SetLinkSource(
  1187. lpLI->dwLink,
  1188. szTmp,
  1189. (ULONG)nFileLength,
  1190. (ULONG FAR*)&ulDummy,
  1191. TRUE
  1192. );
  1193. if (hErr != NOERROR)
  1194. {
  1195. lpOleUILinkCntr->SetLinkSource(
  1196. lpLI->dwLink,
  1197. szTmp,
  1198. (ULONG)nFileLength,
  1199. (ULONG FAR*)&ulDummy,
  1200. FALSE);
  1201. }
  1202. lpLI->fIsMarked = TRUE;
  1203. }
  1204. }
  1205. }
  1206. /* have to do the refreshing after processing all links, otherwise
  1207. ** the item positions will change during the process as the
  1208. ** listbox stores items in order
  1209. */
  1210. if (bFound)
  1211. RefreshLinkLB(hListBox, lpOleUILinkCntr);
  1212. }
  1213. /* LoadLinkLB
  1214. * ----------
  1215. *
  1216. * Purpose:
  1217. * Enumerate all links from the Link Container and build up the Link
  1218. * ListBox
  1219. *
  1220. * Parameters:
  1221. * hListBox window handle of
  1222. * lpOleUILinkCntr pointer to OleUI Link Container
  1223. * lpszFrom prefix for matching
  1224. * lpszTo prefix to substitution
  1225. *
  1226. * Returns:
  1227. * number of link items loaded, -1 if error
  1228. */
  1229. int LoadLinkLB(HWND hListBox, LPOLEUILINKCONTAINER lpOleUILinkCntr)
  1230. {
  1231. DWORD dwLink = 0;
  1232. LPLINKINFO lpLI;
  1233. int nIndex;
  1234. int cLinks;
  1235. cLinks = 0;
  1236. while ((dwLink = lpOleUILinkCntr->GetNextLink(dwLink)) != 0)
  1237. {
  1238. lpLI = (LPLINKINFO)OleStdMalloc(sizeof(LINKINFO));
  1239. if (NULL == lpLI)
  1240. return -1;
  1241. lpLI->fIsMarked = FALSE;
  1242. lpLI->fIsSelected = FALSE;
  1243. lpLI->fDontFree = FALSE;
  1244. lpLI->lpszAMX = (LPTSTR)OleStdMalloc((LINKTYPELEN+1)*sizeof(TCHAR));
  1245. lpLI->dwLink = dwLink;
  1246. cLinks++;
  1247. if ((nIndex = AddLinkLBItem(hListBox,lpOleUILinkCntr,lpLI,TRUE)) < 0)
  1248. // can't load list box
  1249. return -1;
  1250. if (lpLI->fIsSelected)
  1251. SendMessage(hListBox, LB_SETSEL, TRUE, MAKELPARAM(nIndex, 0));
  1252. }
  1253. if (SendMessage(hListBox,LB_GETSELITEMS,(WPARAM)1,(LPARAM)(int FAR*)&nIndex))
  1254. SendMessage(hListBox, LB_SETCARETINDEX, (WPARAM)nIndex, MAKELPARAM(TRUE, 0));
  1255. return cLinks;
  1256. }
  1257. /* RefreshLinkLB
  1258. * -------------
  1259. *
  1260. * Purpose:
  1261. * Enumerate all items in the links listbox and update those with
  1262. * fIsMarked set.
  1263. * Note that this is a time consuming routine as it keeps iterating
  1264. * all items in the listbox until all of them are unmarked.
  1265. *
  1266. * Parameters:
  1267. * hListBox window handle of listbox
  1268. * lpOleUILinkCntr pointer to OleUI Link Container
  1269. *
  1270. * Returns:
  1271. *
  1272. */
  1273. VOID RefreshLinkLB(HWND hListBox, LPOLEUILINKCONTAINER lpOleUILinkCntr)
  1274. {
  1275. int cItems;
  1276. int nIndex;
  1277. LPLINKINFO lpLI;
  1278. BOOL bStop;
  1279. OleDbgAssert(hListBox);
  1280. cItems = (int)SendMessage(hListBox, LB_GETCOUNT, 0, 0L);
  1281. OleDbgAssert(cItems >= 0);
  1282. do
  1283. {
  1284. bStop = TRUE;
  1285. for (nIndex = 0; nIndex < cItems; nIndex++)
  1286. {
  1287. lpLI = (LPLINKINFO)SendMessage(hListBox, LB_GETITEMDATA, nIndex, 0);
  1288. if (lpLI->fIsMarked)
  1289. {
  1290. lpLI->fIsMarked = FALSE;
  1291. lpLI->fDontFree = TRUE;
  1292. SendMessage(hListBox, LB_DELETESTRING, nIndex, 0L);
  1293. nIndex=AddLinkLBItem(hListBox, lpOleUILinkCntr, lpLI, FALSE);
  1294. if (lpLI->fIsSelected)
  1295. {
  1296. SendMessage(hListBox, LB_SETSEL, (WPARAM)TRUE,
  1297. MAKELPARAM(nIndex, 0));
  1298. SendMessage(hListBox, LB_SETCARETINDEX, (WPARAM)nIndex,
  1299. MAKELPARAM(TRUE, 0));
  1300. }
  1301. bStop = FALSE;
  1302. break;
  1303. }
  1304. }
  1305. } while (!bStop);
  1306. }