home *** CD-ROM | disk | FTP | other *** search
/ C Programming Starter Kit 2.0 / SamsPublishing-CProgrammingStarterKit-v2.0-Win31.iso / bc45 / owlsrc.pak / LINKS.CPP < prev    next >
C/C++ Source or Header  |  1997-07-23  |  32KB  |  1,306 lines

  1. //----------------------------------------------------------------------------
  2. // ObjectWindows
  3. // (C) Copyright 1991, 1994 by Borland International, All Rights Reserved
  4. //
  5. //----------------------------------------------------------------------------
  6. #define INC_OLE2
  7. #include <owl/owlpch.h>
  8. #include <owl/listbox.h>
  9. #include <owl/radiobut.h>
  10. #include <owl/edit.h>
  11. #include <ocf/ocview.h>
  12. #include <owl/oledlg.h>
  13. #include <owl/except.h>
  14. #include <bwcc.h>   // for IDHELP
  15. #include <dir.h>
  16.  
  17. static char szNULL[] = "";
  18. DEFINE_GUID(IID_IOleUILinkContainer, 0x000004FF, 0x0000, 0x0000, 0xC0, 0x00,
  19.                          0x00, 0x00, 0x00, 0x00, 0x00, 0x46);
  20.  
  21. //
  22. // OWL OLE Dialog diagnostic group.
  23. //
  24. DIAG_DECLARE_GROUP(OwlOleDlg);
  25.  
  26.  
  27. //
  28. // Constructor of customized (for validation) FileOpen dialog
  29. //
  30. TEditLinksDlg::TChgSrcFileOpenDlg::TChgSrcFileOpenDlg(TWindow* parent,
  31.                                                       TData&   data,
  32.                                                       TChgSrcData& chgSrcData,
  33.                                                       TResId   templateId,
  34.                                                       const char far* title,
  35.                                                       TModule* module)
  36. :
  37.   TFileOpenDialog(parent, data, templateId, title, module),
  38.   ChgSrcData(chgSrcData), Helper(*new THelper)
  39. {
  40. }
  41.  
  42.  
  43.  
  44. //
  45. // Cleanup memory allocated
  46. //
  47. TEditLinksDlg::TChgSrcFileOpenDlg::~TChgSrcFileOpenDlg()
  48. {
  49.   delete &Helper;
  50. }
  51.  
  52.  
  53. //
  54. // Initializes custom FileOpen dialog
  55. //
  56. void TEditLinksDlg::TChgSrcFileOpenDlg::SetupWindow()
  57. {
  58.   TLinkInfo far* lpLinkInfo = ChgSrcData.lpLI;
  59.  
  60.   Helper.bFileNameStored = true;
  61.   Helper.bItemNameStored = true;
  62.   if (lpLinkInfo->lpszDisplayName) {
  63.     strcpyn(Helper.szFileName, lpLinkInfo->lpszDisplayName, MaxPathLen);
  64.     strcpyn(Helper.szEdit, lpLinkInfo->lpszDisplayName, MaxPathLen);
  65.   }
  66.   if (lpLinkInfo->lpszItemName) {
  67.     strcpyn(Helper.szItemName, lpLinkInfo->lpszItemName, MaxPathLen);
  68.   }
  69. }
  70.  
  71.  
  72. //
  73. // Builds a TEditLinksDlg::TData using a TOcView - retrieves
  74. // Bolero's implemetation of the IOLEUILinkContainer interface.
  75. //
  76. TEditLinksDlg::TData::TData(const TOcView& ocView)
  77. {
  78.   dwFlags = elShowHelp;
  79.  
  80.   //
  81.   // Retrieve BOLERO's IOLEUILinkContainer Interface
  82.   //
  83.   lpOleUILinkContainer = 0;
  84.   CONST_CAST(TOcView*, &ocView)->QueryInterface(IID_IOleUILinkContainer,
  85.                                 &(LPVOID)lpOleUILinkContainer);
  86. }
  87.  
  88.  
  89. //
  90. // Release Bolero's IOLEUILinkContainer Interface
  91. //
  92. TEditLinksDlg::TData::~TData()
  93. {
  94.   //
  95.   // Release BOLERO's IOLEUILinkContainer Interface
  96.   //
  97.   if (lpOleUILinkContainer)
  98.     lpOleUILinkContainer->Release();
  99. }
  100.  
  101.  
  102. //
  103. // Constructor of structure which keeps track of the state of
  104. // a particular link.
  105. // NOTE: The 'link' parameter is a container-defined unique
  106. //       identifier for each link - Bolero provides this
  107. //       value.
  108. //
  109. TEditLinksDlg::TLinkInfo::TLinkInfo(DWORD link)
  110. {
  111.   dwLink            = link;
  112.   lpszDisplayName   = 0;
  113.   lpszItemName      = 0;
  114.   lpszShortFileName = 0;
  115.   lpszShortLinkType = 0;
  116.   lpszFullLinkType  = 0;
  117.   clenFileName      = 0;
  118.   fSourceAvailable  = false;
  119.   fIsAuto           = false;
  120.   fIsMarked         = false;
  121.   fDontFree         = false;
  122.   fIsSelected       = false;
  123.  
  124.   lpszAMX    = new char[LinkTypeLen+1];
  125.   lpszAMX[0] = 0;
  126. }
  127.  
  128.  
  129. //
  130. // Cleanup memory.
  131. //
  132. TEditLinksDlg::TLinkInfo::~TLinkInfo()
  133. {
  134.   if (lpszAMX)
  135.    delete []lpszAMX;
  136. }
  137.  
  138.  
  139. //
  140. // Initialized Helper object used internally by TEditLinksDlg
  141. //
  142. TEditLinksDlg::THelper::THelper()
  143. {
  144.   //
  145.   // Use memset to initialize private PODS
  146.   //
  147.   memset(this, 0, sizeof(THelper));
  148. }
  149.  
  150.  
  151. //
  152. // Initializes data structure for Custom FileOpen dialog.
  153. //
  154. TEditLinksDlg::TChgSrcFileOpenDlg::TChgSrcData::TChgSrcData(TLinkInfo far* li,
  155.                                              TEditLinksDlg::TData& data) :
  156.                                              Data(data)
  157. {
  158.   lpLI = li;
  159.   lpszFrom = 0;
  160.   lpszTo   = 0;
  161.   fValidLink = false;
  162. }
  163.  
  164.  
  165. DEFINE_RESPONSE_TABLE1(TEditLinksDlg, TOleDialog)
  166.   EV_WM_COMPAREITEM,
  167.   EV_WM_DRAWITEM,
  168.   EV_WM_DELETEITEM,
  169.   EV_WM_MEASUREITEM,
  170.   EV_BN_CLICKED(IDC_CHANGESOURCE, ChangeSourceClicked),
  171.   EV_BN_CLICKED(IDC_AUTOMATIC, AutomaticClicked),
  172.   EV_BN_CLICKED(IDC_MANUAL, ManualClicked),
  173.   EV_BN_CLICKED(IDC_BREAKLINK, BreakLinkClicked),
  174.   EV_BN_CLICKED(IDC_UPDATENOW, UpdateNowClicked),
  175.   EV_BN_CLICKED(IDC_OPENSOURCE, OpenSourceClicked),
  176. END_RESPONSE_TABLE;
  177.  
  178.  
  179. //
  180. //
  181. //
  182. TEditLinksDlg::TEditLinksDlg(TWindow* parent,
  183.                              const TOcView &ocView,
  184.                              TResId templateId,
  185.                              const char far* title,
  186.                              TModule* module):
  187.                TOleDialog(parent,
  188.                           templateId ? templateId : TResId(DLG_EDITLINKS),
  189.                           title, module), Helper(*new THelper)
  190. {
  191.   LinksList     = new TListBox(this, IDC_LINKLIST);
  192.   UpdateBtn     = new TButton(this, IDC_UPDATENOW);
  193.   OpenBtn       = new TButton(this, IDC_OPENSOURCE);
  194.   ChangeBtn     = new TButton(this, IDC_CHANGESOURCE);
  195.   BreakLinkBtn  = new TButton(this, IDC_BREAKLINK);
  196.   Automatic     = new TRadioButton(this, IDC_AUTOMATIC);
  197.   Manual        = new TRadioButton(this, IDC_MANUAL);
  198.   LinkSource    = new TStatic(this, IDC_SOURCE);
  199.   LinkType      = new TStatic(this, IDC_TYPE);
  200.   Help          = new TButton(this, IDHELP);
  201.   Cancel        = new TButton(this, IDCANCEL);
  202.   Data          = new TData(ocView);
  203.  
  204.   nMaxCharWidth = 0;
  205.   nHeightLine   = 0;
  206. }
  207.  
  208.  
  209. //
  210. // Cleanup objects allocated
  211. //
  212. TEditLinksDlg::~TEditLinksDlg()
  213. {
  214.   delete Data;
  215.   delete &Helper;
  216. }
  217.  
  218.  
  219. //
  220. //
  221. //
  222. bool
  223. TEditLinksDlg::EvInitDialog(HWND hwndFocus)
  224. {
  225.   //
  226.   // Chain to base allow control aliasing
  227.   //
  228.   TOleDialog::EvInitDialog(hwndFocus);
  229.  
  230.   //
  231.   // Compute column position of listbox
  232.   //
  233.   TRect rect;
  234.   LinksList->GetWindowRect(rect);
  235.  
  236.   int nStart = rect.left;
  237.   ::GetWindowRect(GetDlgItem(IDC_COL1), &rect);
  238.   nColPos[0] = rect.left - nStart;
  239.  
  240.   ::GetWindowRect(GetDlgItem(IDC_COL2), &rect);
  241.   nColPos[1] = rect.left - nStart;
  242.  
  243.   ::GetWindowRect(GetDlgItem(IDC_COL3), &rect);
  244.   nColPos[2] = rect.left - nStart;
  245.  
  246.   //
  247.   // Fill listbox with
  248.   //
  249.   Helper.fItemsExist = LoadLinkLB() ? true : false;
  250.  
  251.   //
  252.   //
  253.   //
  254.   InitControls();
  255.  
  256.   //
  257.   // Hide/Disable controls based on flag settings
  258.   //
  259.   if  (!(Data->dwFlags & elShowHelp))
  260.     Activate(Help, false);
  261.  
  262.   if (Data->dwFlags & elDisableUpdateNow)
  263.     Activate(UpdateBtn, false);
  264.  
  265.   if (Data->dwFlags & elDisableOpenSource)
  266.     Activate(OpenBtn, false);
  267.  
  268.   if (Data->dwFlags & elDisableChangeSource)
  269.     Activate(ChangeBtn, false);
  270.  
  271.   if (Data->dwFlags & elDisableCancelLink)
  272.     Activate(BreakLinkBtn, false);
  273.  
  274.   //
  275.   // Retrieve 'Close' string to rename CANCEL button
  276.   //
  277.   GetModule()->LoadString(IDS_CLOSE, Helper.szClose, sizeof(Helper.szClose));
  278.  
  279.   //
  280.   // Set focus to listbox if we have links
  281.   //
  282.   if (Helper.fItemsExist > 0)
  283.     LinksList->SetFocus();
  284.   else
  285.     ::SetFocus(GetDlgItem(IDCANCEL));
  286.  
  287.   return false;
  288. }
  289.  
  290.  
  291. //
  292. //
  293. //
  294. int
  295. TEditLinksDlg::DoExecute()
  296. {
  297.   return TDialog::DoExecute();
  298. }
  299.  
  300.  
  301. //
  302. //
  303. //
  304. void
  305. TEditLinksDlg::EvMeasureItem(uint ctlId, MEASUREITEMSTRUCT far& measureInfo)
  306. {
  307.   if (ctlId != IDC_LINKLIST) {
  308.     TOleDialog::EvMeasureItem(ctlId, measureInfo);
  309.     return;
  310.   }
  311.  
  312.   HFONT hFont = GetWindowFont();
  313.   if (!hFont)
  314.     hFont = (HFONT)GetStockObject(SYSTEM_FONT);
  315.  
  316.   TFont font(hFont);
  317.   TClientDC hdc(*this);
  318.   hdc.SelectObject(font);
  319.  
  320.   TEXTMETRIC tm;
  321.   hdc.GetTextMetrics(tm);
  322.  
  323.   measureInfo.itemHeight = tm.tmHeight;
  324.   nHeightLine   = tm.tmHeight;
  325.   nMaxCharWidth = tm.tmMaxCharWidth;
  326.  
  327.   hdc.RestoreFont();
  328. }
  329.  
  330.  
  331. //
  332. //
  333. //
  334. int
  335. TEditLinksDlg::LBPad() const
  336. {
  337.   return nMaxCharWidth > 0 ? nMaxCharWidth : 5;
  338. }
  339.  
  340.  
  341. //
  342. //
  343. //
  344. void
  345. TEditLinksDlg::EvDrawItem(uint ctlId, DRAWITEMSTRUCT far& drawInfo)
  346. {
  347.   if (ctlId != IDC_LINKLIST) {
  348.     TOleDialog::EvDrawItem(ctlId, drawInfo);
  349.     return;
  350.   }
  351.  
  352.   if ((int)drawInfo.itemID < 0)
  353.     return;
  354.  
  355.   if (drawInfo.itemAction & (ODA_DRAWENTIRE | ODA_SELECT))
  356.     DrawLinksListEntry(drawInfo);
  357.  
  358.   InitControls();
  359.  
  360.   if (drawInfo.itemAction & ODA_FOCUS)  {
  361.     DrawFocusRect(drawInfo.hDC, &drawInfo.rcItem);
  362.   }
  363. }
  364.  
  365.  
  366. //
  367. //
  368. //
  369. void
  370. TEditLinksDlg::DrawLinksListEntry(DRAWITEMSTRUCT far& drawInfo)
  371. {
  372.   TDC dc(drawInfo.hDC);
  373.   TLinkInfo* lpLinkInfo = (TLinkInfo*)drawInfo.itemData;
  374.  
  375.   //
  376.   // Update selection flag and set text color (if selected)
  377.   //
  378.   TColor oldTxtColor;
  379.   if (drawInfo.itemState & ODS_SELECTED) {
  380.     oldTxtColor = dc.SetTextColor(TColor(GetSysColor(COLOR_HIGHLIGHTTEXT)));
  381.     lpLinkInfo->fIsSelected = true;
  382.   }
  383.   else {
  384.     lpLinkInfo->fIsSelected = false;
  385.   }
  386.  
  387.   //
  388.   // Fill background
  389.   //
  390.   TBrush brush(GetSysColor(drawInfo.itemState & ODS_SELECTED ? COLOR_HIGHLIGHT :
  391.                                           COLOR_WINDOW));
  392.   dc.FillRect(drawInfo.rcItem, brush);
  393.  
  394.   //
  395.   // Set transparent mode
  396.   //
  397.   int oldMode;
  398.   oldMode = dc.SetBkMode(TRANSPARENT);
  399.  
  400.   TRect rcClip;
  401.   char* pStr;
  402.   char str[MaxPathLen];
  403.   if (lpLinkInfo->lpszDisplayName) {
  404.     strcpy(str, lpLinkInfo->lpszDisplayName);
  405.     pStr = ChopText(*LinksList, nColPos[1] - nColPos[0] - LBPad(), str);
  406.  
  407.     rcClip = drawInfo.rcItem;
  408.     rcClip.left  += nColPos[0];
  409.     rcClip.right  = drawInfo.rcItem.left + (nColPos[1] - LBPad());
  410.  
  411.     dc.ExtTextOut(rcClip.left, rcClip.top, ETO_CLIPPED, &rcClip, pStr,
  412.                   strlen(pStr));
  413.   }
  414.  
  415.   if (lpLinkInfo->lpszShortLinkType) {
  416.     rcClip = drawInfo.rcItem;
  417.     rcClip.left += nColPos[1];
  418.     rcClip.right = drawInfo.rcItem.left + nColPos[2] - LBPad();
  419.     dc.ExtTextOut(rcClip.left, rcClip.top, ETO_CLIPPED, &rcClip,
  420.                   lpLinkInfo->lpszShortLinkType,
  421.                   strlen(lpLinkInfo->lpszShortLinkType));
  422.   }
  423.  
  424.   if (lpLinkInfo->lpszAMX) {
  425.     rcClip = drawInfo.rcItem;
  426.     rcClip.left += nColPos[2];
  427.     dc.ExtTextOut(rcClip.left, rcClip.top, ETO_CLIPPED, &rcClip,
  428.                   lpLinkInfo->lpszAMX, strlen(lpLinkInfo->lpszAMX));
  429.   }
  430.  
  431.   //
  432.   // Restore DC attributes
  433.   //
  434.   dc.SetBkMode(oldMode);
  435.   if (drawInfo.itemState & ODS_SELECTED)
  436.     dc.SetTextColor(oldTxtColor);
  437. }
  438.  
  439.  
  440. //
  441. //
  442. //
  443. LRESULT
  444. TEditLinksDlg::EvCompareItem(uint ctlid, COMPAREITEMSTRUCT far& compareInfo)
  445. {
  446.   if (ctlid != IDC_LINKLIST) {
  447.     return TOleDialog::EvCompareItem(ctlid, compareInfo);
  448.   }
  449.  
  450.   TLinkInfo* lpLI1 = (TLinkInfo*)compareInfo.itemData1;
  451.   TLinkInfo* lpLI2 = (TLinkInfo*)compareInfo.itemData2;
  452.  
  453.   if (lpLI1->lpszDisplayName  && lpLI2->lpszDisplayName)
  454.     return strcmp(lpLI1->lpszDisplayName, lpLI2->lpszDisplayName);
  455.  
  456.   return 0;
  457. }
  458.  
  459.  
  460. //
  461. //
  462. //
  463. void
  464. TEditLinksDlg::EvDeleteItem(uint ctlid, DELETEITEMSTRUCT far& deleteInfo)
  465. {
  466.   if (ctlid != IDC_LINKLIST) {
  467.     TOleDialog::EvDeleteItem(ctlid, deleteInfo);
  468.     return;
  469.   }
  470.  
  471.   TLinkInfo* lpLinkInfo = (TLinkInfo*)deleteInfo.itemData;
  472.  
  473.   if (lpLinkInfo->lpszDisplayName)
  474.     delete []lpLinkInfo->lpszDisplayName;
  475.  
  476.   if (lpLinkInfo->lpszShortLinkType)
  477.     delete []lpLinkInfo->lpszShortLinkType;
  478.  
  479.   if (lpLinkInfo->lpszFullLinkType)
  480.     delete []lpLinkInfo->lpszFullLinkType;
  481.  
  482.   if (lpLinkInfo->fDontFree)
  483.     lpLinkInfo->fDontFree = false;
  484.   else
  485.     delete lpLinkInfo;
  486. }
  487.  
  488.  
  489. //
  490. // Handles ChangeSource button by displaying a customized version
  491. // of FileOpen dialog with the LinkName.
  492. //
  493. void
  494. TEditLinksDlg::ChangeSourceClicked()
  495. {
  496.   if (!Container_ChangeSource())
  497.     PopupMessage(IDS_FAILED, IDS_LINKS, MB_ICONEXCLAMATION|MB_OK);
  498.   InitControls();
  499. }
  500.  
  501.  
  502. //
  503. // Sets a Link [or Links for multiple selections] to automatic
  504. //
  505. void
  506. TEditLinksDlg::AutomaticClicked()
  507. {
  508.   CheckDlgButton(IDC_AUTOMATIC, BF_CHECKED);
  509.   CheckDlgButton(IDC_MANUAL, BF_UNCHECKED);
  510.  
  511.   if (Container_AutomaticManual(true) != NOERROR)
  512.     PopupMessage(IDS_FAILED, IDS_LINKS, MB_ICONEXCLAMATION|MB_OK);
  513.  
  514.   InitControls();
  515. }
  516.  
  517.  
  518. //
  519. // Set Link [or Links for multiple selections] to manual
  520. //
  521. void
  522. TEditLinksDlg::ManualClicked()
  523. {
  524.   CheckDlgButton(IDC_MANUAL, BF_CHECKED);
  525.   CheckDlgButton(IDC_AUTOMATIC, BF_UNCHECKED);
  526.  
  527.   if (Container_AutomaticManual(false) != NOERROR)
  528.     PopupMessage(IDS_FAILED, IDS_LINKS, MB_ICONEXCLAMATION|MB_OK);
  529.  
  530.   InitControls();
  531. }
  532.  
  533.  
  534. //
  535. // Breaks the Link.
  536. // NOTE: Object retains its data and becomes a static object
  537. //
  538. void
  539. TEditLinksDlg::BreakLinkClicked()
  540. {
  541.   CancelLink();
  542.   InitControls();
  543. }
  544.  
  545.  
  546. //
  547. // Causes immediate update of Link(s). Will start Servers if necessary.
  548. //
  549. void
  550. TEditLinksDlg::UpdateNowClicked()
  551. {
  552.   Container_UpdateNow();
  553.   InitControls();
  554. }
  555.  
  556.  
  557. //
  558. // Open the current selection.
  559. // NOTE: This options causes the dialog to close.
  560. //
  561. void
  562. TEditLinksDlg::OpenSourceClicked()
  563. {
  564.   if (Container_OpenSource() != NOERROR)
  565.     InitControls();
  566.   else  {
  567.     //
  568.     // Terminate dialog by simulating an OK
  569.     //
  570.     SendNotification(IDOK, BN_CLICKED, GetDlgItem(IDOK));
  571.   }
  572. }
  573.  
  574.  
  575. //
  576. //
  577. //
  578. bool
  579. TEditLinksDlg::ChangeSource(char* file,
  580.                             TChgSrcFileOpenDlg::TChgSrcData& chgSrcData,
  581.                             uint filterId)
  582. {
  583.   if (!file)
  584.    return false;
  585.  
  586.   //
  587.   // Load Filter(s) string
  588.   //
  589.   char* pFilter = 0;
  590.   TPointer<char> filters = new char[MaxPathLen];
  591.   if (GetModule()->LoadString(filterId, filters, MaxPathLen))
  592.     pFilter = filters;
  593.  
  594.   //
  595.   // Load Title string
  596.   //
  597.   char* pTitle = 0;
  598.   TPointer<char> title = new char[MaxPathLen];
  599.   if (GetModule()->LoadString(IDS_CHANGESOURCE, title, MaxPathLen))
  600.     pTitle = title;
  601.  
  602.   //
  603.   // Attempt to retrieve initial directory from file name
  604.   //
  605.   char *pInitDir = 0;
  606.   char *initDir = new char[MaxPathLen];
  607.   TPointer<char> _cln(initDir);
  608.   strcpyn(initDir, file, MaxPathLen);
  609.   for (int i=strlen(initDir)-1; i>=0; i--) {
  610.     if ((initDir[i]=='\\') || (initDir[i]==':') || (initDir[i]=='/'))
  611.       break;
  612.   }
  613.   if (i > 0) {
  614.     initDir[i] = 0;
  615.     pInitDir  = initDir;
  616.   }
  617.  
  618.   //
  619.   // Execute customized fileOpen dialog
  620.   //
  621.   TPointer<TOpenSaveDialog::TData> data =
  622.       new TOpenSaveDialog::TData(OFN_NOVALIDATE|OFN_HIDEREADONLY,
  623.                                  pFilter, 0, pInitDir);
  624.  
  625.   TChgSrcFileOpenDlg foDlg(this, *data, chgSrcData,
  626.                            TResId(DLG_FILEOPEN), pTitle);
  627.   if (foDlg.Execute()==IDOK) {
  628.     return true;
  629.   }
  630.   return false;
  631. }
  632.  
  633.  
  634. //
  635. // Allows user to change Links using a customized FileOpen dialog.
  636. //
  637. bool
  638. TEditLinksDlg::Container_ChangeSource()
  639. {
  640.   int* rgIndex  = 0;
  641.   int cSelItems = GetSelectedItems(rgIndex);
  642.  
  643.   if (cSelItems < 0)
  644.     return false;
  645.  
  646.   if (!cSelItems)
  647.     return true;
  648.  
  649.   if (!Helper.fClose) {
  650.     Cancel->SetWindowText(Helper.szClose);
  651.     Helper.fClose = true;
  652.   }
  653.  
  654.   TLinkInfo FAR *lpLinkInfo;
  655.   for( int i=cSelItems-1; i>=0; i--) {
  656.     //
  657.     // Retrieve link information
  658.     //
  659.     LinksList->HandleMessage(LB_GETTEXT, rgIndex[i],
  660.                             (LPARAM)(TLinkInfo far*)&lpLinkInfo);
  661.  
  662.     //
  663.     // Data for dialog
  664.     //
  665.     TChgSrcFileOpenDlg::TChgSrcData chgSrcData(lpLinkInfo, *Data);
  666.  
  667.     if (!ChangeSource(lpLinkInfo->lpszDisplayName,
  668.                       chgSrcData, IDS_FILTERS)) {
  669.       //
  670.       // The Cancel button was probably pressed - Stop processing
  671.       // for all remaining links
  672.       //
  673.       delete []rgIndex;
  674.       return true;
  675.     }
  676.  
  677.     UpdateLinkLBItem(rgIndex[i], true);
  678.  
  679.     if (chgSrcData.lpszFrom  && chgSrcData.lpszTo) {
  680.       ChangeAllLinks(chgSrcData.lpszFrom, chgSrcData.lpszTo);
  681.  
  682.       //! BB - Need to free lpszFrom and lpszTo???
  683.     }
  684.   }
  685.  
  686.   delete []rgIndex;
  687.   return true;
  688. }
  689.  
  690.  
  691. //
  692. //
  693. //
  694. HRESULT
  695. TEditLinksDlg::Container_AutomaticManual(bool fAutoMan)
  696. {
  697.   HRESULT hErr  = NOERROR;
  698.   int* rgIndex  = 0;
  699.   int cSelItems = GetSelectedItems(rgIndex);
  700.  
  701.   if (cSelItems < 0)
  702.     return ResultFromScode(E_FAIL);
  703.  
  704.   if (!cSelItems)
  705.     return NOERROR;
  706.  
  707.   if (!Helper.fClose) {
  708.     Cancel->SetWindowText(Helper.szClose);
  709.     Helper.fClose = true;
  710.   }
  711.  
  712.   bool bUpdate = false;
  713.   TLinkInfo*  lpLinkInfo;
  714.   LPOLEUILINKCONTAINER lpLnkCntnr = Data->lpOleUILinkContainer;
  715.  
  716.   for (int i=0; i < cSelItems; i++) {
  717.     LinksList->HandleMessage(LB_GETTEXT, rgIndex[i],
  718.                             (LPARAM)(TLinkInfo far*)&lpLinkInfo);
  719.     if (fAutoMan) {
  720.       if (!lpLinkInfo->fIsAuto) {
  721.         hErr = lpLnkCntnr->SetLinkUpdateOptions(lpLinkInfo->dwLink,
  722.                                                 OLEUPDATE_ALWAYS);
  723.         lpLinkInfo->fIsAuto = true;
  724.         lpLinkInfo->fIsMarked = true;
  725.         bUpdate = true;
  726.       }
  727.     }
  728.     else {
  729.       if (lpLinkInfo->fIsAuto) {
  730.         hErr = lpLnkCntnr->SetLinkUpdateOptions(lpLinkInfo->dwLink,
  731.                                                 OLEUPDATE_ONCALL);
  732.         lpLinkInfo->fIsAuto = false;
  733.         lpLinkInfo->fIsMarked = true;
  734.         bUpdate = true;
  735.       }
  736.     }
  737.   }
  738.  
  739.   if (bUpdate)
  740.     RefreshLinkLB();
  741.  
  742.   if (rgIndex)
  743.     delete []rgIndex;
  744.  
  745.   return hErr;
  746. }
  747.  
  748.  
  749. HRESULT
  750. TEditLinksDlg::CancelLink()
  751. {
  752.   HRESULT hErr  = NOERROR;
  753.   int* rgIndex  = 0;
  754.   int cSelItems = GetSelectedItems(rgIndex);
  755.  
  756.   if (cSelItems < 0)
  757.     return ResultFromScode(E_FAIL);
  758.  
  759.   if (!cSelItems)
  760.     return NOERROR;
  761.  
  762.   if (!Helper.fClose) {
  763.     Cancel->SetWindowText(Helper.szClose);
  764.     Helper.fClose = true;
  765.   }
  766.  
  767.   bool bUpdate = false;
  768.   TLinkInfo* lpLinkInfo;
  769.   LPOLEUILINKCONTAINER lpLnkCntnr = Data->lpOleUILinkContainer;
  770.  
  771.   for (int i=0; i<cSelItems; i++) {
  772.     LinksList->HandleMessage(LB_GETTEXT, rgIndex[i],
  773.                             (LPARAM)(TLinkInfo far*)&lpLinkInfo);
  774.  
  775.     hErr = lpLnkCntnr->CancelLink(lpLinkInfo->dwLink);
  776.  
  777.     if (hErr != NOERROR) {
  778.       lpLinkInfo->fIsMarked = true;
  779.       bUpdate = true;
  780.     }
  781.     else {
  782.       LinksList->DeleteString(rgIndex[i]);
  783.     }
  784.   }
  785.  
  786.   if (bUpdate)
  787.     RefreshLinkLB();
  788.  
  789.   if (rgIndex)
  790.     delete []rgIndex;
  791.  
  792.   return hErr;
  793. }
  794.  
  795.  
  796. //
  797. //
  798. //
  799. HRESULT
  800. TEditLinksDlg::Container_UpdateNow()
  801. {
  802.   HRESULT hErr   = NOERROR;
  803.   int* rgIndex   = 0;
  804.   int cSelItems  = GetSelectedItems(rgIndex);
  805.  
  806.   if (cSelItems < 0)
  807.     return ResultFromScode(E_FAIL);
  808.  
  809.   if (!cSelItems)
  810.     return NOERROR;
  811.  
  812.   if (!Helper.fClose) {
  813.     Cancel->SetWindowText(Helper.szClose);
  814.     Helper.fClose = true;
  815.   }
  816.  
  817.   bool bUpdate = false;
  818.   TLinkInfo FAR *lpLinkInfo;
  819.   LPOLEUILINKCONTAINER lpLnkCntnr = Data->lpOleUILinkContainer;
  820.  
  821.   for (int i=0; i<cSelItems; i++) {
  822.     LinksList->HandleMessage(LB_GETTEXT, rgIndex[i],
  823.                             (LPARAM)(TLinkInfo far*)&lpLinkInfo);
  824.  
  825.     hErr = lpLnkCntnr->UpdateLink(lpLinkInfo->dwLink, true, false);
  826.     bUpdate = true;
  827.     lpLinkInfo->fIsMarked = true;
  828.  
  829.     if (hErr != NOERROR)
  830.       break;
  831.   }
  832.  
  833.   if (bUpdate)
  834.     RefreshLinkLB();
  835.  
  836.   if (rgIndex)
  837.     delete []rgIndex;
  838.  
  839.   return hErr;
  840. }
  841.  
  842.  
  843. //
  844. //
  845. //
  846. HRESULT
  847. TEditLinksDlg::Container_OpenSource()
  848. {
  849.   HRESULT hErr   = NOERROR;
  850.   int* rgIndex   = 0;
  851.   int cSelItems  = GetSelectedItems(rgIndex);
  852.  
  853.   if (cSelItems < 0)
  854.     return ResultFromScode(E_FAIL);
  855.  
  856.   if (cSelItems != 1) {
  857.     TRACEX(OwlOleDlg, 1, "Attempt to open source of multiple items.");
  858.     return NOERROR;
  859.   }
  860.  
  861.   if (!Helper.fClose) {
  862.     Cancel->SetWindowText(Helper.szClose);
  863.     Helper.fClose = true;
  864.   }
  865.  
  866.   TLinkInfo* lpLinkInfo;
  867.   LinksList->HandleMessage(LB_GETTEXT, rgIndex[0],
  868.                           (LPARAM)(TLinkInfo far*)&lpLinkInfo);
  869.  
  870.   LPOLEUILINKCONTAINER lpLnkCntnr = Data->lpOleUILinkContainer;
  871.   hErr = lpLnkCntnr->OpenLinkSource(lpLinkInfo->dwLink);
  872.  
  873.   UpdateLinkLBItem(rgIndex[0], true);
  874.  
  875.   if (rgIndex)
  876.     delete []rgIndex;
  877.  
  878.   return hErr;
  879. }
  880.  
  881.  
  882. //
  883. //
  884. //
  885. void
  886. TEditLinksDlg::BreakString(TLinkInfo* lpLinkInfo)
  887. {
  888.   if (!lpLinkInfo->clenFileName  ||
  889.       (strlen(lpLinkInfo->lpszDisplayName) == lpLinkInfo->clenFileName)) {
  890.     lpLinkInfo->lpszItemName = 0;
  891.   }
  892.   else {
  893.     lpLinkInfo->lpszItemName = lpLinkInfo->lpszDisplayName +
  894.                                (int)lpLinkInfo->clenFileName;
  895.   }
  896.  
  897.   char* str;
  898.   str = lpLinkInfo->lpszDisplayName + strlen(lpLinkInfo->lpszDisplayName);
  899.   while (str > lpLinkInfo->lpszDisplayName) {
  900.     str = AnsiPrev(lpLinkInfo->lpszDisplayName, str);
  901.     if ((*str == '\\') || (*str == '/') || (*str == ':'))
  902.       break;
  903.   }
  904.  
  905.   if (str == lpLinkInfo->lpszDisplayName)
  906.     lpLinkInfo->lpszShortFileName = str;
  907.   else
  908.     lpLinkInfo->lpszShortFileName = AnsiNext(str);
  909. }
  910.  
  911.  
  912. //
  913. //
  914. //
  915. int
  916. TEditLinksDlg::GetSelectedItems(int* &lprgIndex)
  917. {
  918.   lprgIndex = 0;
  919.  
  920.   int count = LinksList->GetSelCount();
  921.  
  922.   if (count < 0)    // Error
  923.     return count;
  924.  
  925.   if (count == 0)
  926.     return 0;
  927.  
  928.   lprgIndex = new int[count];
  929.  
  930.   if (LinksList->GetSelIndexes(lprgIndex, count) == count) {
  931.     return count;   // Caller will free lprgIndex!
  932.   }
  933.   else {
  934.     if (lprgIndex)
  935.       delete []lprgIndex;
  936.     lprgIndex = 0;
  937.     return 0;
  938.   }
  939. }
  940.  
  941.  
  942. //
  943. // Update state of Auto/Manual, Link Source and Link Type information based
  944. // on currently selected entry
  945. //
  946. void
  947. TEditLinksDlg::InitControls()
  948. {
  949.   int* rgIndex   = 0;
  950.   int cSelItems  = GetSelectedItems(rgIndex);
  951.   if (cSelItems < 0)      // Error!
  952.     return;
  953.  
  954.   //
  955.   // Enable/Disable controls
  956.   //
  957.   Automatic->EnableWindow(cSelItems ? true : false);
  958.   Manual->EnableWindow(cSelItems ? true : false);
  959.  
  960.   if (!(Data->dwFlags & elDisableCancelLink))
  961.     BreakLinkBtn->EnableWindow(cSelItems ? true : false);
  962.  
  963.   if (!(Data->dwFlags & elDisableOpenSource))
  964.     OpenBtn->EnableWindow(cSelItems ? true : false);
  965.  
  966.   if (!(Data->dwFlags & elDisableChangeSource))
  967.     ChangeBtn->EnableWindow(cSelItems ? true : false);
  968.  
  969.   if (!(Data->dwFlags & elDisableUpdateNow))
  970.     UpdateBtn->EnableWindow(cSelItems ? true : false);
  971.  
  972.   int cAuto = 0;
  973.   int cManual = 0;
  974.   char* lpszType   = 0;
  975.   char* lpszSource = 0;
  976.   bool bSameType   = true;
  977.   bool bSameSource = true;
  978.   TLinkInfo* lpLinkInfo;
  979.   for (int i=0; i < cSelItems; i++) {
  980.     LinksList->HandleMessage(LB_GETTEXT, rgIndex[i],
  981.                             (LPARAM)(TLinkInfo far*)&lpLinkInfo);
  982.     if (lpszSource && lpLinkInfo->lpszDisplayName) {
  983.       if (bSameSource  &&  strcmp(lpszSource, lpLinkInfo->lpszDisplayName)) {
  984.         bSameSource = false;
  985.       }
  986.     }
  987.     else {
  988.       lpszSource = lpLinkInfo->lpszDisplayName;
  989.     }
  990.  
  991.     if (lpszType  && lpLinkInfo->lpszFullLinkType) {
  992.       if (bSameType  && strcmp(lpszType, lpLinkInfo->lpszFullLinkType)) {
  993.         bSameType = false;
  994.       }
  995.     }
  996.     else {
  997.       lpszType = lpLinkInfo->lpszFullLinkType;
  998.     }
  999.  
  1000.     if (lpLinkInfo->fIsAuto)
  1001.       cAuto++;
  1002.     else
  1003.       cManual++;
  1004.   }
  1005.  
  1006.   CheckDlgButton(IDC_AUTOMATIC, cAuto && !cManual);
  1007.   CheckDlgButton(IDC_MANUAL, !cAuto && cManual);
  1008.  
  1009.   if (!bSameSource || !lpszSource)
  1010.     lpszSource = szNULL;
  1011.  
  1012.   char* lpsz = szNULL;
  1013.   TPointer<char> sz = new char[MaxPathLen];
  1014.   strcpy(sz, lpszSource);
  1015.   lpsz = ChopText(*LinkSource, 0, sz);
  1016.   LinkSource->SetText(lpsz);
  1017.  
  1018.  
  1019.   if (!bSameType || !lpszType)
  1020.     lpszType = szNULL;
  1021.   LinkType->SetText(lpszType);
  1022.  
  1023.   if (rgIndex)
  1024.     delete []rgIndex;
  1025. }
  1026.  
  1027.  
  1028. void
  1029. TEditLinksDlg::UpdateLinkLBItem(int nIndex, bool bSelect)
  1030. {
  1031.   if (nIndex <0)
  1032.    return;
  1033.  
  1034.   TLinkInfo* lpLinkInfo = 0;
  1035.   long result = (long)LinksList->HandleMessage(LB_GETTEXT, nIndex,
  1036.                                       (LPARAM)(TLinkInfo far*)&lpLinkInfo);
  1037.  
  1038.   if (result == LB_ERR  ||  !lpLinkInfo)
  1039.     return;
  1040.  
  1041.   lpLinkInfo->fDontFree = true;
  1042.   LinksList->DeleteString(nIndex);
  1043.  
  1044.   nIndex = AddLinkLBItem(lpLinkInfo, false);
  1045.   if (bSelect) {
  1046.     LinksList->SetSel(nIndex, true);
  1047.     LinksList->SetCaretIndex(nIndex, true);
  1048.   }
  1049. }
  1050.  
  1051.  
  1052. void
  1053. TEditLinksDlg::DiffPrefix(const char* lpsz1, const char* lpsz2,
  1054.                           char* &pref1, char* &pref2)
  1055. {
  1056.   PRECONDITION(lpsz1 && lpsz2 && *lpsz1 && *lpsz2);
  1057.  
  1058.   pref1 = 0;
  1059.   pref2 = 0;
  1060.  
  1061.   pref1 = new char[strlen(lpsz1)+1];
  1062.   pref2 = new char[strlen(lpsz2)+1];
  1063.  
  1064.   strcpy(pref1, lpsz1);
  1065.   strcpy(pref2, lpsz2);
  1066.  
  1067.   char* lpstr1 = pref1 + strlen(pref1);
  1068.   char* lpstr2 = pref2 + strlen(pref2);
  1069.  
  1070.   while ((lpstr1 > pref1) && (lpstr2 > pref2)) {
  1071.     lpstr1 = AnsiPrev(pref1, lpstr1);
  1072.     lpstr2 = AnsiPrev(pref1, lpstr2);
  1073.     if (*lpstr1 != *lpstr2) {
  1074.       lpstr1 = AnsiNext(lpstr1);
  1075.       lpstr2 = AnsiNext(lpstr2);
  1076.       break;
  1077.     }
  1078.   }
  1079.  
  1080.   while(*lpstr1 && *lpstr1!='\\' && *lpstr1!='!')
  1081.     lpstr1 = AnsiNext(lpstr1);
  1082.  
  1083.   while(*lpstr2 && *lpstr2!='\\' && *lpstr2!='!')
  1084.     lpstr2 = AnsiNext(lpstr2);
  1085.  
  1086.   *lpstr1 = 0;
  1087.   *lpstr2 = 0;
  1088. }
  1089.  
  1090.  
  1091. void
  1092. TEditLinksDlg::ChangeAllLinks(char* lpszFrom, char* lpszTo)
  1093. {
  1094.   bool bFound = false;
  1095.   int cFrom   = strlen(lpszFrom);
  1096.   int cItems  = LinksList->GetCount();
  1097.  
  1098.   char szTmp[MaxPathLen];
  1099.   TLinkInfo* lpLinkInfo = 0;
  1100.   for (int nIndex=0; nIndex<cItems; nIndex++) {
  1101.     LinksList->HandleMessage(LB_GETTEXT, nIndex,
  1102.                             (LPARAM)(TLinkInfo far*)&lpLinkInfo);
  1103.  
  1104.     lpLinkInfo->fIsMarked = false;
  1105.  
  1106.     if (!*(lpLinkInfo->lpszDisplayName + cFrom) ||
  1107.         (*(lpLinkInfo->lpszDisplayName + cFrom) == '\\') ||
  1108.         (*(lpLinkInfo->lpszDisplayName + cFrom) == '!')) {
  1109.       strcpyn(szTmp, lpLinkInfo->lpszDisplayName, cFrom+1);
  1110.  
  1111.       if (!strcmp(szTmp, lpszFrom)) {
  1112.         HRESULT hErr;
  1113.         int nFileLength;
  1114.         ULONG ulDummy;
  1115.  
  1116.         if (!bFound) {
  1117.           TPointer<char>  pTitle = new char[MaxPathLen];
  1118.           TPointer<char>  pMsg   = new char[MaxPathLen];
  1119.           TPointer<char>  pBuff  = new char[MaxPathLen];
  1120.  
  1121.           GetModule()->LoadString(IDS_CHANGESOURCE, (LPSTR)(char*)pTitle,
  1122.                                   MaxPathLen);
  1123.           GetModule()->LoadString(IDS_CHANGEADDITIONALLINKS,
  1124.                                   (LPSTR)(char*)pMsg, MaxPathLen);
  1125.           wsprintf((LPSTR)(char*)pBuff, (LPSTR)(char*)pMsg, lpszFrom);
  1126.           if (MessageBox((LPSTR)(char*)pBuff, (LPSTR)(char*)pTitle,
  1127.                           MB_ICONQUESTION|MB_YESNO) != IDYES)
  1128.             return;
  1129.  
  1130.           bFound = true;
  1131.         }
  1132.  
  1133.         strcpy(szTmp, lpszTo);
  1134.         strcat(szTmp, lpLinkInfo->lpszDisplayName + cFrom);
  1135.  
  1136.         nFileLength = strlen(szTmp) -
  1137.           (lpLinkInfo->lpszItemName ? strlen(lpLinkInfo->lpszItemName) : 0);
  1138.  
  1139.         LPOLEUILINKCONTAINER lpLnkCntnr = Data->lpOleUILinkContainer;
  1140.         hErr = lpLnkCntnr->SetLinkSource(lpLinkInfo->dwLink, szTmp,nFileLength,
  1141.                                          (ULONG FAR*)&ulDummy, true);
  1142.         if (hErr != NOERROR)
  1143.           lpLnkCntnr->SetLinkSource(lpLinkInfo->dwLink, szTmp, nFileLength,
  1144.                                     (ULONG FAR*)&ulDummy, false);
  1145.         lpLinkInfo->fIsMarked = true;
  1146.       }
  1147.     }
  1148.   }
  1149. }
  1150.  
  1151.  
  1152. int
  1153. TEditLinksDlg::AddLinkLBItem(TLinkInfo* lpLinkInfo, bool sel)
  1154. {
  1155.   PRECONDITION(lpLinkInfo);
  1156.  
  1157.   TOleAllocator oleAllocator;
  1158.   TRY {
  1159.     DWORD dwUpdateOpt;
  1160.     HRESULT hErr = NOERROR;
  1161.     lpLinkInfo->fDontFree = false;
  1162.     LPOLEUILINKCONTAINER lpLnkCntnr = Data->lpOleUILinkContainer;
  1163.  
  1164.     CHECK(lpLnkCntnr);
  1165.  
  1166.     //
  1167.     // Retrieve Link Source Information
  1168.     //
  1169.     LPSTR lpszDisplayName   = lpLinkInfo->lpszDisplayName;
  1170.     LPSTR lpszFullLinkType  = lpLinkInfo->lpszFullLinkType;
  1171.     LPSTR lpszShortLinkType = lpLinkInfo->lpszShortLinkType;
  1172.     hErr = lpLnkCntnr->GetLinkSource(lpLinkInfo->dwLink,
  1173.                                     &lpszDisplayName,
  1174.                                     &lpLinkInfo->clenFileName,
  1175.                                     &lpszFullLinkType,
  1176.                                     &lpszShortLinkType,
  1177.                                     &lpLinkInfo->fSourceAvailable,
  1178.                                     sel ? &lpLinkInfo->fIsSelected : 0);
  1179.     if (hErr != NOERROR)
  1180.       THROW(IDS_ERR_GETLINKSOURCE;)
  1181.  
  1182.     //
  1183.     // Ask for the Update Options
  1184.     //
  1185.     hErr = lpLnkCntnr->GetLinkUpdateOptions(lpLinkInfo->dwLink, &dwUpdateOpt);
  1186.     if (hErr != NOERROR)
  1187.       THROW(IDS_ERR_GETLINKUPDATEOPTIONS;)
  1188.  
  1189.     if (lpLinkInfo->fSourceAvailable) {
  1190.       if (dwUpdateOpt == OLEUPDATE_ALWAYS) {
  1191.         lpLinkInfo->fIsAuto = true;
  1192.         GetModule()->LoadString(IDS_LINK_AUTO, lpLinkInfo->lpszAMX,
  1193.                                 LinkTypeLen+1);
  1194.       }
  1195.       else {
  1196.         lpLinkInfo->fIsAuto = false;
  1197.         GetModule()->LoadString(IDS_LINK_MANUAL, lpLinkInfo->lpszAMX,
  1198.                                 LinkTypeLen+1);
  1199.       }
  1200.     }
  1201.     else {
  1202.       GetModule()->LoadString(IDS_LINK_UNKNOWN, lpLinkInfo->lpszAMX,
  1203.                               LinkTypeLen+1);
  1204.     }
  1205.  
  1206.     BreakString(lpLinkInfo);
  1207.  
  1208.     int index = (int)LinksList->HandleMessage(LB_ADDSTRING, 0,
  1209.                                              (LPARAM)lpLinkInfo);
  1210.  
  1211.     if (index == LB_ERR)
  1212.       THROW(IDS_ERR_ADDSTRING;)
  1213.  
  1214.     return index;
  1215.   }
  1216.  
  1217.   CATCH( ( int errMsgId) {                                        \
  1218.     //                                                            \
  1219.     // Display error message                                      \
  1220.     //                                                            \
  1221.     PopupMessage(errMsgId, IDS_LINKS, MB_ICONEXCLAMATION|MB_OK);  \
  1222.                                                                   \
  1223.     //                                                            \
  1224.     // Cleanup up buffers allocated by container                  \
  1225.     //                                                            \
  1226.     if (lpLinkInfo->lpszDisplayName) {                            \
  1227.       oleAllocator.Free(lpLinkInfo->lpszDisplayName);             \
  1228.       lpLinkInfo->lpszDisplayName = 0;                            \
  1229.     }                                                             \
  1230.                                                                   \
  1231.     if (lpLinkInfo->lpszShortLinkType) {                          \
  1232.       oleAllocator.Free(lpLinkInfo->lpszShortLinkType);           \
  1233.       lpLinkInfo->lpszShortLinkType = 0;                          \
  1234.     }                                                             \
  1235.                                                                   \
  1236.     if (lpLinkInfo->lpszDisplayName) {                            \
  1237.       oleAllocator.Free(lpLinkInfo->lpszFullLinkType);            \
  1238.       lpLinkInfo->lpszFullLinkType = 0;                           \
  1239.     }                                                             \
  1240.     return -1;                                                    \
  1241.   } )           // End-Of-CATCH macro //
  1242. }
  1243.  
  1244.  
  1245. int
  1246. TEditLinksDlg::LoadLinkLB()
  1247. {
  1248.   int   cLinks = 0;
  1249.   DWORD dwLink = 0;
  1250.   LPOLEUILINKCONTAINER lpLnkCntnr = Data->lpOleUILinkContainer;
  1251.  
  1252.   int index;
  1253.   TLinkInfo* lpLinkInfo;
  1254.   while((dwLink = lpLnkCntnr->GetNextLink(dwLink)) != 0) {
  1255.     lpLinkInfo = new TLinkInfo(dwLink);
  1256.     cLinks++;
  1257.  
  1258.    index = AddLinkLBItem(lpLinkInfo, true);
  1259.     if (index < 0)
  1260.       return -1;
  1261.  
  1262.     if (lpLinkInfo->fIsSelected)
  1263.       LinksList->SetSel(index, true);
  1264.   }
  1265.  
  1266.   if (LinksList->GetSelIndexes(&index, 1) > 0)
  1267.     LinksList->SetCaretIndex(index, true);
  1268.  
  1269.   return cLinks;
  1270. }
  1271.  
  1272.  
  1273. void
  1274. TEditLinksDlg::RefreshLinkLB()
  1275. {
  1276.   int cItems = LinksList->GetCount();
  1277.   CHECK(cItems > 0);
  1278.  
  1279.   bool bStop;
  1280.   TLinkInfo* lpLinkInfo;
  1281.   do {
  1282.     bStop = true;
  1283.     for (int nIndex=0; nIndex<cItems; nIndex++) {
  1284.       LinksList->HandleMessage(LB_GETTEXT, nIndex,
  1285.                                (LPARAM)(TLinkInfo far*)&lpLinkInfo);
  1286.       if (lpLinkInfo->fIsMarked) {
  1287.         lpLinkInfo->fIsMarked = false;
  1288.         lpLinkInfo->fDontFree = true;
  1289.  
  1290.         LinksList->DeleteString(nIndex);
  1291.  
  1292.         nIndex =AddLinkLBItem(lpLinkInfo, false);
  1293.  
  1294.         if (lpLinkInfo->fIsSelected) {
  1295.           LinksList->SetSel(nIndex, true);
  1296.           LinksList->SetCaretIndex(nIndex, true);
  1297.         }
  1298.         bStop = false;
  1299.         break;
  1300.       }
  1301.     }
  1302.   } while (!bStop);
  1303. }
  1304.  
  1305.  
  1306.