oledlgs1.cpp 38 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471
  1. // This is a part of the Microsoft Foundation Classes C++ library.
  2. // Copyright (C) 1992-1998 Microsoft Corporation
  3. // All rights reserved.
  4. //
  5. // This source code is only intended as a supplement to the
  6. // Microsoft Foundation Classes Reference and related
  7. // electronic documentation provided with the library.
  8. // See these sources for detailed information regarding the
  9. // Microsoft Foundation Classes product.
  10. #include "stdafx.h"
  11. #ifdef AFX_OLE2_SEG
  12. #pragma code_seg(AFX_OLE2_SEG)
  13. #endif
  14. #ifdef _DEBUG
  15. #undef THIS_FILE
  16. static char THIS_FILE[] = __FILE__;
  17. #endif
  18. #define new DEBUG_NEW
  19. UINT CALLBACK
  20. AfxOleHookProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
  21. ////////////////////////////////////////////////////////////////////////////
  22. // implementation helpers
  23. BOOL AFXAPI _AfxOlePropertiesEnabled()
  24. {
  25. // edit properties is enabled if there is a handler
  26. // for ID_OLE_EDIT_PROPERTIES
  27. AFX_CMDHANDLERINFO info;
  28. // check main window first
  29. CWnd* pWnd = AfxGetMainWnd();
  30. if (pWnd != NULL && pWnd->OnCmdMsg(ID_OLE_EDIT_PROPERTIES, CN_COMMAND, NULL, &info))
  31. return TRUE;
  32. // check app last
  33. return AfxGetApp()->OnCmdMsg(ID_OLE_EDIT_PROPERTIES, CN_COMMAND, NULL, &info);
  34. }
  35. SCODE _AfxParseDisplayName(LPMONIKER lpmk, LPBC lpbc, LPTSTR lpszRemainder,
  36. ULONG* cchEaten, LPMONIKER* plpmkOut)
  37. {
  38. USES_CONVERSION;
  39. ASSERT(lpmk != NULL);
  40. ASSERT(AfxIsValidString(lpszRemainder));
  41. ASSERT(cchEaten != NULL);
  42. ASSERT(plpmkOut != NULL);
  43. SCODE sc;
  44. if (lpbc != NULL)
  45. {
  46. // ask moniker to parse the display name itself
  47. sc = lpmk->ParseDisplayName(lpbc, NULL, T2OLE(lpszRemainder), cchEaten,
  48. plpmkOut);
  49. }
  50. else
  51. {
  52. // skip leading delimiters
  53. int cEaten = 0;
  54. LPTSTR lpszSrc = lpszRemainder;
  55. while (*lpszSrc != '\0' && (*lpszSrc == '\\' || *lpszSrc == '/' ||
  56. *lpszSrc == ':' || *lpszSrc == '!' || *lpszSrc == '['))
  57. {
  58. if (_istlead(*lpszSrc))
  59. ++lpszSrc, ++cEaten;
  60. ++lpszSrc;
  61. ++cEaten;
  62. }
  63. // parse next token in lpszRemainder
  64. TCHAR szItemName[_MAX_PATH];
  65. LPTSTR lpszDest = szItemName;
  66. while (*lpszSrc != '\0' && *lpszSrc != '\\' && *lpszSrc != '/' &&
  67. *lpszSrc != ':' && *lpszSrc != '!' && *lpszSrc != '[' &&
  68. cEaten < _MAX_PATH-1)
  69. {
  70. if (_istlead(*lpszSrc))
  71. *lpszDest++ = *lpszSrc++, ++cEaten;
  72. *lpszDest++ = *lpszSrc++;
  73. ++cEaten;
  74. }
  75. *cchEaten = cEaten;
  76. sc = CreateItemMoniker(OLESTDDELIMOLE, T2COLE(szItemName), plpmkOut);
  77. }
  78. return sc;
  79. }
  80. ////////////////////////////////////////////////////////////////////////////
  81. // COleUILinkInfo
  82. COleUILinkInfo::COleUILinkInfo(COleDocument* pDocument)
  83. {
  84. ASSERT(pDocument == NULL ||
  85. pDocument->IsKindOf(RUNTIME_CLASS(COleDocument)));
  86. m_pDocument = pDocument;
  87. m_pSelectedItem = NULL;
  88. m_pos = NULL;
  89. m_bUpdateLinks = FALSE;
  90. m_bUpdateEmbeddings = FALSE;
  91. }
  92. STDMETHODIMP_(ULONG) COleUILinkInfo::AddRef()
  93. {
  94. return 0;
  95. }
  96. STDMETHODIMP_(ULONG) COleUILinkInfo::Release()
  97. {
  98. return 0;
  99. }
  100. STDMETHODIMP COleUILinkInfo::QueryInterface(
  101. REFIID, LPVOID*)
  102. {
  103. return E_NOTIMPL;
  104. }
  105. STDMETHODIMP_(DWORD) COleUILinkInfo::GetNextLink(
  106. DWORD dwLink)
  107. {
  108. ASSERT(m_pDocument != NULL);
  109. if (dwLink == 0)
  110. {
  111. // start enumerating from the beginning
  112. m_pos = m_pDocument->GetStartPosition();
  113. }
  114. COleClientItem* pItem;
  115. while ((pItem = m_pDocument->GetNextClientItem(m_pos)) != NULL)
  116. {
  117. // check for links
  118. OLE_OBJTYPE objType = pItem->GetType();
  119. if (m_bUpdateLinks && objType == OT_LINK)
  120. {
  121. // link found -- return it
  122. return (DWORD)(void*)pItem;
  123. }
  124. // check for embeddings
  125. if (m_bUpdateEmbeddings && objType == OT_EMBEDDED)
  126. {
  127. // embedding w/mismatched target device
  128. return (DWORD)(void*)pItem;
  129. }
  130. }
  131. return 0; // link not found
  132. }
  133. STDMETHODIMP COleUILinkInfo::SetLinkUpdateOptions(
  134. DWORD dwLink, DWORD dwUpdateOpt)
  135. {
  136. COleClientItem* pItem = (COleClientItem*)dwLink;
  137. ASSERT_VALID(pItem);
  138. ASSERT_KINDOF(COleClientItem, pItem);
  139. ASSERT(pItem->GetType() == OT_LINK);
  140. SCODE sc;
  141. TRY
  142. {
  143. // item is a link -- get its link options
  144. pItem->SetLinkUpdateOptions((OLEUPDATE)dwUpdateOpt);
  145. sc = S_OK;
  146. }
  147. CATCH_ALL(e)
  148. {
  149. sc = COleException::Process(e);
  150. DELETE_EXCEPTION(e);
  151. }
  152. END_CATCH_ALL
  153. return sc;
  154. }
  155. STDMETHODIMP COleUILinkInfo::GetLinkUpdateOptions(
  156. DWORD dwLink, DWORD* lpdwUpdateOpt)
  157. {
  158. COleClientItem* pItem = (COleClientItem*)dwLink;
  159. ASSERT_VALID(pItem);
  160. ASSERT_KINDOF(COleClientItem, pItem);
  161. SCODE sc;
  162. TRY
  163. {
  164. if (pItem->GetType() == OT_LINK)
  165. *lpdwUpdateOpt = pItem->GetLinkUpdateOptions();
  166. else
  167. *lpdwUpdateOpt = OLEUPDATE_ALWAYS; // make believe it is auto-link
  168. sc = S_OK;
  169. }
  170. CATCH_ALL(e)
  171. {
  172. sc = COleException::Process(e);
  173. DELETE_EXCEPTION(e);
  174. }
  175. END_CATCH_ALL
  176. return sc;
  177. }
  178. STDMETHODIMP COleUILinkInfo::SetLinkSource(
  179. DWORD dwLink, LPTSTR lpszDisplayName, ULONG lenFileName,
  180. ULONG* pchEaten, BOOL fValidateSource)
  181. {
  182. USES_CONVERSION;
  183. COleClientItem* pItem = (COleClientItem*)dwLink;
  184. ASSERT_VALID(pItem);
  185. ASSERT_KINDOF(COleClientItem, pItem);
  186. ASSERT(pItem->GetType() == OT_LINK);
  187. LPOLEOBJECT lpObject = NULL;
  188. CLSID clsid;
  189. // parse the portion known to be a file name into a file moniker
  190. TCHAR szName[_MAX_PATH];
  191. lstrcpyn(szName, lpszDisplayName, (int)lenFileName + 1);
  192. LPMONIKER lpmk = NULL;
  193. SCODE sc = CreateFileMoniker(T2COLE(szName), &lpmk);
  194. if (lpmk == NULL)
  195. return sc;
  196. LPBC lpbc = NULL;
  197. if (fValidateSource)
  198. {
  199. sc = CreateBindCtx(0, &lpbc);
  200. if (sc != S_OK)
  201. {
  202. lpmk->Release();
  203. return sc;
  204. }
  205. }
  206. // nUneaten is the number of chars left to parse
  207. UINT nUneaten = lstrlen(lpszDisplayName) - lenFileName;
  208. // lpszRemainder is the left over display name
  209. LPTSTR lpszRemainder = lpszDisplayName + lenFileName;
  210. *pchEaten = lenFileName;
  211. // parse the rest of the display name
  212. while (nUneaten > 0)
  213. {
  214. // attempt to parse next moniker
  215. ULONG nEaten = 0;
  216. LPMONIKER lpmkNext = NULL;
  217. sc = _AfxParseDisplayName(lpmk, lpbc, lpszRemainder, &nEaten, &lpmkNext);
  218. if (sc != S_OK)
  219. {
  220. lpmk->Release();
  221. lpbc->Release();
  222. return sc;
  223. }
  224. // advance through the display name
  225. nUneaten -= nEaten;
  226. *pchEaten += nEaten;
  227. lpszRemainder += nEaten;
  228. if (lpmkNext != NULL)
  229. {
  230. // create composite out of current and next
  231. LPMONIKER lpmkTemp = NULL;
  232. sc = CreateGenericComposite(lpmk, lpmkNext, &lpmkTemp);
  233. if (FAILED(sc))
  234. {
  235. lpmk->Release();
  236. lpmkNext->Release();
  237. lpbc->Release();
  238. return sc;
  239. }
  240. // make current = next
  241. lpmkNext->Release();
  242. lpmk->Release();
  243. lpmk = lpmkTemp;
  244. }
  245. }
  246. if (fValidateSource)
  247. {
  248. // attempt to bind the the object
  249. sc = lpmk->BindToObject(lpbc, NULL, IID_IOleObject, (LPLP)&lpObject);
  250. if (FAILED(sc))
  251. {
  252. pItem->m_bLinkUnavail = TRUE;
  253. lpbc->Release();
  254. lpmk->Release();
  255. RELEASE(lpObject);
  256. return sc;
  257. }
  258. ASSERT(lpObject != NULL);
  259. // call GetUserClassID while bound so default handler updates
  260. lpObject->GetUserClassID(&clsid);
  261. pItem->m_bLinkUnavail = FALSE;
  262. }
  263. // get IOleLink interface
  264. LPOLELINK lpOleLink = QUERYINTERFACE(pItem->m_lpObject, IOleLink);
  265. ASSERT(lpOleLink != NULL);
  266. // set source from moniker
  267. sc = lpOleLink->SetSourceMoniker(lpmk, clsid);
  268. // update the cache if object was successfully bound
  269. if (lpObject != NULL)
  270. {
  271. lpObject->Update();
  272. lpObject->Release();
  273. }
  274. // cleanup
  275. lpOleLink->Release();
  276. RELEASE(lpmk);
  277. RELEASE(lpbc);
  278. return sc;
  279. }
  280. STDMETHODIMP COleUILinkInfo::GetLinkSource(
  281. DWORD dwLink, LPTSTR* lplpszDisplayName, ULONG* lplenFileName,
  282. LPTSTR* lplpszFullLinkType, LPTSTR* lplpszShortLinkType,
  283. BOOL* lpfSourceAvailable, BOOL* lpfIsSelected)
  284. {
  285. COleClientItem* pItem = (COleClientItem*)dwLink;
  286. ASSERT_VALID(pItem);
  287. ASSERT_KINDOF(COleClientItem, pItem);
  288. ASSERT(pItem->GetType() == OT_LINK);
  289. // set OUT params to NULL
  290. ASSERT(lplpszDisplayName != NULL);
  291. *lplpszDisplayName = NULL;
  292. if (lplpszFullLinkType != NULL)
  293. *lplpszFullLinkType = NULL;
  294. if (lplpszShortLinkType != NULL)
  295. *lplpszShortLinkType = NULL;
  296. if (lplenFileName != NULL)
  297. *lplenFileName = 0;
  298. if (lpfSourceAvailable != NULL)
  299. *lpfSourceAvailable = !pItem->m_bLinkUnavail;
  300. // get IOleLink interface
  301. LPOLELINK lpOleLink = QUERYINTERFACE(pItem->m_lpObject, IOleLink);
  302. ASSERT(lpOleLink != NULL);
  303. // get moniker & object information
  304. LPMONIKER lpmk;
  305. if (lpOleLink->GetSourceMoniker(&lpmk) == S_OK)
  306. {
  307. if (lplenFileName != NULL)
  308. *lplenFileName = _AfxOleGetLenFilePrefixOfMoniker(lpmk);
  309. lpmk->Release();
  310. }
  311. // attempt to get the type names of the link
  312. if (lplpszFullLinkType != NULL)
  313. {
  314. LPOLESTR lpOleStr = NULL;
  315. pItem->m_lpObject->GetUserType(USERCLASSTYPE_FULL, &lpOleStr);
  316. *lplpszFullLinkType = TASKSTRINGOLE2T(lpOleStr);
  317. if (*lplpszFullLinkType == NULL)
  318. {
  319. TCHAR szUnknown[256];
  320. VERIFY(AfxLoadString(AFX_IDS_UNKNOWNTYPE, szUnknown) != 0);
  321. *lplpszFullLinkType = AfxAllocTaskString(szUnknown);
  322. }
  323. }
  324. if (lplpszShortLinkType != NULL)
  325. {
  326. LPOLESTR lpOleStr = NULL;
  327. pItem->m_lpObject->GetUserType(USERCLASSTYPE_SHORT, &lpOleStr);
  328. *lplpszShortLinkType = TASKSTRINGOLE2T(lpOleStr);
  329. if (*lplpszShortLinkType == NULL)
  330. {
  331. TCHAR szUnknown[256];
  332. VERIFY(AfxLoadString(AFX_IDS_UNKNOWNTYPE, szUnknown) != 0);
  333. *lplpszShortLinkType = AfxAllocTaskString(szUnknown);
  334. }
  335. }
  336. // get source display name for moniker
  337. LPOLESTR lpOleStr = NULL;
  338. SCODE sc = lpOleLink->GetSourceDisplayName(&lpOleStr);
  339. *lplpszDisplayName = TASKSTRINGOLE2T(lpOleStr);
  340. lpOleLink->Release();
  341. if (sc != S_OK)
  342. return sc;
  343. // see if item is selected if specified
  344. if (lpfIsSelected)
  345. {
  346. *lpfIsSelected = (m_pSelectedItem == pItem);
  347. }
  348. return S_OK;
  349. }
  350. STDMETHODIMP COleUILinkInfo::OpenLinkSource(DWORD dwLink)
  351. {
  352. COleClientItem* pItem = (COleClientItem*)dwLink;
  353. ASSERT_VALID(pItem);
  354. ASSERT_KINDOF(COleClientItem, pItem);
  355. ASSERT(pItem->GetType() == OT_LINK);
  356. SCODE sc;
  357. TRY
  358. {
  359. // Note: no need for valid CView* since links don't activate inplace
  360. pItem->DoVerb(OLEIVERB_SHOW, NULL);
  361. sc = S_OK;
  362. }
  363. CATCH_ALL(e)
  364. {
  365. sc = COleException::Process(e);
  366. DELETE_EXCEPTION(e);
  367. }
  368. END_CATCH_ALL
  369. return sc;
  370. }
  371. STDMETHODIMP COleUILinkInfo::UpdateLink(
  372. DWORD dwLink, BOOL /*fErrorMessage*/, BOOL /*fErrorAction*/)
  373. {
  374. COleClientItem* pItem = (COleClientItem*)dwLink;
  375. ASSERT_VALID(pItem);
  376. ASSERT_KINDOF(COleClientItem, pItem);
  377. SCODE sc;
  378. TRY
  379. {
  380. // link not up-to-date, attempt to update it
  381. if (!pItem->UpdateLink())
  382. AfxThrowOleException(pItem->GetLastStatus());
  383. pItem->m_bLinkUnavail = FALSE;
  384. sc = S_OK;
  385. }
  386. CATCH_ALL(e)
  387. {
  388. pItem->m_bLinkUnavail = TRUE;
  389. sc = COleException::Process(e);
  390. pItem->ReportError(sc);
  391. DELETE_EXCEPTION(e);
  392. }
  393. END_CATCH_ALL
  394. return sc;
  395. }
  396. STDMETHODIMP COleUILinkInfo::CancelLink(DWORD dwLink)
  397. {
  398. COleClientItem* pItem = (COleClientItem*)dwLink;
  399. ASSERT_VALID(pItem);
  400. ASSERT_KINDOF(COleClientItem, pItem);
  401. ASSERT(pItem->GetType() == OT_LINK);
  402. SCODE sc = E_FAIL;
  403. TRY
  404. {
  405. if (pItem->FreezeLink())
  406. sc = S_OK;
  407. }
  408. CATCH_ALL(e)
  409. {
  410. sc = COleException::Process(e);
  411. DELETE_EXCEPTION(e);
  412. }
  413. END_CATCH_ALL
  414. // report error
  415. if (sc != S_OK)
  416. pItem->ReportError(sc);
  417. return S_OK;
  418. }
  419. STDMETHODIMP COleUILinkInfo::GetLastUpdate(DWORD dwLink, FILETIME*)
  420. {
  421. COleClientItem* pItem = (COleClientItem*)dwLink;
  422. ASSERT_VALID(pItem);
  423. // Note: leave last update time at unknown!
  424. return S_OK;
  425. }
  426. ////////////////////////////////////////////////////////////////////////////
  427. // InsertObject dialog wrapper
  428. COleInsertDialog::COleInsertDialog(DWORD dwFlags, CWnd* pParentWnd)
  429. : COleDialog(pParentWnd)
  430. {
  431. memset(&m_io, 0, sizeof(m_io)); // initialize structure to 0/NULL
  432. // fill in common part
  433. m_io.cbStruct = sizeof(m_io);
  434. m_io.dwFlags = dwFlags;
  435. if (!afxData.bWin4 && AfxHelpEnabled())
  436. m_io.dwFlags |= IOF_SHOWHELP;
  437. if (_AfxOlePropertiesEnabled())
  438. m_io.dwFlags |= IOF_HIDECHANGEICON;
  439. m_io.lpfnHook = AfxOleHookProc;
  440. m_nIDHelp = AFX_IDD_INSERTOBJECT;
  441. // specific to this dialog
  442. m_io.lpszFile = m_szFileName;
  443. m_io.cchFile = _countof(m_szFileName);
  444. m_szFileName[0] = '\0';
  445. }
  446. COleInsertDialog::~COleInsertDialog()
  447. {
  448. _AfxDeleteMetafilePict(m_io.hMetaPict);
  449. }
  450. void COleInsertDialog::AddClassIDToList(LPCLSID& lpList,
  451. int& nListCount, int& nBufferLen, LPCLSID lpNewID)
  452. {
  453. // if the list doesn't exist, create it
  454. if (lpList == NULL)
  455. {
  456. nListCount = 0;
  457. nBufferLen = 16;
  458. lpList = new CLSID[nBufferLen];
  459. }
  460. // if the list isn't big enough grow it by twice
  461. if (nListCount == nBufferLen)
  462. {
  463. LPCLSID lpOldList = lpList;
  464. nBufferLen <<= 2;
  465. lpList = new CLSID[nBufferLen];
  466. memcpy(lpList, lpOldList, sizeof(CLSID) * nListCount);
  467. delete [] lpOldList;
  468. }
  469. lpList[nListCount] = *lpNewID;
  470. nListCount++;
  471. return;
  472. }
  473. int COleInsertDialog::DoModal(DWORD dwFlags)
  474. {
  475. LPCLSID lpNewExcludeList = NULL;
  476. int nNewExcludeCount = 0;
  477. int nNewExcludeLen = 0;
  478. // support for controls is built-in
  479. // support doc objects by filtering what the dialog shows
  480. if (dwFlags == ControlsOnly)
  481. m_io.dwFlags |= IOF_SELECTCREATECONTROL | IOF_SHOWINSERTCONTROL;
  482. else if (dwFlags == DocObjectsOnly)
  483. {
  484. m_io.dwFlags |= IOF_DISABLEDISPLAYASICON | IOF_DISABLELINK;
  485. HKEY hkClassesRoot;
  486. HKEY hkCLSID;
  487. HKEY hkItem;
  488. HKEY hkDocObject;
  489. DWORD dwIndex = 0;
  490. TCHAR szName[MAX_PATH+1];
  491. if (RegOpenKeyEx(HKEY_CLASSES_ROOT, NULL, 0, KEY_READ,
  492. &hkClassesRoot) == ERROR_SUCCESS)
  493. {
  494. if(RegOpenKeyEx(hkClassesRoot, _T("CLSID"), 0,
  495. KEY_ENUMERATE_SUB_KEYS, &hkCLSID) == ERROR_SUCCESS)
  496. {
  497. while(RegEnumKey(hkCLSID, dwIndex++,
  498. szName, sizeof(szName)) == ERROR_SUCCESS)
  499. {
  500. if (RegOpenKeyEx(hkCLSID, szName, 0,
  501. KEY_READ, &hkItem) == ERROR_SUCCESS)
  502. {
  503. if ((RegOpenKeyEx(hkItem, _T("Insertable"), 0,
  504. KEY_READ, &hkDocObject) == ERROR_SUCCESS) ||
  505. (RegOpenKeyEx(hkItem, _T("Ole1Class"),0,
  506. KEY_READ, &hkDocObject) == ERROR_SUCCESS))
  507. {
  508. RegCloseKey(hkDocObject);
  509. if ((RegOpenKeyEx(hkItem, _T("DocObject"), 0,
  510. KEY_READ, &hkDocObject) != ERROR_SUCCESS ) )
  511. {
  512. USES_CONVERSION;
  513. CLSID clsid;
  514. CLSIDFromString(T2OLE(szName), &clsid);
  515. AddClassIDToList(lpNewExcludeList,
  516. nNewExcludeCount, nNewExcludeLen, &clsid);
  517. RegCloseKey(hkItem);
  518. }
  519. RegCloseKey(hkDocObject);
  520. }
  521. }
  522. }
  523. RegCloseKey(hkCLSID);
  524. }
  525. }
  526. RegCloseKey(hkClassesRoot);
  527. }
  528. UINT cOldClsidExclude = m_io.cClsidExclude;
  529. LPCLSID lpOldClsidExclude = m_io.lpClsidExclude;
  530. if (lpNewExcludeList != NULL)
  531. {
  532. m_io.lpClsidExclude = lpNewExcludeList;
  533. m_io.cClsidExclude = nNewExcludeCount;
  534. }
  535. QueryAgain:
  536. int nDisposition = DoModal();
  537. if (nDisposition == IDOK && GetSelectionType() == insertFromFile &&
  538. dwFlags == DocObjectsOnly)
  539. {
  540. USES_CONVERSION;
  541. // Double-check that the requested file really is serviced by a
  542. // DocObject server.
  543. CLSID clsidFile;
  544. BOOL bIsDocObject = FALSE;
  545. if (GetClassFile(T2COLE(m_io.lpszFile), &clsidFile) == S_OK)
  546. {
  547. CString strKey;
  548. CString strCLSID = AfxStringFromCLSID(clsidFile);
  549. strKey.Format(_T("CLSID\\%s\\DocObject"), strCLSID);
  550. HKEY hKey;
  551. if (ERROR_SUCCESS ==
  552. RegOpenKeyEx(HKEY_CLASSES_ROOT, strKey, 0, KEY_QUERY_VALUE, &hKey))
  553. {
  554. RegCloseKey(hKey);
  555. bIsDocObject = TRUE;
  556. }
  557. }
  558. if (!bIsDocObject)
  559. {
  560. nDisposition =
  561. AfxMessageBox(AFX_IDS_NOT_DOCOBJECT, MB_RETRYCANCEL | MB_ICONHAND);
  562. if (nDisposition == IDRETRY)
  563. goto QueryAgain;
  564. else
  565. nDisposition = IDCANCEL;
  566. }
  567. }
  568. delete [] lpNewExcludeList;
  569. m_io.cClsidExclude = cOldClsidExclude;
  570. m_io.lpClsidExclude = lpOldClsidExclude;
  571. return nDisposition;
  572. }
  573. int COleInsertDialog::DoModal()
  574. {
  575. ASSERT_VALID(this);
  576. ASSERT(m_io.lpfnHook != NULL); // can still be a user hook
  577. m_io.hWndOwner = PreModal();
  578. int iResult = MapResult(::OleUIInsertObject(&m_io));
  579. PostModal();
  580. return iResult;
  581. }
  582. UINT COleInsertDialog::GetSelectionType() const
  583. {
  584. ASSERT_VALID(this);
  585. if (m_io.dwFlags & IOF_SELECTCREATEFROMFILE)
  586. {
  587. if (m_io.dwFlags & IOF_CHECKLINK)
  588. return linkToFile;
  589. else
  590. return insertFromFile;
  591. }
  592. ASSERT(m_io.dwFlags & IOF_SELECTCREATENEW);
  593. return createNewItem;
  594. }
  595. // allocate an item first, then call this fuction to create it
  596. BOOL COleInsertDialog::CreateItem(COleClientItem* pNewItem)
  597. {
  598. ASSERT_VALID(pNewItem);
  599. // switch on selection type
  600. UINT selType = GetSelectionType();
  601. BOOL bResult;
  602. switch (selType)
  603. {
  604. case linkToFile:
  605. // link to file selected
  606. ASSERT(m_szFileName[0] != 0);
  607. bResult = pNewItem->CreateLinkFromFile(m_szFileName);
  608. break;
  609. case insertFromFile:
  610. // insert file selected
  611. ASSERT(m_szFileName[0] != 0);
  612. bResult = pNewItem->CreateFromFile(m_szFileName);
  613. break;
  614. default:
  615. // otherwise must be create new
  616. ASSERT(selType == createNewItem);
  617. bResult = pNewItem->CreateNewItem(m_io.clsid);
  618. break;
  619. }
  620. // deal with Display As Iconic option
  621. if (bResult && GetDrawAspect() == DVASPECT_ICON)
  622. {
  623. // setup iconic cache (it will draw iconic by default as well)
  624. if (!pNewItem->SetIconicMetafile(m_io.hMetaPict))
  625. {
  626. TRACE0("Warning: failed to set iconic aspect in CreateItem.\n");
  627. return TRUE;
  628. }
  629. // since picture was set OK, draw as iconic as well...
  630. pNewItem->SetDrawAspect(DVASPECT_ICON);
  631. }
  632. return bResult;
  633. }
  634. /////////////////////////////////////////////////////////////////////////////
  635. // COleInsertDialog diagnostics
  636. #ifdef _DEBUG
  637. void COleInsertDialog::Dump(CDumpContext& dc) const
  638. {
  639. COleDialog::Dump(dc);
  640. dc << "m_szFileName = " << m_szFileName;
  641. dc << "\nm_io.cbStruct = " << m_io.cbStruct;
  642. dc << "\nm_io.dwFlags = " << (LPVOID)m_io.dwFlags;
  643. dc << "\nm_io.hWndOwner = " << (UINT)m_io.hWndOwner;
  644. dc << "\nm_io.lpszCaption = " << m_io.lpszCaption;
  645. dc << "\nm_io.lCustData = " << (LPVOID)m_io.lCustData;
  646. dc << "\nm_io.hInstance = " << (UINT)m_io.hInstance;
  647. dc << "\nm_io.lpszTemplate = " << (LPVOID)m_io.lpszTemplate;
  648. dc << "\nm_io.hResource = " << (UINT)m_io.hResource;
  649. if (m_io.lpfnHook == AfxOleHookProc)
  650. dc << "\nhook function set to standard MFC hook function";
  651. else
  652. dc << "\nhook function set to non-standard hook function";
  653. dc << "\nm_io.hMetaPict = " << (UINT)m_io.hMetaPict;
  654. dc << "\n";
  655. }
  656. #endif //_DEBUG
  657. /////////////////////////////////////////////////////////////////////////////
  658. // COleConvertDialog
  659. COleConvertDialog::COleConvertDialog(COleClientItem* pItem, DWORD dwFlags,
  660. CLSID* pClassID, CWnd* pParentWnd) : COleDialog(pParentWnd)
  661. {
  662. if (pItem != NULL)
  663. ASSERT_VALID(pItem);
  664. ASSERT(pClassID == NULL || AfxIsValidAddress(pClassID, sizeof(CLSID), FALSE));
  665. memset(&m_cv, 0, sizeof(m_cv)); // initialize structure to 0/NULL
  666. if (pClassID != NULL)
  667. m_cv.clsid = *pClassID;
  668. // fill in common part
  669. m_cv.cbStruct = sizeof(m_cv);
  670. m_cv.dwFlags = dwFlags;
  671. if (!afxData.bWin4 && AfxHelpEnabled())
  672. m_cv.dwFlags |= CF_SHOWHELPBUTTON;
  673. m_cv.lpfnHook = AfxOleHookProc;
  674. m_nIDHelp = AFX_IDD_CONVERT;
  675. // specific to this dialog
  676. m_cv.fIsLinkedObject = pItem->GetType() == OT_LINK;
  677. m_cv.dvAspect = pItem->GetDrawAspect();
  678. if (pClassID == NULL && !m_cv.fIsLinkedObject)
  679. {
  680. // for embeddings, attempt to get class ID from the storage
  681. if (ReadClassStg(pItem->m_lpStorage, &m_cv.clsid) == S_OK)
  682. pClassID = &m_cv.clsid;
  683. // attempt to get user type from storage
  684. CLIPFORMAT cf = 0;
  685. LPOLESTR lpOleStr = NULL;
  686. ReadFmtUserTypeStg(pItem->m_lpStorage, &cf, &lpOleStr);
  687. m_cv.lpszUserType = TASKSTRINGOLE2T(lpOleStr);
  688. m_cv.wFormat = (WORD)cf;
  689. }
  690. // get class id if neded
  691. if (pClassID == NULL)
  692. {
  693. // no class ID in the storage, use class ID of the object
  694. pItem->GetClassID(&m_cv.clsid);
  695. }
  696. // get user type if needed
  697. if (m_cv.lpszUserType == NULL)
  698. {
  699. // no user type in storge, get user type from class ID
  700. LPTSTR lpszUserType = NULL;
  701. LPOLESTR lpOleStr = NULL;
  702. if (OleRegGetUserType(m_cv.clsid, USERCLASSTYPE_FULL,
  703. &lpOleStr) == S_OK)
  704. {
  705. lpszUserType = TASKSTRINGOLE2T(lpOleStr);
  706. }
  707. else
  708. {
  709. lpszUserType = (LPTSTR)CoTaskMemAlloc(256 * sizeof(TCHAR));
  710. if (lpszUserType != NULL)
  711. {
  712. lpszUserType[0] = '?';
  713. lpszUserType[1] = 0;
  714. VERIFY(AfxLoadString(AFX_IDS_UNKNOWNTYPE, lpszUserType) != 0);
  715. }
  716. }
  717. m_cv.lpszUserType = lpszUserType;
  718. }
  719. m_cv.hMetaPict = pItem->GetIconicMetafile();
  720. }
  721. COleConvertDialog::~COleConvertDialog()
  722. {
  723. _AfxDeleteMetafilePict(m_cv.hMetaPict);
  724. }
  725. int COleConvertDialog::DoModal()
  726. {
  727. ASSERT_VALID(this);
  728. ASSERT(m_cv.lpfnHook != NULL); // can still be a user hook
  729. m_cv.hWndOwner = PreModal();
  730. int iResult = MapResult(::OleUIConvert(&m_cv));
  731. PostModal();
  732. return iResult;
  733. }
  734. BOOL COleConvertDialog::DoConvert(COleClientItem* pItem)
  735. {
  736. ASSERT_VALID(pItem);
  737. CWaitCursor wait;
  738. UINT selType = GetSelectionType();
  739. BOOL bResult = TRUE;
  740. if (m_cv.clsidNew != CLSID_NULL)
  741. {
  742. switch (selType)
  743. {
  744. case convertItem:
  745. bResult = pItem->ConvertTo(m_cv.clsidNew);
  746. break;
  747. case activateAs:
  748. bResult = pItem->ActivateAs(m_cv.lpszUserType, m_cv.clsid,
  749. m_cv.clsidNew);
  750. break;
  751. default:
  752. ASSERT(selType == noConversion);
  753. break;
  754. }
  755. }
  756. if (!bResult)
  757. {
  758. // if unable to convert the object show message box
  759. AfxMessageBox(AFX_IDP_FAILED_TO_CONVERT);
  760. return FALSE;
  761. }
  762. // change to iconic/content view if changed
  763. if ((DVASPECT)m_cv.dvAspect != pItem->GetDrawAspect())
  764. {
  765. pItem->OnChange(OLE_CHANGED_ASPECT, (DWORD)m_cv.dvAspect);
  766. pItem->SetDrawAspect((DVASPECT)m_cv.dvAspect);
  767. }
  768. // change the actual icon as well
  769. if (m_cv.fObjectsIconChanged)
  770. {
  771. pItem->SetIconicMetafile(m_cv.hMetaPict);
  772. if (pItem->GetDrawAspect() == DVASPECT_ICON)
  773. pItem->OnChange(OLE_CHANGED, (DWORD)DVASPECT_ICON);
  774. }
  775. return TRUE;
  776. }
  777. UINT COleConvertDialog::GetSelectionType() const
  778. {
  779. ASSERT_VALID(this);
  780. if (m_cv.clsid != m_cv.clsidNew)
  781. {
  782. if (m_cv.dwFlags & CF_SELECTCONVERTTO)
  783. return convertItem;
  784. else if (m_cv.dwFlags & CF_SELECTACTIVATEAS)
  785. return activateAs;
  786. }
  787. return noConversion;
  788. }
  789. /////////////////////////////////////////////////////////////////////////////
  790. // COleConvertDialog diagnostics
  791. #ifdef _DEBUG
  792. void COleConvertDialog::Dump(CDumpContext& dc) const
  793. {
  794. COleDialog::Dump(dc);
  795. dc << "m_cv.cbStruct = " << m_cv.cbStruct;
  796. dc << "\nm_cv.dwFlags = " << (LPVOID)m_cv.dwFlags;
  797. dc << "\nm_cv.hWndOwner = " << (UINT)m_cv.hWndOwner;
  798. dc << "\nm_cv.lpszCaption = " << m_cv.lpszCaption;
  799. dc << "\nm_cv.lCustData = " << (LPVOID)m_cv.lCustData;
  800. dc << "\nm_cv.hInstance = " << (UINT)m_cv.hInstance;
  801. dc << "\nm_cv.lpszTemplate = " << (LPVOID)m_cv.lpszTemplate;
  802. dc << "\nm_cv.hResource = " << (UINT)m_cv.hResource;
  803. if (m_cv.lpfnHook == AfxOleHookProc)
  804. dc << "\nhook function set to standard MFC hook function";
  805. else
  806. dc << "\nhook function set to non-standard hook function";
  807. dc << "\nm_cv.dvAspect = " << (UINT)m_cv.dvAspect;
  808. dc << "\nm_cv.wFormat = " << (UINT)m_cv.wFormat;
  809. dc << "\nm_cv.fIsLinkedObject = " << m_cv.fIsLinkedObject;
  810. dc << "\nm_cv.hMetaPict = " << (UINT)m_cv.hMetaPict;
  811. dc << "\nm_cv.lpszUserType = " << m_cv.lpszUserType;
  812. dc << "\nm_cv.fObjectsIconChanged = " << m_cv.fObjectsIconChanged;
  813. dc << "\n";
  814. }
  815. #endif
  816. /////////////////////////////////////////////////////////////////////////////
  817. // COleChangeIconDialog
  818. COleChangeIconDialog::COleChangeIconDialog(COleClientItem* pItem,
  819. DWORD dwFlags, CWnd* pParentWnd) : COleDialog(pParentWnd)
  820. {
  821. if (pItem != NULL)
  822. ASSERT_VALID(pItem);
  823. memset(&m_ci, 0, sizeof(m_ci)); // initialize structure to 0/NULL
  824. // fill in common part
  825. m_ci.cbStruct = sizeof(m_ci);
  826. m_ci.dwFlags = dwFlags;
  827. if (!afxData.bWin4 && AfxHelpEnabled())
  828. m_ci.dwFlags |= CIF_SHOWHELP;
  829. m_ci.lpfnHook = AfxOleHookProc;
  830. m_nIDHelp = AFX_IDD_CHANGEICON;
  831. // specific to this dialog
  832. if (pItem != NULL)
  833. {
  834. pItem->GetClassID(&m_ci.clsid);
  835. m_ci.hMetaPict = pItem->GetIconicMetafile();
  836. }
  837. }
  838. COleChangeIconDialog::~COleChangeIconDialog()
  839. {
  840. _AfxDeleteMetafilePict(m_ci.hMetaPict);
  841. }
  842. int COleChangeIconDialog::DoModal()
  843. {
  844. ASSERT_VALID(this);
  845. ASSERT(m_ci.lpfnHook != NULL); // can still be a user hook
  846. m_ci.hWndOwner = PreModal();
  847. int iResult = MapResult(::OleUIChangeIcon(&m_ci));
  848. PostModal();
  849. return iResult;
  850. }
  851. BOOL COleChangeIconDialog::DoChangeIcon(COleClientItem* pItem)
  852. {
  853. ASSERT_VALID(this);
  854. ASSERT_VALID(pItem);
  855. // set the picture
  856. if (!pItem->SetIconicMetafile(GetIconicMetafile()))
  857. return FALSE;
  858. // notify the item of the change if the current draw aspect is ICON
  859. if (pItem->GetDrawAspect() == DVASPECT_ICON)
  860. pItem->OnChange(OLE_CHANGED, (DWORD)DVASPECT_ICON);
  861. return TRUE;
  862. }
  863. /////////////////////////////////////////////////////////////////////////////
  864. // COleChangeIconDialog diagnostics
  865. #ifdef _DEBUG
  866. void COleChangeIconDialog::Dump(CDumpContext& dc) const
  867. {
  868. COleDialog::Dump(dc);
  869. dc << "m_ci.cbStruct = " << m_ci.cbStruct;
  870. dc << "\nm_ci.dwFlags = " << (LPVOID)m_ci.dwFlags;
  871. dc << "\nm_ci.hWndOwner = " << (UINT)m_ci.hWndOwner;
  872. dc << "\nm_ci.lpszCaption = " << m_ci.lpszCaption;
  873. dc << "\nm_ci.lCustData = " << (LPVOID)m_ci.lCustData;
  874. dc << "\nm_ci.hInstance = " << (UINT)m_ci.hInstance;
  875. dc << "\nm_ci.lpszTemplate = " << (LPVOID)m_ci.lpszTemplate;
  876. dc << "\nm_ci.hResource = " << (UINT)m_ci.hResource;
  877. if (m_ci.lpfnHook == AfxOleHookProc)
  878. dc << "\nhook function set to standard MFC hook function";
  879. else
  880. dc << "\nhook function set to non-standard hook function";
  881. dc << "\nm_ci.hMetaPict = " << (UINT)m_ci.hMetaPict;
  882. dc << "\n";
  883. }
  884. #endif
  885. /////////////////////////////////////////////////////////////////////////////
  886. // COleLinksDialog
  887. COleLinksDialog::COleLinksDialog(COleDocument* pDoc, CView* pView,
  888. DWORD dwFlags, CWnd* pParentWnd) : COleDialog(pParentWnd),
  889. m_xLinkInfo(pDoc)
  890. {
  891. ASSERT_VALID(pDoc);
  892. if (pView != NULL)
  893. ASSERT_VALID(pView);
  894. memset(&m_el, 0, sizeof(m_el)); // initialize structure to 0/NULL
  895. // fill in common part
  896. m_el.cbStruct = sizeof(m_el);
  897. m_el.dwFlags = dwFlags;
  898. if (!afxData.bWin4 && AfxHelpEnabled())
  899. m_el.dwFlags |= ELF_SHOWHELP;
  900. m_el.lpfnHook = AfxOleHookProc;
  901. m_nIDHelp = AFX_IDD_EDITLINKS;
  902. // specific to this dialog
  903. if (pView != NULL)
  904. m_xLinkInfo.m_pSelectedItem = pDoc->GetPrimarySelectedItem(pView);
  905. else
  906. m_xLinkInfo.m_pSelectedItem = NULL;
  907. m_el.lpOleUILinkContainer = &m_xLinkInfo;
  908. }
  909. COleLinksDialog::~COleLinksDialog()
  910. {
  911. }
  912. int COleLinksDialog::DoModal()
  913. {
  914. ASSERT_VALID(this);
  915. ASSERT(m_el.lpfnHook != NULL); // can still be a user hook
  916. // this function is always used for updating links
  917. m_xLinkInfo.m_bUpdateLinks = TRUE;
  918. m_el.hWndOwner = PreModal();
  919. int iResult = MapResult(::OleUIEditLinks(&m_el));
  920. PostModal();
  921. return iResult;
  922. }
  923. /////////////////////////////////////////////////////////////////////////////
  924. // COleLinksDialog diagnostics
  925. #ifdef _DEBUG
  926. void COleLinksDialog::Dump(CDumpContext& dc) const
  927. {
  928. COleDialog::Dump(dc);
  929. dc << "\nm_el.cbStruct = " << m_el.cbStruct;
  930. dc << "\nm_el.dwFlags = " << (void*)m_el.dwFlags;
  931. dc << "\nm_el.hWndOwner = " << (UINT)m_el.hWndOwner;
  932. dc << "\nm_el.lpszCaption = " << m_el.lpszCaption;
  933. dc << "\nm_el.lCustData = " << (void*)m_el.lCustData;
  934. dc << "\nm_el.hInstance = " << (UINT)m_el.hInstance;
  935. dc << "\nm_el.lpszTemplate = " << (void*)m_el.lpszTemplate;
  936. dc << "\nm_el.hResource = " << (UINT)m_el.hResource;
  937. if (m_el.lpfnHook == AfxOleHookProc)
  938. dc << "\nhook function set to standard MFC hook function";
  939. else
  940. dc << "\nhook function set to non-standard hook function";
  941. dc << "\n";
  942. }
  943. void COleLinksDialog::AssertValid() const
  944. {
  945. COleDialog::AssertValid();
  946. }
  947. #endif
  948. /////////////////////////////////////////////////////////////////////////////
  949. // COleUpdateDialog
  950. COleUpdateDialog::COleUpdateDialog(COleDocument* pDoc,
  951. BOOL bUpdateLinks, BOOL bUpdateEmbeddings, CWnd* pParentWnd)
  952. : COleLinksDialog(pDoc, NULL, 0, pParentWnd)
  953. {
  954. ASSERT_VALID(pDoc);
  955. ASSERT(bUpdateLinks || bUpdateEmbeddings);
  956. // non-base class parameters
  957. m_xLinkInfo.m_bUpdateLinks = bUpdateLinks;
  958. m_xLinkInfo.m_bUpdateEmbeddings = bUpdateEmbeddings;
  959. m_strCaption.LoadString(AFX_IDS_UPDATING_ITEMS);
  960. }
  961. COleUpdateDialog::~COleUpdateDialog()
  962. {
  963. }
  964. int COleUpdateDialog::DoModal()
  965. {
  966. ASSERT_VALID(this);
  967. // first count number of links/embeddings to be updated
  968. DWORD dwLink = 0;
  969. int cLinks = 0;
  970. while ((dwLink = m_el.lpOleUILinkContainer->GetNextLink(dwLink)) != 0)
  971. ++cLinks;
  972. // when no links are out-of-date, don't bother
  973. if (cLinks == 0)
  974. return IDCANCEL;
  975. // bring up the dialog that processes all the links
  976. HWND hWndParent = PreModal();
  977. BOOL bResult = OleUIUpdateLinks(m_el.lpOleUILinkContainer,
  978. hWndParent, (LPTSTR)(LPCTSTR)m_strCaption, cLinks);
  979. PostModal();
  980. return bResult ? IDOK : -1;
  981. }
  982. /////////////////////////////////////////////////////////////////////////////
  983. // COleUpdateDialog diagnostics
  984. #ifdef _DEBUG
  985. void COleUpdateDialog::Dump(CDumpContext& dc) const
  986. {
  987. COleLinksDialog::Dump(dc);
  988. dc << "m_strCaption = " << m_strCaption;
  989. dc << "\n";
  990. }
  991. #endif
  992. /////////////////////////////////////////////////////////////////////////////
  993. // COlePasteSpecialDialog
  994. COlePasteSpecialDialog::COlePasteSpecialDialog(DWORD dwFlags,
  995. COleDataObject* pDataObject, CWnd* pParentWnd) : COleDialog(pParentWnd)
  996. {
  997. memset(&m_ps, 0, sizeof(m_ps)); // initialize structure to 0/NULL
  998. // fill in common part
  999. m_ps.cbStruct = sizeof(m_ps);
  1000. m_ps.dwFlags = dwFlags | PSF_STAYONCLIPBOARDCHANGE;
  1001. if (!afxData.bWin4 && AfxHelpEnabled())
  1002. m_ps.dwFlags |= PSF_SHOWHELP;
  1003. if (_AfxOlePropertiesEnabled())
  1004. m_ps.dwFlags |= PSF_HIDECHANGEICON;
  1005. m_ps.lpfnHook = AfxOleHookProc;
  1006. m_nIDHelp = AFX_IDD_PASTESPECIAL;
  1007. // get LPDATAOBJECT for paste special dialog
  1008. COleDataObject dataObject;
  1009. if (pDataObject == NULL)
  1010. {
  1011. VERIFY(dataObject.AttachClipboard());
  1012. pDataObject = &dataObject;
  1013. }
  1014. ASSERT(pDataObject != NULL);
  1015. m_ps.lpSrcDataObj = pDataObject->GetIDataObject(TRUE);
  1016. // complete initialization
  1017. m_ps.arrPasteEntries = NULL;
  1018. m_ps.cPasteEntries = 0;
  1019. m_ps.arrLinkTypes = m_arrLinkTypes;
  1020. m_ps.cLinkTypes = 0;
  1021. }
  1022. COlePasteSpecialDialog::~COlePasteSpecialDialog()
  1023. {
  1024. _AfxDeleteMetafilePict(m_ps.hMetaPict);
  1025. for (int i = 0; i < m_ps.cPasteEntries; i++)
  1026. {
  1027. free((void*)m_ps.arrPasteEntries[i].lpstrFormatName);
  1028. free((void*)m_ps.arrPasteEntries[i].lpstrResultText);
  1029. }
  1030. free(m_ps.arrPasteEntries);
  1031. RELEASE(m_ps.lpSrcDataObj);
  1032. }
  1033. int COlePasteSpecialDialog::DoModal()
  1034. {
  1035. ASSERT_VALID(this);
  1036. ASSERT(m_ps.lpfnHook != NULL); // can still be a user hook
  1037. // return error if IDataObject* not available
  1038. if (m_ps.lpSrcDataObj == NULL)
  1039. return -1;
  1040. m_ps.hWndOwner = PreModal();
  1041. int iResult = MapResult(::OleUIPasteSpecial(&m_ps));
  1042. PostModal();
  1043. return iResult;
  1044. }
  1045. UINT COlePasteSpecialDialog::GetSelectionType() const
  1046. {
  1047. ASSERT_VALID(this);
  1048. ASSERT(m_ps.dwFlags & (PSF_SELECTPASTE|PSF_SELECTPASTELINK));
  1049. UINT cf = m_ps.arrPasteEntries[m_ps.nSelectedIndex].fmtetc.cfFormat;
  1050. Selection selType = pasteOther;
  1051. if (m_ps.dwFlags & PSF_SELECTPASTELINK)
  1052. {
  1053. selType = pasteLink;
  1054. }
  1055. else if (cf == _oleData.cfEmbedSource || cf == _oleData.cfEmbeddedObject ||
  1056. cf == _oleData.cfLinkSource)
  1057. {
  1058. selType = pasteNormal;
  1059. }
  1060. else if (cf == CF_METAFILEPICT || cf == CF_DIB || cf == CF_BITMAP)
  1061. {
  1062. selType = pasteStatic;
  1063. }
  1064. return selType;
  1065. }
  1066. /////////////////////////////////////////////////////////////////////////////
  1067. // COlePasteSpecialDialog diagnostics
  1068. #ifdef _DEBUG
  1069. void COlePasteSpecialDialog::Dump(CDumpContext& dc) const
  1070. {
  1071. COleDialog::Dump(dc);
  1072. dc << "m_ps.cbStruct = " << m_ps.cbStruct;
  1073. dc << "\nm_ps.dwFlags = " << (LPVOID)m_ps.dwFlags;
  1074. dc << "\nm_ps.hWndOwner = " << (UINT)m_ps.hWndOwner;
  1075. dc << "\nm_ps.lpszCaption = " << m_ps.lpszCaption;
  1076. dc << "\nm_ps.lCustData = " << (LPVOID)m_ps.lCustData;
  1077. dc << "\nm_ps.hInstance = " << (UINT)m_ps.hInstance;
  1078. dc << "\nm_ps.lpszTemplate = " << (LPVOID)m_ps.lpszTemplate;
  1079. dc << "\nm_ps.hResource = " << (UINT)m_ps.hResource;
  1080. if (m_ps.lpfnHook == AfxOleHookProc)
  1081. dc << "\nhook function set to standard MFC hook function";
  1082. else
  1083. dc << "\nhook function set to non-standard hook function";
  1084. dc << "\nm_ps.lpSrcDataObj = " << (LPVOID)m_ps.lpSrcDataObj;
  1085. dc << "\nm_ps.cPasteEntries = " << m_ps.cPasteEntries;
  1086. dc << "\nm_ps.cLinkTypes = " << m_ps.cLinkTypes;
  1087. dc << "\nm_ps.nSelectedIndex = " << m_ps.nSelectedIndex;
  1088. dc << "\nm_ps.fLink = " << m_ps.fLink;
  1089. dc << "\n";
  1090. }
  1091. void COlePasteSpecialDialog::AssertValid() const
  1092. {
  1093. COleDialog::AssertValid();
  1094. ASSERT(m_ps.cPasteEntries == 0 || m_ps.arrPasteEntries != NULL);
  1095. ASSERT(m_ps.arrLinkTypes != NULL);
  1096. ASSERT(m_ps.cLinkTypes <= 8);
  1097. }
  1098. #endif
  1099. ////////////////////////////////////////////////////////////////////////////
  1100. OLEUIPASTEFLAG COlePasteSpecialDialog::AddLinkEntry(UINT cf)
  1101. {
  1102. ASSERT_VALID(this);
  1103. ASSERT(m_ps.cLinkTypes <= 8);
  1104. for (int i = 0; i < m_ps.cLinkTypes; i++)
  1105. {
  1106. if (m_ps.arrLinkTypes[i] == cf)
  1107. break;
  1108. }
  1109. if (i == 8)
  1110. return (OLEUIPASTEFLAG)0;
  1111. m_ps.arrLinkTypes[i] = cf;
  1112. if (i == m_ps.cLinkTypes)
  1113. m_ps.cLinkTypes++;
  1114. return (OLEUIPASTEFLAG) (OLEUIPASTE_LINKTYPE1 << i);
  1115. }
  1116. void COlePasteSpecialDialog::AddFormat(UINT cf, DWORD tymed, UINT nFormatID,
  1117. BOOL bEnableIcon, BOOL bLink)
  1118. {
  1119. TCHAR szFormat[256];
  1120. if (AfxLoadString(nFormatID, szFormat) == 0)
  1121. AfxThrowResourceException();
  1122. // the format and result strings are delimited by a newline
  1123. LPTSTR lpszResult = _tcschr(szFormat, '\n');
  1124. ASSERT(lpszResult != NULL); // must contain a newline
  1125. *lpszResult = '\0';
  1126. ++lpszResult; // one char past newline
  1127. // add it to the array of acceptable formats
  1128. m_ps.arrPasteEntries = (OLEUIPASTEENTRY *)realloc(m_ps.arrPasteEntries,
  1129. sizeof(OLEUIPASTEENTRY) * (m_ps.cPasteEntries +1));
  1130. OLEUIPASTEENTRY* pEntry = &m_ps.arrPasteEntries[m_ps.cPasteEntries];
  1131. pEntry->fmtetc.cfFormat = (CLIPFORMAT)cf;
  1132. pEntry->fmtetc.dwAspect = DVASPECT_CONTENT;
  1133. pEntry->fmtetc.ptd = NULL;
  1134. pEntry->fmtetc.tymed = tymed;
  1135. pEntry->fmtetc.lindex = -1;
  1136. pEntry->lpstrFormatName = _tcsdup(szFormat);
  1137. pEntry->lpstrResultText = _tcsdup(lpszResult);
  1138. pEntry->dwFlags = OLEUIPASTE_PASTE;
  1139. if (bEnableIcon)
  1140. pEntry->dwFlags |= OLEUIPASTE_ENABLEICON;
  1141. if (bLink)
  1142. pEntry->dwFlags |= AddLinkEntry(cf);
  1143. if (pEntry->dwFlags == OLEUIPASTE_PASTE)
  1144. pEntry->dwFlags = OLEUIPASTE_PASTEONLY;
  1145. pEntry->dwScratchSpace = NULL;
  1146. m_ps.cPasteEntries++;
  1147. }
  1148. // if the flags parameter includes a LINKTYPE# flag, it should be obtained
  1149. // from AddLinkEntry
  1150. void COlePasteSpecialDialog::AddFormat(const FORMATETC& formatEtc,
  1151. LPTSTR lpszFormat, LPTSTR lpszResult, DWORD dwFlags)
  1152. {
  1153. ASSERT_VALID(this);
  1154. m_ps.arrPasteEntries = (OLEUIPASTEENTRY *)realloc(
  1155. m_ps.arrPasteEntries, sizeof(OLEUIPASTEENTRY) * (m_ps.cPasteEntries +1));
  1156. OLEUIPASTEENTRY* pEntry = &m_ps.arrPasteEntries[m_ps.cPasteEntries];
  1157. pEntry->fmtetc = formatEtc;
  1158. pEntry->lpstrFormatName = _tcsdup(lpszFormat);
  1159. pEntry->lpstrResultText = _tcsdup(lpszResult);
  1160. pEntry->dwFlags = dwFlags;
  1161. pEntry->dwScratchSpace = NULL;
  1162. m_ps.cPasteEntries++;
  1163. }
  1164. void COlePasteSpecialDialog::AddStandardFormats(BOOL bEnableLink)
  1165. {
  1166. // Note: only need to add Embedded Object because Embed Source is
  1167. // automatically recognized by the paste special dialog implementation.
  1168. ASSERT(_oleData.cfEmbeddedObject != NULL);
  1169. AddFormat(_oleData.cfEmbeddedObject, TYMED_ISTORAGE, AFX_IDS_EMBED_FORMAT,
  1170. TRUE, FALSE);
  1171. // add link source if requested
  1172. if (bEnableLink)
  1173. {
  1174. ASSERT(_oleData.cfLinkSource != NULL);
  1175. AddFormat(_oleData.cfLinkSource, TYMED_ISTREAM, AFX_IDS_LINKSOURCE_FORMAT,
  1176. TRUE, TRUE);
  1177. }
  1178. // add formats that can be used for 'static' items
  1179. AddFormat(CF_METAFILEPICT, TYMED_MFPICT, AFX_IDS_METAFILE_FORMAT,
  1180. FALSE, FALSE);
  1181. AddFormat(CF_DIB, TYMED_HGLOBAL, AFX_IDS_DIB_FORMAT, FALSE, FALSE);
  1182. AddFormat(CF_BITMAP, TYMED_GDI, AFX_IDS_BITMAP_FORMAT, FALSE, FALSE);
  1183. }
  1184. BOOL COlePasteSpecialDialog::CreateItem(COleClientItem *pNewItem)
  1185. {
  1186. ASSERT_VALID(this);
  1187. ASSERT(pNewItem != NULL);
  1188. ASSERT(m_ps.lpSrcDataObj != NULL);
  1189. CWaitCursor wait;
  1190. COleDataObject dataObject;
  1191. dataObject.Attach(m_ps.lpSrcDataObj, FALSE);
  1192. UINT selType = GetSelectionType();
  1193. BOOL bResult = TRUE;
  1194. switch (selType)
  1195. {
  1196. case pasteLink:
  1197. // paste link
  1198. if (!pNewItem->CreateLinkFromData(&dataObject))
  1199. {
  1200. TRACE0("Warning: CreateLinkFromData failed.\n");
  1201. bResult = FALSE;
  1202. }
  1203. break;
  1204. case pasteStatic:
  1205. if (!pNewItem->CreateStaticFromData(&dataObject))
  1206. {
  1207. TRACE0("Warning: CreateStaticFromData failed.\n");
  1208. bResult = FALSE;
  1209. }
  1210. break;
  1211. default:
  1212. ASSERT(selType == pasteNormal);
  1213. if (!pNewItem->CreateFromData(&dataObject))
  1214. {
  1215. TRACE0("Warning: CreateFromData failed.\n");
  1216. bResult = FALSE;
  1217. }
  1218. break;
  1219. }
  1220. // deal with Display As Iconic option
  1221. if (bResult && GetDrawAspect() == DVASPECT_ICON)
  1222. {
  1223. // setup iconic cache (it will draw iconic by default as well)
  1224. if (!pNewItem->SetIconicMetafile(m_ps.hMetaPict))
  1225. {
  1226. TRACE0("Warning: failed to set iconic aspect.\n");
  1227. bResult = FALSE;
  1228. }
  1229. else
  1230. {
  1231. // since picture was set OK, draw as iconic as well...
  1232. pNewItem->SetDrawAspect(DVASPECT_ICON);
  1233. }
  1234. }
  1235. return bResult;
  1236. }
  1237. /////////////////////////////////////////////////////////////////////////////
  1238. // Inline function declarations expanded out-of-line
  1239. #ifndef _AFX_ENABLE_INLINES
  1240. // expand inlines for OLE dialog APIs
  1241. static char _szAfxOleInl[] = "afxole.inl";
  1242. #undef THIS_FILE
  1243. #define THIS_FILE _szAfxOleInl
  1244. #define _AFXODLGS_INLINE
  1245. #include "afxole.inl"
  1246. #endif //!_AFX_ENABLE_INLINES
  1247. #ifdef AFX_INIT_SEG
  1248. #pragma code_seg(AFX_INIT_SEG)
  1249. #endif
  1250. IMPLEMENT_DYNAMIC(COleInsertDialog, COleDialog)
  1251. IMPLEMENT_DYNAMIC(COleConvertDialog, COleDialog)
  1252. IMPLEMENT_DYNAMIC(COleChangeIconDialog, COleDialog)
  1253. IMPLEMENT_DYNAMIC(COleLinksDialog, COleDialog)
  1254. IMPLEMENT_DYNAMIC(COleUpdateDialog, COleLinksDialog)
  1255. IMPLEMENT_DYNAMIC(COlePasteSpecialDialog, COleDialog)
  1256. /////////////////////////////////////////////////////////////////////////////