home *** CD-ROM | disk | FTP | other *** search
/ Supercompiler 1997 / SUPERCOMPILER97.iso / MS_VC.50 / VC / MFC / SRC / OLEDLGS1.CPP < prev    next >
Encoding:
C/C++ Source or Header  |  1996-10-30  |  34.4 KB  |  1,326 lines

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