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.

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