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.

1990 lines
61 KiB

  1. /************************************************************/
  2. /* Windows Write, Copyright 1985-1992 Microsoft Corporation */
  3. /************************************************************/
  4. #include "windows.h"
  5. #include "mw.h"
  6. #include "winddefs.h"
  7. #include "obj.h"
  8. #include "menudefs.h"
  9. #include "cmddefs.h"
  10. #include "str.h"
  11. #include "objreg.h"
  12. #include "docdefs.h"
  13. #include "editdefs.h"
  14. #include "propdefs.h"
  15. #include "wwdefs.h"
  16. #include "filedefs.h"
  17. #include "shellapi.h"
  18. #include <commdlg.h>
  19. extern BOOL ferror;
  20. extern HCURSOR vhcArrow;
  21. extern HCURSOR vhcIBeam;
  22. extern struct DOD (**hpdocdod)[];
  23. extern struct PAP vpapAbs;
  24. extern struct UAB vuab;
  25. extern struct WWD rgwwd[];
  26. extern BOOL bKillMe;
  27. extern BOOL fPropsError;
  28. extern int docScrap;
  29. extern int docUndo;
  30. extern PRINTDLG PD;
  31. static BOOL DoLinksCommand(WORD wParam, DWORD lParam, HWND hDlg, BOOL *bError);
  32. /****************************************************************/
  33. /*********************** OLE DISPLAY HANDLING *******************/
  34. /****************************************************************/
  35. BOOL ObjDisplayObjectInDoc(OBJPICINFO far *lpPicInfo,
  36. int doc, typeCP cpParaStart,
  37. HDC hDC, LPRECT lpBounds)
  38. {
  39. BOOL bSuccess;
  40. if (lpOBJ_QUERY_INFO(lpPicInfo) == NULL)
  41. return(FALSE);
  42. #ifndef JAPAN // added by Hiraisi (BUG#2732/WIN31)
  43. // If we return here, we can never redraw the object again.
  44. if (lpOBJ_QUERY_INFO(lpPicInfo)->fCantDisplay)
  45. return(FALSE);
  46. #endif // not JAPAN
  47. if (otOBJ_QUERY_TYPE(lpPicInfo) == NONE)
  48. switch(otOBJ_QUERY_TYPE(lpPicInfo))
  49. {
  50. case NONE:
  51. {
  52. #if OBJ_EMPTY_OBJECT_FRAME
  53. extern DrawBlank(HDC hDC, RECT FAR *rc);
  54. DrawBlank(hDC,lpBounds);
  55. #else
  56. #ifdef DEBUG
  57. OutputDebugString( (LPSTR) "Displaying empty object\n\r");
  58. #endif
  59. #endif
  60. return TRUE;
  61. }
  62. }
  63. #ifdef DEBUG
  64. OutputDebugString( (LPSTR) "Displaying object\n\r");
  65. #endif
  66. #ifdef JAPAN // added by Hiraisi (BUG#2732/WIN31)
  67. if (lpOBJ_QUERY_INFO(lpPicInfo)->fCantDisplay)
  68. bSuccess = (OLE_OK == OleDraw(lpOBJ_QUERY_OBJECT(lpPicInfo),hDC,lpBounds,NULL,NULL));
  69. else
  70. bSuccess = !ObjError(OleDraw(lpOBJ_QUERY_OBJECT(lpPicInfo),hDC,lpBounds,NULL,NULL));
  71. if (!bSuccess)
  72. lpOBJ_QUERY_INFO(lpPicInfo)->fCantDisplay = TRUE;
  73. else
  74. lpOBJ_QUERY_INFO(lpPicInfo)->fCantDisplay = FALSE;
  75. #else
  76. bSuccess = !ObjError(OleDraw(lpOBJ_QUERY_OBJECT(lpPicInfo),hDC,lpBounds,NULL,NULL));
  77. if (!bSuccess)
  78. lpOBJ_QUERY_INFO(lpPicInfo)->fCantDisplay = TRUE;
  79. #endif // JAPAN
  80. return bSuccess;
  81. }
  82. BOOL ObjQueryObjectBounds(OBJPICINFO far *lpPicInfo, HDC hDC,
  83. int *pdxa, int *pdya)
  84. /* return bounds in twips */
  85. {
  86. RECT bounds;
  87. BOOL bRetval;
  88. OLESTATUS olestat;
  89. int mmOld;
  90. POINT pt;
  91. if (otOBJ_QUERY_TYPE(lpPicInfo) == NONE)
  92. {
  93. /* set to default */
  94. *pdxa = nOBJ_BLANKOBJECT_X;
  95. *pdya = nOBJ_BLANKOBJECT_Y;
  96. return TRUE;
  97. }
  98. if ((olestat = OleQueryBounds(lpOBJ_QUERY_OBJECT(lpPicInfo),&bounds))
  99. == OLE_ERROR_BLANK)
  100. {
  101. Assert(0);
  102. if (ObjWaitForObject(lpOBJ_QUERY_INFO(lpPicInfo),TRUE))
  103. return FALSE;
  104. olestat = OleQueryBounds(lpOBJ_QUERY_OBJECT(lpPicInfo),&bounds);
  105. }
  106. if (ObjError(olestat))
  107. return FALSE;
  108. pt.x = bounds.right - bounds.left;
  109. pt.y = -(bounds.bottom - bounds.top);
  110. #ifdef DEBUG
  111. {
  112. char szMsg[180];
  113. wsprintf(szMsg,"Object HIMETRIC width: %d height: %d\n\r",pt.x,-pt.y);
  114. OutputDebugString(szMsg);
  115. }
  116. #endif
  117. mmOld = SetMapMode(hDC,MM_HIMETRIC);
  118. LPtoDP(hDC,&pt,1);
  119. SetMapMode(hDC,MM_TWIPS);
  120. DPtoLP(hDC,&pt,1);
  121. SetMapMode(hDC,mmOld);
  122. *pdxa = pt.x;
  123. *pdya = pt.y;
  124. return TRUE;
  125. }
  126. void ObjInvalidatePict(OBJPICINFO *pPicInfo, typeCP cp)
  127. {
  128. struct EDL *pedl;
  129. RECT rc;
  130. extern int wwCur;
  131. ObjPushParms(docCur);
  132. ObjCachePara(docCur,cp);
  133. Select(vcpFirstParaCache,vcpLimParaCache);
  134. FreezeHp();
  135. if (FGetPictPedl(&pedl)) // find pedl at selCur.cpFirst;
  136. {
  137. ComputePictRect( &rc, pPicInfo, pedl, wwCur );
  138. InvalidateRect(hDOCWINDOW, &rc, FALSE);
  139. }
  140. MeltHp();
  141. ObjPopParms(TRUE);
  142. UPDATE_INVALID();
  143. }
  144. void ObjInvalidateObj(LPOLEOBJECT lpObject)
  145. {
  146. typeCP cp;
  147. OBJPICINFO picInfo;
  148. ObjPushParms(docCur);
  149. if (ObjGetPicInfo(lpObject,docCur,&picInfo,&cp))
  150. ObjInvalidatePict(&picInfo,cp);
  151. ObjPopParms(TRUE);
  152. }
  153. /****************************************************************/
  154. /*********************** OLE CLIPBOARD *************************/
  155. /****************************************************************/
  156. BOOL ObjCreateObjectInClip(OBJPICINFO *pPicInfo)
  157. {
  158. LONG otobject;
  159. szOBJNAME szObjName;
  160. OLESTATUS olestat;
  161. BOOL bRetval = FALSE;
  162. Assert (lhClientDoc != NULL);
  163. if (ObjAllocObjInfo(pPicInfo,selCur.cpFirst,NONE,TRUE,szObjName))
  164. goto error;
  165. if (vbObjLinkOnly)
  166. {
  167. if (ObjError(OleCreateLinkFromClip(PROTOCOL, (LPOLECLIENT)lpOBJ_QUERY_INFO(pPicInfo),
  168. lhClientDoc, szObjName,
  169. &lpOBJ_QUERY_OBJECT(pPicInfo), olerender_draw, 0)))
  170. {
  171. lpOBJ_QUERY_OBJECT(pPicInfo) = NULL;
  172. goto error;
  173. }
  174. }
  175. else if (vObjPasteLinkSpecial)
  176. {
  177. if (ObjError(OleCreateLinkFromClip(PROTOCOL, (LPOLECLIENT)lpOBJ_QUERY_INFO(pPicInfo),
  178. lhClientDoc, szObjName,
  179. &lpOBJ_QUERY_OBJECT(pPicInfo), olerender_format, cfObjPasteSpecial)))
  180. {
  181. lpOBJ_QUERY_OBJECT(pPicInfo) = NULL;
  182. goto error;
  183. }
  184. }
  185. else
  186. {
  187. WORD cfClipFormat=0;
  188. OLEOPT_RENDER orRender = olerender_draw;
  189. if (cfObjPasteSpecial && (cfObjPasteSpecial != vcfOwnerLink))
  190. /* from PasteSpecial. There's a format on clipboard that
  191. user wants to paste and its not the embedded object format.
  192. So we'll do it as a static object. */
  193. {
  194. cfClipFormat = cfObjPasteSpecial;
  195. orRender = olerender_format;
  196. olestat = OLE_ERROR_CLIPBOARD; // force get static object
  197. }
  198. else // try for embedded
  199. olestat = OleCreateFromClip(PROTOCOL, (LPOLECLIENT)lpOBJ_QUERY_INFO(pPicInfo),
  200. lhClientDoc, szObjName,
  201. &lpOBJ_QUERY_OBJECT(pPicInfo), orRender, cfClipFormat);
  202. switch(olestat)
  203. {
  204. case OLE_ERROR_CLIPBOARD:
  205. /* try static protocol */
  206. olestat = OleCreateFromClip(SPROTOCOL, (LPOLECLIENT)lpOBJ_QUERY_INFO(pPicInfo),
  207. lhClientDoc, szObjName,
  208. &lpOBJ_QUERY_OBJECT(pPicInfo), orRender, cfClipFormat);
  209. switch(olestat)
  210. {
  211. case OLE_ERROR_CLIPBOARD:
  212. goto error;
  213. case OLE_WAIT_FOR_RELEASE:
  214. case OLE_OK:
  215. break;
  216. default:
  217. lpOBJ_QUERY_OBJECT(pPicInfo) = NULL;
  218. goto error;
  219. }
  220. break;
  221. case OLE_WAIT_FOR_RELEASE:
  222. case OLE_OK:
  223. break;
  224. default:
  225. ObjError(olestat);
  226. goto error;
  227. }
  228. }
  229. /* Figure out what kind of object we have */
  230. if (ObjError(OleQueryType(lpOBJ_QUERY_OBJECT(pPicInfo),&otobject)))
  231. goto error;
  232. switch(otobject)
  233. {
  234. case OT_LINK:
  235. otOBJ_QUERY_TYPE(pPicInfo) = LINK;
  236. break;
  237. case OT_EMBEDDED:
  238. otOBJ_QUERY_TYPE(pPicInfo) = EMBEDDED;
  239. break;
  240. default:
  241. otOBJ_QUERY_TYPE(pPicInfo) = STATIC;
  242. break;
  243. }
  244. if (ObjInitServerInfo(lpOBJ_QUERY_INFO(pPicInfo)))
  245. goto error;
  246. if (!FComputePictSize(pPicInfo, &(pPicInfo->dxaSize),
  247. &(pPicInfo->dyaSize) ))
  248. goto error;
  249. return TRUE;
  250. error:
  251. if (lpOBJ_QUERY_INFO(pPicInfo))
  252. ObjDeleteObject(lpOBJ_QUERY_INFO(pPicInfo),TRUE);
  253. Error(IDPMTFailedToCreateObject);
  254. return FALSE;
  255. }
  256. BOOL ObjWriteToClip(OBJPICINFO FAR *lpPicInfo)
  257. /* return TRUE if OK, FALSE if not */
  258. {
  259. #ifdef DEBUG
  260. OutputDebugString( (LPSTR) "Copying Object to Clipboard\n\r");
  261. #endif
  262. if (otOBJ_QUERY_TYPE(lpPicInfo) == NONE)
  263. return FALSE;
  264. if (ObjWaitForObject(lpOBJ_QUERY_INFO(lpPicInfo),TRUE))
  265. return FALSE;
  266. return (!ObjError(OleCopyToClipboard(lpOBJ_QUERY_OBJECT(lpPicInfo))));
  267. }
  268. /****************************************************************/
  269. /*********************** OLE MENU HANDLING **********************/
  270. /****************************************************************/
  271. void ObjUpdateMenu(HMENU hMenu)
  272. /* this *MUST* be called *AFTER* paste menuitem has already been enabled
  273. according to presence of non-object contents of the clipboard!!! (1.25.91) D. Kent */
  274. {
  275. int mfPaste = MF_GRAYED;
  276. #if !defined(SMALL_OLE_UI)
  277. int mfPasteLink = MF_GRAYED;
  278. int mfLinks = MF_GRAYED;
  279. #endif
  280. int mfPasteSpecial = MF_GRAYED;
  281. int mfInsertNew = MF_GRAYED;
  282. WORD cfFormat = NULL;
  283. BOOL bIsEmbed=FALSE,bIsLink=FALSE;
  284. extern BOOL vfOutOfMemory;
  285. extern int vfOwnClipboard;
  286. if (!vfOutOfMemory)
  287. {
  288. if (vfOwnClipboard)
  289. {
  290. if (CpMacText( docScrap ) != cp0) // something in scrap
  291. mfPaste = MF_ENABLED;
  292. }
  293. else
  294. {
  295. if (OleQueryCreateFromClip(PROTOCOL, olerender_draw, 0) == OLE_OK)
  296. mfPaste = MF_ENABLED, bIsEmbed=TRUE;
  297. else if (OleQueryCreateFromClip(SPROTOCOL, olerender_draw, 0) == OLE_OK)
  298. mfPaste = MF_ENABLED;
  299. // Enable "Paste Link" if there is a link-able object in the clipboard
  300. if (OleQueryLinkFromClip(PROTOCOL, olerender_draw, 0) == OLE_OK)
  301. {
  302. bIsLink=TRUE;
  303. #if !defined(SMALL_OLE_UI)
  304. mfPasteLink = MF_ENABLED;
  305. #endif
  306. }
  307. }
  308. /* There's no point in putting up pastespecial if there are no
  309. alternate clip formats to choose from. */
  310. #if defined(SMALL_OLE_UI)
  311. /* except to get paste link */
  312. #endif
  313. if (OpenClipboard( hPARENTWINDOW ) )
  314. {
  315. int ncfCount=0;
  316. while (cfFormat = EnumClipboardFormats(cfFormat))
  317. switch (cfFormat)
  318. {
  319. case CF_TEXT:
  320. mfPaste = MF_ENABLED;
  321. case CF_BITMAP:
  322. case CF_METAFILEPICT:
  323. case CF_DIB:
  324. ++ncfCount;
  325. break;
  326. }
  327. CloseClipboard();
  328. if (bIsLink || bIsEmbed)
  329. {
  330. #if !defined(SMALL_OLE_UI)
  331. if (ncfCount >= 1)
  332. #endif
  333. mfPasteSpecial = MF_ENABLED;
  334. }
  335. else if (ncfCount > 1)
  336. mfPasteSpecial = MF_ENABLED;
  337. }
  338. #if !defined(SMALL_OLE_UI)
  339. mfLinks = MF_ENABLED;
  340. #endif
  341. // Insert_New is always enabled?
  342. mfInsertNew = MF_ENABLED;
  343. }
  344. ObjUpdateMenuVerbs( hMenu );
  345. EnableMenuItem(hMenu, imiPaste, mfPaste);
  346. #if !defined(SMALL_OLE_UI)
  347. EnableMenuItem(hMenu, imiPasteLink, mfPasteLink);
  348. EnableMenuItem(hMenu, imiProperties, mfLinks);
  349. #endif
  350. EnableMenuItem(hMenu, imiPasteSpecial, mfPasteSpecial);
  351. EnableMenuItem(hMenu, imiInsertNew, mfInsertNew);
  352. }
  353. /****************************************************************/
  354. /*********************** OLE DIALOG PROCS ***********************/
  355. /****************************************************************/
  356. #if !defined(SMALL_OLE_UI)
  357. /* Properties... dialog */
  358. BOOL FAR PASCAL fnProperties(HWND hDlg, unsigned msg, WORD wParam, LONG lParam)
  359. {
  360. ATOM aDocName = 0;
  361. ATOM aCurName = 0;
  362. static int idButton = 0;
  363. OBJPICINFO picInfo;
  364. BOOL bSelected;
  365. int cSelected = 0;
  366. int iListItem = 0;
  367. HWND vhwndObjListBox = GetDlgItem(hDlg, IDD_LISTBOX);
  368. extern HWND vhWndMsgBoxParent;
  369. static BOOL bDidSomething;
  370. switch (msg) {
  371. case WM_ACTIVATE:
  372. if (wParam)
  373. vhWndMsgBoxParent = hDlg;
  374. break;
  375. case WM_UPDATELB: /* Redrawing listbox contents */
  376. SendMessage(vhwndObjListBox, WM_SETREDRAW, 0, 0L);
  377. case WM_UPDATEBN: /* Updating Buttons only */
  378. case WM_INITDIALOG: {
  379. HANDLE hData = NULL;
  380. LPSTR lpstrData = NULL;
  381. LPSTR lpstrTemp;
  382. char szType[40];
  383. char szFull[cchMaxSz];
  384. typeCP cpPicInfo;
  385. struct SEL selSave;
  386. OLESTATUS olestat;
  387. idButton = 0;
  388. /* Reset the list box */
  389. if (msg == WM_INITDIALOG) // see fall through above
  390. {
  391. SendMessage(vhwndObjListBox, LB_RESETCONTENT, 0, 0L);
  392. EnableOtherModeless(FALSE);
  393. selSave=selCur;
  394. //ObjWriteFixup(docCur,TRUE,cp0);
  395. bLinkProps = TRUE;
  396. bDidSomething = FALSE;
  397. ObjSetSelectionType(docCur, selSave.cpFirst, selSave.cpLim);
  398. }
  399. /* Insert all the items in list box */
  400. cpPicInfo = cpNil;
  401. while (ObjPicEnumInRange(&picInfo,docCur,cp0,CpMacText(docCur),&cpPicInfo))
  402. {
  403. if (otOBJ_QUERY_TYPE(&picInfo) != LINK)
  404. {
  405. if (msg == WM_UPDATEBN)
  406. continue; // object ain't in list box
  407. if (msg == WM_INITDIALOG)
  408. fOBJ_QUERY_IN_PROP_LIST(&picInfo) = OUT;
  409. else if (fOBJ_QUERY_IN_PROP_LIST(&picInfo) == IN)
  410. /** then this is an object which was in the list and
  411. has been frozen */
  412. {
  413. fOBJ_QUERY_IN_PROP_LIST(&picInfo) = DELETED;
  414. SendMessage(vhwndObjListBox, LB_DELETESTRING, iListItem, 0L);
  415. }
  416. else
  417. continue; // object ain't in list box
  418. continue;
  419. }
  420. else if (msg == WM_INITDIALOG)
  421. {
  422. fOBJ_QUERY_IN_PROP_LIST(&picInfo) = IN;
  423. /**
  424. This flag causes object to be cloned if any changes
  425. are made to it. Clone will be used for cancel button.
  426. **/
  427. if (ObjLoadObjectInDoc(&picInfo,docCur,cpPicInfo) == cp0)
  428. goto onOut;
  429. }
  430. if (msg == WM_INITDIALOG) // select in list if selected in doc
  431. {
  432. if (OBJ_SELECTIONTYPE == LINK)
  433. bSelected = (cpPicInfo >= selSave.cpFirst &&
  434. cpPicInfo < selSave.cpLim);
  435. else // no selection, select first item
  436. bSelected = iListItem == 0;
  437. /* OR if its a bad link, take the liberty of selecting it */
  438. if (fOBJ_BADLINK(&picInfo))
  439. bSelected = TRUE;
  440. }
  441. else // select in list if already selected in list
  442. bSelected = SendMessage(vhwndObjListBox, LB_GETSEL, iListItem, 0L);
  443. /* Get the update options */
  444. if (fOBJ_BADLINK(&picInfo))
  445. {
  446. LoadString(hINSTANCE, IDSTRFrozen, szType, sizeof(szType));
  447. if (bSelected)
  448. idButton = -1;
  449. }
  450. else switch (ObjGetUpdateOptions(&picInfo))
  451. {
  452. case oleupdate_always:
  453. LoadString(hINSTANCE, IDSTRAuto, szType, sizeof(szType));
  454. if (bSelected)
  455. switch (idButton) {
  456. case 0: idButton = IDD_AUTO; break;
  457. case IDD_MANUAL: idButton = -1; break;
  458. default: break;
  459. }
  460. break;
  461. case oleupdate_oncall:
  462. LoadString(hINSTANCE, IDSTRManual, szType, sizeof(szType));
  463. if (bSelected)
  464. switch (idButton) {
  465. case 0: idButton = IDD_MANUAL; break;
  466. case IDD_AUTO: idButton = -1; break;
  467. default: break;
  468. }
  469. break;
  470. default:
  471. LoadString(hINSTANCE, IDSTRFrozen, szType, sizeof(szType));
  472. if (bSelected)
  473. idButton = -1;
  474. /* Disable the change link button, can't change frozen link */
  475. aCurName = -1;
  476. }
  477. /* Retrieve the server name */
  478. olestat = ObjGetData(lpOBJ_QUERY_INFO(&picInfo), vcfLink, &hData);
  479. if ((olestat != OLE_WARN_DELETE_DATA) && (olestat != OLE_OK))
  480. return TRUE;
  481. lpstrData = MAKELP(hData,0);
  482. /* The link format is: "szClass0szDocument0szItem00" */
  483. /* Retrieve the server's class ID */
  484. RegGetClassId(szFull, lpstrData);
  485. lstrcat(szFull, "\t");
  486. /* Display the Document and Item names */
  487. while (*lpstrData++);
  488. /* Get this document name */
  489. aDocName = AddAtom(lpstrData);
  490. /* Make sure only one document selected for Change Link */
  491. if (bSelected)
  492. switch (aCurName) {
  493. case 0:
  494. aCurName = aDocName;
  495. break;
  496. case -1:
  497. break;
  498. default:
  499. if (aCurName != aDocName)
  500. aCurName = -1;
  501. break;
  502. }
  503. DeleteAtom(aDocName);
  504. /* Strip off the path name and drive letter */
  505. lpstrTemp = lpstrData;
  506. while (*lpstrTemp)
  507. {
  508. if (*lpstrTemp == '\\' || *lpstrTemp == ':')
  509. lpstrData = lpstrTemp + 1;
  510. #ifdef DBCS //T-HIROYN 1992.07.13
  511. lpstrTemp = AnsiNext(lpstrTemp);
  512. #else
  513. lpstrTemp++;
  514. #endif
  515. }
  516. /* Append the file name */
  517. lstrcat(szFull, lpstrData);
  518. lstrcat(szFull, "\t");
  519. /* Append the item name */
  520. while (*lpstrData++);
  521. lstrcat(szFull, lpstrData);
  522. lstrcat(szFull, "\t");
  523. if (olestat == OLE_WARN_DELETE_DATA)
  524. GlobalFree(hData);
  525. /* Append the type of link */
  526. lstrcat(szFull, szType);
  527. switch (msg)
  528. {
  529. case WM_UPDATELB:
  530. SendMessage(vhwndObjListBox, LB_DELETESTRING, iListItem, 0L);
  531. // fall through...
  532. case WM_INITDIALOG:
  533. SendMessage(vhwndObjListBox, LB_INSERTSTRING, iListItem, (DWORD)(LPSTR)szFull);
  534. SendMessage(vhwndObjListBox, LB_SETSEL, bSelected, (DWORD)iListItem);
  535. break;
  536. }
  537. if (bSelected)
  538. cSelected++;
  539. iListItem++;
  540. }
  541. /* Uncheck those buttons that shouldn't be checked */
  542. CheckDlgButton(hDlg, IDD_AUTO, idButton == IDD_AUTO);
  543. CheckDlgButton(hDlg, IDD_MANUAL, idButton == IDD_MANUAL);
  544. /* Gray the Change Link... button, as appropriate */
  545. EnableWindow(GetDlgItem(hDlg, IDD_CHANGE), (aCurName && aCurName != -1));
  546. EnableWindow(GetDlgItem(hDlg, IDD_EDIT), cSelected);
  547. EnableWindow(GetDlgItem(hDlg, IDD_PLAY), cSelected);
  548. EnableWindow(GetDlgItem(hDlg, IDD_UPDATE), cSelected);
  549. EnableWindow(GetDlgItem(hDlg, IDD_FREEZE), cSelected);
  550. EnableWindow(GetDlgItem(hDlg, IDD_AUTO), cSelected);
  551. EnableWindow(GetDlgItem(hDlg, IDD_MANUAL), cSelected);
  552. if (msg == WM_UPDATELB)
  553. {
  554. /* WM_UPDATELB case: Redraw the list box */
  555. InvalidateRect(vhwndObjListBox, NULL, TRUE);
  556. SendMessage(vhwndObjListBox, WM_SETREDRAW, 1, 0L);
  557. }
  558. return TRUE;
  559. }
  560. case WM_SYSCOMMAND:
  561. switch(wParam & 0xFFF0)
  562. {
  563. case SC_CLOSE:
  564. goto onOut;
  565. break;
  566. }
  567. break;
  568. case WM_DOLINKSCOMMAND:
  569. {
  570. BOOL bError;
  571. bDidSomething |= DoLinksCommand(wParam,lParam,hDlg,&bError);
  572. switch (wParam)
  573. {
  574. case IDD_PLAY:
  575. case IDD_EDIT:
  576. InvalidateRect(hDOCWINDOW, NULL, TRUE);
  577. if (!bError) // don't leave if there was an error
  578. goto onOut;
  579. }
  580. }
  581. break;
  582. case WM_COMMAND:
  583. switch (wParam)
  584. {
  585. case IDCANCEL:
  586. if (bDidSomething)
  587. {
  588. SendMessage(hDlg,WM_DOLINKSCOMMAND,IDD_UNDO,0L);
  589. InvalidateRect(hDOCWINDOW, NULL, TRUE);
  590. bDidSomething = FALSE; // cause its undone now
  591. }
  592. // fall through...
  593. case IDOK:
  594. onOut:
  595. if (bDidSomething)
  596. {
  597. ObjEnumInDoc(docCur,ObjClearCloneInDoc);
  598. }
  599. NoUndo();
  600. bLinkProps = FALSE;
  601. //ObjWriteFixup(docCur,FALSE,cp0);
  602. OurEndDialog(hDlg, TRUE);
  603. UpdateWindow(hDOCWINDOW); // cause we may have lost activation
  604. return TRUE;
  605. default:
  606. /** posting message avoids some weird asynchronicities when
  607. waiting for objects before returning after pressing a
  608. button **/
  609. PostMessage(hDlg,WM_DOLINKSCOMMAND,wParam,lParam);
  610. break;
  611. }
  612. break;
  613. }
  614. return FALSE;
  615. }
  616. static BOOL DoLinksCommand(WORD wParam, DWORD lParam, HWND hDlg, BOOL *bError)
  617. {
  618. int cItems;
  619. int i;
  620. HANDLE hSelected=NULL;
  621. int far *lpSelected;
  622. typeCP cpSuccess;
  623. typeCP cpPicInfo;
  624. BOOL bFirst=TRUE;
  625. OBJPICINFO picInfo;
  626. BOOL bDidSomething=FALSE;
  627. HWND vhwndObjListBox = GetDlgItem(hDlg, IDD_LISTBOX);
  628. StartLongOp();
  629. *bError = FALSE;
  630. switch (wParam)
  631. {
  632. case IDD_REFRESH:
  633. /** update a link if its been set to AUTOMATIC update */
  634. {
  635. OLEOPT_UPDATE UpdateOpt;
  636. if (!ObjError(OleGetLinkUpdateOptions(((LPOBJINFO)lParam)->lpobject,&UpdateOpt)))
  637. if (UpdateOpt == oleupdate_always)
  638. fnObjUpdate((LPOBJINFO)lParam);
  639. goto SkipIt;
  640. }
  641. break;
  642. case IDD_LISTBOX:
  643. switch (HIWORD(lParam))
  644. {
  645. case LBN_SELCHANGE:
  646. PostMessage(hDlg, WM_UPDATEBN, 0, 0L); // fall through
  647. default:
  648. goto SkipIt;
  649. }
  650. break;
  651. case IDD_CHANGE:
  652. aNewName = aOldName = 0;
  653. // fall through...
  654. case IDD_UPDATE:
  655. ObjEnumInDoc(docCur,ObjSetNoUpdate);
  656. break;
  657. case IDD_AUTO:
  658. case IDD_MANUAL:
  659. if (IsDlgButtonChecked(hDlg,wParam))
  660. goto SkipIt;
  661. /* work around for bug #8280 */
  662. CheckDlgButton(hDlg,wParam,TRUE);
  663. break;
  664. }
  665. /**
  666. Everything after here is done for each item selected in
  667. links list box *
  668. **/
  669. /* If nothing is selected, quit! */
  670. if (wParam != IDD_UNDO)
  671. {
  672. if ((cItems = SendMessage(vhwndObjListBox, LB_GETSELCOUNT, 0, 0L)) <= 0)
  673. goto SkipIt;
  674. if ((hSelected = GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT,
  675. cItems * sizeof(int))) == NULL)
  676. {
  677. Error(IDPMTNoMemory);
  678. goto SkipIt;
  679. }
  680. if ((lpSelected = (int far *)GlobalLock(hSelected)) == NULL)
  681. {
  682. Error(IDPMTNoMemory);
  683. goto SkipIt;
  684. }
  685. /* Retrieve the selected items (in sorted order) */
  686. SendMessage(vhwndObjListBox, LB_GETSELITEMS,
  687. cItems, (DWORD)lpSelected);
  688. }
  689. for (i = 0, cpPicInfo = cpNil;
  690. ObjPicEnumInRange(&picInfo,docCur,cp0,CpMacText(docCur),&cpPicInfo);)
  691. {
  692. /**
  693. For IDD_UNDO we do all. Dirty flag will filter in the ones
  694. we've operated on. Assumes Saved before calling (see
  695. fnObjProperties())
  696. **/
  697. if (fOBJ_QUERY_IN_PROP_LIST(&picInfo)) // is or was in list
  698. {
  699. if (wParam == IDD_UNDO)
  700. {
  701. cpSuccess = ObjUseCloneInDoc(&picInfo,docCur,cpPicInfo);
  702. if ((cpSuccess == cp0) || ferror || fPropsError)
  703. break; // there was an error
  704. }
  705. else if (fOBJ_QUERY_IN_PROP_LIST(&picInfo) == IN)
  706. {
  707. /** We're enumerating all objects, not just
  708. ones in list box **/
  709. if (*lpSelected == i) // selected item
  710. {
  711. ObjCachePara(docCur,cpPicInfo);
  712. switch(wParam)
  713. {
  714. case IDD_AUTO: /* Change the (link) update options */
  715. case IDD_MANUAL:
  716. if (!fOBJ_BADLINK(&picInfo))
  717. {
  718. cpSuccess = ObjBackupInDoc(&picInfo,docCur,cpPicInfo);
  719. if (cpSuccess)
  720. cpSuccess = (typeCP)ObjSetUpdateOptions(&picInfo, wParam, docCur, cpPicInfo);
  721. }
  722. break;
  723. case IDD_CHANGE:
  724. if (bFirst)
  725. {
  726. if (!ObjQueryNewLinkName(&picInfo,docCur,cpPicInfo))
  727. // then didn't get new link name
  728. goto SkipIt;
  729. bFirst=FALSE;
  730. }
  731. cpSuccess = ObjBackupInDoc(&picInfo,docCur,cpPicInfo);
  732. if (cpSuccess)
  733. cpSuccess = ObjChangeLinkInDoc(&picInfo,docCur,cpPicInfo);
  734. /* must do this because we don't want to put up
  735. ChangeOtherLinks dialog until we know the first
  736. change was a success */
  737. if (cpSuccess)
  738. {
  739. lpOBJ_QUERY_INFO(&picInfo)->fCompleteAsync = TRUE;
  740. if (ObjWaitForObject(lpOBJ_QUERY_INFO(&picInfo),TRUE))
  741. cpSuccess = cp0;
  742. else if (ferror || fPropsError)
  743. cpSuccess = cp0;
  744. }
  745. break;
  746. case IDD_PLAY:
  747. cpSuccess = ObjPlayObjectInDoc(&picInfo,docCur,cpPicInfo);
  748. break;
  749. case IDD_EDIT:
  750. cpSuccess = ObjEditObjectInDoc(&picInfo,docCur,cpPicInfo);
  751. break;
  752. case IDD_UPDATE:
  753. cpSuccess = ObjBackupInDoc(&picInfo,docCur,cpPicInfo);
  754. if (cpSuccess)
  755. cpSuccess = ObjUpdateObjectInDoc(&picInfo,docCur,cpPicInfo);
  756. /* must do this because we don't want to put up
  757. ChangeOtherLinks dialog until we know the first
  758. change was a success */
  759. if (cpSuccess)
  760. {
  761. lpOBJ_QUERY_INFO(&picInfo)->fCompleteAsync = TRUE;
  762. if (ObjWaitForObject(lpOBJ_QUERY_INFO(&picInfo),TRUE))
  763. cpSuccess = cp0;
  764. else if (ferror || fPropsError)
  765. cpSuccess = cp0;
  766. }
  767. break;
  768. case IDD_UPDATEOTHER:
  769. aOldName = aOBJ_QUERY_DOCUMENT_LINK(&picInfo);
  770. if (cpSuccess)
  771. ChangeOtherLinks(docCur,FALSE,TRUE);
  772. aOldName=0;
  773. break;
  774. case IDD_FREEZE:
  775. cpSuccess = ObjBackupInDoc(&picInfo,docCur,cpPicInfo);
  776. if (cpSuccess)
  777. cpSuccess = ObjFreezeObjectInDoc(&picInfo,docCur,cpPicInfo);
  778. break;
  779. }
  780. if ((cpSuccess == cp0) || ferror || fPropsError)
  781. break; // there was an error
  782. lpSelected++;
  783. }
  784. i++; // counting all objects in list box
  785. } // end if IN
  786. }
  787. }
  788. /*** Handle error conditions ***/
  789. if ((cpSuccess == cp0) || ferror || fPropsError)
  790. {
  791. *bError = TRUE;
  792. if (!ferror) // issue error message
  793. {
  794. switch (wParam)
  795. {
  796. case IDD_UPDATE:
  797. case IDD_CHANGE:
  798. Error(IDPMTLinkUnavailable);
  799. break;
  800. default:
  801. Error(IDPMTOLEError);
  802. break;
  803. }
  804. }
  805. if (wParam != IDD_UNDO)
  806. {
  807. /** so we can continue calling Replace(), etc */
  808. ferror = FALSE;
  809. /* undo whatever we tried to do that failed */
  810. ObjCachePara(docCur,cpPicInfo); // for use clone
  811. ObjUseCloneInDoc(&picInfo,docCur,cpPicInfo);
  812. lpOBJ_QUERY_INFO(&picInfo)->fCompleteAsync = TRUE;
  813. ObjWaitForObject(lpOBJ_QUERY_INFO(&picInfo),TRUE);
  814. ObjInvalidatePict(&picInfo,cpPicInfo);
  815. PostMessage(hDlg,WM_UPDATELB,0,0L);
  816. ferror = FALSE; // again
  817. }
  818. fPropsError = FALSE;
  819. }
  820. switch (wParam)
  821. {
  822. /* Dismiss the dialog on Open */
  823. case IDD_UPDATEOTHER:
  824. UPDATE_INVALID();
  825. break;
  826. case IDD_PLAY:
  827. case IDD_EDIT:
  828. case IDD_UNDO:
  829. break;
  830. case IDD_UPDATE:
  831. if (cpSuccess)
  832. SendMessage(hDlg,WM_COMMAND,IDD_UPDATEOTHER,0L);
  833. bDidSomething = TRUE;
  834. break;
  835. case IDD_CHANGE:
  836. if (cpSuccess)
  837. {
  838. /** aOldName and aNewName are now set, change other links having
  839. aOldName */
  840. /** if first change is bad, don't change others */
  841. ChangeOtherLinks(docCur,TRUE,TRUE);
  842. UPDATE_INVALID();
  843. }
  844. aOldName=0;
  845. aNewName=0;
  846. // fall through....
  847. case IDD_FREEZE:
  848. case IDD_AUTO:
  849. case IDD_MANUAL:
  850. PostMessage(hDlg,WM_UPDATELB,0,0L);
  851. bDidSomething = TRUE;
  852. break;
  853. }
  854. SkipIt:
  855. if (hSelected)
  856. GlobalFree(hSelected);
  857. EndLongOp(vhcArrow);
  858. return bDidSomething;
  859. }
  860. #else
  861. // cause I don't wanna change def file yet...
  862. BOOL FAR PASCAL fnProperties(HWND hDlg, unsigned msg, WORD wParam, LONG lParam)
  863. {
  864. hDlg;
  865. }
  866. #endif
  867. /* Invalid Link dialog */
  868. int FAR PASCAL fnInvalidLink(HWND hDlg, unsigned msg, WORD wParam, LONG lParam)
  869. {
  870. switch (msg) {
  871. case WM_INITDIALOG:
  872. #if 0
  873. {
  874. char lpString[120];
  875. LoadString(hINSTANCE, (WORD)lParam, lpString, sizeof(lpString));
  876. SetDlgItemText(hDlg,IDD_MESSAGE,lpString);
  877. }
  878. #endif
  879. break;
  880. case WM_SYSCOMMAND:
  881. switch(wParam & 0xFFF0)
  882. {
  883. case SC_CLOSE:
  884. EndDialog(hDlg, IDOK);
  885. break;
  886. }
  887. break;
  888. case WM_COMMAND:
  889. switch (wParam) {
  890. case IDOK:
  891. case IDD_CHANGE:
  892. EndDialog(hDlg, wParam);
  893. }
  894. }
  895. return FALSE;
  896. }
  897. /* Insert New... dialog */
  898. int FAR PASCAL fnInsertNew(HWND hDlg, unsigned msg, WORD wParam, LONG lParam)
  899. {
  900. HWND hwndList = GetDlgItem(hDlg, IDD_LISTBOX);
  901. switch (msg) {
  902. case WM_INITDIALOG:
  903. if (!RegGetClassNames(hwndList))
  904. OurEndDialog(hDlg, IDCANCEL);
  905. EnableOtherModeless(FALSE);
  906. SendMessage(hwndList, LB_SETCURSEL, 0, 0L);
  907. break;
  908. case WM_ACTIVATE:
  909. if (wParam)
  910. vhWndMsgBoxParent = hDlg;
  911. break;
  912. case WM_SYSCOMMAND:
  913. switch(wParam & 0xFFF0)
  914. {
  915. case SC_CLOSE:
  916. OurEndDialog(hDlg, IDCANCEL);
  917. break;
  918. }
  919. break;
  920. case WM_COMMAND:
  921. switch (wParam) {
  922. case IDD_LISTBOX:
  923. if (HIWORD(lParam) != LBN_DBLCLK)
  924. break;
  925. case IDOK:
  926. StartLongOp();
  927. if (!RegCopyClassName(hwndList, (LPSTR)szClassName))
  928. wParam = IDCANCEL;
  929. // fall through ...
  930. case IDCANCEL:
  931. OurEndDialog(hDlg, wParam);
  932. break;
  933. }
  934. break;
  935. }
  936. return FALSE;
  937. }
  938. BOOL vbCancelOK=FALSE;
  939. /* Waiting for object dialog */
  940. BOOL FAR PASCAL fnObjWait(HWND hDlg, unsigned msg, WORD wParam, LONG lParam)
  941. {
  942. static LPOLEOBJECT lpObject;
  943. static LPOBJINFO lpOInfo;
  944. static BOOL bCanCancel;
  945. extern HWND hwndWait;
  946. extern int vfDeactByOtherApp;
  947. extern int flashID;
  948. switch (msg) {
  949. case WM_INITDIALOG:
  950. {
  951. /**
  952. NOTE: the key idea in setting these options is that the cancel
  953. button must cancel what the user thinks is the current operation.
  954. vbCancelOK == TRUE,
  955. cancel button may be enabled, depending on other flags
  956. vbCancelOK is set in WMsgLoop.
  957. lpOInfo->fCancelAsync == TRUE,
  958. Cancel is enabled if vbCancelOK
  959. Cancel button cancels dialog without regard to pending async.
  960. Pending async is killed quietly in CallBack if possible.
  961. Generally use if the pending async is not part of the operation
  962. being cancelled, and:
  963. 1) You're about to make a very important call which justifies
  964. silently killing any pending operation.
  965. Note: this one is weird if you're trying to release or delete, because
  966. the pending async could itself be a release or delete.
  967. lpOInfo->fCompleteAsync == TRUE,
  968. Cancel is enabled only if pending async can be cancelled.
  969. Cancel button cancels pending async.
  970. Generally use if the pending async *is* part of the operation
  971. being cancelled, and:
  972. 1) You're in a sequence of async calls and cancelling
  973. would require cancelling the previous async in the
  974. sequence, or
  975. 2) You have just made an async call which you want to make
  976. synchronous but don't mind if the user cancels it.
  977. lpOInfo->fCanKillAsync == TRUE,
  978. Use with lpOInfo->fCompleteAsync.
  979. Indicates that we already know that the async can be cancelled,
  980. so Cancel button can be enabled immediately.
  981. **/
  982. hwndWait = hDlg;
  983. lpObject = (LPOLEOBJECT)lParam;
  984. Assert (lpObject != NULL);
  985. lpOInfo = GetObjInfo(lpObject);
  986. Assert(lpOInfo != NULL);
  987. bCanCancel=FALSE;
  988. if (vbCancelOK && (!lpOInfo->fCompleteAsync || lpOInfo->fCanKillAsync))
  989. SendMessage(hDlg,WM_UKANKANCEL,0,0L);
  990. if (lpOInfo->fCancelAsync)
  991. /* we'll cancel async in CallBack if get a QUERY_RETRY */
  992. lpOInfo->fKillMe = TRUE;
  993. SetTimer(hDlg, 1234, 250, (FARPROC)NULL);
  994. return TRUE;
  995. }
  996. break;
  997. case WM_ACTIVATE:
  998. if (wParam)
  999. vhWndMsgBoxParent = hDlg;
  1000. break;
  1001. case WM_RUTHRUYET:
  1002. case WM_TIMER:
  1003. /* this is a lot easier than making this modeless */
  1004. /* we gotta check this because if server dies we don't get
  1005. an OLE_RELEASE (the 'normal way this dialog is knocked off),
  1006. rather OleQueryReleaseStatus will return OLE_OK */
  1007. if (OleQueryReleaseStatus(lpObject) != OLE_BUSY)
  1008. PostMessage(hDlg,WM_DIESCUMSUCKINGPIG,0,0L);
  1009. break;
  1010. case WM_UKANKANCEL:
  1011. /* we got a QUERY_RETRY or are initing */
  1012. if (!bCanCancel && vbCancelOK)
  1013. {
  1014. char szMsg[20];
  1015. LoadString(hINSTANCE, IDSTRCancel, szMsg, sizeof(szMsg));
  1016. SetDlgItemText(hDlg,IDOK,szMsg);
  1017. bCanCancel=TRUE;
  1018. }
  1019. break;
  1020. case WM_DIESCUMSUCKINGPIG:
  1021. hwndWait = NULL;
  1022. KillTimer(hDlg, 1234);
  1023. /* clear flags */
  1024. if (CheckPointer(lpOInfo,1))
  1025. {
  1026. lpOInfo->fCompleteAsync =
  1027. lpOInfo->fCancelAsync =
  1028. lpOInfo->fCanKillAsync = FALSE;
  1029. }
  1030. /* wParam is TRUE if error */
  1031. OurEndDialog(hDlg,wParam);
  1032. break;
  1033. case WM_COMMAND:
  1034. switch (wParam) {
  1035. case IDOK:
  1036. if (bCanCancel) // pressed cancel button
  1037. {
  1038. if (lpOInfo->fCompleteAsync)
  1039. lpOInfo->fKillMe = TRUE; // cancel async asynchronously
  1040. else if (lpOInfo->fCancelAsync)
  1041. lpOInfo->fKillMe = FALSE; // had a chance to kill, user doesn't care anymore
  1042. PostMessage(hDlg,WM_DIESCUMSUCKINGPIG,1,0L);
  1043. }
  1044. else
  1045. {
  1046. /* retry */
  1047. if (OleQueryReleaseStatus(lpObject) != OLE_BUSY)
  1048. PostMessage(hDlg,WM_DIESCUMSUCKINGPIG,0,0L);
  1049. }
  1050. break;
  1051. case IDD_SWITCH:
  1052. /* bring up task list */
  1053. DefWindowProc(hDlg,WM_SYSCOMMAND,SC_TASKLIST,0L);
  1054. break;
  1055. }
  1056. break;
  1057. default:
  1058. break;
  1059. }
  1060. return FALSE;
  1061. }
  1062. /****************************************************************/
  1063. /*********************** VARIOUS OLE FUNCTIONS ******************/
  1064. /****************************************************************/
  1065. void fnObjInsertNew(void)
  1066. {
  1067. OBJPICINFO picInfo;
  1068. typeCP cpNext=selCur.cpFirst;
  1069. if (!FWriteOk( fwcInsert ))
  1070. return;
  1071. /* this'll set global szClassName */
  1072. if (OurDialogBox(hINSTANCE, "DTCREATE" ,hMAINWINDOW, lpfnInsertNew) == IDCANCEL)
  1073. return;
  1074. StartLongOp();
  1075. ObjCachePara( docCur, cpNext);
  1076. if (!ObjCreateObjectInDoc(docCur, cpNext))
  1077. {
  1078. ClearInsertLine();
  1079. fnClearEdit(OBJ_INSERTING);
  1080. NoUndo();
  1081. }
  1082. EndLongOp(vhcIBeam);
  1083. }
  1084. BOOL ObjCreateObjectInDoc(int doc,typeCP cpParaStart)
  1085. /* assumes szClassName is set to server class */
  1086. /* called only for InsertObject */
  1087. /* return whether error */
  1088. {
  1089. szOBJNAME szObjName;
  1090. LPOBJINFO lpObjInfo=NULL;
  1091. if ((lpObjInfo = ObjGetObjInfo(szObjName)) == NULL)
  1092. goto err;
  1093. if (ObjError(OleCreate(PROTOCOL, (LPOLECLIENT)lpObjInfo,
  1094. (LPSTR)szClassName,
  1095. lhClientDoc, szObjName, &(lpObjInfo->lpobject), olerender_draw, 0)))
  1096. {
  1097. /* will free memory later */
  1098. lpObjInfo->lpobject = NULL;
  1099. goto err;
  1100. }
  1101. /* normally set in ObjAllocObjInfo, but for unfinished objects we need it now! */
  1102. lpObjInfo->cpWhere = cpParaStart;
  1103. lpObjInfo->objectType = NONE;
  1104. //lpObjInfo->aName = AddAtom(szClassName);
  1105. if (ObjInitServerInfo(lpObjInfo))
  1106. goto err;
  1107. return FALSE;
  1108. err:
  1109. if (lpObjInfo)
  1110. ObjDeleteObject(lpObjInfo,TRUE);
  1111. Error(IDPMTFailedToCreateObject);
  1112. return TRUE;
  1113. }
  1114. #define DRAG_EMBED 0 /* nothing */
  1115. #define DRAG_LINK 6 /* Ctrl + Shift + Drag */
  1116. #define DRAG_MULTIPLE 4 /* Shift + Drag */
  1117. void ObjGetDrop(HANDLE hDrop, BOOL bOpenFile)
  1118. {
  1119. int nNumFiles,count;
  1120. char szFileName[cchMaxFile];
  1121. extern struct CHP vchpSel;
  1122. struct CHP chpT;
  1123. BYTE bKeyState = 0;
  1124. typeCP cpFirst=selCur.cpFirst, dcp = 0;
  1125. int cchAddedEol=0;
  1126. typeCP cpNext=selCur.cpFirst,cpPrev=selCur.cpFirst,cpSel;
  1127. OBJPICINFO picInfo;
  1128. BOOL bError=FALSE;
  1129. static char szPackage[] = "Package";
  1130. MSG msg;
  1131. if (!FWriteOk( fwcInsert ))
  1132. return;
  1133. /* get number of files dropped */
  1134. nNumFiles = DragQueryFile(hDrop,0xFFFF,NULL,0);
  1135. /* See what the user wants us to do */
  1136. PeekMessage(&msg, (HWND)NULL, NULL, NULL, PM_NOREMOVE);
  1137. bKeyState = ((((GetKeyState(VK_SHIFT) < 0) << 2)
  1138. | ((GetKeyState(VK_CONTROL) < 0) << 1)));
  1139. if ((nNumFiles == 0) ||
  1140. ((bKeyState != DRAG_EMBED) && (bKeyState != DRAG_LINK) && (bKeyState != DRAG_MULTIPLE)) ||
  1141. (bOpenFile && (bKeyState != DRAG_EMBED) && (bKeyState != DRAG_MULTIPLE)))
  1142. {
  1143. DragFinish(hDrop);
  1144. return;
  1145. }
  1146. if (bOpenFile)
  1147. {
  1148. DragQueryFile(hDrop,0,szFileName,sizeof(szFileName));
  1149. fnOpenFile((LPSTR)szFileName);
  1150. DragFinish(hDrop);
  1151. return;
  1152. }
  1153. ClearInsertLine();
  1154. if (fnClearEdit(OBJ_INSERTING))
  1155. return;
  1156. StartLongOp();
  1157. chpT = vchpSel;
  1158. (**hpdocdod)[docCur].fFormatted = fTrue;
  1159. if (cpFirst > cp0)
  1160. {
  1161. ObjCachePara(docCur, cpFirst - 1);
  1162. if (vcpLimParaCache != cpFirst)
  1163. {
  1164. cchAddedEol = ccpEol;
  1165. InsertEolPap(docCur, selCur.cpFirst, &vpapAbs);
  1166. cpNext += (typeCP)ccpEol;
  1167. }
  1168. }
  1169. ObjCachePara( docCur, cpNext );
  1170. /* create object for each file dropped */
  1171. for (count=0; count < nNumFiles; ++count)
  1172. {
  1173. szOBJNAME szObjName;
  1174. typeCP cpTmp;
  1175. /* get the filename */
  1176. DragQueryFile(hDrop,count,szFileName,sizeof(szFileName));
  1177. if (ObjAllocObjInfo(&picInfo,cpNext,EMBEDDED,TRUE,szObjName))
  1178. {
  1179. bError=TRUE;
  1180. goto end;
  1181. }
  1182. if ((bKeyState == DRAG_LINK))
  1183. {
  1184. if (ObjError(OleCreateLinkFromFile(PROTOCOL, (LPOLECLIENT)lpOBJ_QUERY_INFO(&picInfo),
  1185. szPackage,
  1186. szFileName, NULL,
  1187. lhClientDoc, szObjName,
  1188. &lpOBJ_QUERY_OBJECT(&picInfo), olerender_draw, 0)))
  1189. {
  1190. bError=TRUE;
  1191. lpOBJ_QUERY_OBJECT(&picInfo) = NULL;
  1192. goto end;
  1193. }
  1194. }
  1195. else // if ((bKeyState == DRAG_EMBED))
  1196. {
  1197. if (ObjError(OleCreateFromFile(PROTOCOL, (LPOLECLIENT)lpOBJ_QUERY_INFO(&picInfo),
  1198. szPackage,
  1199. szFileName,
  1200. lhClientDoc, szObjName,
  1201. &lpOBJ_QUERY_OBJECT(&picInfo), olerender_draw, 0)))
  1202. {
  1203. bError=TRUE;
  1204. lpOBJ_QUERY_OBJECT(&picInfo) = NULL;
  1205. goto end;
  1206. }
  1207. }
  1208. if (ObjInitServerInfo(lpOBJ_QUERY_INFO(&picInfo)))
  1209. {
  1210. bError=TRUE;
  1211. goto end;
  1212. }
  1213. if (!FComputePictSize(&picInfo, &(picInfo.dxaSize),
  1214. &(picInfo.dyaSize)))
  1215. {
  1216. bError=TRUE;
  1217. goto end;
  1218. }
  1219. ObjCachePara(docCur,cpNext);
  1220. if ((cpTmp = ObjSaveObjectToDoc(&picInfo,docCur,cpNext)) == cp0)
  1221. {
  1222. bError=TRUE;
  1223. goto end;
  1224. }
  1225. cpNext = cpTmp;
  1226. }
  1227. end:
  1228. dcp = cpNext-cpFirst;
  1229. if (dcp)
  1230. {
  1231. cpSel=CpFirstSty(cpFirst + dcp, styChar );
  1232. SetUndo( uacInsert, docCur, cpFirst, dcp, docNil, cpNil, cp0, 0 );
  1233. SetUndoMenuStr(IDSTRUndoEdit);
  1234. if (vuab.uac == uacReplNS)
  1235. /* Special UNDO code for picture paste */
  1236. vuab.uac = uacReplPic;
  1237. Select(cpSel, cpSel);
  1238. vchpSel = chpT; /* Preserve insert point props across this operation */
  1239. if (wwdCurrentDoc.fEditHeader || wwdCurrentDoc.fEditFooter)
  1240. { /* If running head/foot, remove chSects & set para props */
  1241. MakeRunningCps( docCur, cpFirst, dcp );
  1242. }
  1243. if (ferror)
  1244. NoUndo();
  1245. }
  1246. if (bError)
  1247. {
  1248. Error(IDPMTFailedToCreateObject);
  1249. ObjDeleteObject(lpOBJ_QUERY_INFO(&picInfo),TRUE);
  1250. }
  1251. EndLongOp(vhcIBeam);
  1252. DragFinish(hDrop);
  1253. }
  1254. int vcVerbs;
  1255. void fnObjDoVerbs(WORD wVerb)
  1256. {
  1257. NoUndo();
  1258. if ((wVerb == imiVerb) // more than one object selected
  1259. || (vcVerbs == 1)) // one verb
  1260. OBJ_PLAYEDIT = OLEVERB_PRIMARY;
  1261. else
  1262. OBJ_PLAYEDIT = (int)(wVerb - imiVerb - 1);
  1263. ObjEnumInRange(docCur,selCur.cpFirst,selCur.cpLim,ObjPlayObjectInDoc);
  1264. OBJ_PLAYEDIT = OLEVERB_PRIMARY;
  1265. }
  1266. void fnObjProperties(void)
  1267. {
  1268. int nRetval;
  1269. if (nRetval != -1)
  1270. OurDialogBox(hINSTANCE, "DTPROP", hMAINWINDOW, lpfnLinkProps);
  1271. }
  1272. BOOL fnObjUpdate(LPOBJINFO lpObjInfo)
  1273. {
  1274. BOOL bRetval;
  1275. #ifdef DEBUG
  1276. OutputDebugString( (LPSTR) "Updating object\n\r");
  1277. #endif
  1278. if (ObjWaitForObject(lpObjInfo,TRUE))
  1279. return TRUE;
  1280. StartLongOp();
  1281. if ((bRetval = ObjError(OleUpdate(lpObjInfo->lpobject))))
  1282. Error(IDPMTFailedToUpdate);
  1283. EndLongOp(vhcArrow);
  1284. return bRetval;
  1285. }
  1286. BOOL ObjDeleteObject(LPOBJINFO lpObjInfo, BOOL bDelete)
  1287. /** Delete object as well as objinfo. Note this must be synchronous.
  1288. Return whether an error.
  1289. **/
  1290. {
  1291. LPOLEOBJECT lpObject;
  1292. Assert(lpObjInfo != NULL);
  1293. if (!CheckPointer((LPSTR)lpObjInfo,1))
  1294. return FALSE; // already deleted
  1295. lpObject = lpObjInfo->lpobject;
  1296. if (lpObject == NULL)
  1297. {
  1298. ObjDeleteObjInfo(lpObjInfo);
  1299. return FALSE;
  1300. }
  1301. /* make sure not already deleted */
  1302. if (!ObjIsValid(lpObject))
  1303. {
  1304. ObjDeleteObjInfo(lpObjInfo);
  1305. return FALSE;
  1306. }
  1307. /** asynchronous deletion **/
  1308. if (OleQueryReleaseStatus(lpObject) != OLE_BUSY)
  1309. {
  1310. OLESTATUS olestat;
  1311. if (bDelete)
  1312. olestat = OleDelete(lpObject);
  1313. else
  1314. olestat = OleRelease(lpObject);
  1315. switch (olestat)
  1316. {
  1317. case OLE_OK:
  1318. ObjDeleteObjInfo(lpObjInfo);
  1319. break;
  1320. case OLE_WAIT_FOR_RELEASE:
  1321. lpObjInfo->fFreeMe = TRUE;
  1322. break;
  1323. }
  1324. }
  1325. else if (bDelete)
  1326. lpObjInfo->fDeleteMe = TRUE; // delete on OLE_RELEASE
  1327. else
  1328. lpObjInfo->fReleaseMe = TRUE; // release on OLE_RELEASE
  1329. return FALSE;
  1330. }
  1331. #include <print.h>
  1332. HANDLE hStdTargetDevice=NULL;
  1333. void ObjSetTargetDevice(BOOL bSetObjects)
  1334. {
  1335. extern PRINTDLG PD; /* Common print dlg structure, initialized in the init code */
  1336. extern CHAR (**hszPrinter)[];
  1337. extern CHAR (**hszPrDriver)[];
  1338. extern CHAR (**hszPrPort)[];
  1339. LPSTDTARGETDEVICE lpStdTargetDevice;
  1340. WORD nCount;
  1341. DEVMODE FAR *lpDevmodeData;
  1342. char FAR *lpData;
  1343. LPOLEOBJECT lpObject;
  1344. STDTARGETDEVICE stdT;
  1345. if (!PD.hDevMode)
  1346. /* then get for default printer */
  1347. {
  1348. if (hszPrinter == NULL || hszPrDriver == NULL || hszPrPort == NULL)
  1349. return;
  1350. if (**hszPrinter == '\0' || **hszPrDriver == '\0' || **hszPrPort == '\0')
  1351. return;
  1352. if (fnPrGetDevmode())
  1353. return;
  1354. }
  1355. lpDevmodeData = MAKELP(PD.hDevMode,0);
  1356. /* get the offsets */
  1357. stdT.deviceNameOffset = 0;
  1358. nCount = CchSz(*hszPrinter);
  1359. stdT.driverNameOffset = nCount;
  1360. nCount += CchSz(*hszPrDriver);
  1361. stdT.portNameOffset = nCount;
  1362. nCount += CchSz(*hszPrPort);
  1363. stdT.extDevmodeOffset = nCount;
  1364. nCount += (stdT.extDevmodeSize = lpDevmodeData->dmSize);
  1365. stdT.environmentOffset = nCount;
  1366. nCount += (stdT.environmentSize = lpDevmodeData->dmSize);
  1367. /* alloc the buffer */
  1368. if (hStdTargetDevice == NULL)
  1369. {
  1370. if ((hStdTargetDevice = GlobalAlloc(GMEM_MOVEABLE|GMEM_ZEROINIT,nCount+sizeof(STDTARGETDEVICE))) == NULL)
  1371. return;
  1372. }
  1373. else
  1374. {
  1375. if ((hStdTargetDevice =
  1376. GlobalReAlloc(hStdTargetDevice,
  1377. nCount+sizeof(STDTARGETDEVICE),GMEM_MOVEABLE|GMEM_ZEROINIT)) == NULL)
  1378. {
  1379. return;
  1380. }
  1381. }
  1382. lpStdTargetDevice = (LPSTDTARGETDEVICE)GlobalLock(hStdTargetDevice);
  1383. GlobalUnlock(hStdTargetDevice);
  1384. /* copy stdT into lpStdTargetDevice */
  1385. bltbx((LPSTR)&stdT, lpStdTargetDevice, sizeof(STDTARGETDEVICE));
  1386. /* get temporary pointer to the end of StdTargetDevice (the data buffer) */
  1387. lpData = ((LPSTR)lpStdTargetDevice) + sizeof(STDTARGETDEVICE);
  1388. /* now fill the buffer */
  1389. nCount = lpStdTargetDevice->driverNameOffset;
  1390. bltbx((LPSTR)*hszPrinter, lpData, nCount);
  1391. lpData += nCount;
  1392. nCount = lpStdTargetDevice->portNameOffset -
  1393. lpStdTargetDevice->driverNameOffset;
  1394. bltbx((LPSTR)*hszPrDriver, lpData, nCount);
  1395. lpData += nCount;
  1396. nCount = lpStdTargetDevice->extDevmodeOffset -
  1397. lpStdTargetDevice->portNameOffset;
  1398. bltbx((LPSTR)*hszPrPort, lpData, nCount);
  1399. lpData += nCount;
  1400. nCount = lpStdTargetDevice->extDevmodeSize;
  1401. bltbx(lpDevmodeData, (LPSTR)lpData, nCount);
  1402. lpData += nCount;
  1403. /* environment info is the same as the devmode info */
  1404. bltbx(lpDevmodeData, (LPSTR)lpData, nCount);
  1405. /* now set all the objects to this printer */
  1406. if (bSetObjects)
  1407. {
  1408. lpObject=NULL;
  1409. do
  1410. {
  1411. OleEnumObjects(lhClientDoc,&lpObject);
  1412. if (lpObject)
  1413. {
  1414. #ifdef DEBUG
  1415. OutputDebugString("Setting Target Device\n\r");
  1416. #endif
  1417. OleSetTargetDevice(lpObject,hStdTargetDevice);
  1418. }
  1419. }
  1420. while (lpObject);
  1421. }
  1422. }
  1423. BOOL ObjSetTargetDeviceForObject(LPOBJINFO lpObjInfo)
  1424. /* return whether error */
  1425. /* we assume object ain't busy!! */
  1426. {
  1427. extern CHAR (**hszPrinter)[];
  1428. extern CHAR (**hszPrDriver)[];
  1429. extern CHAR (**hszPrPort)[];
  1430. if (lpObjInfo == NULL)
  1431. {
  1432. Assert(0);
  1433. return TRUE;
  1434. }
  1435. if (lpObjInfo->lpobject == NULL)
  1436. {
  1437. Assert(0);
  1438. return TRUE;
  1439. }
  1440. if (lpObjInfo->objectType == STATIC)
  1441. return FALSE;
  1442. if (hszPrinter == NULL || hszPrDriver == NULL || hszPrPort == NULL)
  1443. return FALSE;
  1444. if (**hszPrinter == '\0' || **hszPrDriver == '\0' || **hszPrPort == '\0')
  1445. return FALSE;
  1446. if (PD.hDevMode == NULL)
  1447. ObjSetTargetDevice(FALSE);
  1448. if (PD.hDevMode == NULL)
  1449. {
  1450. return FALSE; // punt, couldn't get extdevmode structure.
  1451. // device doesn't support it
  1452. }
  1453. #ifdef DEBUG
  1454. OutputDebugString("Setting Target Device\n\r");
  1455. #endif
  1456. return (ObjError(OleSetTargetDevice(lpObjInfo->lpobject,hStdTargetDevice)));
  1457. }
  1458. #if 0
  1459. BOOL ObjContainsUnfinished(int doc, typeCP cpFirst, typeCP cpLim)
  1460. {
  1461. OBJPICINFO picInfo;
  1462. typeCP cpPicInfo;
  1463. BOOL bRetval=FALSE;
  1464. StartLongOp();
  1465. for (cpPicInfo = cpNil;
  1466. ObjPicEnumInRange(&picInfo,doc,cpFirst,cpLim,&cpPicInfo);
  1467. )
  1468. {
  1469. if (lpOBJ_QUERY_INFO(&picInfo) == NULL)
  1470. continue;
  1471. if (otOBJ_QUERY_TYPE(&picInfo) == NONE)
  1472. {
  1473. bRetval = TRUE;
  1474. break;
  1475. }
  1476. }
  1477. EndLongOp(vhcArrow);
  1478. return bRetval;
  1479. }
  1480. #endif
  1481. BOOL ObjContainsOpenEmb(int doc, typeCP cpFirst, typeCP cpLim, BOOL bLookForUnfinished)
  1482. {
  1483. OBJPICINFO picInfo;
  1484. typeCP cpPicInfo;
  1485. BOOL bRetval=FALSE;
  1486. LPLPOBJINFO lplpObjTmp;
  1487. StartLongOp();
  1488. for (cpPicInfo = cpNil;
  1489. ObjPicEnumInRange(&picInfo,doc,cpFirst,cpLim,&cpPicInfo);
  1490. )
  1491. {
  1492. if (lpOBJ_QUERY_INFO(&picInfo) == NULL)
  1493. continue;
  1494. if (lpOBJ_QUERY_OBJECT(&picInfo) == NULL)
  1495. continue;
  1496. #if 0 // see new check below (NONEs are no longer saved to doc)
  1497. if (otOBJ_QUERY_TYPE(&picInfo) == NONE)
  1498. {
  1499. bRetval = TRUE;
  1500. break;
  1501. }
  1502. #endif
  1503. if ((otOBJ_QUERY_TYPE(&picInfo) == EMBEDDED) &&
  1504. OleQueryOpen(lpOBJ_QUERY_OBJECT(&picInfo)) == OLE_OK)
  1505. {
  1506. bRetval = TRUE;
  1507. break;
  1508. }
  1509. }
  1510. if (bLookForUnfinished)
  1511. for (lplpObjTmp = NULL; lplpObjTmp = EnumObjInfos(lplpObjTmp) ;)
  1512. {
  1513. if (((*lplpObjTmp)->objectType == NONE) &&
  1514. ((*lplpObjTmp)->cpWhere >= cpFirst) &&
  1515. ((*lplpObjTmp)->cpWhere <= cpLim))
  1516. {
  1517. bRetval = TRUE;
  1518. break;
  1519. }
  1520. }
  1521. EndLongOp(vhcArrow);
  1522. return bRetval;
  1523. }
  1524. BOOL ObjDeletionOK(int nMode)
  1525. /**
  1526. Return whether OK to delete objects in current selection.
  1527. We don't worry about unfinished objects because they are just floating around in space
  1528. (ie, no picinfo has been yet saved to the doc),
  1529. and we don't allow the user to delete them until they are finished or the
  1530. document is abandonded.
  1531. **/
  1532. {
  1533. if (ObjContainsOpenEmb(docCur, selCur.cpFirst, selCur.cpLim,FALSE))
  1534. {
  1535. switch (nMode)
  1536. {
  1537. case OBJ_INSERTING:
  1538. Error(IDPMTInsertOpenEmb);
  1539. return FALSE;
  1540. break;
  1541. case OBJ_CUTTING:
  1542. case OBJ_DELETING:
  1543. {
  1544. char szMsg[cchMaxSz];
  1545. LoadString(hINSTANCE,
  1546. nMode == OBJ_DELETING ? IDPMTDeleteOpenEmb : IDPMTCutOpenEmb,
  1547. szMsg, sizeof(szMsg));
  1548. if (MessageBox(hPARENTWINDOW, (LPSTR)szMsg, (LPSTR)szAppName, MB_OKCANCEL) == IDCANCEL)
  1549. return FALSE;
  1550. if (ObjEnumInRange(docCur,selCur.cpFirst,selCur.cpLim,ObjCloseObjectInDoc) < 0)
  1551. return FALSE;
  1552. /* handle any unfinished objects in selection region */
  1553. ObjAdjustCpsForDeletion(docCur);
  1554. return TRUE;
  1555. }
  1556. break;
  1557. }
  1558. }
  1559. else
  1560. {
  1561. /* handle any unfinished objects in selection region */
  1562. ObjAdjustCpsForDeletion(docCur);
  1563. return TRUE;
  1564. }
  1565. }
  1566. void ObjAdjustCps(int doc,typeCP cpLim, typeCP dcpAdj)
  1567. /* for every picinfo after cpLim, adjust the cp value in its objinfo */
  1568. {
  1569. LPLPOBJINFO lplpObjTmp;
  1570. typeCP cpMac = CpMacText(doc);
  1571. if (dcpAdj == cp0)
  1572. return;
  1573. if (doc != docCur)
  1574. return;
  1575. for (lplpObjTmp = NULL; lplpObjTmp = EnumObjInfos(lplpObjTmp) ;)
  1576. {
  1577. if (((*lplpObjTmp)->objectType == NONE) &&
  1578. ((*lplpObjTmp)->cpWhere >= cpLim))
  1579. {
  1580. typeCP cpNew = (*lplpObjTmp)->cpWhere + dcpAdj;
  1581. if (cpNew > cpMac)
  1582. cpNew = cpMac;
  1583. else if (cpNew < cp0)
  1584. cpNew = cp0;
  1585. (*lplpObjTmp)->cpWhere = cpNew;
  1586. }
  1587. }
  1588. }
  1589. void ObjAdjustCpsForDeletion(int doc)
  1590. /* for every picinfo in selCur, set cpWhere to selCur.cpFirst (presumably
  1591. selCur is about to be deleted) */
  1592. {
  1593. LPLPOBJINFO lplpObjTmp;
  1594. if (selCur.cpFirst == selCur.cpLim)
  1595. return;
  1596. if (doc != docCur)
  1597. return;
  1598. for (lplpObjTmp = NULL; lplpObjTmp = EnumObjInfos(lplpObjTmp) ;)
  1599. {
  1600. if (((*lplpObjTmp)->objectType == NONE) &&
  1601. ((*lplpObjTmp)->cpWhere >= selCur.cpFirst) &&
  1602. ((*lplpObjTmp)->cpWhere <= selCur.cpLim))
  1603. (*lplpObjTmp)->cpWhere = selCur.cpFirst;
  1604. }
  1605. }
  1606. #include <stdlib.h>
  1607. BOOL GimmeNewPicinfo(OBJPICINFO *pPicInfo, LPOBJINFO lpObjInfo)
  1608. /* assume lpObjInfo already is filled out */
  1609. /* return whether error */
  1610. {
  1611. szOBJNAME szObjName;
  1612. char *pdumb;
  1613. if (lpObjInfo == NULL)
  1614. return TRUE;
  1615. bltbc( pPicInfo, 0, cchPICINFOX );
  1616. /* objinfo */
  1617. lpOBJ_QUERY_INFO(pPicInfo) = lpObjInfo;
  1618. /* so Save'll save */
  1619. fOBJ_QUERY_DIRTY_OBJECT(pPicInfo) = TRUE;
  1620. /* only save picinfo until File.Save */
  1621. bOBJ_QUERY_DONT_SAVE_DATA(pPicInfo) = TRUE;
  1622. ObjUpdateFromObjInfo(pPicInfo);
  1623. /* data size */
  1624. dwOBJ_QUERY_DATA_SIZE(pPicInfo) = 0xFFFFFFFF; // to indicate brand new object
  1625. pPicInfo->mx = mxMultByOne;
  1626. pPicInfo->my = myMultByOne;
  1627. pPicInfo->cbHeader = cchPICINFOX;
  1628. pPicInfo->dxaOffset = 0;
  1629. pPicInfo->mm = MM_OLE;
  1630. pPicInfo->dxaSize = nOBJ_BLANKOBJECT_X;
  1631. pPicInfo->dyaSize = nOBJ_BLANKOBJECT_Y;
  1632. return FALSE;
  1633. }
  1634. BOOL ObjInitServerInfo(LPOBJINFO lpObjInfo)
  1635. /* this is called right after creating an object */
  1636. /* return whether error */
  1637. {
  1638. lpObjInfo->fCompleteAsync = TRUE; // kill prev async (OleCreate...)
  1639. if (ObjWaitForObject(lpObjInfo,TRUE))
  1640. return TRUE;
  1641. /* make sure Create succeeded */
  1642. if (lpObjInfo->fDeleteMe)
  1643. /* this is how we know it failed asynchronously */
  1644. return TRUE;
  1645. if ((lpObjInfo->objectType == EMBEDDED) ||
  1646. (lpObjInfo->objectType == NONE))
  1647. {
  1648. if (ObjSetHostName(lpObjInfo,docCur))
  1649. return TRUE;
  1650. lpObjInfo->fCompleteAsync = TRUE; // kill SetHostName if Cancel
  1651. if (ObjWaitForObject(lpObjInfo,TRUE))
  1652. return TRUE;
  1653. }
  1654. if (ObjSetTargetDeviceForObject(lpObjInfo))
  1655. return TRUE;
  1656. if (lpObjInfo->aName == NULL)
  1657. if (lpObjInfo->objectType == LINK)
  1658. {
  1659. lpObjInfo->fCompleteAsync = TRUE; // kill SetTarget if Cancel
  1660. if (ObjWaitForObject(lpObjInfo,TRUE))
  1661. return TRUE;
  1662. if ((lpObjInfo->aName = MakeLinkAtom(lpObjInfo)) == NULL)
  1663. return TRUE;
  1664. }
  1665. /* note: Caller needs to handle getting the size of object. */
  1666. return FALSE;
  1667. }
  1668.