Source code of Windows XP (NT5)
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.

1151 lines
37 KiB

  1. /*
  2. * dialog.c - Handles the Windows 3.1 common dialogs.
  3. *
  4. * Created by Microsoft Corporation.
  5. * (c) Copyright Microsoft Corp. 1990 - 1992 All Rights Reserved
  6. */
  7. //*** INCLUDES ****
  8. #include <windows.h> //* WINDOWS
  9. #include <ole.h> //* OLE
  10. #include "global.h" //* global
  11. #include "demorc.h" //* String table constants
  12. #include "register.h" //* Class registration library
  13. #include "utility.h"
  14. #include "dialog.h"
  15. #include "object.h"
  16. //*** GLOBALS ***
  17. //* strings used with commdlg
  18. CHAR szDefExtension[CBMESSAGEMAX];
  19. CHAR szFilterSpec[CBFILTERMAX];
  20. CHAR szInsertFilter[CBFILTERMAX];
  21. CHAR szLastDir[CBPATHMAX];
  22. OPENFILENAME OFN;
  23. HWND hwndProp = NULL;
  24. HWND hRetry;
  25. /***************************************************************************
  26. * OfnInit()
  27. * Initializes the standard file dialog OFN structure.
  28. **************************************************************************/
  29. VOID FAR OfnInit( //* ENTRY:
  30. HANDLE hInst //* instance handle
  31. ){ //* LOCAL:
  32. LPSTR lpstr; //* string pointer
  33. LoadString(hInst, IDS_FILTER, szFilterSpec, CBMESSAGEMAX);
  34. LoadString(hInst, IDS_EXTENSION, szDefExtension, CBMESSAGEMAX);
  35. OFN.lStructSize = sizeof(OPENFILENAME);
  36. OFN.hInstance = hInst;
  37. OFN.nMaxCustFilter = CBFILTERMAX;
  38. OFN.nMaxFile = CBPATHMAX;
  39. OFN.lCustData = 0;
  40. OFN.lpfnHook = NULL;
  41. OFN.lpTemplateName = NULL;
  42. OFN.lpstrFileTitle = NULL;
  43. //* Construct the filter string
  44. //* for the Open and Save dialogs
  45. lpstr = (LPSTR)szFilterSpec;
  46. lstrcat(lpstr, " (*.");
  47. lstrcat(lpstr, szDefExtension);
  48. lstrcat(lpstr, ")");
  49. lpstr += lstrlen(lpstr) + 1;
  50. lstrcpy(lpstr, "*.");
  51. lstrcat(lpstr, szDefExtension);
  52. lpstr += lstrlen(lpstr) + 1;
  53. *lpstr = 0;
  54. RegMakeFilterSpec(NULL, NULL, (LPSTR)szInsertFilter);
  55. }
  56. /***************************************************************************
  57. * OfnGetName()
  58. *
  59. * Calls the standard file dialogs to get a file name
  60. **************************************************************************/
  61. BOOL FAR OfnGetName( //* ENTRY:
  62. HWND hwnd, //* parent window handle
  63. LPSTR szFileName, //* File name
  64. WORD msg //* operation
  65. ){ //* LOCAL:
  66. BOOL frc; //* return flag
  67. CHAR szCaption[CBMESSAGEMAX];//* dialog caption
  68. OFN.hwndOwner = hwnd; //* window
  69. OFN.nFilterIndex = 1;
  70. OFN.lpstrInitialDir = (LPSTR)szLastDir;
  71. OFN.Flags = OFN_HIDEREADONLY;
  72. switch (msg) //* message
  73. {
  74. case IDM_OPEN: //* open file
  75. Normalize(szFileName);
  76. OFN.lpstrDefExt = (LPSTR)szDefExtension;
  77. OFN.lpstrFile = (LPSTR)szFileName;
  78. OFN.lpstrFilter = (LPSTR)szFilterSpec;
  79. LoadString(hInst, IDS_OPENFILE, szCaption, CBMESSAGEMAX);
  80. OFN.lpstrTitle = (LPSTR)szCaption;
  81. OFN.Flags |= OFN_FILEMUSTEXIST;
  82. return GetOpenFileName((LPOPENFILENAME)&OFN);
  83. break;
  84. case IDM_SAVEAS: //* save as file
  85. Normalize(szFileName);
  86. OFN.lpstrDefExt = (LPSTR)szDefExtension;
  87. OFN.lpstrFile = (LPSTR)szFileName;
  88. OFN.lpstrFilter = (LPSTR)szFilterSpec;
  89. LoadString(hInst, IDS_SAVEFILE, szCaption, CBMESSAGEMAX);
  90. OFN.lpstrTitle = (LPSTR)szCaption;
  91. OFN.Flags |= OFN_PATHMUSTEXIST;
  92. return GetSaveFileName((LPOPENFILENAME)&OFN);
  93. break;
  94. case IDM_INSERTFILE: //* insert file
  95. OFN.lpstrDefExt = NULL;
  96. OFN.lpstrFile = (LPSTR)szFileName;
  97. OFN.lpstrFilter = (LPSTR)szInsertFilter;
  98. LoadString(hInst, IDS_INSERTFILE, szCaption, CBMESSAGEMAX);
  99. OFN.lpstrTitle = (LPSTR)szCaption;
  100. OFN.Flags |= OFN_FILEMUSTEXIST;
  101. frc = GetOpenFileName((LPOPENFILENAME)&OFN);
  102. AddExtension(&OFN);
  103. return frc;
  104. break;
  105. default: //* default
  106. break;
  107. }
  108. return FALSE;
  109. }
  110. /***************************************************************************
  111. * OfnGetNewLinkName() - Sets up the "Change Link..." dialog box
  112. *
  113. * returns LPSTR - fully qualified filename
  114. **************************************************************************/
  115. LPSTR FAR OfnGetNewLinkName( //* ENTRY:
  116. HWND hwnd, //* calling window or dialog
  117. LPSTR lpstrData //* link data
  118. ){ //* LOCAL:
  119. LPSTR lpReturn = NULL; //* return string
  120. LPSTR lpstrFile = NULL; //* non-qualified file name
  121. LPSTR lpstrPath = NULL; //* pathname
  122. LPSTR lpstrTemp = NULL; //* work string
  123. CHAR szDocFile[CBPATHMAX];//* document name
  124. CHAR szDocPath[CBPATHMAX];//* document path name
  125. CHAR szServerFilter[CBPATHMAX];
  126. CHAR szCaption[CBMESSAGEMAX];
  127. //* Figure out the link's path
  128. //* name and file name
  129. lpstrTemp = lpstrData;
  130. while (*lpstrTemp++);
  131. lpstrPath = lpstrFile = lpstrTemp;
  132. while (*(lpstrTemp = AnsiNext(lpstrTemp)))
  133. if (*lpstrTemp == '\\')
  134. lpstrFile = lpstrTemp + 1;
  135. //* Copy the document name
  136. lstrcpy(szDocFile, lpstrFile);
  137. *(lpstrFile - 1) = 0;
  138. //* Copy the path name
  139. lstrcpy(szDocPath, ((lpstrPath != lpstrFile) ? lpstrPath : ""));
  140. if (lpstrPath != lpstrFile) //* Restore the backslash
  141. *(lpstrFile - 1) = '\\';
  142. while (*lpstrFile != '.' && *lpstrFile)//* Get the extension
  143. lpstrFile++;
  144. //* Make a filter that respects
  145. //* the link's class name
  146. OFN.hwndOwner = hwnd;
  147. OFN.nFilterIndex = RegMakeFilterSpec(lpstrData, lpstrFile, szServerFilter);
  148. OFN.lpstrDefExt = NULL;
  149. OFN.lpstrFile = (LPSTR)szDocFile;
  150. OFN.lpstrFilter = (LPSTR)szServerFilter;
  151. OFN.lpstrInitialDir = (LPSTR)szDocPath;
  152. LoadString(hInst, IDS_CHANGELINK, szCaption, CBMESSAGEMAX);
  153. OFN.lpstrTitle = (LPSTR)szCaption;
  154. OFN.lpstrCustomFilter = NULL;
  155. OFN.Flags = OFN_HIDEREADONLY | OFN_FILEMUSTEXIST;
  156. //* If we get a file... */
  157. if (GetOpenFileName((LPOPENFILENAME)&OFN))
  158. {
  159. if (!(lpReturn = GlobalLock(GlobalAlloc(LHND, CBPATHMAX))))
  160. goto Error;
  161. AddExtension(&OFN);
  162. lstrcpy(lpReturn, szDocFile);
  163. OFN.lpstrInitialDir = (LPSTR)szLastDir;
  164. }
  165. return lpReturn; //* SUCCESS return
  166. Error: //* ERROR Tag
  167. return NULL; //* ERROR return
  168. }
  169. /***************************************************************************
  170. * Normalize()
  171. * Removes the path specification from the file name.
  172. *
  173. * Note: It isn't possible to get "<drive>:<filename>" as input because
  174. * the path received will always be fully qualified.
  175. **************************************************************************/
  176. VOID Normalize( //* ENTRY:
  177. LPSTR lpstrFile //* file name
  178. ){ //* LOCAL:
  179. LPSTR lpstrBackslash = NULL;//* back slash
  180. LPSTR lpstrTemp = lpstrFile;//* file name
  181. while (*lpstrTemp)
  182. {
  183. if (*lpstrTemp == '\\')
  184. lpstrBackslash = lpstrTemp;
  185. lpstrTemp = AnsiNext(lpstrTemp);
  186. }
  187. if (lpstrBackslash)
  188. lstrcpy(lpstrFile, lpstrBackslash + 1);
  189. }
  190. /***************************************************************************
  191. * AddExtension()
  192. *
  193. * Adds the extension corresponding to the filter dropdown.
  194. **************************************************************************/
  195. VOID AddExtension( //* ENTRY:
  196. LPOPENFILENAME lpOFN //* open file structure
  197. ){
  198. if (lpOFN->nFileExtension == (WORD)lstrlen(lpOFN->lpstrFile)
  199. && lpOFN->nFilterIndex)
  200. {
  201. LPSTR lpstrFilter = (LPSTR)lpOFN->lpstrFilter;
  202. while (*lpstrFilter && --lpOFN->nFilterIndex)
  203. {
  204. while (*lpstrFilter++) ;
  205. while (*lpstrFilter++) ;
  206. }
  207. //* If we got to the filter,
  208. if (*lpstrFilter) //* retrieve the extension
  209. {
  210. while (*lpstrFilter++) ;
  211. lpstrFilter++;
  212. //* Copy the extension
  213. if (lpstrFilter[1] != '*')
  214. lstrcat(lpOFN->lpstrFile, lpstrFilter);
  215. }
  216. }
  217. }
  218. /****************************************************************************
  219. * fnInsertNew()
  220. *
  221. * Dialog procedure for the Insert New dialog.
  222. *
  223. * Returns int - TRUE if message processed, FALSE otherwise
  224. ***************************************************************************/
  225. BOOL APIENTRY fnInsertNew( //* ENTRY:
  226. HWND hDlg, //* standard dialog box paramters
  227. UINT msg,
  228. WPARAM wParam,
  229. LPARAM lParam //* (LPSTR) class name
  230. ){ //* LOCAL:
  231. HWND hwndList; //* handle to listbox
  232. static LPSTR lpClassName; //* classname for return value
  233. hwndList = GetDlgItem(hDlg, IDD_LISTBOX);
  234. switch (msg)
  235. {
  236. case WM_INITDIALOG:
  237. if (!RegGetClassNames(hwndList))
  238. EndDialog(hDlg, IDCANCEL);
  239. lpClassName = (LPSTR)lParam;
  240. SetFocus(hwndList);
  241. SendMessage(hwndList, LB_SETCURSEL, 0, 0L);
  242. return (FALSE);
  243. case WM_COMMAND:
  244. {
  245. WORD wID = LOWORD(wParam);
  246. WORD wCmd = HIWORD(wParam);
  247. switch (wID)
  248. {
  249. case IDD_LISTBOX:
  250. if (wCmd != LBN_DBLCLK)
  251. break;
  252. case IDOK:
  253. if (!RegCopyClassName(hwndList, lpClassName))
  254. wParam = IDCANCEL;
  255. case IDCANCEL:
  256. EndDialog(hDlg, wParam);
  257. break;
  258. }
  259. break;
  260. }
  261. }
  262. return FALSE;
  263. }
  264. /***************************************************************************
  265. * LinkProperties();
  266. *
  267. * Manage the link properties dialog box.
  268. **************************************************************************/
  269. VOID FAR LinkProperties()
  270. { //* LOCAL
  271. DialogBox (
  272. hInst,
  273. MAKEINTRESOURCE(DTPROP),
  274. hwndFrame,
  275. (DLGPROC)fnProperties
  276. );
  277. }
  278. /***************************************************************************
  279. * fnProperties()
  280. *
  281. * Dialog procedure for link properties. The Links dialog allows the user to
  282. * change the link options, edit/play the object, cancel the link as
  283. * well change links.
  284. *
  285. * returns BOOL - TRUE if processed, FALSE otherwise
  286. **************************************************************************/
  287. BOOL APIENTRY fnProperties( //* ENTRY:
  288. HWND hDlg, //* standard dialog box parameters
  289. UINT msg,
  290. WPARAM wParam,
  291. LPARAM lParam //* (HWND) child window with focus
  292. ){ //* LOCAL:
  293. static APPITEMPTR *pLinks; //* pointer to links (associated windows)
  294. static INT nLinks; //* number of links
  295. static HWND hwndList; //* handle to listbox window
  296. static BOOL fTry;
  297. switch (msg)
  298. {
  299. case WM_INITDIALOG:
  300. hwndProp = hDlg;
  301. hwndList = GetDlgItem(hDlg, IDD_LINKNAME);
  302. if (!(InitLinkDlg(hDlg, &nLinks, hwndList, &pLinks)))
  303. EndDialog(hDlg, TRUE);
  304. UpdateLinkButtons(hDlg,nLinks,hwndList,pLinks);
  305. break;
  306. case WM_COMMAND:
  307. {
  308. WORD wID = LOWORD(wParam);
  309. switch (wID)
  310. {
  311. case IDD_CHANGE: //* change links
  312. BLOCK_BUSY(fTry);
  313. if (ChangeLinks(hDlg,nLinks,hwndList,pLinks))
  314. DisplayUpdate(nLinks,hwndList,pLinks, FALSE);
  315. return TRUE;
  316. case IDD_FREEZE: //* cancel links
  317. BLOCK_BUSY(fTry);
  318. CancelLinks(hDlg,nLinks,hwndList,pLinks);
  319. UpdateLinkButtons(hDlg,nLinks,hwndList,pLinks);
  320. return TRUE;
  321. case IDD_UPDATE: //* update links
  322. BLOCK_BUSY(fTry);
  323. DisplayUpdate(nLinks,hwndList,pLinks,TRUE);
  324. UpdateLinkButtons(hDlg,nLinks,hwndList,pLinks);
  325. return TRUE;
  326. case IDD_AUTO:
  327. case IDD_MANUAL: //* change link update options
  328. BLOCK_BUSY(fTry);
  329. if (!SendMessage(GetDlgItem(hDlg,wParam),BM_GETCHECK, 0, 0L))
  330. {
  331. CheckRadioButton(hDlg, IDD_AUTO ,IDD_MANUAL ,wParam);
  332. ChangeUpdateOptions(hDlg,nLinks,hwndList,pLinks,
  333. (wParam == IDD_AUTO ? oleupdate_always : oleupdate_oncall));
  334. UpdateLinkButtons(hDlg,nLinks,hwndList,pLinks);
  335. }
  336. return TRUE;
  337. case IDD_LINKNAME:
  338. if (HIWORD(wParam) == LBN_SELCHANGE)
  339. UpdateLinkButtons(hDlg,nLinks,hwndList,pLinks);
  340. return TRUE;
  341. case IDCANCEL:
  342. BLOCK_BUSY(fTry);
  343. UndoObjects();
  344. END_PROP_DLG(hDlg,pLinks);
  345. return TRUE;
  346. case IDOK:
  347. BLOCK_BUSY(fTry);
  348. DelUndoObjects(FALSE);
  349. END_PROP_DLG(hDlg,pLinks);
  350. return TRUE;
  351. }
  352. }
  353. }
  354. return FALSE;
  355. }
  356. /****************************************************************************
  357. * InitLinkDlg();
  358. *
  359. * Initialize the list box of links.
  360. ***************************************************************************/
  361. static BOOL InitLinkDlg ( //* ENTRY:
  362. HWND hDlg, //* dialog box handle
  363. INT *nLinks, //* pointer to number of links
  364. HWND hwndList, //* listbox handle
  365. APPITEMPTR **pLinks //* list of window handles of links
  366. ){ //* LOCAL
  367. APPITEMPTR pItem; //* application item pointer
  368. LPSTR lpstrData = NULL; //* pointer to link data
  369. CHAR szFull[CBMESSAGEMAX * 4];//* list box entry string
  370. CHAR pLinkData[OBJECT_LINK_MAX];//* holder of link data
  371. BOOL fSelect = FALSE; //* item selected flag
  372. HANDLE hWork; //* working memory handle
  373. APPITEMPTR pTop; //* pointer to the top object
  374. if (!(*pLinks = (APPITEMPTR *)LocalLock(LocalAlloc(LHND,sizeof(APPITEMPTR)*10))))
  375. {
  376. ErrorMessage(E_FAILED_TO_ALLOC);
  377. return 0;
  378. }
  379. *nLinks = 0;
  380. //* set tabs
  381. SendMessage(hwndList,WM_SETREDRAW,FALSE,0L);
  382. //* enumerate child windows
  383. for (pTop = pItem = GetTopItem(); pItem; pItem = GetNextItem(pItem))
  384. {
  385. if (pItem->otObject == OT_LINK && pItem->fVisible)
  386. {
  387. *(*pLinks + *nLinks) = pItem;
  388. if (!((*nLinks += 1)%10))
  389. { //* add blocks of ten
  390. hWork = LocalHandle((LPSTR)(*pLinks));
  391. LocalUnlock(hWork);
  392. if (!(hWork = LocalReAlloc(hWork,(*nLinks+10)*sizeof(APPITEMPTR),0)))
  393. {
  394. ErrorMessage(E_FAILED_TO_ALLOC);
  395. return FALSE; //* ERROR return
  396. }
  397. *pLinks = (APPITEMPTR *)LocalLock(hWork);
  398. }
  399. if (pTop == pItem)
  400. fSelect = TRUE;
  401. if (!ObjGetData(pItem, pLinkData))
  402. continue;
  403. //* make listbox entry
  404. MakeListBoxString(pLinkData, szFull, pItem->uoObject);
  405. //* add listbox entry
  406. SendMessage(hwndList, LB_ADDSTRING, 0, (LONG)(LPSTR)szFull);
  407. }
  408. }
  409. if (fSelect)
  410. SendMessage(hwndList, LB_SETSEL, 1, 0L);
  411. SendMessage(hwndList,WM_SETREDRAW,TRUE,0L);
  412. UpdateWindow(hwndList);
  413. return TRUE; //* SUCCESS return
  414. }
  415. /****************************************************************************
  416. * MakeListBoxString()
  417. *
  418. * build an listbox entry string
  419. ***************************************************************************/
  420. static VOID MakeListBoxString( //* ENTRY:
  421. LPSTR lpLinkData, //* pointer to link data
  422. LPSTR lpBoxData, //* return string
  423. OLEOPT_UPDATE oleopt_update //* OLE update option
  424. ){ //* LOCAL:
  425. CHAR szType[CBMESSAGEMAX];//* holds update option string
  426. LPSTR lpTemp; //* working string pointer
  427. INT i; //* index
  428. //* get classname
  429. RegGetClassId(lpBoxData, lpLinkData);
  430. lstrcat(lpBoxData, " - "); //* ads tab
  431. while (*lpLinkData++); //* skip to document name
  432. lpTemp = lpLinkData;
  433. while (*lpTemp) //* copy document name;
  434. { //* strip drive an directory
  435. if (*lpTemp == '\\' || *lpTemp == ':')
  436. lpLinkData = lpTemp + 1;
  437. lpTemp = AnsiNext(lpTemp);
  438. }
  439. lstrcat(lpBoxData, lpLinkData);
  440. lstrcat(lpBoxData, " - ");
  441. while (*lpLinkData++); //* copy item data
  442. lstrcat(lpBoxData, lpLinkData);
  443. lstrcat(lpBoxData, " - ");
  444. //* add update option string
  445. switch (oleopt_update)
  446. {
  447. case oleupdate_always: i = SZAUTO; break;
  448. case oleupdate_oncall: i = SZMANUAL; break;
  449. default: i = SZFROZEN;
  450. }
  451. LoadString(hInst, i, szType, CBMESSAGEMAX);
  452. lstrcat(lpBoxData, szType);
  453. } //* SUCCESS return
  454. /***************************************************************************
  455. * UpdateLinkButtons()
  456. *
  457. * Keep link buttons active as appropriate. This routine is called after
  458. * a selection is made so the buttons reflect the selected items.
  459. **************************************************************************/
  460. static VOID UpdateLinkButtons( //* ENTRY:
  461. HWND hDlg, //* dialog box handle
  462. INT nLinks, //* number of links
  463. HWND hwndList, //* listbox handle
  464. APPITEMPTR *pLinks //* pointer to link's window handles
  465. ){ //* LOCAL:
  466. ATOM aCurName=0; //* atom of current doc
  467. BOOL fChangeLink = TRUE; //* enable/disable changelink button
  468. INT iAuto,iManual,i; //* count of manual and auto links
  469. APPITEMPTR pItem; //* application item pointer
  470. INT iStatic;
  471. iStatic = iAuto = iManual = 0;
  472. for (i = 0; i < nLinks; i++) //* enum selected links
  473. {
  474. if (SendMessage(hwndList, LB_GETSEL, i, 0L))
  475. {
  476. pItem = *(pLinks+i);
  477. if (pItem->otObject == OT_STATIC)
  478. iStatic++;
  479. else
  480. {
  481. switch(pItem->uoObject)
  482. { //* count number of manual and
  483. case oleupdate_always: //* automatic links selected
  484. iAuto++;
  485. break;
  486. case oleupdate_oncall:
  487. iManual++;
  488. break;
  489. }
  490. //* check if all selected links are
  491. if (!aCurName) //* linked to same file
  492. aCurName = pItem->aLinkName;
  493. else if (aCurName != pItem->aLinkName)
  494. fChangeLink = FALSE;
  495. }
  496. }
  497. }
  498. if (!(iAuto || iManual || iStatic) //* if no links disable all buttons
  499. || (!iAuto && !iManual && iStatic))
  500. {
  501. EnableWindow(GetDlgItem(hDlg, IDD_FREEZE), FALSE );
  502. EnableWindow(GetDlgItem(hDlg, IDD_CHANGE), FALSE );
  503. EnableWindow(GetDlgItem(hDlg, IDD_UPDATE), FALSE );
  504. CheckDlgButton(hDlg, IDD_AUTO, FALSE);
  505. EnableWindow(GetDlgItem(hDlg, IDD_AUTO),FALSE);
  506. CheckDlgButton(hDlg, IDD_MANUAL, FALSE);
  507. EnableWindow(GetDlgItem(hDlg, IDD_MANUAL),FALSE);
  508. }
  509. else
  510. {
  511. EnableWindow(GetDlgItem(hDlg, IDD_UPDATE), TRUE );
  512. EnableWindow(GetDlgItem(hDlg, IDD_FREEZE), TRUE );
  513. if (iAuto && iManual || !(iAuto || iManual))
  514. { //* Set update buttons
  515. CheckDlgButton(hDlg, IDD_AUTO, FALSE);
  516. EnableWindow(GetDlgItem(hDlg, IDD_AUTO),FALSE);
  517. CheckDlgButton(hDlg, IDD_MANUAL, FALSE);
  518. EnableWindow(GetDlgItem(hDlg, IDD_MANUAL),FALSE);
  519. }
  520. else
  521. {
  522. EnableWindow(GetDlgItem(hDlg, IDD_MANUAL), TRUE);
  523. EnableWindow(GetDlgItem(hDlg, IDD_AUTO), TRUE);
  524. if (iAuto)
  525. {
  526. CheckDlgButton(hDlg, IDD_AUTO, TRUE);
  527. CheckDlgButton(hDlg, IDD_MANUAL, FALSE);
  528. }
  529. else
  530. {
  531. CheckDlgButton(hDlg, IDD_AUTO, FALSE);
  532. CheckDlgButton(hDlg, IDD_MANUAL, TRUE);
  533. }
  534. }
  535. }
  536. EnableWindow(GetDlgItem(hDlg, IDD_CHANGE),fChangeLink && aCurName);
  537. }
  538. /****************************************************************************
  539. * ChangeLinks()
  540. *
  541. * This routine changes the linked data if the user chooses a new file to
  542. * replace the old document data portion of the linked date. The routine
  543. * does nothing if the user cancels.
  544. *
  545. * returns TRUE - if data changed FALSE if user cancel or err.
  546. ***************************************************************************/
  547. static BOOL ChangeLinks( //* ENTRY:
  548. HWND hDlg, //* dialog handle
  549. INT nLinks, //* number of links in listbox
  550. HWND hwndList, //* listbox
  551. APPITEMPTR *pLinks //* list of application link handles
  552. ){ //* LOCAL
  553. INT i; //* general index
  554. HANDLE hWork; //* work
  555. APPITEMPTR pItem; //* application item
  556. LPSTR lpNewDoc = NULL; //* new document
  557. ATOM aOldDoc; //* atom of old doc. name
  558. ATOM aCurDoc = 0; //* atom of change-to doc. name
  559. BOOL fMessage = FALSE; //* error message flag
  560. LPSTR lpLinkData; //* pointer to link data
  561. lpLinkData = NULL;
  562. //* This loop finds all selected links
  563. for (i = 0; i < nLinks; i++) //* and updates them
  564. {
  565. if (SendMessage(hwndList, LB_GETSEL, i, 0L))
  566. {
  567. pItem = *(pLinks+i);
  568. CHECK_IF_STATIC(pItem);
  569. pItem->lpLinkData = lpLinkData;
  570. if (!ObjGetData(pItem,NULL))
  571. continue;
  572. if (!lpNewDoc)
  573. {
  574. if (!(lpNewDoc = OfnGetNewLinkName(hDlg, pItem->lpLinkData)))
  575. return FALSE; //* ERROR jump
  576. aOldDoc = pItem->aLinkName;
  577. aCurDoc = AddAtom(lpNewDoc);
  578. SendMessage(hwndList,WM_SETREDRAW,FALSE,0L);
  579. }
  580. ObjSaveUndo(pItem);
  581. ObjChangeLinkData(pItem,lpNewDoc);
  582. pItem->aLinkName = aCurDoc;
  583. lpLinkData = pItem->lpLinkData;
  584. CHANGE_LISTBOX_STRING(hwndList, i, pItem, pItem->lpLinkData);
  585. pItem->lpLinkData = NULL;
  586. }
  587. }
  588. /*************************************************************************
  589. * now deal with non-selected links and look for a match...
  590. *************************************************************************/
  591. //* this loop finds non-selected links
  592. for (i = 0; i < nLinks; i++) //* and asks the user to update these?
  593. {
  594. if (!SendMessage(hwndList, LB_GETSEL, i, 0L))
  595. {
  596. pItem = *(pLinks+i);
  597. if (pItem->otObject == OT_STATIC)
  598. continue;
  599. if (!ObjGetData(pItem,NULL))
  600. continue;
  601. if (pItem->aLinkName == aOldDoc)
  602. {
  603. if (!fMessage)
  604. {
  605. CHAR szMessage[2*CBMESSAGEMAX+3*CBPATHMAX];
  606. CHAR szRename[2*CBMESSAGEMAX];
  607. CHAR szOldDoc[CBMESSAGEMAX];
  608. LPSTR pOldDoc;
  609. GetAtomName(aOldDoc,szOldDoc,CBMESSAGEMAX);
  610. pOldDoc =(LPSTR)UnqualifyPath(szOldDoc);
  611. LoadString(hInst, IDS_RENAME, szRename, 2*CBMESSAGEMAX);
  612. wsprintf(
  613. szMessage,
  614. szRename,
  615. pOldDoc,
  616. (LPSTR)UnqualifyPath(szFileName),
  617. pOldDoc
  618. );
  619. if (MessageBox(hDlg, szMessage,
  620. szAppName, MB_YESNO | MB_ICONEXCLAMATION) == IDNO)
  621. break;
  622. fMessage = TRUE;
  623. }
  624. ObjSaveUndo(pItem);
  625. ObjChangeLinkData(pItem,lpNewDoc);
  626. CHANGE_LISTBOX_STRING(hwndList, i, pItem, pItem->lpLinkData);
  627. pItem->aLinkName = aCurDoc;
  628. }
  629. }
  630. }
  631. if(lpNewDoc)
  632. {
  633. hWork = GlobalHandle(lpNewDoc);
  634. GlobalUnlock(hWork);
  635. GlobalFree(hWork);
  636. }
  637. #if 0
  638. // This is bogus -- this memory is owned by OLECLI32.DLL, not this app,
  639. // so it should not be freed here.
  640. if (lpLinkData)
  641. FreeLinkData(lpLinkData);
  642. #endif
  643. SendMessage(hwndList,WM_SETREDRAW,TRUE,0L);
  644. InvalidateRect(hwndList,NULL,TRUE);
  645. UpdateWindow(hwndList);
  646. WaitForAllObjects();
  647. if (aCurDoc)
  648. DeleteAtom(aCurDoc);
  649. return(TRUE);
  650. }
  651. /****************************************************************************
  652. * DisplayUpdate()
  653. *
  654. * Get the most up to date rendering information and show it.
  655. ***************************************************************************/
  656. static VOID DisplayUpdate( //* ENTRY:
  657. INT nLinks, //* number of links in listbox
  658. HWND hwndList, //* listbox
  659. APPITEMPTR *pLinks, //* list of application link handles
  660. BOOL fSaveUndo //* save undo objects
  661. ){ //* LOCAL:
  662. INT i; //* index
  663. APPITEMPTR pItem; //* temporary item pointer
  664. for (i = 0; i < nLinks; i++)
  665. if (SendMessage(hwndList, LB_GETSEL, i, 0L))
  666. {
  667. pItem = *(pLinks+i);
  668. CHECK_IF_STATIC(pItem);
  669. if (fSaveUndo)
  670. ObjSaveUndo(pItem);
  671. Error(OleUpdate(pItem->lpObject));
  672. }
  673. WaitForAllObjects();
  674. }
  675. /****************************************************************************
  676. * UndoObjects()
  677. *
  678. * Bring objects back to their original state.
  679. ***************************************************************************/
  680. static VOID UndoObjects()
  681. {
  682. APPITEMPTR pItem; //* application item pointer
  683. //* enum objects
  684. for (pItem = GetTopItem(); pItem; pItem = GetNextItem(pItem))
  685. if (pItem->lpObjectUndo)
  686. ObjUndo(pItem);
  687. WaitForAllObjects();
  688. }
  689. /****************************************************************************
  690. * DelUndoObjects()
  691. *
  692. * remove all objects created for undo operation.
  693. ***************************************************************************/
  694. static VOID DelUndoObjects( //* ENTRY:
  695. BOOL fPrompt //* prompt user?
  696. ){ //* LOCAL:
  697. APPITEMPTR pItem; //* application item pointer
  698. BOOL fPrompted = FALSE; //* prompted user?
  699. for (pItem = GetTopItem(); pItem; pItem = GetNextItem(pItem))
  700. {
  701. if (pItem->lpObjectUndo)
  702. {
  703. if (fPrompt && !fPrompted) //* prompt user in activation case
  704. {
  705. CHAR szPrompt[CBMESSAGEMAX];
  706. LoadString(hInst, IDS_SAVE_CHANGES, szPrompt, CBMESSAGEMAX);
  707. if (MessageBox(hwndFrame, szPrompt,
  708. szAppName, MB_YESNO | MB_ICONEXCLAMATION) == IDNO)
  709. {
  710. UndoObjects();
  711. return; //* user canceled operation
  712. }
  713. fPrompted = TRUE;
  714. }
  715. ObjDelUndo(pItem); //* delete udo object
  716. }
  717. }
  718. WaitForAllObjects();
  719. } //* SUCCESS return
  720. /****************************************************************************
  721. * CancelLinks()
  722. ***************************************************************************/
  723. static VOID CancelLinks( //* ENTRY:
  724. HWND hDlg, //* calling dialog
  725. INT nLinks, //* number of links in listbox
  726. HWND hwndList, //* listbox
  727. APPITEMPTR *pLinks //* list of application link handles
  728. ){ //* LOCAL:
  729. APPITEMPTR pItem; //* application item pointer
  730. INT i; //* index
  731. CHAR pLinkData[OBJECT_LINK_MAX];//* holder of link data
  732. SendMessage(hwndList,WM_SETREDRAW,FALSE,0L);
  733. for (i = 0; i < nLinks; i++)
  734. if (SendMessage(hwndList, LB_GETSEL, i, 0L))
  735. {
  736. pItem = *(pLinks+i);
  737. CHECK_IF_STATIC(pItem);
  738. ObjGetData(pItem,pLinkData);
  739. ObjSaveUndo(pItem);
  740. ObjFreeze(pItem);
  741. CHANGE_LISTBOX_STRING(hwndList, i, pItem, pLinkData);
  742. }
  743. SendMessage(hwndList,WM_SETREDRAW,TRUE,0L);
  744. InvalidateRect(hwndList,NULL,TRUE);
  745. UpdateWindow(hwndList);
  746. }
  747. /****************************************************************************
  748. * ChangeUpdateOptions()
  749. *
  750. * Change the update options for all selected objects.
  751. ***************************************************************************/
  752. static VOID ChangeUpdateOptions( //* ENTRY:
  753. HWND hDlg, //* calling dialog
  754. INT nLinks, //* number of links in listbox
  755. HWND hwndList, //* listbox
  756. APPITEMPTR *pLinks, //* list of application link handles
  757. OLEOPT_UPDATE lUpdate //* update option
  758. ){ //* LOCAL:
  759. APPITEMPTR pItem; //* application item
  760. INT i; //* index
  761. CHAR pLinkData[OBJECT_LINK_MAX];
  762. SendMessage(hwndList,WM_SETREDRAW,FALSE,0L);
  763. for (i = 0; i < nLinks; i++) //* enum selected objects
  764. {
  765. if (SendMessage(hwndList, LB_GETSEL, i, 0L))
  766. {
  767. pItem = *(pLinks+i);
  768. CHECK_IF_STATIC(pItem);
  769. ObjGetData(pItem,pLinkData);
  770. ObjSaveUndo(pItem);
  771. if (Error(OleSetLinkUpdateOptions(pItem->lpObject,lUpdate)))
  772. continue;
  773. pItem->uoObject = lUpdate;
  774. CHANGE_LISTBOX_STRING(hwndList, i, pItem, pLinkData);
  775. }
  776. }
  777. SendMessage(hwndList,WM_SETREDRAW,TRUE,0L);
  778. InvalidateRect(hwndList,NULL,TRUE);
  779. UpdateWindow(hwndList);
  780. WaitForAllObjects();
  781. }
  782. /****************************************************************************
  783. * InvalidLink()
  784. *
  785. * Deal with letting the user know that the program has inadvertently come
  786. * across an invalid link.
  787. *
  788. * Global fPropBoxActive - flag to determine whether or not the link dialog
  789. * box is active. If it is not active we give the
  790. * user an opportunity to enter the links property
  791. * dialog directly from here.
  792. ***************************************************************************/
  793. VOID FAR InvalidLink()
  794. {
  795. if (!hwndProp)
  796. DialogBox(hInst, "InvalidLink", hwndFrame, (DLGPROC)fnInvalidLink);
  797. else
  798. ErrorMessage(E_FAILED_TO_CONNECT);
  799. }
  800. /****************************************************************************
  801. * fnABout()
  802. *
  803. * About box dialog box procedure.
  804. ***************************************************************************/
  805. BOOL APIENTRY fnInvalidLink( //* ENTRY:
  806. HWND hDlg, //* standard windows dialog box
  807. UINT message,
  808. WPARAM wParam,
  809. LPARAM lParam
  810. ){
  811. switch (message)
  812. {
  813. case WM_INITDIALOG:
  814. return (TRUE);
  815. case WM_COMMAND:
  816. if (LOWORD(wParam) == IDD_CHANGE)
  817. LinkProperties();
  818. EndDialog(hDlg, TRUE);
  819. return (TRUE);
  820. }
  821. return (FALSE);
  822. }
  823. /****************************************************************************
  824. * AboutBox()
  825. *
  826. * Show the About Box dialog.
  827. ***************************************************************************/
  828. VOID FAR AboutBox()
  829. {
  830. DialogBox(hInst, "AboutBox", hwndFrame, (DLGPROC)fnAbout);
  831. }
  832. /****************************************************************************
  833. * fnABout()
  834. *
  835. * About box dialog box procedure.
  836. ***************************************************************************/
  837. BOOL APIENTRY fnAbout( //* ENTRY:
  838. HWND hDlg, //* standard windows dialog box
  839. UINT message,
  840. WPARAM wParam,
  841. LPARAM lParam
  842. ){
  843. switch (message)
  844. {
  845. case WM_INITDIALOG:
  846. return (TRUE);
  847. case WM_COMMAND:
  848. {
  849. WORD wID = LOWORD(wParam);
  850. if (wID == IDOK || wID == IDCANCEL)
  851. {
  852. EndDialog(hDlg, TRUE);
  853. return (TRUE);
  854. }
  855. break;
  856. }
  857. }
  858. return (FALSE);
  859. }
  860. /***************************************************************************
  861. * RetryMessage()
  862. *
  863. * give the user the chance to abort when a server is in retry case.
  864. *
  865. * Returns BOOL - TRUE if user chooses to cancel
  866. **************************************************************************/
  867. VOID FAR RetryMessage ( //* ENTRY:
  868. APPITEMPTR paItem, //* application item pointer
  869. LONG lParam
  870. ){
  871. RETRYPTR pRetry;
  872. LONG objectType;
  873. HANDLE hData;
  874. static CHAR szServerName[KEYNAMESIZE];
  875. HWND hwnd; //* window handle
  876. if (IsWindow(hwndProp))
  877. hwnd = hwndProp;
  878. else if (IsWindow(hwndFrame))
  879. hwnd = hwndFrame;
  880. else
  881. return; //* should not happen
  882. //* get the busy servers name
  883. lstrcpy(szServerName, "server application");
  884. if (paItem)
  885. {
  886. if (!paItem->aServer)
  887. {
  888. OleQueryType(paItem->lpObject, &objectType );
  889. if (OLE_OK == OleGetData(paItem->lpObject, (OLECLIPFORMAT) (objectType == OT_LINK ? vcfLink : vcfOwnerLink), &hData ))
  890. {
  891. RegGetClassId(szServerName, GlobalLock(hData));
  892. paItem->aServer = AddAtom(szServerName);
  893. GlobalUnlock( hData );
  894. }
  895. }
  896. else
  897. GetAtomName(paItem->aServer,szServerName,KEYNAMESIZE);
  898. }
  899. hData = LocalAlloc(LHND,sizeof(RETRYSTRUCT));
  900. if(!(pRetry = (RETRYPTR)LocalLock(hData)))
  901. return;
  902. pRetry->lpserver = (LPSTR)szServerName;
  903. pRetry->bCancel = (BOOL)(lParam & RD_CANCEL);
  904. pRetry->paItem = paItem;
  905. DialogBoxParam(hInst, "RetryBox", hwnd, (DLGPROC)fnRetry, (LONG)pRetry );
  906. LocalUnlock(hData);
  907. LocalFree(hData);
  908. hRetry = NULL;
  909. }
  910. /****************************************************************************
  911. * fnRetry()
  912. *
  913. * Retry message box nothing to tricky; however, when a server becomes
  914. * unbusy a message is posted to automatically get rid of this dialog.
  915. * I send a no.
  916. ***************************************************************************/
  917. BOOL APIENTRY fnRetry( //* ENTRY
  918. HWND hDlg, //* standard dialog entry
  919. UINT message,
  920. WPARAM wParam,
  921. LPARAM lParam
  922. ){
  923. static RETRYPTR pRetry;
  924. switch (message)
  925. {
  926. case WM_COMMAND:
  927. {
  928. WORD wID = LOWORD(wParam);
  929. switch (wParam)
  930. {
  931. case IDD_SWITCH:
  932. DefWindowProc( hDlg, WM_SYSCOMMAND, SC_TASKLIST, 0);
  933. break;
  934. case IDCANCEL:
  935. if (pRetry->paItem)
  936. pRetry->paItem->fRetry = FALSE;
  937. EndDialog(hDlg, TRUE);
  938. return TRUE;
  939. default:
  940. break;
  941. }
  942. break;
  943. }
  944. case WM_INITDIALOG:
  945. {
  946. CHAR szBuffer[CBMESSAGEMAX];
  947. CHAR szText[2*CBMESSAGEMAX];
  948. pRetry = (RETRYPTR)lParam;
  949. hRetry = hDlg;
  950. LoadString(hInst, IDS_RETRY_TEXT1, szBuffer, CBMESSAGEMAX);
  951. wsprintf(szText, szBuffer, pRetry->lpserver);
  952. SetWindowText (GetDlgItem(hDlg, IDD_RETRY_TEXT1), szText);
  953. LoadString(hInst, IDS_RETRY_TEXT2, szBuffer, CBMESSAGEMAX);
  954. wsprintf(szText, szBuffer, pRetry->lpserver);
  955. SetWindowText (GetDlgItem(hDlg, IDD_RETRY_TEXT2), szText);
  956. EnableWindow (GetDlgItem(hDlg, IDCANCEL), pRetry->bCancel);
  957. return TRUE;
  958. }
  959. default:
  960. break;
  961. }
  962. return FALSE;
  963. }