home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 2 BBS / 02-BBS.zip / fsrc1241.zip / cclist.c < prev    next >
C/C++ Source or Header  |  1999-03-05  |  87KB  |  2,146 lines

  1. /*---------------------------------------------------------------------------+
  2.  | Titel: CCLIST.C                                                           |
  3.  +-----------------------------------------+---------------------------------+
  4.  | Erstellt von: Michael Hohner            | Am: 05.09.93                    |
  5.  +-----------------------------------------+---------------------------------+
  6.  | System: OS/2 2.x PM                                                       |
  7.  +---------------------------------------------------------------------------+
  8.  | Beschreibung:                                                             |
  9.  |                                                                           |
  10.  |    Carbon Copy Lists Setup fuer FleetStreet                               |
  11.  |                                                                           |
  12.  |                                                                           |
  13.  +---------------------------------------------------------------------------+
  14.  | Bemerkungen:                                                              |
  15.  +---------------------------------------------------------------------------*/
  16.  
  17. /*----------------------------- Header-Dateien ------------------------------*/
  18. #pragma strings(readonly)
  19.  
  20. #define INCL_PM
  21. #include <os2.h>
  22. #include <stdlib.h>
  23. #include <stdio.h>
  24. #include <string.h>
  25. #include "main.h"
  26. #include "resids.h"
  27. #include "messages.h"
  28. #include "structs.h"
  29. #include "msgheader.h"
  30. #include "areaman\areaman.h"
  31. #include "dialogids.h"
  32. #include "controls\editwin.h"
  33. #include "utility.h"
  34. #include "cclist.h"
  35. #include "fltv7\fltv7.h"
  36. #include "nodedrag.h"
  37. #include "lookups.h"
  38. #include "util\fltutil.h"
  39. #include "util\addrcnv.h"
  40. #include "ccmanage.h"
  41. #include "nickmanage.h"
  42.  
  43. /*--------------------------------- Defines ---------------------------------*/
  44.  
  45. #ifndef CRA_SOURCE
  46. #define CRA_SOURCE  0x00004000L
  47. #endif
  48.  
  49. #define UNREG_CCLISTS  3
  50.  
  51. /* Name der CC-Liste hat sich geaendert */
  52. #define CCM_UPDATENAME       (WM_USER+1)
  53.  
  54. /* CC-Inhalts-Fenster schließt sich, mp1: HWND */
  55. #define CCM_CLOSE            (WM_USER+2)
  56.  
  57. #define CCM_UPDATELIST       (WM_USER+3)
  58.  
  59. #define CCDRAGTYPE "FleetStreet CCEntry"
  60. #define CCRMF      "<DRM_FLEET,DRF_CCENTRY>,<DRM_DISCARD,DRF_UNKNOWN>"
  61.  
  62. #define CCLISTDRAGTYPE "FleetStreet CCList"
  63. #define CCLISTRMF      "<DRM_FLEET,DRF_CCLIST>,<DRM_DISCARD,DRF_UNKNOWN>"
  64.  
  65. typedef struct ccentrypar {
  66.             USHORT cb;
  67.             CCENTRY CCEntry;
  68.           } CCENTRYPAR, *PCCENTRYPAR;
  69.  
  70. typedef struct cclistdata {
  71.             PCCLIST   pList;
  72.             PCCANCHOR pCCAnchor;
  73.             HPOINTER  hptrCCEntry;
  74.             BOOL      bNotify;
  75.           } CCLISTDATA, *PCCLISTDATA;
  76.  
  77. typedef struct cclistrecord {
  78.             MINIRECORDCORE RecordCore;
  79.             PSZ pchUserName;
  80.             PSZ pchAddress;
  81.             PSZ pchShow;
  82.             PCCENTRY pEntry;
  83.           } CCLISTRECORD, *PCCLISTRECORD;
  84.  
  85. typedef struct ccfolderrecord {
  86.             MINIRECORDCORE RecordCore;
  87.             PCCLIST        pList;
  88.             HWND           hwndContents;
  89.           } CCFOLDERRECORD, *PCCFOLDERRECORD;
  90.  
  91. typedef struct ccfolderdata {
  92.             HWND            hwndListPopup;
  93.             HWND            hwndFolderPopup;
  94.             PCCFOLDERRECORD pPopupRecord;
  95.             PCCFOLDERRECORD pDragRecord;
  96.             HPOINTER        hptrCCList;
  97.             HPOINTER        hptrCCFolder;
  98.             BOOL            bNotify;
  99.             HSWITCH         hSwitch;
  100.             BOOL            bForeground;
  101.           } CCFOLDERDATA, *PCCFOLDERDATA;
  102.  
  103. /*---------------------------- Globale Variablen ----------------------------*/
  104.  
  105. extern HWND hwndCCLists;
  106. extern HMODULE hmodLang;
  107. extern DIRTYFLAGS dirtyflags;
  108. extern HAB anchor;
  109. extern CCANCHOR ccanchor;
  110. extern ULONG ulCCSelected;
  111.  
  112. static PFNWP OldContainerProc;
  113.  
  114. /*--------------------------- Funktionsprototypen ---------------------------*/
  115.  
  116. static void UpdateCCList(HWND hwndListbox, BOOL bEmptyLists);
  117. static void CleanupCCList(HWND hwndContainer);
  118. static void UpdateCCEntries(HWND hwndContainer, PCCLIST pCCList);
  119. static MRESULT EXPENTRY CCEntryProc(HWND parent, ULONG message, MPARAM mp1, MPARAM mp2);
  120. static SHORT EXPENTRY SortCCContents(CCLISTRECORD *p1, CCLISTRECORD *p2, PVOID pStorage);
  121. static MRESULT EXPENTRY NewCCContainerProc(HWND parent, ULONG message, MPARAM mp1, MPARAM mp2);
  122. static MRESULT EXPENTRY ImportCCProc(HWND hwnd, ULONG message, MPARAM mp1, MPARAM mp2);
  123. static int ImportCCList(HWND hwndOwner, PCCANCHOR pCCAnchor, PCCLIST pDestList);
  124. static int ReadCCFile(FILE *pfImport, PCCANCHOR pCCAnchor, PCCLIST pDestList, ULONG ulFlags);
  125. static MRESULT ContentsDragover(HWND hwndDlg, PCNRDRAGINFO pCnrDraginfo);
  126. static void ContentsDrop(HWND hwndDlg, PCCLISTDATA pListData, PCNRDRAGINFO pCnrDraginfo);
  127. static void ContentsInitDrag(HWND hwndDlg, PCCLISTDATA pListData, PCNRDRAGINIT pDragInit);
  128.  
  129. static PCCFOLDERRECORD AddEmptyCCList(HWND hwndContainer, HPOINTER hptr);
  130. static void CCListClosed(HWND hwndCnr, HWND hwndList);
  131. static int InitCCListDrag(HWND hwndDlg, PCNRDRAGINIT pInit);
  132. static int CleanupCCFolder(HWND hwndContainer);
  133. static int DeleteCCListF(HWND hwndContainer, PCCFOLDERRECORD pRecord);
  134. static int FillCCFolder(HWND hwndContainer, HPOINTER hptr);
  135. static int OpenCCList(HWND hwndContainer, PCCFOLDERRECORD pRecord);
  136. static MRESULT CCFolderDragOver(HWND hwndCnr, PCNRDRAGINFO pCnrDrag);
  137. static void CCFolderDrop(HWND hwndCnr, PCNRDRAGINFO pCnrDrag);
  138. static void CCListSendUpdate(HWND hwndCnr, ULONG ulListID);
  139. static void InitCCFolder(HWND hwndCnr);
  140. static SHORT EXPENTRY SortCCFolder(PCCFOLDERRECORD p1, PCCFOLDERRECORD p2, PVOID pStorage);
  141.  
  142. /*------------------------------ NewContainerProc ---------------------------*/
  143. /* Neue Window-Prozedur f. Container, um OS/2-Bug zu umschiffen              */
  144. /*---------------------------------------------------------------------------*/
  145.  
  146. static MRESULT EXPENTRY NewCCContainerProc(HWND parent, ULONG message, MPARAM mp1, MPARAM mp2)
  147. {
  148.    switch(message)
  149.    {
  150.       case DM_DRAGOVER:
  151.          /*DrgAccessDraginfo(mp1);*/
  152.          break;
  153.  
  154.       case WM_BUTTON2DOWN:
  155.          return (MRESULT) FALSE;
  156.  
  157.       default:
  158.          break;
  159.    }
  160.    return OldContainerProc(parent, message, mp1, mp2);
  161. }
  162.  
  163. /*------------------------------ UpdateCCList    ----------------------------*/
  164. /* Fuellt die Listbox mit den CC-List-Tags neu                               */
  165. /*---------------------------------------------------------------------------*/
  166.  
  167. static  void UpdateCCList(HWND hwndListbox, BOOL bEmptyLists)
  168. {
  169.    PCCLIST pList;
  170.    SHORT sItem;
  171.  
  172.    WinEnableWindowUpdate(hwndListbox, FALSE);
  173.    SendMsg(hwndListbox, LM_DELETEALL, NULL, NULL);
  174.    pList=ccanchor.pLists;
  175.    while (pList)
  176.    {
  177.       if (bEmptyLists || pList->pEntries)
  178.       {
  179.          char *pchTempTitle;
  180.          char *pchTemp;
  181.  
  182.          pchTempTitle = strdup(pList->pchListName);
  183.          pchTemp = pchTempTitle;
  184.          while (*pchTemp)
  185.             if (*pchTemp == '\r' ||
  186.                 *pchTemp == '\n')
  187.                *pchTemp++ = ' ';
  188.             else
  189.                pchTemp++;
  190.          sItem = (SHORT)WinInsertLboxItem(hwndListbox, LIT_SORTASCENDING, pchTempTitle);
  191.          free(pchTempTitle);
  192.          SendMsg(hwndListbox, LM_SETITEMHANDLE, MPFROMSHORT(sItem), MPFROMLONG(pList->ulListID));
  193.       }
  194.       pList=pList->next;
  195.    }
  196.    SendMsg(hwndListbox, LM_SELECTITEM, MPFROMSHORT(0), MPFROMSHORT(TRUE));
  197.    WinEnableWindowUpdate(hwndListbox, TRUE);
  198.    return;
  199. }
  200.  
  201. /*------------------------------ CCListContentsProc -------------------------*/
  202. /* Fenster-Prozedur fuer CC-List-Inhalt                                      */
  203. /*---------------------------------------------------------------------------*/
  204.  
  205. MRESULT EXPENTRY CCListContentsProc(HWND parent, ULONG message, MPARAM mp1, MPARAM mp2)
  206. {
  207.    extern HWND hwndhelp;
  208.    extern WINDOWFONTS windowfonts;
  209.    extern WINDOWCOLORS windowcolors;
  210.    extern GENERALOPT generaloptions;
  211.    static pchTitleName[50];
  212.    static pchTitleAddress[50];
  213.    static pchTitleShow[50];
  214.    CNRINFO cnrinfo;
  215.    PFIELDINFO pField, pFirstField;
  216.    FIELDINFOINSERT FieldinfoInsert;
  217.    PCCLISTDATA pListData = (PCCLISTDATA) WinQueryWindowULong(parent, QWL_USER);
  218.    BOOL bTemp;
  219.  
  220.    switch (message)
  221.    {
  222.       case WM_INITDLG:
  223.          /* Instanzdaten anfordern */
  224.          pListData = malloc(sizeof(CCLISTDATA));
  225.          memset(pListData, 0, sizeof(CCLISTDATA));
  226.          WinSetWindowULong(parent, QWL_USER, (ULONG) pListData);
  227.  
  228.          /* Daten setzen */
  229.          pListData->pList=((PCCLISTPAR) mp2)->pList;
  230.          pListData->pCCAnchor=((PCCLISTPAR) mp2)->pCCAnchor;
  231.          pListData->hptrCCEntry=LoadIcon(IDIC_CCENTRY);
  232.  
  233.          OldContainerProc=WinSubclassWindow(WinWindowFromID(parent, IDD_CCLIST+1),
  234.                                             NewCCContainerProc);
  235.  
  236.          SetFont(WinWindowFromID(parent, IDD_CCLIST+1), windowfonts.cclistfont);
  237.          SetBackground(WinWindowFromID(parent, IDD_CCLIST+1), &windowcolors.cccontentsback);
  238.          SetForeground(WinWindowFromID(parent, IDD_CCLIST+1), &windowcolors.cccontentsfore);
  239.  
  240.          /* Felder einfuegen */
  241.          pFirstField=WinSendDlgItemMsg(parent, IDD_CCLIST+1, CM_ALLOCDETAILFIELDINFO,
  242.                                        MPFROMSHORT(3), NULL);
  243.          pField=pFirstField;
  244.          pField->cb=sizeof(FIELDINFO);
  245.          pField->flData=CFA_STRING | CFA_HORZSEPARATOR | CFA_SEPARATOR | CFA_FIREADONLY;
  246.          pField->flTitle=CFA_FITITLEREADONLY;
  247.          pField->pTitleData=pchTitleName;
  248.          LoadString(IDST_CC_NAME, 50, pField->pTitleData);
  249.          pField->offStruct=FIELDOFFSET(CCLISTRECORD, pchUserName);
  250.          pField=pField->pNextFieldInfo;
  251.  
  252.          pField->cb=sizeof(FIELDINFO);
  253.          pField->flData=CFA_STRING | CFA_HORZSEPARATOR | CFA_SEPARATOR | CFA_FIREADONLY;
  254.          pField->flTitle=CFA_FITITLEREADONLY;
  255.          pField->pTitleData=pchTitleAddress;
  256.          LoadString(IDST_CC_ADDRESS, 50, pField->pTitleData);
  257.          pField->offStruct=FIELDOFFSET(CCLISTRECORD, pchAddress);
  258.          pField=pField->pNextFieldInfo;
  259.  
  260.          pField->cb=sizeof(FIELDINFO);
  261.          pField->flData=CFA_STRING | CFA_HORZSEPARATOR | CFA_FIREADONLY;
  262.          pField->flTitle=CFA_FITITLEREADONLY;
  263.          pField->pTitleData=pchTitleShow;
  264.          LoadString(IDST_CC_SHOW, 50, pField->pTitleData);
  265.          pField->offStruct=FIELDOFFSET(CCLISTRECORD, pchShow);
  266.  
  267.          FieldinfoInsert.cb=sizeof(FIELDINFOINSERT);
  268.          FieldinfoInsert.pFieldInfoOrder=(PFIELDINFO)CMA_FIRST;
  269.          FieldinfoInsert.fInvalidateFieldInfo=TRUE;
  270.          FieldinfoInsert.cFieldInfoInsert=3;
  271.  
  272.          WinSendDlgItemMsg(parent, IDD_CCLIST+1, CM_INSERTDETAILFIELDINFO,
  273.                            pFirstField, &FieldinfoInsert);
  274.  
  275.          cnrinfo.cb=sizeof(CNRINFO);
  276.          cnrinfo.flWindowAttr=CV_DETAIL | CA_TITLEREADONLY |
  277.                               CA_TITLESEPARATOR | CA_DETAILSVIEWTITLES;
  278.          cnrinfo.pSortRecord=(PVOID)SortCCContents;
  279.          WinSendDlgItemMsg(parent, IDD_CCLIST+1, CM_SETCNRINFO, &cnrinfo,
  280.                            MPFROMLONG(CMA_FLWINDOWATTR | CMA_PSORTRECORD));
  281.  
  282.          UpdateCCEntries(WinWindowFromID(parent, IDD_CCLIST+1), pListData->pList);
  283.  
  284.          if (pListData->pList->ulFlags & CCLIST_KILLSENT)
  285.             WinCheckButton(parent, IDD_CCLIST+7, TRUE);
  286.  
  287.          if (pListData->pList->pEntries)
  288.          {
  289.             WinEnableControl(parent, IDD_CCLIST+4, TRUE);
  290.             WinEnableControl(parent, IDD_CCLIST+5, TRUE);
  291.          }
  292.          WinSetWindowText(parent, pListData->pList->pchListName);
  293.          RestoreWinPos(parent, &pListData->pList->ListPos, FALSE, FALSE);
  294.          pListData->bNotify = TRUE;
  295.          break;
  296.  
  297.       case WM_ACTIVATE:
  298.          if (mp1)
  299.             WinAssociateHelpInstance(hwndhelp, parent);
  300.          else
  301.             WinAssociateHelpInstance(hwndhelp, NULLHANDLE);
  302.          break;
  303.  
  304.       case WM_COMMAND:
  305.          switch(SHORT1FROMMP(mp1))
  306.          {
  307.             CCENTRYPAR CCEntryPar;
  308.             CCLISTRECORD *pRecord;
  309.  
  310.             /* Add-Button */
  311.             case IDD_CCLIST+3:
  312.                CCEntryPar.cb=sizeof(CCENTRYPAR);
  313.                CCEntryPar.CCEntry.ulFlags= CCENTRY_MENTION;
  314.                CCEntryPar.CCEntry.pchName[0]='\0';
  315.                CCEntryPar.CCEntry.pchAddress[0]='\0';
  316.                CCEntryPar.CCEntry.pchFirstLine[0]='\0';
  317.                if (WinDlgBox(HWND_DESKTOP, parent, CCEntryProc, hmodLang,
  318.                              IDD_CCLISTENTRY, &CCEntryPar)==DID_OK)
  319.                {
  320.                   /* Eintrag einfuegen */
  321.                   if (AddCCEntry(pListData->pCCAnchor, pListData->pList, &CCEntryPar.CCEntry))
  322.                   {
  323.                     UpdateCCEntries(WinWindowFromID(parent, IDD_CCLIST+1), pListData->pList);
  324.                     if (pListData->pList->pEntries)
  325.                     {
  326.                        WinEnableControl(parent, IDD_CCLIST+4, TRUE);
  327.                        WinEnableControl(parent, IDD_CCLIST+5, TRUE);
  328.                     }
  329.                   }
  330.                }
  331.                return (MRESULT) FALSE;
  332.  
  333.             /* Delete-Button */
  334.             case IDD_CCLIST+4:
  335.                if (generaloptions.safety & SAFETY_CHANGESETUP)
  336.                {
  337.                   if (MessageBox(parent, IDST_MSG_DELCCENTRY, IDST_TITLE_DELCCENTRY,
  338.                                  IDD_DELCCENTRY, MB_YESNO | MB_QUERY | MB_DEFBUTTON2)!=MBID_YES)
  339.                      return (MRESULT) FALSE;
  340.                }
  341.                pRecord = NULL;
  342.                while (pRecord=WinSendDlgItemMsg(parent, IDD_CCLIST+1, CM_QUERYRECORDEMPHASIS,
  343.                                                 pRecord?pRecord:MPFROMLONG(CMA_FIRST),
  344.                                                 MPFROMSHORT(CRA_SELECTED)))
  345.                {
  346.                   DeleteCCEntry(pListData->pCCAnchor, pListData->pList, pRecord->pEntry);
  347.                }
  348.                UpdateCCEntries(WinWindowFromID(parent, IDD_CCLIST+1), pListData->pList);
  349.                if (pListData->pList->pEntries)
  350.                {
  351.                   WinEnableControl(parent, IDD_CCLIST+4, TRUE);
  352.                   WinEnableControl(parent, IDD_CCLIST+5, TRUE);
  353.                }
  354.                return (MRESULT) FALSE;
  355.  
  356.             /* Change-Button */
  357.             case IDD_CCLIST+5:
  358.                pRecord=(CCLISTRECORD *)WinSendDlgItemMsg(parent, IDD_CCLIST+1,
  359.                                          CM_QUERYRECORDEMPHASIS, (MPARAM) CMA_FIRST,
  360.                                          MPFROMSHORT(CRA_SELECTED));
  361.                if (pRecord)
  362.                {
  363.                   CCEntryPar.cb=sizeof(CCENTRYPAR);
  364.                   strcpy(CCEntryPar.CCEntry.pchName, pRecord->pEntry->pchName);
  365.                   strcpy(CCEntryPar.CCEntry.pchAddress, pRecord->pEntry->pchAddress);
  366.                   strcpy(CCEntryPar.CCEntry.pchFirstLine, pRecord->pEntry->pchFirstLine);
  367.                   CCEntryPar.CCEntry.ulFlags = pRecord->pEntry->ulFlags;
  368.                   if (WinDlgBox(HWND_DESKTOP, parent, CCEntryProc, hmodLang,
  369.                                 IDD_CCLISTENTRY, &CCEntryPar)==DID_OK)
  370.                   {
  371.                      strcpy(pRecord->pEntry->pchName, CCEntryPar.CCEntry.pchName);
  372.                      strcpy(pRecord->pEntry->pchAddress, CCEntryPar.CCEntry.pchAddress);
  373.                      strcpy(pRecord->pEntry->pchFirstLine, CCEntryPar.CCEntry.pchFirstLine);
  374.                      pRecord->pEntry->ulFlags = CCEntryPar.CCEntry.ulFlags;
  375.                      if (CCEntryPar.CCEntry.ulFlags & CCENTRY_MENTION)
  376.                         LoadString(IDST_CC_YES, 10, pRecord->pchShow);
  377.                      else
  378.                         LoadString(IDST_CC_NO, 10, pRecord->pchShow);
  379.                      WinSendDlgItemMsg(parent, IDD_CCLIST+1, CM_INVALIDATERECORD,
  380.                                        &pRecord, MPFROM2SHORT(1,CMA_TEXTCHANGED));
  381.                      WinSendDlgItemMsg(parent, IDD_CCLIST+1, CM_SORTRECORD,
  382.                                        MPFROMP(SortCCContents), NULL);
  383.                      WinSendDlgItemMsg(parent, IDD_CCLIST+1, CM_INVALIDATERECORD, NULL, NULL);
  384.                      pListData->pList->bDirty = TRUE;
  385.                      if (pListData->pCCAnchor)
  386.                         pListData->pCCAnchor->bDirty = TRUE;
  387.                   }
  388.                }
  389.                return (MRESULT) FALSE;
  390.  
  391.             /* Import-Button */
  392.             case IDD_CCLIST+6:
  393.                if (!ImportCCList(parent, pListData->pCCAnchor, pListData->pList))
  394.                   UpdateCCEntries(WinWindowFromID(parent, IDD_CCLIST+1), pListData->pList);
  395.                if (pListData->pList->pEntries)
  396.                {
  397.                   WinEnableControl(parent, IDD_CCLIST+4, TRUE);
  398.                   WinEnableControl(parent, IDD_CCLIST+5, TRUE);
  399.                }
  400.                return (MRESULT) FALSE;
  401.  
  402.             case DID_OK:
  403.             case DID_CANCEL:
  404.                if (hwndCCLists)
  405.                   WinPostMsg(hwndCCLists, CCM_CLOSE, (MPARAM) parent,
  406.                              NULL);
  407.                break;
  408.  
  409.             default:
  410.                return (MRESULT) FALSE;
  411.          }
  412.          break;
  413.  
  414.       case WM_CONTROL:
  415.          if (SHORT1FROMMP(mp1)==IDD_CCLIST+1)
  416.          {
  417.             switch(SHORT2FROMMP(mp1))
  418.             {
  419.                case CN_ENTER:
  420.                   if (mp2)
  421.                      SendMsg(parent, WM_COMMAND, MPFROMSHORT(IDD_CCLIST+5), NULL);
  422.                   break;
  423.  
  424.                case CN_INITDRAG:
  425.                   ContentsInitDrag(parent, pListData, (PCNRDRAGINIT)mp2);
  426.                   break;
  427.  
  428.                case CN_DRAGOVER:
  429.                   return ContentsDragover(parent, (PCNRDRAGINFO) mp2);
  430.  
  431.                case CN_DROP:
  432.                   ContentsDrop(parent, pListData, (PCNRDRAGINFO) mp2);
  433.                   break;
  434.  
  435.                default:
  436.                   break;
  437.             }
  438.          }
  439.          break;
  440.  
  441.       case DM_DISCARDOBJECT:
  442.          if (mp1)
  443.          {
  444.             PDRAGINFO pDraginfo=(PDRAGINFO) mp1;
  445.             PDRAGITEM pItem;
  446.             PCCENTRY pSource;
  447.             CCLISTRECORD *pRecord;
  448.             ULONG ulNum;
  449.             int i;
  450.  
  451.             DrgAccessDraginfo(pDraginfo);
  452.             ulNum = DrgQueryDragitemCount(pDraginfo);
  453.             for (i=0; i< ulNum; i++)
  454.             {
  455.                pItem=DrgQueryDragitemPtr(pDraginfo, i);
  456.                pSource=(PCCENTRY)pItem->ulItemID;
  457.  
  458.                /* Record aus Container loeschen */
  459.                pRecord=(CCLISTRECORD *)WinSendDlgItemMsg(parent, IDD_CCLIST+1, CM_QUERYRECORD, NULL,
  460.                                                          MPFROM2SHORT(CMA_FIRST, CMA_ITEMORDER));
  461.                while (pRecord && pRecord->pEntry != pSource)
  462.                   pRecord=(CCLISTRECORD *)WinSendDlgItemMsg(parent, IDD_CCLIST+1,
  463.                                                             CM_QUERYRECORD, pRecord,
  464.                                                             MPFROM2SHORT(CMA_NEXT, CMA_ITEMORDER));
  465.                if (pRecord)
  466.                   WinSendDlgItemMsg(parent, IDD_CCLIST+1, CM_ERASERECORD,
  467.                                     pRecord, NULL);
  468.                DeleteCCEntry(pListData->pCCAnchor, pListData->pList, pSource);
  469.             }
  470.             UpdateCCEntries(WinWindowFromID(parent, IDD_CCLIST+1), pListData->pList);
  471.             DrgFreeDraginfo(pDraginfo);
  472.          }
  473.          return MRFROMLONG(DRR_SOURCE);
  474.  
  475.       case WM_CLOSE:
  476.          if (hwndCCLists)
  477.             WinPostMsg(hwndCCLists, CCM_CLOSE, (MPARAM) parent,
  478.                        NULL);
  479.          break;
  480.  
  481.       case WM_DESTROY:
  482.          bTemp = WinQueryButtonCheckstate(parent, IDD_CCLIST+7);
  483.          if (bTemp && !(pListData->pList->ulFlags & CCLIST_KILLSENT))
  484.          {
  485.             pListData->pList->ulFlags |= CCLIST_KILLSENT;
  486.             pListData->pList->bDirty = TRUE;
  487.             if (pListData->pCCAnchor)
  488.                 pListData->pCCAnchor->bDirty = TRUE;
  489.          }
  490.          else
  491.             if (!bTemp && (pListData->pList->ulFlags & CCLIST_KILLSENT))
  492.             {
  493.                pListData->pList->ulFlags &= ~CCLIST_KILLSENT;
  494.                pListData->pList->bDirty = TRUE;
  495.                if (pListData->pCCAnchor)
  496.                    pListData->pCCAnchor->bDirty = TRUE;
  497.             }
  498.  
  499.          QueryFont(WinWindowFromID(parent, IDD_CCLIST+1), windowfonts.cclistfont);
  500.          QueryBackground(WinWindowFromID(parent, IDD_CCLIST+1), &windowcolors.cccontentsback);
  501.          QueryForeground(WinWindowFromID(parent, IDD_CCLIST+1), &windowcolors.cccontentsfore);
  502.          CleanupCCList(WinWindowFromID(parent, IDD_CCLIST+1));
  503.          if (pListData->hptrCCEntry)
  504.             WinDestroyPointer(pListData->hptrCCEntry);
  505.          free(pListData);
  506.          break;
  507.  
  508.       case CCM_UPDATENAME:
  509.          WinSetWindowText(parent, pListData->pList->pchListName);
  510.          return (MRESULT) TRUE;
  511.  
  512.       case CCM_UPDATELIST:
  513.          UpdateCCEntries(WinWindowFromID(parent, IDD_CCLIST+1), pListData->pList);
  514.          if (pListData->pList->pEntries)
  515.          {
  516.             WinEnableControl(parent, IDD_CCLIST+4, TRUE);
  517.             WinEnableControl(parent, IDD_CCLIST+5, TRUE);
  518.          }
  519.          return (MRESULT) FALSE;
  520.  
  521.       case WM_WINDOWPOSCHANGED:
  522.          if (pListData && pListData->bNotify)
  523.          {
  524.             if (SaveWinPos(parent, (PSWP) mp1, &pListData->pList->ListPos, &pListData->pList->bDirty))
  525.             {
  526.                if (pListData->pCCAnchor)
  527.                   pListData->pCCAnchor->bDirty = TRUE;
  528.             }
  529.          }
  530.          break;
  531.  
  532.       default:
  533.          break;
  534.    }
  535.    return WinDefDlgProc(parent, message, mp1, mp2);
  536. }
  537.  
  538. static void ContentsInitDrag(HWND hwndDlg, PCCLISTDATA pListData, PCNRDRAGINIT pDragInit)
  539. {
  540.    ULONG ulNum=0;
  541.    int i=0;
  542.    PCCLISTRECORD pRecord= (PCCLISTRECORD) pDragInit->pRecord;
  543.    HWND hwndCnr = WinWindowFromID(hwndDlg, IDD_CCLIST+1);
  544.  
  545.    if (pRecord)
  546.    {
  547.       /* Record draggen */
  548.       PDRAGINFO pDraginfo;
  549.       DRAGITEM dItem;
  550.       DRAGIMAGE dImage[3];
  551.  
  552.       if (pRecord->RecordCore.flRecordAttr & CRA_SELECTED)
  553.       {
  554.          /* zaehlen und Source-Emphasis */
  555.          pRecord=NULL;
  556.          while (pRecord = SendMsg(hwndCnr, CM_QUERYRECORDEMPHASIS, pRecord?pRecord:MPFROMLONG(CMA_FIRST),
  557.                                      MPFROMLONG(CRA_SELECTED)))
  558.          {
  559.             ulNum++;
  560.             SendMsg(hwndCnr, CM_SETRECORDEMPHASIS, pRecord, MPFROM2SHORT(TRUE, CRA_SOURCE));
  561.          }
  562.          pDraginfo = DrgAllocDraginfo(ulNum);
  563.          pDraginfo->usOperation=DO_COPY;
  564.          pDraginfo->hwndSource=hwndDlg;
  565.  
  566.          pRecord = NULL;
  567.          while (pRecord = SendMsg(hwndCnr, CM_QUERYRECORDEMPHASIS, pRecord?pRecord:MPFROMLONG(CMA_FIRST),
  568.                                      MPFROMLONG(CRA_SELECTED)))
  569.          {
  570.             dItem.hwndItem=hwndDlg;
  571.             dItem.ulItemID=(ULONG)pRecord->pEntry;
  572.             dItem.hstrType=DrgAddStrHandle(CCDRAGTYPE);
  573.             dItem.hstrRMF=DrgAddStrHandle(CCRMF);
  574.             dItem.hstrContainerName=DrgAddStrHandle(pListData->pList->pchListName);
  575.             dItem.hstrSourceName=0;
  576.             dItem.hstrTargetName=0;
  577.             dItem.cxOffset=pDragInit->cx;
  578.             dItem.cyOffset=pDragInit->cx;
  579.             dItem.fsControl=0;
  580.             dItem.fsSupportedOps=DO_COPYABLE | DO_MOVEABLE;
  581.  
  582.             DrgSetDragitem(pDraginfo, &dItem, sizeof(dItem), i);
  583.             i++;
  584.          }
  585.          for (i=0; i < ulNum && i <3; i++)
  586.          {
  587.             /* Drag-Image vorbereiten */
  588.             dImage[i].cb=sizeof(DRAGIMAGE);
  589.             dImage[i].hImage=pListData->hptrCCEntry;
  590.             dImage[i].fl=DRG_ICON;
  591.             dImage[i].cxOffset=i*10;
  592.             dImage[i].cyOffset=i*10;
  593.          }
  594.          DrgDrag(hwndDlg, pDraginfo, dImage, (ulNum <3)?ulNum:3, VK_ENDDRAG, NULL);
  595.          DrgFreeDraginfo(pDraginfo);
  596.  
  597.          /* Source-Emphasis aus */
  598.          RemoveSourceEmphasis(hwndCnr);
  599.       }
  600.       else
  601.       {
  602.          /* nur ein Record */
  603.          SendMsg(hwndCnr, CM_SETRECORDEMPHASIS, pRecord, MPFROM2SHORT(TRUE, CRA_SOURCE));
  604.  
  605.          pDraginfo = DrgAllocDraginfo(1);
  606.          pDraginfo->usOperation=DO_COPY;
  607.          pDraginfo->hwndSource=hwndDlg;
  608.  
  609.          dItem.hwndItem=hwndDlg;
  610.          dItem.ulItemID=(ULONG)pRecord->pEntry;
  611.          dItem.hstrType=DrgAddStrHandle(CCDRAGTYPE);
  612.          dItem.hstrRMF=DrgAddStrHandle(CCRMF);
  613.          dItem.hstrContainerName=DrgAddStrHandle(pListData->pList->pchListName);
  614.          dItem.hstrSourceName=0;
  615.          dItem.hstrTargetName=0;
  616.          dItem.cxOffset=pDragInit->cx;
  617.          dItem.cyOffset=pDragInit->cx;
  618.          dItem.fsControl=0;
  619.          dItem.fsSupportedOps=DO_COPYABLE | DO_MOVEABLE;
  620.  
  621.          DrgSetDragitem(pDraginfo, &dItem, sizeof(dItem), 0);
  622.  
  623.          /* Drag-Image vorbereiten */
  624.          dImage[0].cb=sizeof(DRAGIMAGE);
  625.          dImage[0].hImage=pListData->hptrCCEntry;
  626.          dImage[0].fl=DRG_ICON;
  627.          dImage[0].cxOffset=0;
  628.          dImage[0].cyOffset=0;
  629.  
  630.          DrgDrag(hwndDlg, pDraginfo, dImage, 1, VK_ENDDRAG, NULL);
  631.          DrgFreeDraginfo(pDraginfo);
  632.  
  633.          /* Source-Emphasis aus */
  634.          SendMsg(hwndCnr, CM_SETRECORDEMPHASIS, pRecord, MPFROM2SHORT(FALSE, CRA_SOURCE));
  635.       }
  636.    }
  637.  
  638.    return;
  639. }
  640.  
  641. static MRESULT ContentsDragover(HWND hwndDlg, PCNRDRAGINFO pCnrDraginfo)
  642. {
  643.    MRESULT mrReply;
  644.    PID pid, pid2;
  645.    TID tid, tid2;
  646.    ULONG ulNum;
  647.    int i;
  648.  
  649.    DrgAccessDraginfo(pCnrDraginfo->pDragInfo);
  650.    WinQueryWindowProcess(pCnrDraginfo->pDragInfo->hwndSource, &pid, &tid);
  651.    WinQueryWindowProcess(hwndDlg, &pid2, &tid2);
  652.    if (pid != pid2)
  653.       mrReply=(MRESULT) DOR_NEVERDROP;
  654.    else
  655.       if (pCnrDraginfo->pDragInfo->hwndSource == hwndDlg)
  656.          mrReply=(MRESULT) DOR_NODROP;
  657.       else
  658.       {
  659.          if ((pCnrDraginfo->pDragInfo->usOperation == DO_LINK) ||
  660.              (pCnrDraginfo->pDragInfo->usOperation >= DO_UNKNOWN))
  661.             mrReply=(MRESULT) DOR_NODROPOP;
  662.          else
  663.          {
  664.             ulNum = DrgQueryDragitemCount(pCnrDraginfo->pDragInfo);
  665.             for (i=0; i< ulNum; i++)
  666.             {
  667.                PDRAGITEM pItem;
  668.  
  669.                pItem=DrgQueryDragitemPtr(pCnrDraginfo->pDragInfo, i);
  670.                if (!DrgVerifyTrueType(pItem, CCDRAGTYPE) &&
  671.                    !DrgVerifyTrueType(pItem, NODEDRAGTYPE))
  672.                   mrReply=(MRESULT) DOR_NEVERDROP;
  673.                else
  674.                   if (!DrgVerifyNativeRMF(pItem, CCRMF) &&
  675.                       !DrgVerifyNativeRMF(pItem, NODERMF))
  676.                      mrReply=(MRESULT) DOR_NEVERDROP;
  677.                   else
  678.                      if (pCnrDraginfo->pDragInfo->usOperation == DO_DEFAULT)
  679.                         mrReply=MRFROM2SHORT(DOR_DROP, DO_MOVE);
  680.                      else
  681.                         mrReply=MRFROM2SHORT(DOR_DROP, pCnrDraginfo->pDragInfo->usOperation);
  682.             }
  683.          }
  684.       }
  685.    DrgFreeDraginfo(pCnrDraginfo->pDragInfo);
  686.    return mrReply;
  687. }
  688.  
  689. static void ContentsDrop(HWND hwndDlg, PCCLISTDATA pListData, PCNRDRAGINFO pCnrDraginfo)
  690. {
  691.    ULONG ulNum;
  692.    int i;
  693.    PCCENTRY pSource;
  694.    PDRAGITEM pItem;
  695.    BOOL bNeedUpdate=FALSE;
  696.    BOOL bMoved = FALSE;
  697.  
  698.    DrgAccessDraginfo(pCnrDraginfo->pDragInfo);
  699.    ulNum = DrgQueryDragitemCount(pCnrDraginfo->pDragInfo);
  700.    for (i=0; i<ulNum; i++)
  701.    {
  702.       pItem=DrgQueryDragitemPtr(pCnrDraginfo->pDragInfo, i);
  703.       if (DrgVerifyTrueType(pItem, NODEDRAGTYPE))
  704.       {
  705.          /* Node-Eintrag, neu erzeugen */
  706.          CCENTRY NewCC;
  707.          char pchTemp[LEN_5DADDRESS+LEN_USERNAME+2];
  708.          char *pchTemp2;
  709.  
  710.          DrgQueryStrName(pItem->hstrSourceName, sizeof(pchTemp)-1, pchTemp);
  711.          pchTemp2 = strchr(pchTemp, ' ');
  712.          *pchTemp2 = 0;
  713.          pchTemp2++;
  714.  
  715.          strcpy(NewCC.pchName, pchTemp2);
  716.          strcpy(NewCC.pchAddress, pchTemp);
  717.          NewCC.ulFlags = CCENTRY_MENTION;
  718.  
  719.          /* einfuegen */
  720.          AddCCEntry(pListData->pCCAnchor, pListData->pList, &NewCC);
  721.          bNeedUpdate=TRUE;
  722.       }
  723.       else
  724.          if (DrgVerifyTrueType(pItem, CCDRAGTYPE))
  725.          {
  726.             /* Carbon-Copy-Eintrag, uebertragen */
  727.             switch (pCnrDraginfo->pDragInfo->usOperation)
  728.             {
  729.                case DO_MOVE:
  730.                case DO_COPY:
  731.                   pSource=(PCCENTRY)pItem->ulItemID;
  732.                   AddCCEntry(pListData->pCCAnchor, pListData->pList, pSource);
  733.                   bNeedUpdate=TRUE;
  734.                   if (pCnrDraginfo->pDragInfo->usOperation == DO_MOVE)
  735.                      bMoved = TRUE;
  736.                   break;
  737.  
  738.                default:
  739.                   WinAlarm(HWND_DESKTOP, WA_ERROR);
  740.                   break;
  741.             }
  742.          }
  743.    }
  744.    if (bMoved)
  745.       SendMsg(pCnrDraginfo->pDragInfo->hwndSource, DM_DISCARDOBJECT,
  746.                  pCnrDraginfo->pDragInfo, NULL);
  747.    DrgDeleteDraginfoStrHandles(pCnrDraginfo->pDragInfo);
  748.    DrgFreeDraginfo(pCnrDraginfo->pDragInfo);
  749.  
  750.    if (bNeedUpdate)
  751.    {
  752.       UpdateCCEntries(WinWindowFromID(hwndDlg, IDD_CCLIST+1), pListData->pList);
  753.       if (pListData->pList->pEntries)
  754.       {
  755.          WinEnableControl(hwndDlg, IDD_CCLIST+4, TRUE);
  756.          WinEnableControl(hwndDlg, IDD_CCLIST+5, TRUE);
  757.       }
  758.    }
  759.  
  760.    return;
  761. }
  762.  
  763. /*------------------------------ SortCCContents     -------------------------*/
  764. /* Sortiert Die CC-Liste                                                     */
  765. /*---------------------------------------------------------------------------*/
  766.  
  767. static  SHORT EXPENTRY SortCCContents(CCLISTRECORD *p1, CCLISTRECORD *p2, PVOID pStorage)
  768. {
  769.    pStorage=pStorage;
  770.  
  771.    return strcmp(p1->pchAddress, p2->pchAddress);
  772. }
  773.  
  774. /*------------------------------ CleanupCCList      -------------------------*/
  775. /* Loescht den Container fuer die CC-Liste                                   */
  776. /*---------------------------------------------------------------------------*/
  777.  
  778. static  void CleanupCCList(HWND hwndContainer)
  779. {
  780.    CCLISTRECORD *pRecord;
  781.  
  782.    pRecord=(CCLISTRECORD *)SendMsg(hwndContainer, CM_QUERYRECORD, NULL,
  783.                                       MPFROM2SHORT(CMA_FIRST, CMA_ITEMORDER));
  784.    while (pRecord)
  785.    {
  786.       free (pRecord->pchShow);
  787.       pRecord=(CCLISTRECORD *)SendMsg(hwndContainer, CM_QUERYRECORD, pRecord,
  788.                                          MPFROM2SHORT(CMA_NEXT, CMA_ITEMORDER));
  789.    }
  790.    SendMsg(hwndContainer, CM_REMOVERECORD, NULL, MPFROM2SHORT(0, CMA_FREE | CMA_INVALIDATE));
  791.  
  792.    return;
  793. }
  794.  
  795. /*------------------------------ UpdateCCEntries    -------------------------*/
  796. /* Fuellt den Container neu mit den Eintraegen der Liste                     */
  797. /*---------------------------------------------------------------------------*/
  798.  
  799. static  void UpdateCCEntries(HWND hwndContainer, PCCLIST pCCList)
  800. {
  801.    PCCENTRY pTemp;
  802.    PCCLISTRECORD pRecord, pFirstRecord;
  803.    RECORDINSERT RecordInsert;
  804.    ULONG ulCount=0;
  805.  
  806.    CleanupCCList(hwndContainer);
  807.  
  808.    /* zaehlen */
  809.    pTemp = pCCList->pEntries;
  810.    while (pTemp)
  811.    {
  812.       ulCount++;
  813.       pTemp = pTemp->next;
  814.    }
  815.  
  816.    if (ulCount)
  817.    {
  818.       pFirstRecord=(CCLISTRECORD *)SendMsg(hwndContainer, CM_ALLOCRECORD,
  819.                                               MPFROMLONG(sizeof(CCLISTRECORD)-sizeof(MINIRECORDCORE)),
  820.                                               MPFROMLONG(ulCount));
  821.       pRecord = pFirstRecord;
  822.  
  823.       pTemp=pCCList->pEntries;
  824.       while (pTemp && pRecord)
  825.       {
  826.          pRecord->pEntry = pTemp;   /* Pointer sichern */
  827.          pRecord->pchUserName=pTemp->pchName;
  828.          pRecord->pchAddress=pTemp->pchAddress;
  829.          pRecord->pchShow=malloc(10);
  830.          if (pTemp->ulFlags & CCENTRY_MENTION)
  831.             LoadString(IDST_CC_YES, 10, pRecord->pchShow);
  832.          else
  833.             LoadString(IDST_CC_NO, 10, pRecord->pchShow);
  834.  
  835.          pRecord = (CCLISTRECORD *) pRecord->RecordCore.preccNextRecord;
  836.          pTemp=pTemp->next;
  837.       }
  838.       RecordInsert.cb=sizeof(RECORDINSERT);
  839.       RecordInsert.pRecordOrder=(PRECORDCORE) CMA_END;
  840.       RecordInsert.pRecordParent=NULL;
  841.       RecordInsert.fInvalidateRecord=TRUE;
  842.       RecordInsert.zOrder=CMA_TOP;
  843.       RecordInsert.cRecordsInsert=ulCount;
  844.       SendMsg(hwndContainer, CM_INSERTRECORD, pFirstRecord, &RecordInsert);
  845.    }
  846.    return;
  847. }
  848.  
  849. /*--------------------------------- CCEntryProc -----------------------------*/
  850. /* Fenster-Prozedur fuer CC-Eintrag                                          */
  851. /*---------------------------------------------------------------------------*/
  852.  
  853. static  MRESULT EXPENTRY CCEntryProc(HWND parent, ULONG message, MPARAM mp1, MPARAM mp2)
  854. {
  855.    extern WINDOWPOSITIONS windowpositions;
  856.    extern HWND hwndhelp;
  857.    PCCENTRYPAR pCCEntryPar;
  858.    extern char CurrentAddress[LEN_5DADDRESS+1];
  859.  
  860.    switch(message)
  861.    {
  862.       case WM_INITDLG:
  863.          pCCEntryPar=(PCCENTRYPAR) mp2;
  864.          WinSetWindowULong(parent, QWL_USER, (ULONG) pCCEntryPar);
  865.          WinAssociateHelpInstance(hwndhelp, parent);
  866.          WinSubclassWindow(WinWindowFromID(parent, IDD_CCLISTENTRY+3), FidoEntryProc);
  867.          RestoreWinPos(parent, &windowpositions.ccentrypos, FALSE, TRUE);
  868.          WinSendDlgItemMsg(parent, IDD_CCLISTENTRY+2, EM_SETTEXTLIMIT,
  869.                            MPFROMSHORT(LEN_USERNAME), NULL);
  870.          WinSendDlgItemMsg(parent, IDD_CCLISTENTRY+3, EM_SETTEXTLIMIT,
  871.                            MPFROMSHORT(LEN_5DADDRESS), NULL);
  872.          WinSendDlgItemMsg(parent, IDD_CCLISTENTRY+9, EM_SETTEXTLIMIT,
  873.                            MPFROMSHORT(LEN_FIRSTLINE), NULL);
  874.          if (pCCEntryPar->CCEntry.ulFlags & CCENTRY_MENTION)
  875.            WinCheckButton(parent, IDD_CCLISTENTRY+4, TRUE);
  876.  
  877.          WinSetDlgItemText(parent, IDD_CCLISTENTRY+2, pCCEntryPar->CCEntry.pchName);
  878.          WinSetDlgItemText(parent, IDD_CCLISTENTRY+3, pCCEntryPar->CCEntry.pchAddress);
  879.          WinSetDlgItemText(parent, IDD_CCLISTENTRY+9, pCCEntryPar->CCEntry.pchFirstLine);
  880.          if (pCCEntryPar->CCEntry.pchName[0] &&
  881.              pCCEntryPar->CCEntry.pchAddress[0])
  882.            WinEnableControl(parent, DID_OK, TRUE);
  883.          break;
  884.  
  885.       case WM_CHAR:
  886.          if (WinQueryDlgItemTextLength(parent, IDD_CCLISTENTRY+2) &&
  887.              WinQueryDlgItemTextLength(parent, IDD_CCLISTENTRY+3))
  888.            WinEnableControl(parent, DID_OK, TRUE);
  889.          else
  890.            WinEnableControl(parent, DID_OK, FALSE);
  891.          break;
  892.  
  893.       case WM_COMMAND:
  894.          pCCEntryPar=(PCCENTRYPAR)WinQueryWindowULong(parent, QWL_USER);
  895.          if (SHORT1FROMMP(mp1)==DID_OK)
  896.          {
  897.             WinQueryDlgItemText(parent, IDD_CCLISTENTRY+2, LEN_USERNAME+1, pCCEntryPar->CCEntry.pchName);
  898.             WinQueryDlgItemText(parent, IDD_CCLISTENTRY+3, LEN_5DADDRESS+1, pCCEntryPar->CCEntry.pchAddress);
  899.             WinQueryDlgItemText(parent, IDD_CCLISTENTRY+9, LEN_FIRSTLINE+1, pCCEntryPar->CCEntry.pchFirstLine);
  900.             pCCEntryPar->CCEntry.ulFlags = 0;
  901.             if (WinQueryButtonCheckstate(parent, IDD_CCLISTENTRY+4))
  902.                pCCEntryPar->CCEntry.ulFlags |= CCENTRY_MENTION;
  903.          }
  904.  
  905.          if (SHORT1FROMMP(mp1)==IDD_CCLISTENTRY+7)
  906.          {
  907.             /* Nodelist-Lookup */
  908.             char FoundName[LEN_USERNAME+1];
  909.             char FoundAddress[LEN_5DADDRESS+1];
  910.  
  911.             WinQueryDlgItemText(parent, IDD_CCLISTENTRY+2, sizeof(FoundName), FoundName);
  912.             if (PerformNameLookup(FoundName, parent, LOOKUP_NORMAL, FoundName, FoundAddress))
  913.             {
  914.                WinSetDlgItemText(parent, IDD_CCLISTENTRY+2, FoundName);
  915.                WinSetDlgItemText(parent, IDD_CCLISTENTRY+3, FoundAddress);
  916.                WinEnableControl(parent, DID_OK, TRUE);
  917.             }
  918.             return (MRESULT) FALSE;
  919.          }
  920.          break;
  921.  
  922.       case WM_CONTROL:
  923.          pCCEntryPar=(PCCENTRYPAR)WinQueryWindowULong(parent, QWL_USER);
  924.          if (SHORT1FROMMP(mp1)==IDD_CCLISTENTRY+2 &&
  925.              SHORT2FROMMP(mp1)==EN_KILLFOCUS)
  926.          {
  927.             char pchTemp[LEN_USERNAME+1];
  928.             PNICKNAME pNickEntry;
  929.             extern NICKNAMELIST NickNameList;
  930.  
  931.             WinQueryWindowText((HWND) mp2, LEN_USERNAME+1, pchTemp);
  932.  
  933.             if (pNickEntry=FindNickname(&NickNameList, pchTemp, NULL))
  934.             {
  935.                WinSetDlgItemText(parent, IDD_CCLISTENTRY+2,
  936.                                  pNickEntry->username);
  937.                WinSetDlgItemText(parent, IDD_CCLISTENTRY+3,
  938.                                  pNickEntry->address);
  939.                WinSetDlgItemText(parent, IDD_CCLISTENTRY+9,
  940.                                  pNickEntry->firstline);
  941.             }
  942.          }
  943.          if (SHORT1FROMMP(mp1)==IDD_CCLISTENTRY+3)
  944.             if (SHORT2FROMMP(mp1)==EN_KILLFOCUS)
  945.             {
  946.                FTNADDRESS NetAddr;
  947.                char pchTemp[LEN_5DADDRESS+1];
  948.  
  949.                WinQueryDlgItemText(parent, SHORT1FROMMP(mp1),
  950.                                    LEN_5DADDRESS+1, pchTemp);
  951.                StringToNetAddr(pchTemp, &NetAddr, CurrentAddress);
  952.                NetAddrToString(pchTemp, &NetAddr);
  953.                WinSetDlgItemText(parent, SHORT1FROMMP(mp1), pchTemp);
  954.             }
  955.          break;
  956.  
  957.       case WM_DESTROY:
  958.       case WM_CLOSE:
  959.          QueryWinPos(parent, &windowpositions.ccentrypos);
  960.          WinAssociateHelpInstance(hwndhelp, WinQueryWindow(parent, QW_OWNER));
  961.          break;
  962.  
  963.       default:
  964.          break;
  965.    }
  966.    return WinDefDlgProc(parent, message, mp1, mp2);
  967. }
  968.  
  969. /*------------------------------ CCListSelectProc ---------------------------*/
  970. /* Fenster-Prozedur der CC-List-Auswahl                                      */
  971. /*---------------------------------------------------------------------------*/
  972.  
  973. MRESULT EXPENTRY CCListSelectProc(HWND parent, ULONG message, MPARAM mp1, MPARAM mp2)
  974. {
  975.    extern HWND hwndhelp, frame;
  976.    extern WINDOWPOSITIONS windowpositions;
  977.    static CCSELECTPAR *pCCSelectPar;
  978.  
  979.    switch (message)
  980.    {
  981.       case WM_INITDLG:
  982.          pCCSelectPar=(CCSELECTPAR *)mp2;
  983.          WinAssociateHelpInstance(hwndhelp, parent);
  984.          RestoreWinPos(parent, &windowpositions.ccselectpos, FALSE, TRUE);
  985.          if (!ccanchor.pLists)
  986.             WinEnableControl(parent, DID_OK, FALSE);
  987.          UpdateCCList(WinWindowFromID(parent, IDD_CCLISTSELECT+1), pCCSelectPar->bEmptyLists);
  988.          break;
  989.  
  990.       case WM_COMMAND:
  991.          if (SHORT1FROMMP(mp1)==DID_OK)
  992.          {
  993.             USHORT usItem;
  994.  
  995.             usItem=(USHORT)WinSendDlgItemMsg(parent, IDD_CCLISTSELECT+1, LM_QUERYSELECTION,
  996.                                              MPFROMSHORT(LIT_FIRST), NULL);
  997.             pCCSelectPar->ulSelectID=(ULONG)WinSendDlgItemMsg(parent, IDD_CCLISTSELECT+1,
  998.                                                               LM_QUERYITEMHANDLE,
  999.                                                               MPFROMSHORT(usItem),
  1000.                                                               NULL);
  1001.          }
  1002.          break;
  1003.  
  1004.       case WM_CONTROL:
  1005.          if (SHORT1FROMMP(mp1) == IDD_CCLISTSELECT+1)
  1006.          {
  1007.             if (SHORT2FROMMP(mp1) == LN_ENTER)
  1008.             {
  1009.                SendMsg(parent, WM_COMMAND, MPFROMSHORT(DID_OK), NULL);
  1010.             }
  1011.          }
  1012.          break;
  1013.  
  1014.       case WM_CLOSE:
  1015.       case WM_DESTROY:
  1016.          WinAssociateHelpInstance(hwndhelp, frame);
  1017.          QueryWinPos(parent, &windowpositions.ccselectpos);
  1018.          break;
  1019.  
  1020.       default:
  1021.          break;
  1022.    }
  1023.    return WinDefDlgProc(parent, message, mp1, mp2);
  1024. }
  1025.  
  1026. /*---------------------------------------------------------------------------*/
  1027. /* Funktionsname: AddToCCList                                                */
  1028. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  1029. /* Beschreibung: Fuegt einen Absender in eine CC-Liste ein                   */
  1030. /*                                                                           */
  1031. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  1032. /* Parameter: hwndOwner: Owner-Window des Auswahl-Dialogs                    */
  1033. /*            pHeader: Aktueller Header                                      */
  1034. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  1035. /* Rückgabewerte: -                                                          */
  1036. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  1037. /* Sonstiges:                                                                */
  1038. /*                                                                           */
  1039. /*---------------------------------------------------------------------------*/
  1040.  
  1041. void AddToCCList(HWND hwndOwner, MSGHEADER *pHeader)
  1042. {
  1043.    CCSELECTPAR CCSelect;
  1044.    extern HWND client;
  1045.  
  1046.    if (ccanchor.ulNumLists == 0)
  1047.       return;
  1048.  
  1049.    SendMsg(client, WORKM_DISABLEVIEWS, NULL, NULL);
  1050.  
  1051.    CCSelect.cb=sizeof(CCSelect);
  1052.    CCSelect.ulSelectID = 0;
  1053.    CCSelect.bEmptyLists=TRUE;
  1054.    if (WinDlgBox(HWND_DESKTOP, hwndOwner, CCListSelectProc, hmodLang,
  1055.              IDD_CCLISTSELECT, &CCSelect)==DID_OK)
  1056.    {
  1057.       if (CCSelect.ulSelectID)
  1058.       {
  1059.          PCCLIST pList;
  1060.  
  1061.          pList = QueryCCList(&ccanchor, CCSelect.ulSelectID);
  1062.  
  1063.          if (pList)
  1064.          {
  1065.             CCENTRY CCEntry;
  1066.  
  1067.             memcpy(CCEntry.pchName, pHeader->pchFromName, LEN_USERNAME+1);
  1068.             NetAddrToString(CCEntry.pchAddress, &pHeader->FromAddress);
  1069.             CCEntry.pchFirstLine[0] = '\0';
  1070.             CCEntry.ulFlags = CCENTRY_MENTION;
  1071.  
  1072.             AddCCEntry(&ccanchor, pList, &CCEntry);
  1073.  
  1074.             if (hwndCCLists)
  1075.                SendMsg(hwndCCLists, CCM_UPDATELIST, MPFROMLONG(CCSelect.ulSelectID),
  1076.                           NULL);
  1077.          }
  1078.       }
  1079.    }
  1080.  
  1081.    SendMsg(client, WORKM_ENABLEVIEWS, NULL, NULL);
  1082.    return;
  1083. }
  1084.  
  1085. /*---------------------------------------------------------------------------*/
  1086. /* Funktionsname: ImportCCList                                               */
  1087. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  1088. /* Beschreibung: Importieren einer CC-Liste                                  */
  1089. /*                                                                           */
  1090. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  1091. /* Parameter: hwndOwner: Owner-Window des Auswahl-Dialogs                    */
  1092. /*            pDestList: Liste für den Eintrag                               */
  1093. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  1094. /* Rückgabewerte: 0 OK                                                       */
  1095. /*                1 Abgebrochen                                              */
  1096. /*                2 Fehler beim Lesen des Files                              */
  1097. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  1098. /* Sonstiges:                                                                */
  1099. /*                                                                           */
  1100. /*---------------------------------------------------------------------------*/
  1101.  
  1102. static  int ImportCCList(HWND hwndOwner, PCCANCHOR pCCAnchor, PCCLIST pDestList)
  1103. {
  1104.    FILEDLG dlgpar;
  1105.    FILE *pfImport;
  1106.  
  1107.    /* Filename holen */
  1108.  
  1109.    dlgpar.cbSize=sizeof(dlgpar);
  1110.    dlgpar.fl= FDS_CENTER | FDS_CUSTOM | FDS_HELPBUTTON |
  1111.               FDS_OPEN_DIALOG;
  1112.    dlgpar.pszTitle=NULL;
  1113.    dlgpar.pszOKButton="OK";
  1114.    dlgpar.pfnDlgProc=ImportCCProc;
  1115.    dlgpar.pszIType=NULL;
  1116.    dlgpar.papszITypeList=NULL;
  1117.    dlgpar.pszIDrive=NULL;
  1118.    dlgpar.papszIDriveList=NULL;
  1119.    dlgpar.hMod=hmodLang;
  1120.    strcpy(dlgpar.szFullFile, "*");
  1121.    dlgpar.usDlgId=IDD_IMPORTCCLIST;
  1122.  
  1123.    WinFileDlg(HWND_DESKTOP,
  1124.               hwndOwner,
  1125.               &dlgpar);
  1126.  
  1127.    if (dlgpar.lReturn != DID_OK)
  1128.       return 1;
  1129.  
  1130.    /* Datei oeffnen */
  1131.    pfImport = fopen(dlgpar.szFullFile, "r");
  1132.  
  1133.    if (!pfImport)
  1134.       return 2;
  1135.  
  1136.    /* Eintraege lesen */
  1137.    if (ReadCCFile(pfImport, pCCAnchor, pDestList, dlgpar.ulUser))
  1138.       MessageBox(hwndOwner, IDST_MSG_INVALIDFILE, 0,
  1139.                  IDD_INVALIDFILE, MB_OK | MB_ERROR);
  1140.  
  1141.    /* Datei schliessen */
  1142.    fclose(pfImport);
  1143.  
  1144.    return 0;
  1145. }
  1146.  
  1147. /*---------------------------------------------------------------------------*/
  1148. /* Funktionsname: ImportCCProc                                               */
  1149. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  1150. /* Beschreibung: Window-Procedure für den File-Dialog                        */
  1151. /*                                                                           */
  1152. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  1153. /* Parameter: (Window-Proc)                                                  */
  1154. /*                                                                           */
  1155. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  1156. /* Rückgabewerte: MRESULT                                                    */
  1157. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  1158. /* Sonstiges: Bit 1 des User-Felds                                           */
  1159. /*               1 = Default "Yes"                                           */
  1160. /*               0 = Default "No"                                            */
  1161. /*---------------------------------------------------------------------------*/
  1162.  
  1163. static  MRESULT EXPENTRY ImportCCProc(HWND hwnd, ULONG message, MPARAM mp1, MPARAM mp2)
  1164. {
  1165.    PFILEDLG pFileDlg;
  1166.  
  1167.    switch (message)
  1168.    {
  1169.       case WM_INITDLG:
  1170.          WinCheckButton(hwnd, IDD_IMPORTCCLIST+2, TRUE);
  1171.          break;
  1172.  
  1173.       case WM_COMMAND:
  1174.          pFileDlg=(PFILEDLG)WinQueryWindowULong(hwnd, QWL_USER);
  1175.          pFileDlg->ulUser=0;
  1176.  
  1177.          /* Radio-Buttons auslesen */
  1178.          if (WinQueryButtonCheckstate(hwnd, IDD_IMPORTCCLIST+2))
  1179.             pFileDlg->ulUser |= CCENTRY_MENTION;
  1180.          else
  1181.             pFileDlg->ulUser &= ~CCENTRY_MENTION;
  1182.          break;
  1183.  
  1184.       default:
  1185.          break;
  1186.    }
  1187.    return WinDefFileDlgProc(hwnd, message, mp1, mp2);
  1188. }
  1189.  
  1190. /*---------------------------------------------------------------------------*/
  1191. /* Funktionsname: ReadCCFile                                                 */
  1192. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  1193. /* Beschreibung: Liesst die Textdatei in die Liste ein                       */
  1194. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  1195. /* Parameter:    pfImport: File, das gelesen wird                            */
  1196. /*               pDestList: Ergebnis-Liste                                   */
  1197. /*               bMention: Default f. bMention                               */
  1198. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  1199. /* Rückgabewerte: 0  OK                                                      */
  1200. /*                !=0 Fehler                                                 */
  1201. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  1202. /* Sonstiges:                                                                */
  1203. /*---------------------------------------------------------------------------*/
  1204.  
  1205. static  int ReadCCFile(FILE *pfImport, PCCANCHOR pCCAnchor, PCCLIST pDestList, ULONG ulFlags)
  1206. {
  1207.    char pchLine[500];
  1208.    char *pchTemp;
  1209.    CCENTRY NewCC;
  1210.    FTNADDRESS Addr;
  1211.  
  1212.    while (!feof(pfImport))
  1213.    {
  1214.       if (!fgets(pchLine, 500, pfImport))
  1215.          continue;
  1216.  
  1217.       StripWhitespace(pchLine);
  1218.  
  1219.       /* leere Zeile uebergehen */
  1220.       if (!pchLine[0])
  1221.          continue;
  1222.  
  1223.       /* Kommentarzeile uebergehen */
  1224.       if (pchLine[0]==';')
  1225.          continue;
  1226.  
  1227.       pchTemp = strrchr(pchLine, ' ');
  1228.  
  1229.       if (!pchTemp)  /* Fehler */
  1230.          continue;
  1231.  
  1232.       NewCC.ulFlags = ulFlags;
  1233.  
  1234.       *pchTemp = '\0';
  1235.       pchTemp++;
  1236.  
  1237.       /* Adresse ermitteln */
  1238.       strncpy(NewCC.pchAddress, pchTemp, LEN_5DADDRESS);
  1239.  
  1240.       StringToNetAddr(NewCC.pchAddress, &Addr, NULL);
  1241.       NetAddrToString(NewCC.pchAddress, &Addr);
  1242.  
  1243.       /* Name */
  1244.       pchTemp = strtok(pchLine, "\t ");
  1245.       NewCC.pchName[0]=0;
  1246.  
  1247.       while (pchTemp && (strlen(pchTemp)+strlen(NewCC.pchName)+
  1248.                          (NewCC.pchName[0]?1:0) <= LEN_USERNAME))
  1249.       {
  1250.          if (NewCC.pchName[0])
  1251.             strcat(NewCC.pchName, " ");
  1252.          strcat(NewCC.pchName, pchTemp);
  1253.  
  1254.          pchTemp = strtok(NULL, "\t ");
  1255.       }
  1256.  
  1257.       if (!NewCC.pchName[0])  /* kein Name */
  1258.          continue;
  1259.  
  1260.       NewCC.pchFirstLine[0]=0;
  1261.  
  1262.       /* an Liste anhaengen */
  1263.       AddCCEntry(pCCAnchor, pDestList, &NewCC);
  1264.    }
  1265.    return 0;
  1266. }
  1267.  
  1268.  
  1269. /*---------------------------------------------------------------------------*/
  1270. /* Funktionsname: AddEmptyCCList                                             */
  1271. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  1272. /* Beschreibung: Erzeugt eine neue CC-Liste                                  */
  1273. /*                                                                           */
  1274. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  1275. /* Parameter: hwndContainer: Container mit Templates                         */
  1276. /*            hptr: verwendetes Icon                                         */
  1277. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  1278. /* Rückgabewerte: Pointer auf neuen Template-Record                          */
  1279. /*                NULL: Fehler                                               */
  1280. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  1281. /* Sonstiges:                                                                */
  1282. /*                                                                           */
  1283. /*---------------------------------------------------------------------------*/
  1284.  
  1285. static PCCFOLDERRECORD AddEmptyCCList(HWND hwndContainer, HPOINTER hptr)
  1286. {
  1287.    PCCLIST pNewList;
  1288.    RECORDINSERT RecordInsert;
  1289.    PCCFOLDERRECORD pNewRecord;
  1290.    char pchNewName[50];
  1291.  
  1292.    pNewList = AddCCList(&ccanchor, CreateUniqueName(IDST_CC_NEWNAME, &ccanchor,
  1293.                                                     HaveCCListName,
  1294.                                                     sizeof(pchNewName), pchNewName));
  1295.  
  1296.    /* Record vom Container anfordern */
  1297.    pNewRecord = SendMsg(hwndContainer, CM_ALLOCRECORD,
  1298.                            MPFROMLONG(sizeof(CCFOLDERRECORD) - sizeof(MINIRECORDCORE)),
  1299.                            MPFROMLONG(1));
  1300.  
  1301.    if (pNewRecord)
  1302.    {
  1303.       pNewRecord->hwndContents = NULLHANDLE;
  1304.       pNewRecord->pList        = pNewList;
  1305.  
  1306.       pNewRecord->RecordCore.flRecordAttr = 0;
  1307.       pNewRecord->RecordCore.pszIcon = pNewList->pchListName;
  1308.       pNewRecord->RecordCore.hptrIcon = hptr;
  1309.  
  1310.       /* Record einfuegen */
  1311.       RecordInsert.cb = sizeof(RECORDINSERT);
  1312.       RecordInsert.pRecordOrder = (PRECORDCORE) CMA_END;
  1313.       RecordInsert.pRecordParent = NULL;
  1314.       RecordInsert.fInvalidateRecord = TRUE;
  1315.       RecordInsert.zOrder = CMA_TOP;
  1316.       RecordInsert.cRecordsInsert = 1;
  1317.  
  1318.       SendMsg(hwndContainer, CM_INSERTRECORD, pNewRecord, &RecordInsert);
  1319.  
  1320.       return pNewRecord;
  1321.    }
  1322.    else
  1323.       return NULL;
  1324. }
  1325.  
  1326. /*---------------------------------------------------------------------------*/
  1327. /* Funktionsname: FillCCFolder                                               */
  1328. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  1329. /* Beschreibung: Fuegt alle Objekte in den CC-Folder ein                     */
  1330. /*                                                                           */
  1331. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  1332. /* Parameter: hwndContainer: Container mit CC-Listen                         */
  1333. /*            hptr: verwendetes Icon                                         */
  1334. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  1335. /* Rückgabewerte: 0   OK                                                     */
  1336. /*                -1  Fehler                                                 */
  1337. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  1338. /* Sonstiges:                                                                */
  1339. /*                                                                           */
  1340. /*---------------------------------------------------------------------------*/
  1341.  
  1342. static  int FillCCFolder(HWND hwndContainer, HPOINTER hptr)
  1343. {
  1344.    RECORDINSERT RecordInsert;
  1345.    PCCFOLDERRECORD pRecord, pFirstRecord;
  1346.    ULONG ulNumLists=0;
  1347.    PCCLIST pList;
  1348.  
  1349.    ulNumLists = ccanchor.ulNumLists;
  1350.  
  1351.    if (ulNumLists == 0)
  1352.       return -1;
  1353.  
  1354.    /* Records vom Container anfordern */
  1355.    pFirstRecord = SendMsg(hwndContainer, CM_ALLOCRECORD,
  1356.                              MPFROMLONG(sizeof(CCFOLDERRECORD) - sizeof(MINIRECORDCORE)),
  1357.                              MPFROMLONG(ulNumLists));
  1358.    pRecord = pFirstRecord;
  1359.  
  1360.    pList = ccanchor.pLists;
  1361.    while (pRecord)
  1362.    {
  1363.       pRecord->hwndContents = NULLHANDLE;
  1364.       pRecord->pList        = pList;
  1365.  
  1366.       pRecord->RecordCore.flRecordAttr = 0;
  1367.       pRecord->RecordCore.pszIcon = pList->pchListName;
  1368.  
  1369.       pRecord->RecordCore.hptrIcon = hptr;
  1370.  
  1371.       pRecord = (PCCFOLDERRECORD) pRecord->RecordCore.preccNextRecord;
  1372.       pList = pList->next;
  1373.    }
  1374.  
  1375.    /* Records einfuegen */
  1376.    RecordInsert.cb = sizeof(RECORDINSERT);
  1377.    RecordInsert.pRecordOrder = (PRECORDCORE) CMA_END;
  1378.    RecordInsert.pRecordParent = NULL;
  1379.    RecordInsert.fInvalidateRecord = TRUE;
  1380.    RecordInsert.zOrder = CMA_TOP;
  1381.    RecordInsert.cRecordsInsert = ulNumLists;
  1382.  
  1383.    SendMsg(hwndContainer, CM_INSERTRECORD, pFirstRecord, &RecordInsert);
  1384.  
  1385.    return 0;
  1386. }
  1387.  
  1388. /*---------------------------------------------------------------------------*/
  1389. /* Funktionsname: OpenCCList                                                 */
  1390. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  1391. /* Beschreibung: Oeffnet ein CC-Listen-Objekt                                */
  1392. /*                                                                           */
  1393. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  1394. /* Parameter: hwndContainer: Container mit Objekt                            */
  1395. /*            pRecord: Record-Pointer der CC-Liste                           */
  1396. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  1397. /* Rückgabewerte: 0 OK                                                       */
  1398. /*                                                                           */
  1399. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  1400. /* Sonstiges: Ein bereits offenes Template bekommt lediglich den Fokus       */
  1401. /*                                                                           */
  1402. /*---------------------------------------------------------------------------*/
  1403.  
  1404. static  int OpenCCList(HWND hwndContainer, PCCFOLDERRECORD pRecord)
  1405. {
  1406.    CCLISTPAR CCListPar;
  1407.  
  1408.    if (pRecord->hwndContents)  /* schon offen ? */
  1409.       SetFocus(pRecord->hwndContents);
  1410.    else
  1411.    {
  1412.       /* in-use-emphasis setzen */
  1413.       SendMsg(hwndContainer, CM_SETRECORDEMPHASIS, pRecord,
  1414.                  MPFROM2SHORT(TRUE, CRA_INUSE));
  1415.  
  1416.       CCListPar.cb=sizeof(CCLISTPAR);
  1417.       CCListPar.pList=pRecord->pList;
  1418.       CCListPar.pCCAnchor=&ccanchor;
  1419.  
  1420.       pRecord->hwndContents=WinLoadDlg(HWND_DESKTOP, HWND_DESKTOP, CCListContentsProc,
  1421.                                        hmodLang, IDD_CCLIST, &CCListPar);
  1422.       WinShowWindow(pRecord->hwndContents, TRUE);
  1423.    }
  1424.  
  1425.    return 0;
  1426. }
  1427.  
  1428. /*---------------------------------------------------------------------------*/
  1429. /* Funktionsname: DeleteCCList                                               */
  1430. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  1431. /* Beschreibung: Loescht ein CC-List-Objekt                                  */
  1432. /*                                                                           */
  1433. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  1434. /* Parameter: hwndContainer: Container mit Objekt                            */
  1435. /*            pRecord: Record-Pointer der CC-Liste                           */
  1436. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  1437. /* Rückgabewerte: 0 OK                                                       */
  1438. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  1439. /* Sonstiges:                                                                */
  1440. /*                                                                           */
  1441. /*---------------------------------------------------------------------------*/
  1442.  
  1443. static  int DeleteCCListF(HWND hwndContainer, PCCFOLDERRECORD pRecord)
  1444. {
  1445.    /* offene Liste schliessen */
  1446.    if (pRecord->hwndContents)
  1447.       WinDestroyWindow(pRecord->hwndContents);
  1448.  
  1449.    /* Record im Container loeschen */
  1450.    SendMsg(hwndContainer, CM_REMOVERECORD, &pRecord,
  1451.               MPFROM2SHORT(1, CMA_INVALIDATE));
  1452.  
  1453.    DeleteCCList(&ccanchor, pRecord->pList);
  1454.  
  1455.    /* endgueltig aus Container entfernen */
  1456.    SendMsg(hwndContainer, CM_FREERECORD, &pRecord, MPFROMLONG(1));
  1457.  
  1458.    return 0;
  1459. }
  1460.  
  1461. /*---------------------------------------------------------------------------*/
  1462. /* Funktionsname: CleanupCCFolder                                            */
  1463. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  1464. /* Beschreibung: Entfernt alle Objekte aus dem CC-List-Folder                */
  1465. /*                                                                           */
  1466. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  1467. /* Parameter: hwndContainer: Container mit Objekt                            */
  1468. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  1469. /* Rückgabewerte: 0 OK                                                       */
  1470. /*                -1  Fehler                                                 */
  1471. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  1472. /* Sonstiges: Schliesst auch alle offenen CC-Listen                          */
  1473. /*                                                                           */
  1474. /*---------------------------------------------------------------------------*/
  1475.  
  1476. static  int CleanupCCFolder(HWND hwndContainer)
  1477. {
  1478.    PCCFOLDERRECORD pRecord = NULL;
  1479.  
  1480.    /* alle offenen Templates schliessen */
  1481.    while (pRecord = SendMsg(hwndContainer, CM_QUERYRECORD, pRecord,
  1482.                                MPFROM2SHORT(pRecord ? CMA_NEXT : CMA_FIRST,
  1483.                                             CMA_ITEMORDER)))
  1484.    {
  1485.       if (pRecord->hwndContents)
  1486.          WinDestroyWindow(pRecord->hwndContents);
  1487.    }
  1488.  
  1489.    /* Folder leeren */
  1490.    SendMsg(hwndContainer, CM_REMOVERECORD, NULL, MPFROM2SHORT(0, CMA_FREE));
  1491.  
  1492.    return 0;
  1493. }
  1494.  
  1495. /*---------------------------------------------------------------------------*/
  1496. /* Funktionsname: CCFolderProc                                               */
  1497. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  1498. /* Beschreibung: Fensterprozedur des CC-List-Folders                         */
  1499. /*                                                                           */
  1500. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  1501. /* Parameter: (WinProc)                                                      */
  1502. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  1503. /* Rückgabewerte: MRESULT                                                    */
  1504. /*                                                                           */
  1505. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  1506. /* Sonstiges:                                                                */
  1507. /*                                                                           */
  1508. /*---------------------------------------------------------------------------*/
  1509.  
  1510. MRESULT EXPENTRY CCFolderProc(HWND hwnd, ULONG message, MPARAM mp1, MPARAM mp2)
  1511. {
  1512.    extern WINDOWCOLORS windowcolors;
  1513.    extern WINDOWFONTS  windowfonts;
  1514.    extern GENERALOPT generaloptions;
  1515.    extern HWND hwndhelp, client;
  1516.    PCCFOLDERDATA pFolderData = (PCCFOLDERDATA) WinQueryWindowULong(hwnd, QWL_USER);
  1517.  
  1518.    switch (message)
  1519.    {
  1520.       case WM_INITDLG:
  1521.          /* Instanzdaten anfordern */
  1522.          pFolderData = malloc(sizeof(CCFOLDERDATA));
  1523.          memset(pFolderData, 0, sizeof(CCFOLDERDATA));
  1524.          WinSetWindowULong(hwnd, QWL_USER, (ULONG) pFolderData);
  1525.  
  1526.          OldContainerProc = WinSubclassWindow(WinWindowFromID(hwnd, IDD_CCFOLDER+1),
  1527.                                               NewCCContainerProc);
  1528.  
  1529.          /* Icon laden */
  1530.          pFolderData->hptrCCList = LoadIcon(IDIC_CCLIST);
  1531.          pFolderData->hptrCCFolder = LoadIcon(IDIC_CCFOLDER);
  1532.  
  1533.          SendMsg(hwnd, WM_SETICON, (MPARAM) pFolderData->hptrCCFolder, NULL);
  1534.  
  1535.          /* Switch-Entry */
  1536.          pFolderData->hSwitch=AddToWindowList(hwnd);
  1537.  
  1538.          /* Menues laden */
  1539.          pFolderData->hwndListPopup = WinLoadMenu(WinWindowFromID(hwnd, IDD_CCFOLDER+1),
  1540.                                                   hmodLang, IDM_CCF_POPUP);
  1541.          pFolderData->hwndFolderPopup = WinLoadMenu(WinWindowFromID(hwnd, IDD_CCFOLDER+1),
  1542.                                                     hmodLang, IDM_CCF_POPUP2);
  1543.  
  1544.          if (pFolderData->hwndFolderPopup)
  1545.             ReplaceSysMenu(hwnd, pFolderData->hwndFolderPopup, 1);
  1546.  
  1547.          if (ccanchor.ulFlags & CCANCHOR_FOREGROUND)
  1548.          {
  1549.             pFolderData->bForeground = TRUE;
  1550.             WinCheckMenuItem(pFolderData->hwndFolderPopup, IDM_CCF_FGROUND, TRUE);
  1551.             WinSetOwner(hwnd, client);
  1552.          }
  1553.          else
  1554.          {
  1555.             pFolderData->bForeground = FALSE;
  1556.             WinCheckMenuItem(pFolderData->hwndFolderPopup, IDM_CCF_FGROUND, FALSE);
  1557.             WinSetOwner(hwnd, HWND_DESKTOP);
  1558.          }
  1559.  
  1560.          /* Farben und Font setzen */
  1561.          SetBackground(WinWindowFromID(hwnd, IDD_CCFOLDER+1), &windowcolors.ccfolderback);
  1562.          SetForeground(WinWindowFromID(hwnd, IDD_CCFOLDER+1), &windowcolors.ccfolderfore);
  1563.          SetFont(WinWindowFromID(hwnd, IDD_CCFOLDER+1), windowfonts.ccfolderfont);
  1564.  
  1565.          /* Icons einfuegen */
  1566.          InitCCFolder(WinWindowFromID(hwnd, IDD_CCFOLDER+1));
  1567.          FillCCFolder(WinWindowFromID(hwnd, IDD_CCFOLDER+1),
  1568.                       pFolderData->hptrCCList);
  1569.          RestoreWinPos(hwnd, &ccanchor.FolderPos, TRUE, TRUE);
  1570.          pFolderData->bNotify = TRUE;
  1571.          break;
  1572.  
  1573.       case WM_DESTROY:
  1574.          /* Farben und Font */
  1575.          CleanupCCFolder(WinWindowFromID(hwnd, IDD_CCFOLDER+1));
  1576.          RemoveFromWindowList(pFolderData->hSwitch);
  1577.          QueryBackground(WinWindowFromID(hwnd, IDD_CCFOLDER+1), &windowcolors.ccfolderback);
  1578.          QueryForeground(WinWindowFromID(hwnd, IDD_CCFOLDER+1), &windowcolors.ccfolderfore);
  1579.          QueryFont(WinWindowFromID(hwnd, IDD_CCFOLDER+1), windowfonts.ccfolderfont);
  1580.          if (pFolderData->hptrCCList)
  1581.             WinDestroyPointer(pFolderData->hptrCCList);
  1582.          if (pFolderData->hptrCCFolder)
  1583.             WinDestroyPointer(pFolderData->hptrCCFolder);
  1584.          if (pFolderData->hwndListPopup)
  1585.             WinDestroyWindow(pFolderData->hwndListPopup);
  1586.          if (pFolderData->hwndFolderPopup)
  1587.             WinDestroyWindow(pFolderData->hwndFolderPopup);
  1588.  
  1589.          if (pFolderData->bForeground)
  1590.          {
  1591.             if (!(ccanchor.ulFlags & CCANCHOR_FOREGROUND))
  1592.             {
  1593.                ccanchor.ulFlags |= CCANCHOR_FOREGROUND;
  1594.                ccanchor.bDirty = TRUE;
  1595.             }
  1596.          }
  1597.          else
  1598.          {
  1599.             if (ccanchor.ulFlags & CCANCHOR_FOREGROUND)
  1600.             {
  1601.                ccanchor.ulFlags &= ~CCANCHOR_FOREGROUND;
  1602.                ccanchor.bDirty = TRUE;
  1603.             }
  1604.          }
  1605.  
  1606.          free(pFolderData);
  1607.          break;
  1608.  
  1609.       case WM_CONTROL:
  1610.          if (SHORT1FROMMP(mp1) == IDD_CCFOLDER+1)
  1611.          {
  1612.             switch(SHORT2FROMMP(mp1))
  1613.             {
  1614.                PCNREDITDATA pEdit;
  1615.                PCCFOLDERRECORD pRecord;
  1616.                PNOTIFYRECORDENTER pEnter;
  1617.  
  1618.                case CN_ENTER:
  1619.                   pEnter = (PNOTIFYRECORDENTER) mp2;
  1620.                   if (pEnter->pRecord)
  1621.                      OpenCCList(pEnter->hwndCnr,
  1622.                                 (PCCFOLDERRECORD) pEnter->pRecord);
  1623.                   break;
  1624.  
  1625.                case CN_REALLOCPSZ:
  1626.                   pEdit = (PCNREDITDATA) mp2;
  1627.                   pRecord = (PCCFOLDERRECORD) pEdit->pRecord;
  1628.                   free (pRecord->pList->pchListName);
  1629.                   pRecord->pList->pchListName = malloc(pEdit->cbText+1);
  1630.                   pRecord->pList->pchListName[0] = '\0';
  1631.                   pRecord->RecordCore.pszIcon = pRecord->pList->pchListName;
  1632.                   pRecord->pList->bDirty=TRUE;
  1633.                   ccanchor.bDirty = TRUE;
  1634.                   return (MRESULT) TRUE;
  1635.  
  1636.                case CN_ENDEDIT:
  1637.                   /* Template offen ? */
  1638.                   pEdit = (PCNREDITDATA) mp2;
  1639.                   if (((PCCFOLDERRECORD)pEdit->pRecord)->hwndContents)
  1640.                      SendMsg(((PCCFOLDERRECORD)pEdit->pRecord)->hwndContents, CCM_UPDATENAME, NULL, NULL);
  1641.                   WinSendDlgItemMsg(hwnd, IDD_CCFOLDER+1, CM_SORTRECORD, MPFROMP(SortCCFolder), NULL);
  1642.                   break;
  1643.  
  1644.                case CN_INITDRAG:
  1645.                   pFolderData->pDragRecord = (PCCFOLDERRECORD) ((PCNRDRAGINIT) mp2)->pRecord;
  1646.                   InitCCListDrag(hwnd, (PCNRDRAGINIT) mp2);
  1647.                   break;
  1648.  
  1649.                case CN_CONTEXTMENU:
  1650.                   pFolderData->pPopupRecord = (PCCFOLDERRECORD) mp2;
  1651.                   if (pFolderData->pPopupRecord)
  1652.                   {
  1653.                      /* Popup-Menue eines Templates */
  1654.                      RECTL rcl;
  1655.                      POINTL ptl;
  1656.                      QUERYRECORDRECT QRecord;
  1657.  
  1658.                      if (pFolderData->pPopupRecord->pList->ulListID == ulCCSelected)
  1659.                         WinEnableMenuItem(pFolderData->hwndListPopup, IDM_CCF_DELETE, FALSE);
  1660.                      else
  1661.                         WinEnableMenuItem(pFolderData->hwndListPopup, IDM_CCF_DELETE, TRUE);
  1662.  
  1663.                      QRecord.cb = sizeof(QUERYRECORDRECT);
  1664.                      QRecord.pRecord = (PRECORDCORE) pFolderData->pPopupRecord;
  1665.                      QRecord.fRightSplitWindow = FALSE;
  1666.                      QRecord.fsExtent = CMA_ICON;
  1667.                      WinSendDlgItemMsg(hwnd, IDD_CCFOLDER+1, CM_QUERYRECORDRECT,
  1668.                                        &rcl, &QRecord);
  1669.                      ptl.x = rcl.xRight;
  1670.                      ptl.y = rcl.yBottom;
  1671.                      WinMapWindowPoints(WinWindowFromID(hwnd, IDD_CCFOLDER+1),
  1672.                                         HWND_DESKTOP, &ptl, 1);
  1673.                      WinPopupMenu(HWND_DESKTOP, hwnd, pFolderData->hwndListPopup,
  1674.                                   ptl.x, ptl.y, 0,
  1675.                                   PU_HCONSTRAIN | PU_VCONSTRAIN | PU_KEYBOARD |
  1676.                                   PU_MOUSEBUTTON1);
  1677.                   }
  1678.                   else
  1679.                   {
  1680.                      /* Popup-Menue des Folders */
  1681.                      POINTL ptl;
  1682.  
  1683.                      WinQueryPointerPos(HWND_DESKTOP, &ptl);
  1684.                      WinPopupMenu(HWND_DESKTOP, hwnd, pFolderData->hwndFolderPopup,
  1685.                                   ptl.x, ptl.y, 0,
  1686.                                   PU_HCONSTRAIN | PU_VCONSTRAIN | PU_KEYBOARD |
  1687.                                   PU_MOUSEBUTTON1);
  1688.                   }
  1689.                   break;
  1690.  
  1691.                case CN_HELP:
  1692.                   SendMsg(hwnd, WM_HELP, MPFROMSHORT(IDD_CCFOLDER+1), NULL);
  1693.                   break;
  1694.  
  1695.                case CN_DROP:
  1696.                   CCFolderDrop(WinWindowFromID(hwnd, IDD_CCFOLDER+1), (PCNRDRAGINFO) mp2);
  1697.                   break;
  1698.  
  1699.                case CN_DRAGOVER:
  1700.                   return CCFolderDragOver(WinWindowFromID(hwnd, IDD_CCFOLDER+1), (PCNRDRAGINFO) mp2);
  1701.  
  1702.                default:
  1703.                   break;
  1704.             }
  1705.          }
  1706.          break;
  1707.  
  1708.       case DM_DISCARDOBJECT:
  1709.          DrgAccessDraginfo((PDRAGINFO) mp1);
  1710.          DeleteCCListF(WinWindowFromID(hwnd, IDD_CCFOLDER+1),
  1711.                        pFolderData->pDragRecord);
  1712.          DrgFreeDraginfo((PDRAGINFO) mp1);
  1713.          return (MRESULT) DRR_SOURCE;
  1714.  
  1715.       case WM_MENUEND:
  1716.          if ((HWND) mp2 == pFolderData->hwndListPopup ||
  1717.              (HWND) mp2 == pFolderData->hwndFolderPopup)
  1718.          {
  1719.             /* Emphasis wegnehmen */
  1720.             WinSendDlgItemMsg(hwnd, IDD_CCFOLDER+1, CM_SETRECORDEMPHASIS,
  1721.                               pFolderData->pPopupRecord,
  1722.                               MPFROM2SHORT(FALSE, CRA_SOURCE));
  1723.             if ( (HWND) mp2 == pFolderData->hwndFolderPopup)
  1724.                ResetMenuStyle(pFolderData->hwndFolderPopup, hwnd);
  1725.          }
  1726.          break;
  1727.  
  1728.       case WM_INITMENU:
  1729.          if ((HWND) mp2 == pFolderData->hwndFolderPopup)
  1730.             pFolderData->pPopupRecord=NULL;
  1731.          if ((HWND) mp2 == pFolderData->hwndListPopup ||
  1732.              (HWND) mp2 == pFolderData->hwndFolderPopup)
  1733.          {
  1734.             /* Emphasis setzen */
  1735.             WinSendDlgItemMsg(hwnd, IDD_CCFOLDER+1, CM_SETRECORDEMPHASIS,
  1736.                               pFolderData->pPopupRecord,
  1737.                               MPFROM2SHORT(TRUE, CRA_SOURCE));
  1738.          }
  1739.          break;
  1740.  
  1741.       case WM_ACTIVATE:
  1742.          if (mp1)
  1743.             WinAssociateHelpInstance(hwndhelp, hwnd);
  1744.          else
  1745.             WinAssociateHelpInstance(hwndhelp, NULLHANDLE);
  1746.          break;
  1747.  
  1748.       case WM_CONTEXTMENU:
  1749.       case WM_TEXTEDIT:
  1750.          if (!SHORT1FROMMP(mp1) &&
  1751.              WinQueryFocus(HWND_DESKTOP) == WinWindowFromID(hwnd, IDD_CCFOLDER+1))
  1752.          {
  1753.             WinSendDlgItemMsg(hwnd, IDD_CCFOLDER+1, message,
  1754.                               mp1, mp2);
  1755.          }
  1756.          break;
  1757.  
  1758.       case WM_CLOSE:
  1759.          WinPostMsg(client, CCFM_CLOSE, NULL, NULL);
  1760.          break;
  1761.  
  1762.       case WM_ADJUSTWINDOWPOS:
  1763.          if (((PSWP)mp1)->fl & SWP_MINIMIZE)
  1764.             WinShowWindow(WinWindowFromID(hwnd, IDD_CCFOLDER+1), FALSE);
  1765.          if (((PSWP)mp1)->fl & (SWP_MAXIMIZE|SWP_RESTORE))
  1766.             WinShowWindow(WinWindowFromID(hwnd, IDD_CCFOLDER+1), TRUE);
  1767.          break;
  1768.  
  1769.       case WM_ADJUSTFRAMEPOS:
  1770.          SizeToClient(anchor, (PSWP) mp1, hwnd, IDD_CCFOLDER+1);
  1771.          break;
  1772.  
  1773.       case WM_WINDOWPOSCHANGED:
  1774.          if (pFolderData && pFolderData->bNotify)
  1775.             SaveWinPos(hwnd, (PSWP) mp1, &ccanchor.FolderPos, &ccanchor.bDirty);
  1776.          break;
  1777.  
  1778.       case WM_COMMAND:
  1779.          switch(SHORT1FROMMP(mp1))
  1780.          {
  1781.             PCCFOLDERRECORD pNewCCList;
  1782.  
  1783.             case IDM_CCF_OPEN:
  1784.                OpenCCList(WinWindowFromID(hwnd, IDD_CCFOLDER+1),
  1785.                           pFolderData->pPopupRecord);
  1786.                return (MRESULT) FALSE;
  1787.  
  1788.             case IDM_CCF_CREATE:
  1789.                if (pNewCCList = AddEmptyCCList(WinWindowFromID(hwnd, IDD_CCFOLDER+1),
  1790.                                                pFolderData->hptrCCList))
  1791.                   OpenCCList(WinWindowFromID(hwnd, IDD_CCFOLDER+1), pNewCCList);
  1792.                return (MRESULT) FALSE;
  1793.  
  1794.             case IDM_CCF_DELETE:
  1795.                if (generaloptions.safety & SAFETY_CHANGESETUP)
  1796.                   if (MessageBox(hwnd, IDST_TITLE_DELCCLIST, IDST_MSG_DELCCLIST,
  1797.                                  IDD_DELCCLIST, MB_YESNO| MB_QUERY| MB_DEFBUTTON2) != MBID_YES)
  1798.                      return (MRESULT) FALSE;
  1799.                DeleteCCListF(WinWindowFromID(hwnd, IDD_CCFOLDER+1),
  1800.                              pFolderData->pPopupRecord);
  1801.                return (MRESULT) FALSE;
  1802.  
  1803.             case DID_CANCEL:
  1804.                break;
  1805.  
  1806.             case IDM_CCF_FGROUND:
  1807.                if (pFolderData->bForeground)
  1808.                {
  1809.                   pFolderData->bForeground = FALSE;
  1810.                   WinCheckMenuItem(pFolderData->hwndFolderPopup, IDM_CCF_FGROUND, FALSE);
  1811.                   WinSetOwner(hwnd, HWND_DESKTOP);
  1812.                }
  1813.                else
  1814.                {
  1815.                   pFolderData->bForeground = TRUE;
  1816.                   WinCheckMenuItem(pFolderData->hwndFolderPopup, IDM_CCF_FGROUND, TRUE);
  1817.                   WinSetOwner(hwnd, client);
  1818.                }
  1819.                return (MRESULT) FALSE;
  1820.  
  1821.             default:
  1822.                return (MRESULT) FALSE;
  1823.          }
  1824.          return (MRESULT) FALSE;
  1825.  
  1826.       case CCM_CLOSE:
  1827.          CCListClosed(WinWindowFromID(hwnd, IDD_CCFOLDER+1),
  1828.                       (HWND) mp1);
  1829.          break;
  1830.  
  1831.       case CCM_UPDATELIST:
  1832.          CCListSendUpdate(WinWindowFromID(hwnd, IDD_CCFOLDER+1), (ULONG) mp1);
  1833.          break;
  1834.  
  1835.       default:
  1836.          break;
  1837.    }
  1838.    return WinDefDlgProc(hwnd, message, mp1, mp2);
  1839. }
  1840.  
  1841. /*---------------------------------------------------------------------------*/
  1842. /* Funktionsname: InitCCListDrag                                             */
  1843. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  1844. /* Beschreibung: Startet Drag für eine CC-Liste                              */
  1845. /*                                                                           */
  1846. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  1847. /* Parameter: hwndDlg: Dialog-Window-Handle                                  */
  1848. /*            pInit:   Drag-Init-Infos vom Container                         */
  1849. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  1850. /* Rückgabewerte: 0  OK                                                      */
  1851. /*                -1 Fehler                                                  */
  1852. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  1853. /* Sonstiges:                                                                */
  1854. /*                                                                           */
  1855. /*---------------------------------------------------------------------------*/
  1856.  
  1857. static  int InitCCListDrag(HWND hwndDlg, PCNRDRAGINIT pInit)
  1858. {
  1859.    PDRAGINFO pDraginfo;
  1860.    DRAGITEM dItem;
  1861.    DRAGIMAGE dImage;
  1862.  
  1863.    if (!pInit->pRecord)
  1864.       return -1;
  1865.  
  1866.    if (((PCCFOLDERRECORD)pInit->pRecord)->pList->ulListID == ulCCSelected)
  1867.       return -1;
  1868.  
  1869.    WinSendDlgItemMsg(hwndDlg, IDD_CCFOLDER+1, CM_SETRECORDEMPHASIS,
  1870.                      pInit->pRecord, MPFROM2SHORT(TRUE, CRA_SOURCE));
  1871.  
  1872.    pDraginfo = DrgAllocDraginfo(1);
  1873.    pDraginfo->usOperation=DO_MOVE;
  1874.    pDraginfo->hwndSource=hwndDlg;
  1875.  
  1876.    /* Drag-Item vorbereiten*/
  1877.    dItem.hwndItem=hwndDlg;
  1878.    dItem.ulItemID= ((PCCFOLDERRECORD)pInit->pRecord)->pList->ulListID;
  1879.    dItem.hstrType=DrgAddStrHandle(CCLISTDRAGTYPE);
  1880.    dItem.hstrRMF=DrgAddStrHandle(CCLISTRMF);
  1881.    dItem.hstrSourceName=DrgAddStrHandle(pInit->pRecord->pszIcon);
  1882.    dItem.hstrTargetName=DrgAddStrHandle(pInit->pRecord->pszIcon);
  1883.    if (((PCCFOLDERRECORD) pInit->pRecord)->hwndContents)
  1884.       dItem.fsControl= DC_OPEN;
  1885.    else
  1886.       dItem.fsControl=0;
  1887.    dItem.fsSupportedOps=DO_MOVEABLE;
  1888.    DrgSetDragitem(pDraginfo, &dItem, sizeof(dItem), 0);
  1889.  
  1890.    /* Drag-Image vorbereiten */
  1891.    dImage.cb=sizeof(DRAGIMAGE);
  1892.    dImage.hImage=pInit->pRecord->hptrIcon;
  1893.    dImage.fl=DRG_ICON;
  1894.    dImage.cxOffset=0;
  1895.    dImage.cyOffset=0;
  1896.  
  1897.    /* Und los gehts */
  1898.    DrgDrag(hwndDlg, pDraginfo, &dImage, 1, VK_ENDDRAG, NULL);
  1899.    DrgFreeDraginfo(pDraginfo);
  1900.  
  1901.    WinSendDlgItemMsg(hwndDlg, IDD_CCFOLDER+1, CM_SETRECORDEMPHASIS,
  1902.                      pInit->pRecord, MPFROM2SHORT(FALSE, CRA_SOURCE));
  1903.  
  1904.    return 0;
  1905. }
  1906.  
  1907. /*---------------------------------------------------------------------------*/
  1908. /* Funktionsname: CCListClosed                                               */
  1909. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  1910. /* Beschreibung: Raeumt nach dem Schliessen einer CC-Liste  wieder auf       */
  1911. /*                                                                           */
  1912. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  1913. /* Parameter: hwndCnr: Container-Window                                      */
  1914. /*            hwndList: Window-Handle der geschlossenen Liste                */
  1915. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  1916. /* Rückgabewerte: -                                                          */
  1917. /*                                                                           */
  1918. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  1919. /* Sonstiges:                                                                */
  1920. /*                                                                           */
  1921. /*---------------------------------------------------------------------------*/
  1922.  
  1923. static  void CCListClosed(HWND hwndCnr, HWND hwndList)
  1924. {
  1925.    PCCFOLDERRECORD pRecord = NULL;
  1926.  
  1927.    while (pRecord = SendMsg(hwndCnr, CM_QUERYRECORD, pRecord,
  1928.                                MPFROM2SHORT(pRecord ? CMA_NEXT : CMA_FIRST,
  1929.                                             CMA_ITEMORDER)))
  1930.    {
  1931.       if (pRecord->hwndContents == hwndList)
  1932.       {
  1933.          if (pRecord->hwndContents)
  1934.             WinDestroyWindow(pRecord->hwndContents);
  1935.          pRecord->hwndContents = NULLHANDLE;
  1936.  
  1937.          SendMsg(hwndCnr, CM_SETRECORDEMPHASIS, pRecord,
  1938.                     MPFROM2SHORT(FALSE, CRA_INUSE));
  1939.          break;
  1940.       }
  1941.    }
  1942.  
  1943.    return;
  1944. }
  1945.  
  1946. /*---------------------------------------------------------------------------*/
  1947. /* Funktionsname: CCListSendUpdate                                           */
  1948. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  1949. /* Beschreibung: Sendet eine Updatemessage an die CC-Liste, falls sie offen  */
  1950. /*               ist                                                         */
  1951. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  1952. /* Parameter: hwndCnr: Container-Window                                      */
  1953. /*            uListID: List-ID                                               */
  1954. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  1955. /* Rückgabewerte: -                                                          */
  1956. /*                                                                           */
  1957. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  1958. /* Sonstiges:                                                                */
  1959. /*                                                                           */
  1960. /*---------------------------------------------------------------------------*/
  1961.  
  1962. static  void CCListSendUpdate(HWND hwndCnr, ULONG ulListID)
  1963. {
  1964.    PCCFOLDERRECORD pRecord = NULL;
  1965.  
  1966.    while (pRecord = SendMsg(hwndCnr, CM_QUERYRECORD, pRecord,
  1967.                                MPFROM2SHORT(pRecord ? CMA_NEXT : CMA_FIRST,
  1968.                                             CMA_ITEMORDER)))
  1969.    {
  1970.       if (pRecord->pList->ulListID == ulListID)
  1971.       {
  1972.          if (pRecord->hwndContents)
  1973.             SendMsg(pRecord->hwndContents, CCM_UPDATELIST, NULL, NULL);
  1974.          break;
  1975.       }
  1976.    }
  1977.  
  1978.    return;
  1979. }
  1980.  
  1981. /*---------------------------------------------------------------------------*/
  1982. /* Funktionsname: CCFolderDragOver                                           */
  1983. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  1984. /* Beschreibung: Behandelt Drag-Over des CC-Folders                          */
  1985. /*                                                                           */
  1986. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  1987. /* Parameter: hwndCnr: Container-Window                                      */
  1988. /*            pCnrDrag: Drag-Infos des Containers                            */
  1989. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  1990. /* Rückgabewerte: siehe CN_DRAGOVER                                          */
  1991. /*                                                                           */
  1992. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  1993. /* Sonstiges:                                                                */
  1994. /*                                                                           */
  1995. /*---------------------------------------------------------------------------*/
  1996.  
  1997. static  MRESULT CCFolderDragOver(HWND hwndCnr, PCNRDRAGINFO pCnrDrag)
  1998. {
  1999.    USHORT usDrop = DOR_NEVERDROP;
  2000.    USHORT usDefaultOp = DO_UNKNOWN;
  2001.  
  2002.    hwndCnr = hwndCnr;
  2003.  
  2004.    if (pCnrDrag->pRecord)
  2005.    {
  2006.       DrgAccessDraginfo(pCnrDrag->pDragInfo);
  2007.       usDefaultOp = pCnrDrag->pDragInfo->usOperation;
  2008.       if (usDefaultOp == DO_COPY ||
  2009.           usDefaultOp == DO_MOVE ||
  2010.           usDefaultOp == DO_DEFAULT )
  2011.       {
  2012.          if (WinQueryAnchorBlock(pCnrDrag->pDragInfo->hwndSource) == anchor)
  2013.          {
  2014.             PDRAGITEM pdItem;
  2015.             pdItem = DrgQueryDragitemPtr(pCnrDrag->pDragInfo, 0);
  2016.  
  2017.             if (DrgVerifyType(pdItem, CCDRAGTYPE))
  2018.             {
  2019.                usDrop = DOR_DROP;
  2020.                if (usDefaultOp == DO_DEFAULT)
  2021.                   usDefaultOp = DO_MOVE;
  2022.             }
  2023.             else
  2024.                if (DrgVerifyType(pdItem, NODEDRAGTYPE))
  2025.                {
  2026.                   usDrop = DOR_DROP;
  2027.                   if (usDefaultOp == DO_DEFAULT)
  2028.                      usDefaultOp = DO_COPY;
  2029.                }
  2030.          }
  2031.       }
  2032.       else
  2033.          usDrop = DOR_NODROPOP;
  2034.  
  2035.       DrgFreeDraginfo(pCnrDrag->pDragInfo);
  2036.    }
  2037.    else
  2038.       usDrop = DOR_NODROP;
  2039.  
  2040.    return MRFROM2SHORT(usDrop, usDefaultOp);
  2041. }
  2042.  
  2043. /*---------------------------------------------------------------------------*/
  2044. /* Funktionsname: CCFolderDrop                                               */
  2045. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  2046. /* Beschreibung: Behandelt Drop auf den CC-Folder                            */
  2047. /*                                                                           */
  2048. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  2049. /* Parameter: hwndCnr: Container-Window                                      */
  2050. /*            pCnrDrag: Drag-Infos des Containers                            */
  2051. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  2052. /* Rückgabewerte: -                                                          */
  2053. /*                                                                           */
  2054. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  2055. /* Sonstiges:                                                                */
  2056. /*                                                                           */
  2057. /*---------------------------------------------------------------------------*/
  2058.  
  2059. static  void CCFolderDrop(HWND hwndCnr, PCNRDRAGINFO pCnrDrag)
  2060. {
  2061.    PCCENTRY pSource;
  2062.    ULONG ulNum;
  2063.    int i;
  2064.    BOOL bNeedUpdate=FALSE;
  2065.  
  2066.    hwndCnr = hwndCnr;
  2067.  
  2068.    DrgAccessDraginfo(pCnrDrag->pDragInfo);
  2069.  
  2070.    if (pCnrDrag->pDragInfo->usOperation == DO_MOVE ||
  2071.        pCnrDrag->pDragInfo->usOperation == DO_COPY ||
  2072.        pCnrDrag->pDragInfo->usOperation == DO_DEFAULT)
  2073.    {
  2074.       PDRAGITEM pItem;
  2075.  
  2076.       ulNum = DrgQueryDragitemCount(pCnrDrag->pDragInfo);
  2077.       for (i=0; i < ulNum; i++)
  2078.       {
  2079.          pItem=DrgQueryDragitemPtr(pCnrDrag->pDragInfo, i);
  2080.  
  2081.          if (DrgVerifyType(pItem, CCDRAGTYPE))
  2082.          {
  2083.             pSource=(PCCENTRY)pItem->ulItemID;
  2084.             AddCCEntry(&ccanchor, ((PCCFOLDERRECORD)pCnrDrag->pRecord)->pList, pSource);
  2085.             bNeedUpdate=TRUE;
  2086.  
  2087.             if (pCnrDrag->pDragInfo->usOperation == DO_MOVE)
  2088.             {
  2089.                SendMsg(pCnrDrag->pDragInfo->hwndSource, DM_DISCARDOBJECT,
  2090.                           pCnrDrag->pDragInfo, NULL);
  2091.             }
  2092.          }
  2093.          else
  2094.             if (DrgVerifyType(pItem, NODEDRAGTYPE))
  2095.             {
  2096.                /* Node-Eintrag, neu erzeugen */
  2097.                CCENTRY NewCC;
  2098.                char pchTemp[LEN_5DADDRESS+LEN_USERNAME+2];
  2099.                char *pchTemp2;
  2100.  
  2101.                DrgQueryStrName(pItem->hstrSourceName, sizeof(pchTemp)-1, pchTemp);
  2102.                pchTemp2 = strchr(pchTemp, ' ');
  2103.                *pchTemp2 = 0;
  2104.                pchTemp2++;
  2105.  
  2106.                strcpy(NewCC.pchName, pchTemp2);
  2107.                strcpy(NewCC.pchAddress, pchTemp);
  2108.                NewCC.ulFlags = CCENTRY_MENTION;
  2109.  
  2110.                /* einfuegen */
  2111.                AddCCEntry(&ccanchor, ((PCCFOLDERRECORD)pCnrDrag->pRecord)->pList, &NewCC);
  2112.                bNeedUpdate = TRUE;
  2113.             }
  2114.       }
  2115.    }
  2116.  
  2117.    DrgDeleteDraginfoStrHandles(pCnrDrag->pDragInfo);
  2118.    DrgFreeDraginfo(pCnrDrag->pDragInfo);
  2119.  
  2120.    if (bNeedUpdate)
  2121.       if (((PCCFOLDERRECORD)pCnrDrag->pRecord)->hwndContents)
  2122.          SendMsg(((PCCFOLDERRECORD)pCnrDrag->pRecord)->hwndContents, CCM_UPDATELIST,
  2123.                     NULL, NULL);
  2124.  
  2125.    return;
  2126. }
  2127.  
  2128. static SHORT EXPENTRY SortCCFolder(PCCFOLDERRECORD p1, PCCFOLDERRECORD p2, PVOID pStorage)
  2129. {
  2130.    pStorage = pStorage;
  2131.    return stricmp(p1->RecordCore.pszIcon, p2->RecordCore.pszIcon);
  2132. }
  2133.  
  2134. static void InitCCFolder(HWND hwndCnr)
  2135. {
  2136.    CNRINFO cnrinfo;
  2137.  
  2138.    cnrinfo.cb = sizeof(cnrinfo);
  2139.    cnrinfo.pSortRecord=(PVOID)SortCCFolder;
  2140.  
  2141.    WinSendMsg(hwndCnr, CM_SETCNRINFO, &cnrinfo, MPFROMLONG(CMA_PSORTRECORD));
  2142.    return;
  2143. }
  2144.  
  2145. /*-------------------------------- Modulende --------------------------------*/
  2146.