home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 7 / 07.iso / c / c480 / 18.ddi / MFC / SRC / OLEUI2.CP_ / OLEUI2.CP
Encoding:
Text File  |  1993-02-08  |  15.7 KB  |  619 lines

  1. // This is a part of the Microsoft Foundation Classes C++ library. 
  2. // Copyright (C) 1992 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 Microsoft 
  7. // QuickHelp and/or WinHelp documentation provided with the library. 
  8. // See these sources for detailed information regarding the 
  9. // Microsoft Foundation Classes product. 
  10.  
  11. // OLEUI2.CPP - user interface for OLE clients - Links dialog
  12.  
  13. #include "stdafx.h"
  14. #include <shellapi.h>
  15.  
  16. #ifdef AFX_OLE_SEG
  17. #pragma code_seg(AFX_OLE_SEG)
  18. #endif
  19.  
  20. #ifdef _DEBUG
  21. #undef THIS_FILE
  22. static char BASED_CODE THIS_FILE[] = __FILE__;
  23. #endif
  24.  
  25. /////////////////////////////////////////////////////////////////////////////
  26. // User interface for COleClientItem (with Links)
  27.  
  28. // forward references
  29. static void FormatLinkInfo(COleClientItem* pItem, char* pszInfoBuffer,
  30.         char* pszTypeNameBuffer);
  31.  
  32. /////////////////////////////////////////////////////////////////////////////
  33. // Links dialog
  34.  
  35. class COleLinksDlg : public CDialog
  36. {
  37. public:
  38.     COleClientDoc*  m_pDoc;
  39.     CView*          m_pView;
  40.     COleClientItem* m_pSingleSelection; // NULL if 0 or >1 items selected
  41.     int             m_iSingleSelection; // listbox index (if above is not null)
  42.  
  43.     UINT    m_iVerb1;
  44.     UINT    m_iVerb2;
  45.  
  46.     // could be static members if desired
  47.     CString strEditVerb;
  48.     CString strActivateVerb;
  49.  
  50.     //{{AFX_DATA(COleLinksDlg)
  51.     enum { IDD = AFX_IDD_OLELINKS };
  52.     //}}AFX_DATA
  53.  
  54.     COleLinksDlg(COleClientDoc* pDoc, CView* pView)
  55.         : CDialog(COleLinksDlg::IDD)
  56.     {
  57.         m_pDoc = pDoc;
  58.         m_pView = pView;
  59.         m_pSingleSelection = NULL;
  60.         VERIFY(strEditVerb.LoadString(AFX_IDS_EDIT_VERB));
  61.         VERIFY(strActivateVerb.LoadString(AFX_IDS_ACTIVATE_VERB));
  62.     }
  63.  
  64. protected:
  65.     BOOL OnInitDialog();
  66.     void SetVerbButtons(COleClientItem* pSel);
  67.     void DoVerb(UINT iVerb);
  68.  
  69.     //{{AFX_MSG(COleLinksDlg)
  70.     afx_msg void OnSelectionChange();
  71.     afx_msg void OnVerb1();
  72.     afx_msg void OnVerb2();
  73.     afx_msg void OnAuto();
  74.     afx_msg void OnManual();
  75.     afx_msg void OnUpdate();
  76.     afx_msg void OnFreeze();
  77.     afx_msg void OnChange();
  78.     //}}AFX_MSG
  79.     DECLARE_MESSAGE_MAP()
  80. };
  81.  
  82.  
  83. BEGIN_MESSAGE_MAP(COleLinksDlg, CDialog)
  84.     //{{AFX_MSG_MAP(COleLinksDlg)
  85.     ON_LBN_SELCHANGE(AFX_IDC_LISTBOX, OnSelectionChange)
  86.  
  87.     // control notifications
  88.     ON_COMMAND(AFX_IDC_VERB1, OnVerb1)
  89.     ON_COMMAND(AFX_IDC_VERB2, OnVerb2)
  90.     ON_COMMAND(AFX_IDC_AUTO, OnAuto)
  91.     ON_COMMAND(AFX_IDC_MANUAL, OnManual)
  92.     ON_COMMAND(AFX_IDC_UPDATE, OnUpdate)
  93.     ON_COMMAND(AFX_IDC_FREEZE, OnFreeze)
  94.     ON_COMMAND(AFX_IDC_CHANGE, OnChange)
  95.     //}}AFX_MSG_MAP
  96. END_MESSAGE_MAP()
  97.  
  98. /////////////////////////////////////////////////////////////////////////////
  99. // Initialize - fill in the information
  100.  
  101. BOOL COleLinksDlg::OnInitDialog()
  102. {
  103.     CListBox* pList = (CListBox*)GetDlgItem(AFX_IDC_LISTBOX);
  104.     int cLinks = 0;
  105.  
  106.     // fill with links attached to this object
  107.     pList->ResetContent();
  108.  
  109.     int tabStops[3];    // Tab stops in DLUs
  110.     tabStops[0] = 20;
  111.     tabStops[1] = 80;
  112.     tabStops[2] = 120;
  113.     pList->SetTabStops(3, tabStops);
  114.  
  115.     // enumerate the items in the document
  116.  
  117.     POSITION pos = m_pDoc->GetStartPosition();
  118.     while (pos)
  119.     {
  120.         CDocItem* pItem = m_pDoc->GetNextItem(pos);
  121.         if (pItem->IsKindOf(RUNTIME_CLASS(COleClientItem)) &&
  122.             ((COleClientItem*)pItem)->GetType() == OT_LINK)
  123.         {
  124.             // add it to the listbox
  125.             int iItem;
  126.             char szInfo[OLE_MAXNAMESIZE * 2];       // assume this is enough
  127.  
  128.             FormatLinkInfo((COleClientItem*)pItem, szInfo, NULL);
  129.             if ((iItem = pList->AddString(szInfo)) == -1)
  130.             {
  131.                 TRACE0("Warning: error filling listbox\n");
  132.                 EndDialog(IDABORT);
  133.                 return TRUE;
  134.             }
  135.             
  136.             pList->SetItemDataPtr(iItem, pItem);
  137.             if (m_pView != NULL && m_pView->IsSelected(pItem))
  138.                 pList->SetSel(iItem);
  139.             cLinks++;
  140.         }
  141.     }
  142.  
  143.     if (cLinks == 0)
  144.     {
  145.         TRACE0("Warning: no links in this document\n");
  146.         EndDialog(IDABORT);    // no links after all
  147.         return TRUE;
  148.     }
  149.  
  150.     OnSelectionChange();        // enables buttons etc
  151.     return CDialog::OnInitDialog();
  152. }
  153.  
  154.  
  155. struct LinkOptionsInfo
  156. {
  157.     int             nIDString;                  // IDS_ value to LoadString
  158.     int             nIDCheckButton;             // IDC_ for button to check
  159.     BOOL            bCanChangeLink;             // if can change or freeze
  160. };
  161.  
  162. static void GetLinkUpdateInfo(COleClientItem* pItem, LinkOptionsInfo* pInfo)
  163. {
  164.     // sensible defaults
  165.     pInfo->nIDString = AFX_IDS_FROZEN;
  166.     pInfo->nIDCheckButton = -1;
  167.     pInfo->bCanChangeLink = FALSE;
  168.  
  169.     if (pItem->GetType() != OT_LINK)
  170.         return;     // assume static
  171.  
  172.     switch (pItem->GetLinkUpdateOptions())
  173.     {
  174.     case oleupdate_always:
  175.         pInfo->nIDString = AFX_IDS_AUTO;
  176.         pInfo->nIDCheckButton = AFX_IDC_AUTO;
  177.         pInfo->bCanChangeLink = TRUE;
  178.         break;
  179.  
  180.     case oleupdate_oncall:
  181.         pInfo->nIDString = AFX_IDS_MANUAL;
  182.         pInfo->nIDCheckButton = AFX_IDC_MANUAL;
  183.         pInfo->bCanChangeLink = TRUE;
  184.         break;
  185.  
  186.     default:
  187.         break;      // default already setup (static)
  188.     }
  189. }
  190.  
  191.  
  192. static void FormatLinkInfo(COleClientItem* pItem, char* pszInfoBuffer,
  193.         char* pszTypeNameBuffer)
  194. {
  195.     struct LinkOptionsInfo linkInfo;
  196.     CString strLinkType;
  197.  
  198.     GetLinkUpdateInfo(pItem, &linkInfo);
  199.     VERIFY(strLinkType.LoadString(linkInfo.nIDString));
  200.  
  201.     HGLOBAL hData = pItem->GetLinkFormatData();
  202.     ASSERT(hData != NULL);
  203.     LPCSTR lpszData = (LPCSTR)::GlobalLock(hData); // actually 3 strings
  204.     ASSERT(lpszData != NULL);
  205.  
  206.     if (pszTypeNameBuffer != NULL)
  207.         lstrcpy(pszTypeNameBuffer, lpszData);
  208.  
  209.     if (pszInfoBuffer != NULL)
  210.     {
  211.         // first server class name (use localized name if registered)
  212.         LONG    lSize = OLE_MAXNAMESIZE;
  213.         // get real language class of object in szTypeName for menu
  214.         if (::RegQueryValue(HKEY_CLASSES_ROOT, lpszData, pszInfoBuffer,
  215.             &lSize) != ERROR_SUCCESS)
  216.         {
  217.             // no localized class name, use unlocalized name
  218.             lstrcpy(pszInfoBuffer, lpszData);
  219.         }
  220.         lstrcat(pszInfoBuffer, "\t");
  221.  
  222.         // document and item names
  223.         lpszData += lstrlen(lpszData) + 1;
  224.  
  225.         // strip pathname and drive letter
  226.         LPCSTR lpszTemp = lpszData;
  227.         while (*lpszTemp != '\0')
  228.         {
  229.             if (*lpszTemp == '\\' || *lpszTemp == ':')
  230.                 lpszData = lpszTemp + 1;
  231.             lpszTemp = AnsiNext(lpszTemp);
  232.         }
  233.  
  234.         // Append the file name
  235.         lstrcat(pszInfoBuffer, lpszData);
  236.         lstrcat(pszInfoBuffer, "\t");
  237.  
  238.         // Append the item name
  239.         lpszData += lstrlen(lpszData) + 1;
  240.         lstrcat(pszInfoBuffer, lpszData);
  241.         lstrcat(pszInfoBuffer, "\t");
  242.  
  243.         // Append the type of link, and write it out
  244.         lstrcat(pszInfoBuffer, strLinkType);
  245.     }
  246.  
  247.     ::GlobalUnlock(hData);
  248. }
  249.  
  250. // update button states depending on current selection
  251. void COleLinksDlg::OnSelectionChange()
  252. {
  253.     CListBox* pList = (CListBox*)GetDlgItem(AFX_IDC_LISTBOX);
  254.     int nSelectedLinks = 0;
  255.     int nIDCheck = -1;
  256.     BOOL bCanChangeLink = FALSE;
  257.  
  258.     m_pSingleSelection = NULL;
  259.  
  260.     ASSERT(AFX_IDC_MANUAL == AFX_IDC_AUTO + 1);
  261.     if (pList->GetSelCount() != 0)
  262.     {
  263.         int nTotal = pList->GetCount();
  264.         for (int iItem = 0; iItem < nTotal; iItem++)
  265.         {
  266.             if (pList->GetSel(iItem) <= 0)
  267.                 continue;       // not selected
  268.  
  269.             COleClientItem* pItem;
  270.             pItem = (COleClientItem*)pList->GetItemDataPtr(iItem);
  271.             ASSERT(pItem != NULL);
  272.             struct LinkOptionsInfo linkInfo;
  273.  
  274.             GetLinkUpdateInfo(pItem, &linkInfo);
  275.  
  276.             if (nSelectedLinks++ == 0)
  277.             {
  278.                 // first link
  279.                 nIDCheck = linkInfo.nIDCheckButton;
  280.                 bCanChangeLink = linkInfo.bCanChangeLink;
  281.                 m_pSingleSelection = pItem;
  282.                 m_iSingleSelection = iItem;
  283.             }
  284.             else
  285.             {
  286.                 if (nIDCheck != linkInfo.nIDCheckButton)    // not the same
  287.                     nIDCheck = -1;
  288.  
  289.                 // if multiple links selected - don't allow anything complex
  290.                 if (!linkInfo.bCanChangeLink)
  291.                     bCanChangeLink = FALSE;
  292.                 m_pSingleSelection = NULL;
  293.             }
  294.         }
  295.     }
  296.  
  297.     //BLOCK: do pushbutton verb stuff
  298.     SetVerbButtons(m_pSingleSelection);
  299.  
  300.     // disable if all in selection can be changed
  301.     GetDlgItem(AFX_IDC_UPDATE)->EnableWindow(bCanChangeLink);
  302.     GetDlgItem(AFX_IDC_FREEZE)->EnableWindow(bCanChangeLink);
  303.  
  304.     // simple Change button - only one link at a time
  305.     GetDlgItem(AFX_IDC_CHANGE)->EnableWindow(
  306.         (m_pSingleSelection != NULL) && bCanChangeLink);
  307.  
  308.  
  309.     CheckRadioButton(AFX_IDC_AUTO, AFX_IDC_MANUAL, nIDCheck);
  310.     // disable if nothing selected
  311.     GetDlgItem(AFX_IDC_AUTO)->EnableWindow(nSelectedLinks > 0);
  312.     GetDlgItem(AFX_IDC_MANUAL)->EnableWindow(nSelectedLinks > 0);
  313. }
  314.  
  315. /////////////////////////////////////////////////////////////////////////////
  316. // Standard verb buttons
  317.  
  318. static void SmartChangeButton(CWnd* pButton, const char* pszText, BOOL bEnable)
  319. {
  320.     char szOldText[OLE_MAXNAMESIZE];
  321.  
  322.     // avoid flashing if changing to same text
  323.     pButton->GetWindowText(szOldText, sizeof(szOldText));
  324.     if (lstrcmp(szOldText, pszText) != 0)
  325.         pButton->SetWindowText(pszText);
  326.     pButton->EnableWindow(bEnable);
  327. }
  328.  
  329. static char BASED_CODE szFmtVerbs[] = "%s\\protocol\\StdFileEditing\\verb\\%d";
  330.  
  331. void COleLinksDlg::SetVerbButtons(COleClientItem* pSel)
  332. {
  333.     // defaults for no selection
  334.     const char* pszVerb1 = strActivateVerb;
  335.     BOOL bEnable1 = FALSE;
  336.     const char* pszVerb2 = strEditVerb;
  337.     BOOL bEnable2 = FALSE;
  338.  
  339.     // registered verb names
  340.     char szRegVerb0[OLE_MAXNAMESIZE];
  341.     char szRegVerb1[OLE_MAXNAMESIZE];
  342.  
  343.     ASSERT(OLEVERB_PRIMARY == 0);
  344.     m_iVerb1 = m_iVerb2 = 0;    // usually primary verb
  345.  
  346.     if (pSel != NULL)
  347.     {
  348.         // look at verbs for current selection
  349.         char szTypeName[OLE_MAXNAMESIZE];
  350.         FormatLinkInfo(pSel, NULL, szTypeName);
  351.  
  352.         szRegVerb0[0] = szRegVerb1[0] = '\0';
  353.         int cVerbs = 0;
  354.         while (cVerbs < 2)
  355.         {
  356.             char szBuffer[OLE_MAXNAMESIZE+40];
  357.             wsprintf(szBuffer, szFmtVerbs, (LPCSTR)szTypeName, cVerbs);
  358.  
  359.             // get verb name
  360.             char* pszVerb;
  361.             if (cVerbs == 0)
  362.                 pszVerb = szRegVerb0;
  363.             else
  364.                 pszVerb = szRegVerb1;
  365.             LONG lSize = OLE_MAXNAMESIZE;
  366.             if (::RegQueryValue(HKEY_CLASSES_ROOT, szBuffer,
  367.                pszVerb, &lSize) != 0)
  368.                 break; // finished counting verbs
  369.             cVerbs++;
  370.         }
  371.  
  372.         if (cVerbs == 0)
  373.         {
  374.             // no special verbs, enable generic edit
  375.             bEnable2 = TRUE;
  376.         }
  377.         else if (cVerbs == 1)
  378.         {
  379.             // 1 special verb, special case if 'edit'
  380.             if (lstrcmpi(szRegVerb0, strEditVerb) == 0)
  381.             {
  382.                 // edit goes on second button
  383.                 bEnable2 = TRUE;
  384.             }
  385.             else
  386.             {
  387.                 // other verb goes on top
  388.                 pszVerb1 = szRegVerb0;
  389.                 bEnable1 = TRUE;
  390.             }
  391.         }
  392.         else // 2 verbs
  393.         {
  394.             bEnable1 = bEnable2 = TRUE;
  395.             if (lstrcmpi(szRegVerb0, strEditVerb) == 0)
  396.             {
  397.                 pszVerb1 = szRegVerb1;
  398.                 m_iVerb1 = 1;
  399.                 // verb 2 is already edit
  400.             }
  401.             else if (lstrcmpi(szRegVerb1, strEditVerb) == 0)
  402.             {
  403.                 pszVerb1 = szRegVerb0;
  404.                 // verb 2 is already edit
  405.             }
  406.             else
  407.             {
  408.                 pszVerb1 = szRegVerb0;
  409.                 pszVerb2 = szRegVerb1;
  410.                 m_iVerb2 = 1;
  411.             }
  412.         }
  413.     }
  414.  
  415.     SmartChangeButton(GetDlgItem(AFX_IDC_VERB1), pszVerb1, bEnable1);
  416.     SmartChangeButton(GetDlgItem(AFX_IDC_VERB2), pszVerb2, bEnable2);
  417. }
  418.  
  419. /////////////////////////////////////////////////////////////////////////////
  420.  
  421. void COleLinksDlg::DoVerb(UINT iVerb)
  422. {
  423.     ASSERT(m_pSingleSelection != NULL);
  424.  
  425. #ifdef _DEBUG
  426.     if (afxTraceFlags & 0x10)
  427.         TRACE1("Executing verb %d on server\n", iVerb);
  428. #endif // _DEBUG
  429.  
  430.  
  431.     TRY
  432.         m_pSingleSelection->Activate(iVerb);
  433.     CATCH (COleException, e)
  434.         m_pSingleSelection->ReportOleError(e->m_status);
  435.     END_CATCH
  436.  
  437.     // End the dialog after launch
  438.     EndDialog(IDOK);
  439. }
  440.  
  441. void COleLinksDlg::OnVerb1()
  442. {
  443.     DoVerb(m_iVerb1);
  444. }
  445.  
  446. void COleLinksDlg::OnVerb2()
  447. {
  448.     DoVerb(m_iVerb2);
  449. }
  450.  
  451. #define FOR_EACH_SELECTED_ITEM(pItem)   \
  452.     CListBox* _pList = (CListBox*)GetDlgItem(AFX_IDC_LISTBOX);      \
  453.     int _nTotal = _pList->GetCount();                               \
  454.     for (int _iItem = 0; _iItem < _nTotal; _iItem++)                \
  455.     {                                                               \
  456.         if (_pList->GetSel(_iItem) <= 0)                            \
  457.             continue;       /* not selected */                      \
  458.         COleClientItem* pItem;                                      \
  459.         pItem = (COleClientItem*)_pList->GetItemDataPtr(_iItem);\
  460.         ASSERT(pItem != NULL);
  461.  
  462. #define UPDATE_SELECTED(pItem)  \
  463.         UpdateSelectedItem(_pList, pItem, _iItem)
  464.  
  465. #define DELETE_SELECTED()       \
  466.         _pList->DeleteString(_iItem);                   \
  467.         _iItem--;   /* for next in the loop */          \
  468.         _nTotal--;  /* for next in the loop */
  469.  
  470. #define END_EACH_SELECTED_ITEM()    \
  471.     }
  472.  
  473.  
  474. static void UpdateSelectedItem(CListBox* pList,
  475.     COleClientItem* pItem, int iItem)
  476. {
  477.     char szInfo[OLE_MAXNAMESIZE * 2];
  478.     FormatLinkInfo(pItem, szInfo, NULL);
  479.     pList->DeleteString(iItem);
  480.     pList->InsertString(iItem, szInfo);
  481.     pList->SetItemDataPtr(iItem, pItem);
  482.     pList->SetSel(iItem);
  483. }
  484.  
  485.  
  486. void COleLinksDlg::OnAuto()
  487. {
  488.     FOR_EACH_SELECTED_ITEM(pItem)
  489.     {
  490.         pItem->SetLinkUpdateOptions(oleupdate_always);
  491.         UPDATE_SELECTED(pItem);
  492.     }
  493.     END_EACH_SELECTED_ITEM()
  494. }
  495.  
  496. void COleLinksDlg::OnManual()
  497. {
  498.     FOR_EACH_SELECTED_ITEM(pItem)
  499.     {
  500.         pItem->SetLinkUpdateOptions(oleupdate_oncall);
  501.         UPDATE_SELECTED(pItem);
  502.     }
  503.     END_EACH_SELECTED_ITEM()
  504. }
  505.  
  506. void COleLinksDlg::OnUpdate()
  507. {
  508.     FOR_EACH_SELECTED_ITEM(pItem)
  509.     {
  510.         TRY
  511.             pItem->UpdateLink();
  512.         CATCH (COleException, e)
  513.             pItem->ReportOleError(e->m_status);
  514.         END_CATCH
  515.     }
  516.     END_EACH_SELECTED_ITEM()
  517. }
  518.  
  519. void COleLinksDlg::OnFreeze()
  520. {
  521.     FOR_EACH_SELECTED_ITEM(pItem)
  522.     {
  523.         TRY
  524.         {
  525.             if (pItem->FreezeLink(pItem->GetName()))
  526.             {
  527.                 DELETE_SELECTED();
  528.             }
  529.             else
  530.             {
  531.                 pItem->ReportOleError(OLE_ERROR_COMM);     // strange error
  532.             }
  533.         }
  534.         CATCH(COleException, e)
  535.         {
  536.             pItem->ReportOleError(OLE_ERROR_COMM);     // strange error
  537.         }
  538.         END_CATCH
  539.     }
  540.     END_EACH_SELECTED_ITEM()
  541.  
  542.     if (_pList->GetCount() == 0)
  543.         EndDialog(IDOK);
  544. }
  545.  
  546. void COleLinksDlg::OnChange()
  547. {
  548.     // We only support changing of one item at a time
  549.     //  The full UISG UI includes more complicated functionality
  550.     COleClientItem* pItem = m_pSingleSelection;
  551.     ASSERT(pItem != NULL);
  552.     ASSERT(pItem->GetType() == OT_LINK);
  553.  
  554.     HGLOBAL hData = pItem->GetLinkFormatData();
  555.     ASSERT(hData != NULL);
  556.     LPCSTR lpszData = (LPCSTR)::GlobalLock(hData);
  557.     ASSERT(lpszData != NULL);
  558.  
  559.     UINT cbTypeName = lstrlen(lpszData);
  560.     LPCSTR lpszDoc = lpszData + cbTypeName + 1;
  561.     LPCSTR lpszItems = lpszDoc + lstrlen(lpszDoc) + 1;
  562.  
  563.     char szPath[_MAX_PATH];
  564.     lstrcpy(szPath, lpszDoc);
  565.  
  566.     CString title;
  567.     CString filter;
  568.     CFileDialog dlgFile(TRUE, NULL, szPath, 
  569.             OFN_HIDEREADONLY | OFN_FILEMUSTEXIST | OFN_NOCHANGEDIR, 
  570.             (filter.LoadString(AFX_IDS_ALL_FILES) ? (LPCSTR)filter : NULL),
  571.             this);
  572.  
  573.     if (title.LoadString(AFX_IDS_CHANGE_LINK))
  574.         dlgFile.m_ofn.lpstrTitle = title;
  575.  
  576.     dlgFile.m_ofn.lpstrFile = (LPSTR)szPath; // just fill in my own buffer
  577.  
  578.     if (dlgFile.DoModal() != IDOK)
  579.         return;
  580.  
  581.     // change the path name
  582.     HGLOBAL hNewData = ::GlobalAlloc(GMEM_DDESHARE | GMEM_ZEROINIT,
  583.         cbTypeName + 1 + lstrlen(szPath) + 1 + lstrlen(lpszItems) + 1 + 1);
  584.     if (hNewData == NULL)
  585.     {
  586.         pItem->ReportOleError(OLE_ERROR_MEMORY);
  587.         return;
  588.     }
  589.     LPSTR lpszNew = (LPSTR)::GlobalLock(hNewData);
  590.     ASSERT(lpszNew != NULL);
  591.  
  592.     // copy the old class name, new doc name and old item names
  593.     lstrcpy(lpszNew, lpszData);
  594.     lpszNew += cbTypeName + 1;
  595.     lstrcpy(lpszNew, szPath);
  596.     lpszNew += lstrlen(lpszNew) + 1;
  597.     lstrcpy(lpszNew, lpszItems);
  598.     lpszNew += lstrlen(lpszNew) + 1;
  599.     *lpszNew = '\0';        // terminate it
  600.  
  601.     pItem->SetData((OLECLIPFORMAT)afxData.cfObjectLink, hNewData);
  602.     // update the selection in the listbox
  603.     UpdateSelectedItem((CListBox*)GetDlgItem(AFX_IDC_LISTBOX),
  604.         m_pSingleSelection, m_iSingleSelection);
  605. }
  606.  
  607.  
  608. /////////////////////////////////////////////////////////////////////////////
  609. // Public interface for running modal dialog
  610.  
  611. BOOL AFXAPI AfxOleLinksDialog(COleClientDoc* pDoc, CView* pView)
  612. {
  613.     COleLinksDlg dlg(pDoc, pView);
  614.  
  615.     return (dlg.DoModal() == IDOK);
  616. }
  617.  
  618. /////////////////////////////////////////////////////////////////////////////
  619.