home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 2 BBS / 02-BBS.zip / fsrc1241.zip / echomanager.c < prev    next >
C/C++ Source or Header  |  1999-02-14  |  96KB  |  2,412 lines

  1. /*---------------------------------------------------------------------------+
  2.  | Titel: ECHOMANAGER.C                                                      |
  3.  +-----------------------------------------+---------------------------------+
  4.  | Erstellt von: Michael Hohner            | Am: 16.04.1995                  |
  5.  +-----------------------------------------+---------------------------------+
  6.  | System: OS/2 2.x PM                                                       |
  7.  +---------------------------------------------------------------------------+
  8.  | Beschreibung:                                                             |
  9.  |                                                                           |
  10.  |     Echo-Manager von FleetStreet                                          |
  11.  |                                                                           |
  12.  |                                                                           |
  13.  +---------------------------------------------------------------------------+
  14.  | Bemerkungen:                                                              |
  15.  +---------------------------------------------------------------------------*/
  16.  
  17. /*----------------------------- Header-Dateien ------------------------------*/
  18. #pragma strings(readonly)
  19.  
  20. #define INCL_BASE
  21. #define INCL_WIN
  22. #include <os2.h>
  23. #include <stdlib.h>
  24. #include <string.h>
  25. #include <stdio.h>
  26. #include <ctype.h>
  27. #include "main.h"
  28. #include "resids.h"
  29. #include "messages.h"
  30. #include "structs.h"
  31. #include "msgheader.h"
  32. #include "areaman\areaman.h"
  33. #include "utility.h"
  34. #include "dialogids.h"
  35. #include "handlemsg\handlemsg.h"
  36. #include "handlemsg\kludgeapi.h"
  37. #include "areadlg.h"
  38. #include "setupdlg.h"
  39. #include "savemsg.h"
  40. #include "devkit\echoman.h"
  41. #include "util\fltutil.h"
  42. #include "util\addrcnv.h"
  43. #include "dump\expt.h"
  44.  
  45. #include "echomanager.h"
  46.  
  47.  
  48. /*--------------------------------- Defines ---------------------------------*/
  49.  
  50. #define ECHOMGR_STRINGLEN  50
  51.  
  52. #ifndef CRA_SOURCE
  53. #define CRA_SOURCE  0x00004000L
  54. #endif
  55.  
  56. #define TAB_FONT    "8.Helv"
  57. #define RGB_GREY    0x00cccccc
  58.  
  59. #define TEXTBLOCKSIZE   4096
  60.  
  61. #define CMD_LINK       "+%s\n"
  62. #define CMD_LNKRESC    "+%s\n%%RESCAN %s\n"
  63. #define CMD_UNLINK     "-%s\n"
  64. #define CMD_RESCAN     "%%RESCAN %s\n"
  65. #define CMD_REFRESH    "%LIST\n"
  66. #define CMD_PAUSE      "%PAUSE\n"
  67. #define CMD_RESUME     "%RESUME\n"
  68.  
  69. #define WM_SAVEDONE     WM_USER
  70. #define WM_CHANGEDONE   (WM_USER+1)
  71. #define WM_CURRENTDEL   (WM_USER+2)
  72.  
  73. /*---------------------------------- Typen ----------------------------------*/
  74.  
  75. typedef struct
  76. {
  77.    MINIRECORDCORE RecordCore;
  78.    PCHAR pchEchoName;
  79.    PCHAR pchStatus;
  80.    PCHAR pchAction;
  81.    ULONG ulAction;
  82.    ULONG ulStatus;
  83. } ECHOMGRRECORD, *PECHOMGRRECORD;
  84.  
  85. #define ACTION_NONE    0UL
  86. #define ACTION_LINK    1UL
  87. #define ACTION_UNLINK  2UL
  88. #define ACTION_RESCAN  3UL
  89. #define ACTION_PAUSE   4UL
  90. #define ACTION_RESUME  5UL
  91. #define ACTION_REFRESH 6UL
  92. #define ACTION_LNKRESC 7UL
  93.  
  94. #define STATUS_UNLINKED 0UL
  95. #define STATUS_LINKED   1UL
  96.  
  97. typedef struct
  98. {
  99.    HWND hwndDlg;
  100.    FTNMESSAGE Message;
  101.    MSGHEADER Header;
  102. } SAVEPARAM, *PSAVEPARAM;
  103.  
  104. typedef struct
  105. {
  106.    USHORT  usID;    /* Menue-ID */
  107.    PUPLINK pUplink; /* zugehoeriger Uplink */
  108. } MENUTABLE, *PMENUTABLE;
  109.  
  110. typedef struct
  111. {
  112.    HWND hwndPopup;
  113.    HWND hwndFolderPopup;
  114.    char pchTitleEcho[ECHOMGR_STRINGLEN];
  115.    char pchTitleStatus[ECHOMGR_STRINGLEN];
  116.    char pchTitleAction[ECHOMGR_STRINGLEN];
  117.    char pchStatusLinked[ECHOMGR_STRINGLEN];
  118.    char pchStatusUnlinked[ECHOMGR_STRINGLEN];
  119.    char pchActionLink[ECHOMGR_STRINGLEN];
  120.    char pchActionUnlink[ECHOMGR_STRINGLEN];
  121.    char pchActionRescan[ECHOMGR_STRINGLEN];
  122.    char pchActionRefresh[ECHOMGR_STRINGLEN];
  123.    char pchActionPause[ECHOMGR_STRINGLEN];
  124.    char pchActionResume[ECHOMGR_STRINGLEN];
  125.    ULONG ulAction;
  126.    BOOL bNotify;
  127.    BOOL bKeyboard;
  128.    PECHOMGRRECORD pPopupRecord;
  129.    SAVEPARAM SaveParam;
  130.    PUPLINK pUplink;
  131.    PMENUTABLE pMenuTable;
  132.    ULONG ulCountUplinks;
  133. } ECHOMGRDATA, *PECHOMGRDATA;
  134.  
  135. typedef struct
  136. {
  137.    USHORT cb;
  138.    PUPLINK pUplink;
  139.    HWND hwndSettingsDlg;
  140.    PECHOMGRDATA pEchoMgrData;
  141. } EMANSETTINGSDATA, *PEMANSETTINGSDATA;
  142.  
  143. typedef struct stringlist
  144. {
  145.    struct stringlist *next;
  146.    char *pchString;
  147. } STRINGLIST, *PSTRINGLIST;
  148.  
  149. typedef struct actionlist
  150. {
  151.    struct actionlist *next;
  152.    ULONG ulAction;
  153.    char pchAreaTag[LEN_AREATAG+1];
  154. } ACTIONLIST, *PACTIONLIST;
  155.  
  156. typedef struct
  157. {
  158.    HWND hwndDlg;
  159.    PACTIONLIST pActionList;
  160.    PUPLINK pUplink;
  161. } CHANGEPARAM, *PCHANGEPARAM;
  162.  
  163. typedef struct
  164. {
  165.   USHORT cb;
  166.   PUPLINK pUplink;
  167. } UPLINKPARAM, *PUPLINKPARAM;
  168.  
  169. typedef struct
  170. {
  171.    HMODULE hModule;
  172.    ULONG (* APIENTRY QueryVersion)(VOID);
  173.    ULONG (* APIENTRY QueryParamBlockSize)(VOID);
  174.    ULONG (* APIENTRY SetupParams)(PVOID, ULONG, HWND, HAB, HMODULE);
  175.    ULONG (* APIENTRY AddEcho)(PVOID, ULONG, PCHAR, PCHAR, PCHAR, PCHAR, ULONG);
  176.    ULONG (* APIENTRY RemoveEcho)(PVOID, ULONG, PCHAR, PCHAR, PCHAR, PCHAR, ULONG);
  177. } FUNCTABLE, *PFUNCTABLE;
  178.  
  179. #define LOADDLL_OK          0
  180. #define LOADDLL_CANTLOAD    1
  181. #define LOADDLL_VERSION     2
  182. #define LOADDLL_FUNCMISSING 3
  183.  
  184. /*---------------------------- Globale Variablen ----------------------------*/
  185.  
  186. extern HAB anchor;
  187. extern HMODULE hmodLang;
  188.  
  189. extern ECHOMGROPT EchoMgrOpt;
  190.  
  191. /*--------------------------- Funktionsprototypen ---------------------------*/
  192.  
  193. /*----------------------- interne Funktionsprototypen -----------------------*/
  194. static void InsertEchos(HWND hwndCnr, PECHOMGRDATA pEchoMgrData);
  195. static void CleanupContainer(HWND hwndCnr);
  196. static void OpenPopup(HWND hwndDlg, PECHOMGRRECORD pRecord, PECHOMGRDATA pEchoMgrData);
  197. static MRESULT EXPENTRY EchoMgrSettings(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2);
  198. static void InsertPages(HWND hwndDlg, PVOID pParam);
  199. static MRESULT EXPENTRY UplinkSettings(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2);
  200. static MRESULT EXPENTRY DllSettings(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2);
  201. static char *CreateMessageText(HWND hwndCnr, PECHOMGRDATA pEchoMgrData);
  202. static PACTIONLIST CreateActionList(HWND hwndCnr);
  203. static int CreateMessage(HWND hwndCnr, PECHOMGRDATA pEchoMgrData, PFTNMESSAGE pMessage, PMSGHEADER pHeader);
  204. static void _Optlink MessageSaveThread(PVOID pParam);
  205. static void _Optlink CfgChangeThread(PVOID pParam);
  206. static int LoadExtensionDLL(char *pchDllName, PFUNCTABLE pFuncTable);
  207. static void ConfigureDLL(HWND hwndDlg, PFUNCTABLE pFuncTable);
  208. static PUPLINK FindUplink(PECHOMGROPT pEchoMgrOpt, char *pchUplinkAddress);
  209. static PUPLINK FindMatchingUplink(PECHOMGROPT pEchoMgrOpt, char *pchMyAddress);
  210. static char *ExtractAreasFromMessage(char *pchMessageText, char *pchOldAreas);
  211. static int ChangeUplink(HWND hwndDlg, SHORT sItem);
  212. static int DeleteUplink(HWND hwndDlg, SHORT sItem, PECHOMGRDATA pEchoMgrData);
  213. static MRESULT EXPENTRY UplinkProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2);
  214. static int RemoveEchoFromUplink(HWND hwndDlg, PECHOMGRDATA pEchoMgrData);
  215. static void CreateUplinkMenu(PECHOMGRDATA pEchoMgrData, ECHOMGROPT *pEchoMgrOpt);
  216. static void SwitchUplink(HWND hwndDlg, PECHOMGRDATA pEchoMgrData, USHORT usID);
  217. static SHORT _System SortEchos(PRECORDCORE p1, PRECORDCORE p2, PVOID pData);
  218. static BOOL HaveArea(PSTRINGLIST pList, char *pchTag);
  219.  
  220. /*---------------------------------------------------------------------------*/
  221. /* Funktionsname: EchoMgrProc                                                */
  222. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  223. /* Beschreibung: Window-Prozedur des Echo-Managers                           */
  224. /*                                                                           */
  225. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  226. /* Parameter: WINPROC                                                        */
  227. /*                                                                           */
  228. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  229. /* Rückgabewerte: MRESULT                                                    */
  230. /*                                                                           */
  231. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  232. /* Sonstiges: -                                                              */
  233. /*                                                                           */
  234. /*---------------------------------------------------------------------------*/
  235.  
  236. MRESULT EXPENTRY EchoMgrProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
  237. {
  238.    extern HWND hwndhelp;
  239.    extern char CurrentAddress[LEN_5DADDRESS+1];
  240.    PECHOMGRDATA pEchoMgrData = WinQueryWindowPtr(hwnd, 0);
  241.    PFIELDINFO pFieldInfo, pFirstFieldInfo;
  242.    HWND hwndCnr;
  243.    FIELDINFOINSERT FieldInfoInsert;
  244.    CNRINFO CnrInfo;
  245.    PACTIONLIST pActionList=NULL;
  246.  
  247.    switch(msg)
  248.    {
  249.       case WM_INITDLG:
  250.          /* Instanzdaten */
  251.          pEchoMgrData = calloc(1, sizeof(ECHOMGRDATA));
  252.          WinSetWindowPtr(hwnd, 0, pEchoMgrData);
  253.  
  254.          /* Strings laden */
  255.          LoadString(IDST_EM_ECHO, ECHOMGR_STRINGLEN, pEchoMgrData->pchTitleEcho);
  256.          LoadString(IDST_EM_STATUS, ECHOMGR_STRINGLEN, pEchoMgrData->pchTitleStatus);
  257.          LoadString(IDST_EM_ACTION, ECHOMGR_STRINGLEN, pEchoMgrData->pchTitleAction);
  258.          LoadString(IDST_EM_LINKED, ECHOMGR_STRINGLEN, pEchoMgrData->pchStatusLinked);
  259.          LoadString(IDST_EM_UNLINKED, ECHOMGR_STRINGLEN, pEchoMgrData->pchStatusUnlinked);
  260.          LoadString(IDST_EM_LINK, ECHOMGR_STRINGLEN, pEchoMgrData->pchActionLink);
  261.          LoadString(IDST_EM_UNLINK, ECHOMGR_STRINGLEN, pEchoMgrData->pchActionUnlink);
  262.          LoadString(IDST_EM_RESCAN, ECHOMGR_STRINGLEN, pEchoMgrData->pchActionRescan);
  263.          LoadString(IDST_EM_REFRESH, ECHOMGR_STRINGLEN, pEchoMgrData->pchActionRefresh);
  264.          LoadString(IDST_EM_PAUSE, ECHOMGR_STRINGLEN, pEchoMgrData->pchActionPause);
  265.          LoadString(IDST_EM_RESUME, ECHOMGR_STRINGLEN, pEchoMgrData->pchActionResume);
  266.  
  267.          /* Menues laden */
  268.          pEchoMgrData->hwndPopup = WinLoadMenu(HWND_OBJECT, hmodLang, IDM_EM_POPUP);
  269.          pEchoMgrData->hwndFolderPopup = WinLoadMenu(HWND_OBJECT, hmodLang, IDM_EMF_POPUP);
  270.  
  271.          /* Spalten im Container */
  272.          hwndCnr = WinWindowFromID(hwnd, IDD_ECHOMANAGER+1);
  273.          pFirstFieldInfo=(PFIELDINFO)SendMsg(hwndCnr, CM_ALLOCDETAILFIELDINFO,
  274.                                                 MPFROMLONG(3), NULL);
  275.  
  276.          pFieldInfo=pFirstFieldInfo;
  277.  
  278.          pFieldInfo->cb=sizeof(FIELDINFO);
  279.          pFieldInfo->flData=CFA_STRING | CFA_HORZSEPARATOR | CFA_SEPARATOR;
  280.          pFieldInfo->flTitle=0;
  281.          pFieldInfo->pTitleData= pEchoMgrData->pchTitleEcho;
  282.          pFieldInfo->offStruct= FIELDOFFSET(ECHOMGRRECORD, pchEchoName);
  283.          pFieldInfo=pFieldInfo->pNextFieldInfo;
  284.  
  285.          pFieldInfo->cb=sizeof(FIELDINFO);
  286.          pFieldInfo->flData=CFA_STRING | CFA_HORZSEPARATOR | CFA_SEPARATOR;
  287.          pFieldInfo->flTitle=0;
  288.          pFieldInfo->pTitleData= pEchoMgrData->pchTitleStatus;
  289.          pFieldInfo->offStruct= FIELDOFFSET(ECHOMGRRECORD, pchStatus);
  290.          pFieldInfo=pFieldInfo->pNextFieldInfo;
  291.  
  292.          pFieldInfo->cb=sizeof(FIELDINFO);
  293.          pFieldInfo->flData=CFA_STRING | CFA_HORZSEPARATOR;
  294.          pFieldInfo->flTitle=0;
  295.          pFieldInfo->pTitleData= pEchoMgrData->pchTitleAction;
  296.          pFieldInfo->offStruct= FIELDOFFSET(ECHOMGRRECORD, pchAction);
  297.  
  298.          /* Felder des Containers einfuegen */
  299.          FieldInfoInsert.cb=sizeof(FIELDINFOINSERT);
  300.          FieldInfoInsert.pFieldInfoOrder=(PFIELDINFO) CMA_FIRST;
  301.          FieldInfoInsert.fInvalidateFieldInfo=TRUE;
  302.          FieldInfoInsert.cFieldInfoInsert=3;
  303.  
  304.          SendMsg(hwndCnr, CM_INSERTDETAILFIELDINFO,
  305.                     pFirstFieldInfo, &FieldInfoInsert);
  306.  
  307.          pEchoMgrData->pUplink = FindMatchingUplink(&EchoMgrOpt, CurrentAddress);
  308.  
  309.          /* Container-Attribute setzen */
  310.          CnrInfo.cb=sizeof(CNRINFO);
  311.          CnrInfo.flWindowAttr=CV_DETAIL | CA_DETAILSVIEWTITLES | CA_CONTAINERTITLE |
  312.                               CA_TITLEREADONLY | CA_TITLESEPARATOR;
  313.          CnrInfo.pSortRecord = (PVOID) SortEchos;
  314.  
  315.          if (pEchoMgrData->pUplink)
  316.             CnrInfo.pszCnrTitle=pEchoMgrData->pUplink->pchEchoMgrAddress;
  317.          else
  318.             CnrInfo.pszCnrTitle=NULL;
  319.  
  320.          SendMsg(hwndCnr, CM_SETCNRINFO, &CnrInfo,
  321.                     MPFROMLONG(CMA_FLWINDOWATTR | CMA_CNRTITLE | CMA_PSORTRECORD));
  322.  
  323.          CreateUplinkMenu(pEchoMgrData, &EchoMgrOpt);
  324.  
  325.          if (pEchoMgrData->pUplink)
  326.             InsertEchos(hwndCnr, pEchoMgrData);
  327.  
  328.          /* Fenstergroesse herstellen */
  329.          SetForeground(hwndCnr, &EchoMgrOpt.lFolderFore);
  330.          SetBackground(hwndCnr, &EchoMgrOpt.lFolderBack);
  331.          SetFont(hwndCnr, EchoMgrOpt.pchFolderFont);
  332.  
  333.          RestoreWinPos(hwnd, &EchoMgrOpt.FolderPos, TRUE, TRUE);
  334.  
  335.          pEchoMgrData->bNotify=TRUE;
  336.          break;
  337.  
  338.       case WM_DESTROY:
  339.          {
  340.             LONG lColor;
  341.             char pchFont[FACESIZE+5];
  342.             HWND hwndCnr = WinWindowFromID(hwnd, IDD_ECHOMANAGER+1);
  343.  
  344.             QueryForeground(hwndCnr, &lColor);
  345.             if (EchoMgrOpt.lFolderFore != lColor)
  346.             {
  347.                EchoMgrOpt.lFolderFore = lColor;
  348.                EchoMgrOpt.bDirty=TRUE;
  349.             }
  350.             QueryBackground(hwndCnr, &lColor);
  351.             if (EchoMgrOpt.lFolderBack != lColor)
  352.             {
  353.                EchoMgrOpt.lFolderBack = lColor;
  354.                EchoMgrOpt.bDirty=TRUE;
  355.             }
  356.             QueryFont(hwndCnr, pchFont);
  357.             if (strcmp(EchoMgrOpt.pchFolderFont, pchFont))
  358.             {
  359.                strcpy(EchoMgrOpt.pchFolderFont, pchFont);
  360.                EchoMgrOpt.bDirty=TRUE;
  361.             }
  362.             CleanupContainer(hwndCnr);
  363.             if (pEchoMgrData->hwndPopup)
  364.                WinDestroyWindow(pEchoMgrData->hwndPopup);
  365.             if (pEchoMgrData->hwndFolderPopup)
  366.                WinDestroyWindow(pEchoMgrData->hwndFolderPopup);
  367.             if (pEchoMgrData->pMenuTable)
  368.                free(pEchoMgrData->pMenuTable);
  369.             free(pEchoMgrData);
  370.          }
  371.          break;
  372.  
  373.       case WM_COMMAND:
  374.          switch(SHORT1FROMMP(mp1))
  375.          {
  376.             case DID_OK:
  377.                memset(&pEchoMgrData->SaveParam, 0, sizeof(SAVEPARAM));
  378.                pEchoMgrData->SaveParam.hwndDlg = hwnd;
  379.                if (pEchoMgrData->pUplink)
  380.                {
  381.                   switch(CreateMessage(WinWindowFromID(hwnd, IDD_ECHOMANAGER+1), pEchoMgrData,
  382.                                     &pEchoMgrData->SaveParam.Message, &pEchoMgrData->SaveParam.Header))
  383.                   {
  384.                      case 0:
  385.                         if (EchoMgrOpt.pchDllName[0])
  386.                            pActionList = CreateActionList(WinWindowFromID(hwnd, IDD_ECHOMANAGER+1));
  387.  
  388.                         /* Message speichern */
  389.                         WinEnableControl(hwnd, DID_OK, FALSE);
  390.                         WinEnableControl(hwnd, DID_CANCEL, FALSE);
  391.  
  392.                         if (pActionList)
  393.                         {
  394.                            PCHANGEPARAM pChangeParam;
  395.  
  396.                            pChangeParam = malloc(sizeof(CHANGEPARAM));
  397.                            pChangeParam->hwndDlg = hwnd;
  398.                            pChangeParam->pUplink = pEchoMgrData->pUplink;
  399.                            pChangeParam->pActionList = pActionList;
  400.                            _beginthread(CfgChangeThread, NULL, 32768, pChangeParam);
  401.                         }
  402.                         else
  403.                            _beginthread(MessageSaveThread, NULL, 32768, &pEchoMgrData->SaveParam);
  404.  
  405.                         return (MRESULT) FALSE;
  406.  
  407.                      case 1:
  408.                         MessageBox(hwnd, IDST_MSG_NOACTIONS, 0, IDD_NOACTIONS, MB_ERROR | MB_OK);
  409.                         return (MRESULT) FALSE;
  410.  
  411.                      case 2:
  412.                         MessageBox(hwnd, IDST_MSG_EM_NOPASS, 0, IDD_EM_NOPASS, MB_ERROR | MB_OK);
  413.                         return (MRESULT) FALSE;
  414.  
  415.                      default:
  416.                         return (MRESULT) FALSE;
  417.                   }
  418.                }
  419.                break;
  420.  
  421.             case DID_CANCEL:
  422.                if (WinIsWindowEnabled(WinWindowFromID(hwnd, DID_CANCEL)))
  423.                   break;
  424.                else
  425.                   return (MRESULT) FALSE;
  426.  
  427.             case IDM_EMF_SETTINGS:
  428.                {
  429.                   EMANSETTINGSDATA EManSettingsData;
  430.  
  431.                   EManSettingsData.cb = sizeof(EManSettingsData);
  432.                   EManSettingsData.pEchoMgrData = pEchoMgrData;
  433.                   if (WinDlgBox(HWND_DESKTOP, hwnd, EchoMgrSettings, hmodLang,
  434.                                 IDD_ECHOMGRSETTINGS, &EManSettingsData) == DID_OK)
  435.                      WinDismissDlg(hwnd, DID_CANCEL);
  436.                }
  437.                return (MRESULT)FALSE;
  438.  
  439.             case IDM_EMF_REFRESH:
  440.                pEchoMgrData->ulAction = ACTION_REFRESH;
  441.                CnrInfo.cb=sizeof(CNRINFO);
  442.                CnrInfo.pszCnrTitle = pEchoMgrData->pchActionRefresh;
  443.  
  444.                WinSendDlgItemMsg(hwnd, IDD_ECHOMANAGER+1, CM_SETCNRINFO, &CnrInfo,
  445.                           MPFROMLONG(CMA_CNRTITLE));
  446.                return (MRESULT)FALSE;
  447.  
  448.             case IDM_EMF_PAUSE:
  449.                pEchoMgrData->ulAction = ACTION_PAUSE;
  450.                CnrInfo.cb=sizeof(CNRINFO);
  451.                CnrInfo.pszCnrTitle = pEchoMgrData->pchActionPause;
  452.  
  453.                WinSendDlgItemMsg(hwnd, IDD_ECHOMANAGER+1, CM_SETCNRINFO, &CnrInfo,
  454.                           MPFROMLONG(CMA_CNRTITLE));
  455.                return (MRESULT)FALSE;
  456.  
  457.             case IDM_EMF_RESUME:
  458.                pEchoMgrData->ulAction = ACTION_RESUME;
  459.                CnrInfo.cb=sizeof(CNRINFO);
  460.                CnrInfo.pszCnrTitle = pEchoMgrData->pchActionResume;
  461.  
  462.                WinSendDlgItemMsg(hwnd, IDD_ECHOMANAGER+1, CM_SETCNRINFO, &CnrInfo,
  463.                           MPFROMLONG(CMA_CNRTITLE));
  464.                return (MRESULT)FALSE;
  465.  
  466.             case IDM_EMF_RESET:
  467.                pEchoMgrData->ulAction = ACTION_NONE;
  468.                CnrInfo.cb=sizeof(CNRINFO);
  469.                if (pEchoMgrData->pUplink)
  470.                   CnrInfo.pszCnrTitle = pEchoMgrData->pUplink->pchEchoMgrAddress;
  471.                else
  472.                   CnrInfo.pszCnrTitle = NULL;
  473.  
  474.                WinSendDlgItemMsg(hwnd, IDD_ECHOMANAGER+1, CM_SETCNRINFO, &CnrInfo,
  475.                           MPFROMLONG(CMA_CNRTITLE));
  476.                return (MRESULT)FALSE;
  477.  
  478.             case IDM_EM_LINK:
  479.                pEchoMgrData->pPopupRecord->ulAction = ACTION_LINK;
  480.                pEchoMgrData->pPopupRecord->pchAction = pEchoMgrData->pchActionLink;
  481.                WinSendDlgItemMsg(hwnd, IDD_ECHOMANAGER+1, CM_INVALIDATERECORD,
  482.                                  &pEchoMgrData->pPopupRecord, MPFROM2SHORT(1, CMA_TEXTCHANGED));
  483.                return (MRESULT)FALSE;
  484.  
  485.             case IDM_EM_UNLINK:
  486.                pEchoMgrData->pPopupRecord->ulAction = ACTION_UNLINK;
  487.                pEchoMgrData->pPopupRecord->pchAction = pEchoMgrData->pchActionUnlink;
  488.                WinSendDlgItemMsg(hwnd, IDD_ECHOMANAGER+1, CM_INVALIDATERECORD,
  489.                                  &pEchoMgrData->pPopupRecord, MPFROM2SHORT(1, CMA_TEXTCHANGED));
  490.                return (MRESULT)FALSE;
  491.  
  492.             case IDM_EM_RESCAN:
  493.                if (pEchoMgrData->pPopupRecord->ulAction == ACTION_LINK)
  494.                   pEchoMgrData->pPopupRecord->ulAction = ACTION_LNKRESC;
  495.                else
  496.                   pEchoMgrData->pPopupRecord->ulAction = ACTION_RESCAN;
  497.                pEchoMgrData->pPopupRecord->pchAction = pEchoMgrData->pchActionRescan;
  498.                WinSendDlgItemMsg(hwnd, IDD_ECHOMANAGER+1, CM_INVALIDATERECORD,
  499.                                  &pEchoMgrData->pPopupRecord, MPFROM2SHORT(1, CMA_TEXTCHANGED));
  500.                return (MRESULT)FALSE;
  501.  
  502.             case IDM_EM_RESET:
  503.                pEchoMgrData->pPopupRecord->ulAction = ACTION_NONE;
  504.                pEchoMgrData->pPopupRecord->pchAction = NULL;
  505.                WinSendDlgItemMsg(hwnd, IDD_ECHOMANAGER+1, CM_INVALIDATERECORD,
  506.                                  &pEchoMgrData->pPopupRecord, MPFROM2SHORT(1, CMA_TEXTCHANGED));
  507.                return (MRESULT)FALSE;
  508.  
  509.             case IDM_EM_REMOVE:
  510.                RemoveEchoFromUplink(hwnd, pEchoMgrData);
  511.                return (MRESULT)FALSE;
  512.  
  513.             default:
  514.                SwitchUplink(hwnd, pEchoMgrData, SHORT1FROMMP(mp1));
  515.                return (MRESULT)FALSE;
  516.          }
  517.          break;
  518.  
  519.       case WM_CONTROL:
  520.          if (SHORT1FROMMP(mp1) == IDD_ECHOMANAGER+1)
  521.          {
  522.             switch(SHORT2FROMMP(mp1))
  523.             {
  524.                case CN_CONTEXTMENU:
  525.                   if (WinIsWindowEnabled(WinWindowFromID(hwnd, DID_CANCEL)))
  526.                      OpenPopup(hwnd, (PECHOMGRRECORD) mp2, pEchoMgrData);
  527.                   break;
  528.  
  529.                default:
  530.                   break;
  531.             }
  532.          }
  533.          break;
  534.  
  535.       case WM_CLOSE:
  536.          if (WinIsWindowEnabled(WinWindowFromID(hwnd, DID_CANCEL)))
  537.             break;
  538.          else
  539.             return (MRESULT) FALSE;
  540.  
  541.       case WM_ACTIVATE:
  542.          if (mp1)
  543.             WinAssociateHelpInstance(hwndhelp, hwnd);
  544.          else
  545.             WinAssociateHelpInstance(hwndhelp, NULLHANDLE);
  546.          break;
  547.  
  548.       case WM_CONTEXTMENU:
  549.          if (WinIsWindowEnabled(WinWindowFromID(hwnd, DID_CANCEL)) &&
  550.              WinQueryFocus(HWND_DESKTOP) == WinWindowFromID(hwnd, IDD_ECHOMANAGER+1))
  551.          {
  552.             pEchoMgrData->bKeyboard=TRUE;
  553.             WinSendDlgItemMsg(hwnd, IDD_ECHOMANAGER+1, msg, mp1, mp2);
  554.          }
  555.          break;
  556.  
  557.       case WM_WINDOWPOSCHANGED:
  558.          if (pEchoMgrData && pEchoMgrData->bNotify)
  559.             SaveWinPos(hwnd, (PSWP) mp1, &EchoMgrOpt.FolderPos, &EchoMgrOpt.bDirty);
  560.          break;
  561.  
  562.       case WM_ADJUSTFRAMEPOS:
  563.          if (((PSWP)mp1)->fl & (SWP_SIZE|SWP_MAXIMIZE|SWP_MINIMIZE|SWP_RESTORE))
  564.          {
  565.             SWP swp;
  566.             RECTL rectl;
  567.  
  568.             rectl.xLeft=0;
  569.             rectl.xRight=((PSWP)mp1)->cx;
  570.             rectl.yBottom=0;
  571.             rectl.yTop=((PSWP)mp1)->cy;
  572.  
  573.             CalcClientRect(anchor, hwnd, &rectl);
  574.             WinQueryWindowPos(WinWindowFromID(hwnd, DID_OK), &swp);
  575.             rectl.yBottom += swp.y + swp.cy;
  576.             WinSetWindowPos(WinWindowFromID(hwnd, IDD_ECHOMANAGER+1),
  577.                             NULLHANDLE,
  578.                             rectl.xLeft, rectl.yBottom,
  579.                             rectl.xRight-rectl.xLeft, rectl.yTop-rectl.yBottom,
  580.                             SWP_MOVE | SWP_SIZE);
  581.          }
  582.          break;
  583.  
  584.       case WM_QUERYTRACKINFO:
  585.          {
  586.             SWP swp;
  587.             MRESULT resultbuf;
  588.  
  589.             /* Default-Werte aus Original-Prozedur holen */
  590.             resultbuf=WinDefDlgProc(hwnd, msg, mp1, mp2);
  591.  
  592.             WinQueryWindowPos(WinWindowFromID(hwnd, IDD_ECHOMANAGER+2), &swp);
  593.  
  594.             /* Minimale Fenstergroesse einstellen */
  595.             ((PTRACKINFO)mp2)->ptlMinTrackSize.x=swp.x+swp.cx+5;
  596.             ((PTRACKINFO)mp2)->ptlMinTrackSize.y=200;
  597.             return resultbuf;
  598.          }
  599.  
  600.       case WM_MENUEND:
  601.          if ((HWND) mp2 == pEchoMgrData->hwndPopup ||
  602.              (HWND) mp2 == pEchoMgrData->hwndFolderPopup)
  603.             WinSendDlgItemMsg(hwnd, IDD_ECHOMANAGER+1, CM_SETRECORDEMPHASIS,
  604.                               pEchoMgrData->pPopupRecord,
  605.                               MPFROM2SHORT(FALSE, CRA_SOURCE));
  606.          break;
  607.  
  608.       case WM_CHANGEDONE:
  609.          switch((ULONG) mp1)
  610.          {
  611.             case LOADDLL_CANTLOAD:
  612.                MessageBox(hwnd, IDST_MSG_EM_DLLLOAD, 0, IDD_EM_DLLLOAD, MB_ERROR | MB_OK);
  613.                break;
  614.  
  615.             case LOADDLL_VERSION:
  616.                MessageBox(hwnd, IDST_MSG_EM_DLLVER, 0, IDD_EM_DLLVER, MB_ERROR | MB_OK);
  617.                break;
  618.  
  619.             case LOADDLL_FUNCMISSING:
  620.                MessageBox(hwnd, IDST_MSG_EM_DLLFUNC, 0, IDD_EM_DLLFUNC, MB_ERROR | MB_OK);
  621.                break;
  622.  
  623.             default:
  624.                break;
  625.          }
  626.          switch((ULONG) mp1)
  627.          {
  628.             case ECHOMAN_OK:
  629.                break;
  630.  
  631.             case ECHOMAN_PARAMSIZE:
  632.             case ECHOMAN_FORMAT:
  633.                MessageBox(hwnd, IDST_MSG_EM_INIT, 0, IDD_EM_INIT, MB_ERROR | MB_OK);
  634.                break;
  635.  
  636.             case ECHOMAN_CFGNOTFOUND:
  637.                MessageBox(hwnd, IDST_MSG_EM_CFGNOTF, 0, IDD_EM_CFGNOTF, MB_ERROR | MB_OK);
  638.                break;
  639.  
  640.             case ECHOMAN_CFGREAD:
  641.                MessageBox(hwnd, IDST_MSG_EM_CFGREAD, 0, IDD_EM_CFGREAD, MB_ERROR | MB_OK);
  642.                break;
  643.  
  644.             case ECHOMAN_CFGWRITE:
  645.                MessageBox(hwnd, IDST_MSG_EM_CFGWRITE, 0, IDD_EM_CFGWRITE, MB_ERROR | MB_OK);
  646.                break;
  647.  
  648.             case ECHOMAN_CFGFORMAT:
  649.                MessageBox(hwnd, IDST_MSG_EM_CFGFORMAT, 0, IDD_EM_CFGFORMAT, MB_ERROR | MB_OK);
  650.                break;
  651.  
  652.             case ECHOMAN_ALREADYLINKED:
  653.                MessageBox(hwnd, IDST_MSG_EM_CFGLINKED, 0, IDD_EM_CFGLINKED, MB_ERROR | MB_OK);
  654.                break;
  655.  
  656.             case ECHOMAN_NOTLINKED:
  657.                MessageBox(hwnd, IDST_MSG_EM_CFGUNLINKED, 0, IDD_EM_CFGUNLINKED, MB_ERROR | MB_OK);
  658.                break;
  659.  
  660.             default:
  661.                MessageBox(hwnd, IDST_MSG_EM_DLLINT, 0, IDD_EM_DLLINT, MB_ERROR | MB_OK);
  662.                break;
  663.          }
  664.          _beginthread(MessageSaveThread, NULL, 32768, &pEchoMgrData->SaveParam);
  665.          break;
  666.  
  667.       case WM_SAVEDONE:
  668.          switch((ULONG) mp1)
  669.          {
  670.             case 0:
  671.                break;
  672.  
  673.             default:
  674.                MessageBox(hwnd, IDST_MSG_ERRORMSGSAVE, 0, IDD_ERRORMSGSAVE, MB_OK | MB_ERROR);
  675.                break;
  676.          }
  677.          WinDismissDlg(hwnd, DID_OK);
  678.          return (MRESULT) FALSE;
  679.  
  680.       default:
  681.          break;
  682.    }
  683.    return WinDefDlgProc(hwnd, msg, mp1, mp2);
  684. }
  685.  
  686. static SHORT _System SortEchos(PRECORDCORE p1, PRECORDCORE p2, PVOID pData)
  687. {
  688.    pData = pData;
  689.  
  690.    return stricmp(((PECHOMGRRECORD)p1)->pchEchoName, ((PECHOMGRRECORD)p2)->pchEchoName);
  691. }
  692.  
  693. /*-----------------------------------------------------------------------------
  694.  | Funktionsname: SwitchUplink
  695.  |- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  696.  | Beschreibung: Schaltet den aktuellen Uplink um
  697.  |
  698.  |- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  699.  | Parameter: hwndDlg: Dialog-Window-Handle
  700.  |            pEchoMgrData: Instanzdaten des Echo-Managers
  701.  |            usID: ID des gewählten Uplink-Menu-Punktes
  702.  |- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  703.  | Rückgabewerte: -
  704.  |
  705.  |- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  706.  | Sonstiges: -
  707.  |
  708.  +---------------------------------------------------------------------------*/
  709.  
  710. static void SwitchUplink(HWND hwndDlg, PECHOMGRDATA pEchoMgrData, USHORT usID)
  711. {
  712.    int iUplink=0;
  713.  
  714.    /* Uplink in Tabelle suchen */
  715.    while (iUplink < pEchoMgrData->ulCountUplinks)
  716.    {
  717.       if (pEchoMgrData->pMenuTable[iUplink].usID == usID)
  718.          break;
  719.       iUplink++;
  720.    }
  721.  
  722.    if (iUplink < pEchoMgrData->ulCountUplinks) /* gefunden */
  723.    {
  724.       if (pEchoMgrData->pMenuTable[iUplink].pUplink != pEchoMgrData->pUplink) /* anderer als aktueller */
  725.       {
  726.          CNRINFO CnrInfo;
  727.          HWND hwndCnr = WinWindowFromID(hwndDlg, IDD_ECHOMANAGER+1);
  728.  
  729.          /* umschalten */
  730.          CleanupContainer(hwndCnr);
  731.          pEchoMgrData->pUplink = pEchoMgrData->pMenuTable[iUplink].pUplink;
  732.          InsertEchos(hwndCnr, pEchoMgrData);
  733.  
  734.          /* Aktionen zuruecksetzen */
  735.          pEchoMgrData->ulAction = ACTION_NONE;
  736.  
  737.          CnrInfo.cb=sizeof(CNRINFO);
  738.  
  739.          if (pEchoMgrData->pUplink)
  740.             CnrInfo.pszCnrTitle=pEchoMgrData->pUplink->pchEchoMgrAddress;
  741.          else
  742.             CnrInfo.pszCnrTitle=NULL;
  743.  
  744.          SendMsg(hwndCnr, CM_SETCNRINFO, &CnrInfo, MPFROMLONG(CMA_CNRTITLE));
  745.       }
  746.    }
  747.    return;
  748. }
  749.  
  750.  
  751. /*---------------------------------------------------------------------------*/
  752. /* Funktionsname: InsertEchos                                                */
  753. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  754. /* Beschreibung: Fuegt alle Echos in den Container ein                       */
  755. /*                                                                           */
  756. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  757. /* Parameter: hwndCnr: Container-Window                                      */
  758. /*            pEchoMgrData: Instanzdaten des Echomanagers                    */
  759. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  760. /* Rückgabewerte: -                                                          */
  761. /*                                                                           */
  762. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  763. /* Sonstiges: -                                                              */
  764. /*                                                                           */
  765. /*---------------------------------------------------------------------------*/
  766.  
  767. static void InsertEchos(HWND hwndCnr, PECHOMGRDATA pEchoMgrData)
  768. {
  769.    extern AREALIST arealiste;
  770.    ULONG ulNumAreas=0;
  771.    PCHAR pchTemp;
  772.    PCHAR pchCopy;
  773.    PECHOMGRRECORD pRecord, pFirstRecord;
  774.    RECORDINSERT RecordInsert;
  775.  
  776.    if (!pEchoMgrData->pUplink->pchUplinkAreas ||
  777.        !pEchoMgrData->pUplink->pchUplinkAreas[0])
  778.       return;
  779.  
  780.    pchTemp = pEchoMgrData->pUplink->pchUplinkAreas;
  781.    while (*pchTemp == ' ')
  782.       pchTemp++;
  783.  
  784.    while (*pchTemp)
  785.    {
  786.       if (*pchTemp == ' ')
  787.       {
  788.          ulNumAreas++;
  789.          while (*pchTemp == ' ')
  790.             pchTemp++;
  791.       }
  792.       else
  793.          pchTemp++;
  794.    }
  795.    ulNumAreas++;
  796.  
  797.    pchCopy = strdup(pEchoMgrData->pUplink->pchUplinkAreas);
  798.  
  799.    pFirstRecord = SendMsg(hwndCnr, CM_ALLOCRECORD,
  800.                              MPFROMLONG(sizeof(ECHOMGRRECORD) - sizeof(MINIRECORDCORE)),
  801.                              MPFROMLONG(ulNumAreas));
  802.    pRecord = pFirstRecord;
  803.  
  804.    pchTemp = strtok(pchCopy, " ");
  805.  
  806.    while (pchTemp)
  807.    {
  808.       pRecord->pchEchoName = strdup(pchTemp);
  809.       if (AM_FindArea(&arealiste, pchTemp))
  810.       {
  811.          pRecord->pchStatus = pEchoMgrData->pchStatusLinked;
  812.          pRecord->ulStatus = STATUS_LINKED;
  813.       }
  814.       else
  815.       {
  816.          pRecord->pchStatus = pEchoMgrData->pchStatusUnlinked;
  817.          pRecord->ulStatus = STATUS_UNLINKED;
  818.       }
  819.       pRecord->pchAction = "";
  820.       pRecord->ulAction= ACTION_NONE;
  821.  
  822.       pRecord = (PECHOMGRRECORD) pRecord->RecordCore.preccNextRecord;
  823.  
  824.       pchTemp = strtok(NULL, " ");
  825.    }
  826.  
  827.    free(pchCopy);
  828.  
  829.    RecordInsert.cb = sizeof(RecordInsert);
  830.    RecordInsert.pRecordOrder = (PRECORDCORE) CMA_FIRST;
  831.    RecordInsert.pRecordParent = NULL;
  832.    RecordInsert.fInvalidateRecord = TRUE;
  833.    RecordInsert.zOrder = CMA_TOP;
  834.    RecordInsert.cRecordsInsert = ulNumAreas;
  835.  
  836.    SendMsg(hwndCnr, CM_INSERTRECORD, pFirstRecord, &RecordInsert);
  837.  
  838.    return;
  839. }
  840.  
  841. /*-----------------------------------------------------------------------------
  842.  | Funktionsname: CreateUplinkMenu
  843.  |- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  844.  | Beschreibung: Erzeugt das Unter-Menü mit den Uplinks
  845.  |
  846.  |- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  847.  | Parameter: pEchoMgrData: Instanzdaten
  848.  |            pEchoMgrOpt: Echo-Manager-Optionen
  849.  |- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  850.  | Rückgabewerte: -
  851.  |
  852.  |- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  853.  | Sonstiges: -
  854.  |
  855.  +---------------------------------------------------------------------------*/
  856.  
  857. static void CreateUplinkMenu(PECHOMGRDATA pEchoMgrData, ECHOMGROPT *pEchoMgrOpt)
  858. {
  859.    PUPLINK pUplink = pEchoMgrOpt->pUplinks;
  860.    int iNumUplinks=0;
  861.    int iUplink=0;
  862.    MENUITEM SubMenu;
  863.    MENUITEM NewItem = {MIT_END, MIS_TEXT, 0, 0, NULLHANDLE, NULLHANDLE};
  864.    HWND hwndMenu;
  865.  
  866.    /* Uplinks zaehlen */
  867.    while (pUplink)
  868.    {
  869.       iNumUplinks++;
  870.       pUplink = pUplink->next;
  871.    }
  872.  
  873.    /* Anzahl begrenzen */
  874.    if (iNumUplinks >= (IDM_EM_POPUP - IDM_EMF_UPLINK))
  875.       iNumUplinks = IDM_EM_POPUP - IDM_EMF_UPLINK - 1;
  876.  
  877.    if (iNumUplinks) /* nur, wenn wirklich welche da */
  878.    {
  879.       /* Feld anlegen */
  880.       pEchoMgrData->pMenuTable = calloc(iNumUplinks, sizeof(MENUTABLE));
  881.       pEchoMgrData->ulCountUplinks = iNumUplinks;
  882.  
  883.       /* Sub-Menu holen */
  884.       SendMsg(pEchoMgrData->hwndFolderPopup, MM_QUERYITEM,
  885.               MPFROM2SHORT(IDM_EMF_UPLINK, FALSE), &SubMenu);
  886.  
  887.       hwndMenu = SubMenu.hwndSubMenu;
  888.  
  889.       /* alle Uplinks durchgehen */
  890.       pUplink = pEchoMgrOpt->pUplinks;
  891.       while (pUplink && iUplink < iNumUplinks)
  892.       {
  893.          /* Menue-Eintrag erzeugen */
  894.          NewItem.id = IDM_EMF_UPLINK+1+iUplink;
  895.  
  896.          SendMsg(hwndMenu, MM_INSERTITEM, &NewItem, pUplink->pchEchoMgrAddress);
  897.  
  898.          /* in Tabelle eintragen */
  899.          pEchoMgrData->pMenuTable[iUplink].usID = NewItem.id;
  900.          pEchoMgrData->pMenuTable[iUplink].pUplink = pUplink;
  901.  
  902.          /* weiter */
  903.          iUplink++;
  904.          pUplink = pUplink->next;
  905.       }
  906.    }
  907.  
  908.    return;
  909. }
  910.  
  911. /*---------------------------------------------------------------------------*/
  912. /* Funktionsname: CleanupContainer                                           */
  913. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  914. /* Beschreibung: Entfernt alle Records vom Container                         */
  915. /*                                                                           */
  916. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  917. /* Parameter: hwndCnr: Container-Window                                      */
  918. /*                                                                           */
  919. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  920. /* Rückgabewerte: -                                                          */
  921. /*                                                                           */
  922. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  923. /* Sonstiges: -                                                              */
  924. /*                                                                           */
  925. /*---------------------------------------------------------------------------*/
  926.  
  927. static void CleanupContainer(HWND hwndCnr)
  928. {
  929.    PECHOMGRRECORD pRecord = NULL;
  930.  
  931.    while (pRecord = SendMsg(hwndCnr, CM_QUERYRECORD, pRecord,
  932.                                MPFROM2SHORT(pRecord?CMA_NEXT:CMA_FIRST, CMA_ITEMORDER)))
  933.    {
  934.       if (pRecord->pchEchoName)
  935.          free(pRecord->pchEchoName);
  936.    }
  937.  
  938.    SendMsg(hwndCnr, CM_REMOVERECORD, NULL, NULL);
  939.  
  940.    return;
  941. }
  942.  
  943. /*---------------------------------------------------------------------------*/
  944. /* Funktionsname: OpenPopup                                                  */
  945. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  946. /* Beschreibung: Oeffnet das Popup-Menue des Echo-Managers                   */
  947. /*                                                                           */
  948. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  949. /* Parameter: hwndDlg: Echo-Manager-Dialog                                   */
  950. /*            pRecord: Record, fuer den das Popup-Menue geoeffnet wurde      */
  951. /*            pEchoMgrData: Instanz-Daten                                    */
  952. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  953. /* Rückgabewerte: -                                                          */
  954. /*                                                                           */
  955. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  956. /* Sonstiges: -                                                              */
  957. /*                                                                           */
  958. /*---------------------------------------------------------------------------*/
  959.  
  960. static void OpenPopup(HWND hwndDlg, PECHOMGRRECORD pRecord, PECHOMGRDATA pEchoMgrData)
  961. {
  962.    POINTL pointl;
  963.  
  964.    if (!pEchoMgrData->bKeyboard)
  965.       WinQueryPointerPos(HWND_DESKTOP, &pointl);
  966.    else
  967.    {
  968.       QUERYRECORDRECT qRecord;
  969.       RECTL rectl;
  970.       SWP swp;
  971.  
  972.       WinQueryWindowPos(WinWindowFromID(hwndDlg, IDD_ECHOMANAGER+1), &swp);
  973.  
  974.       if (pRecord)
  975.       {
  976.          qRecord.cb = sizeof(qRecord);
  977.          qRecord.pRecord = (PRECORDCORE) pRecord;
  978.          qRecord.fRightSplitWindow=FALSE;
  979.          qRecord.fsExtent = CMA_TEXT;
  980.  
  981.          WinSendDlgItemMsg(hwndDlg, IDD_ECHOMANAGER+1, CM_QUERYRECORDRECT,
  982.                            &rectl, &qRecord);
  983.  
  984.          pointl.x = swp.x + rectl.xLeft+ (rectl.xRight - rectl.xLeft)/2;
  985.          pointl.y = swp.y + rectl.yBottom + (rectl.yTop - rectl.yBottom)/2;
  986.       }
  987.       else
  988.       {
  989.          pointl.x = swp.x + swp.cx/2;
  990.          pointl.y = swp.y + swp.cy/2;
  991.       }
  992.       WinMapWindowPoints(hwndDlg, HWND_DESKTOP, &pointl, 1);
  993.    }
  994.  
  995.    pEchoMgrData->pPopupRecord = pRecord;
  996.    WinSendDlgItemMsg(hwndDlg, IDD_ECHOMANAGER+1, CM_SETRECORDEMPHASIS, pRecord,
  997.                      MPFROM2SHORT(TRUE, CRA_SOURCE));
  998.  
  999.    if (pRecord)
  1000.    {
  1001.       if (pRecord->ulStatus == STATUS_LINKED)
  1002.       {
  1003.          WinEnableMenuItem(pEchoMgrData->hwndPopup, IDM_EM_LINK, FALSE);
  1004.          WinEnableMenuItem(pEchoMgrData->hwndPopup, IDM_EM_UNLINK, TRUE);
  1005.          WinEnableMenuItem(pEchoMgrData->hwndPopup, IDM_EM_RESCAN, TRUE);
  1006.       }
  1007.       else
  1008.       {
  1009.          if (pRecord->ulAction)
  1010.             WinEnableMenuItem(pEchoMgrData->hwndPopup, IDM_EM_LINK, FALSE);
  1011.          else
  1012.             WinEnableMenuItem(pEchoMgrData->hwndPopup, IDM_EM_LINK, TRUE);
  1013.          WinEnableMenuItem(pEchoMgrData->hwndPopup, IDM_EM_UNLINK, FALSE);
  1014.          if (pRecord->ulAction == ACTION_LINK)
  1015.             WinEnableMenuItem(pEchoMgrData->hwndPopup, IDM_EM_RESCAN, TRUE);
  1016.          else
  1017.             WinEnableMenuItem(pEchoMgrData->hwndPopup, IDM_EM_RESCAN, FALSE);
  1018.       }
  1019.  
  1020.       if (pRecord->ulAction)
  1021.          WinEnableMenuItem(pEchoMgrData->hwndPopup, IDM_EM_RESET, TRUE);
  1022.       else
  1023.          WinEnableMenuItem(pEchoMgrData->hwndPopup, IDM_EM_RESET, FALSE);
  1024.  
  1025.       WinPopupMenu(HWND_DESKTOP, hwndDlg, pEchoMgrData->hwndPopup, pointl.x, pointl.y,
  1026.                    0, PU_HCONSTRAIN | PU_VCONSTRAIN | PU_KEYBOARD | PU_MOUSEBUTTON1);
  1027.    }
  1028.    else
  1029.    {
  1030.       if (pEchoMgrData->pUplink)
  1031.       {
  1032.          WinEnableMenuItem(pEchoMgrData->hwndFolderPopup, IDM_EMF_REFRESH, TRUE);
  1033.          WinEnableMenuItem(pEchoMgrData->hwndFolderPopup, IDM_EMF_PAUSE, TRUE);
  1034.          WinEnableMenuItem(pEchoMgrData->hwndFolderPopup, IDM_EMF_RESUME, TRUE);
  1035.          if (pEchoMgrData->ulAction)
  1036.             WinEnableMenuItem(pEchoMgrData->hwndFolderPopup, IDM_EMF_RESET, TRUE);
  1037.          else
  1038.             WinEnableMenuItem(pEchoMgrData->hwndFolderPopup, IDM_EMF_RESET, FALSE);
  1039.       }
  1040.       else
  1041.       {
  1042.          WinEnableMenuItem(pEchoMgrData->hwndFolderPopup, IDM_EMF_REFRESH, FALSE);
  1043.          WinEnableMenuItem(pEchoMgrData->hwndFolderPopup, IDM_EMF_PAUSE, FALSE);
  1044.          WinEnableMenuItem(pEchoMgrData->hwndFolderPopup, IDM_EMF_RESUME, FALSE);
  1045.          WinEnableMenuItem(pEchoMgrData->hwndFolderPopup, IDM_EMF_RESET, FALSE);
  1046.       }
  1047.       if (EchoMgrOpt.pUplinks)
  1048.          WinEnableMenuItem(pEchoMgrData->hwndFolderPopup, IDM_EMF_UPLINK, TRUE);
  1049.       else
  1050.          WinEnableMenuItem(pEchoMgrData->hwndFolderPopup, IDM_EMF_UPLINK, FALSE);
  1051.       WinPopupMenu(HWND_DESKTOP, hwndDlg, pEchoMgrData->hwndFolderPopup, pointl.x, pointl.y,
  1052.                    0, PU_HCONSTRAIN | PU_VCONSTRAIN | PU_KEYBOARD | PU_MOUSEBUTTON1);
  1053.    }
  1054.  
  1055.    pEchoMgrData->bKeyboard = FALSE;
  1056.  
  1057.    return;
  1058. }
  1059.  
  1060. /*---------------------------------------------------------------------------*/
  1061. /* Funktionsname: EchoMgrSettings                                            */
  1062. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  1063. /* Beschreibung: Fenster-Prozedur fuer die Echo-Manager-Settings             */
  1064. /*                                                                           */
  1065. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  1066. /* Parameter: WINPROC                                                        */
  1067. /*                                                                           */
  1068. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  1069. /* Rückgabewerte: MRESULT                                                    */
  1070. /*                                                                           */
  1071. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  1072. /* Sonstiges: Wenn der Dialog mit DID_OK beendet wird, wird angezeigt,       */
  1073. /*            daß die Liste des aktuellen Uplinks geloescht wurde. Der       */
  1074. /*            Echo-Manager muss sich dann mit DID_CANCEL beenden.            */
  1075. /*---------------------------------------------------------------------------*/
  1076.  
  1077. static MRESULT EXPENTRY EchoMgrSettings(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
  1078. {
  1079.    extern HWND hwndhelp;
  1080.  
  1081.    switch(msg)
  1082.    {
  1083.       case WM_INITDLG:
  1084.          ((PEMANSETTINGSDATA)mp2)->hwndSettingsDlg = hwnd;
  1085.          InsertPages(hwnd, (PVOID) mp2);
  1086.          RestoreWinPos(hwnd, &EchoMgrOpt.SettingsPos, TRUE, TRUE);
  1087.          WinSetWindowULong(hwnd, QWL_USER, 1);
  1088.          break;
  1089.  
  1090.       case WM_DESTROY:
  1091.          break;
  1092.  
  1093.       case WM_ACTIVATE:
  1094.          if (mp1)
  1095.             WinAssociateHelpInstance(hwndhelp, hwnd);
  1096.          else
  1097.             WinAssociateHelpInstance(hwndhelp, NULLHANDLE);
  1098.          break;
  1099.  
  1100.       case WM_WINDOWPOSCHANGED:
  1101.          if (WinQueryWindowULong(hwnd, QWL_USER))
  1102.             SaveWinPos(hwnd, (PSWP) mp1, &EchoMgrOpt.SettingsPos, &EchoMgrOpt.bDirty);
  1103.          break;
  1104.  
  1105.       case WM_ADJUSTFRAMEPOS:
  1106.          SizeToClient(anchor, (PSWP) mp1, hwnd, IDD_ECHOMGRSETTINGS+1);
  1107.          break;
  1108.  
  1109.       case WM_CURRENTDEL:
  1110.          WinDismissDlg(hwnd, DID_OK);
  1111.          break;
  1112.  
  1113.       default:
  1114.          break;
  1115.    }
  1116.    return WinDefDlgProc(hwnd, msg, mp1, mp2);
  1117. }
  1118.  
  1119. /*---------------------------------------------------------------------------*/
  1120. /* Funktionsname: InsertPages                                                */
  1121. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  1122. /* Beschreibung: Fuegt alle Seiten in das Notebook ein                       */
  1123. /*                                                                           */
  1124. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  1125. /* Parameter: hwndDlg: Dialog-Window                                         */
  1126. /*                                                                           */
  1127. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  1128. /* Rückgabewerte: -                                                          */
  1129. /*                                                                           */
  1130. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  1131. /* Sonstiges: -                                                              */
  1132. /*                                                                           */
  1133. /*---------------------------------------------------------------------------*/
  1134.  
  1135. static void InsertPages(HWND hwndDlg, PVOID pParam)
  1136. {
  1137.    HWND hwndNotebook = WinWindowFromID(hwndDlg, IDD_ECHOMGRSETTINGS+1);
  1138.  
  1139.    SetNotebookParams(hwndNotebook, 120);
  1140.  
  1141.    InsertOnePage(hwndNotebook, IDD_EMS_UPLINKS, IDST_TAB_UPLINKS, UplinkSettings, pParam);
  1142.    InsertOnePage(hwndNotebook, IDD_EMS_EXTDLL, IDST_TAB_DLLEXT, DllSettings, pParam);
  1143.  
  1144.    return;
  1145. }
  1146.  
  1147. /*---------------------------------------------------------------------------*/
  1148. /* Funktionsname: UplinkSettings                                             */
  1149. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  1150. /* Beschreibung: Fenster-Prozedur der Seite "Uplinks"                        */
  1151. /*                                                                           */
  1152. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  1153. /* Parameter: WINPROC                                                        */
  1154. /*                                                                           */
  1155. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  1156. /* Rückgabewerte: MRESULT                                                    */
  1157. /*                                                                           */
  1158. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  1159. /* Sonstiges: -                                                              */
  1160. /*                                                                           */
  1161. /*---------------------------------------------------------------------------*/
  1162.  
  1163. static MRESULT EXPENTRY UplinkSettings(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
  1164. {
  1165.    SHORT sItem;
  1166.    PUPLINK pUplink;
  1167.    PEMANSETTINGSDATA pEManData = (PEMANSETTINGSDATA) WinQueryWindowULong(hwnd, QWL_USER);
  1168.  
  1169.    switch(msg)
  1170.    {
  1171.       case WM_INITDLG:
  1172.          pEManData = (PEMANSETTINGSDATA) mp2;
  1173.          WinSetWindowULong(hwnd, QWL_USER, (ULONG) mp2);
  1174.  
  1175.          pUplink = EchoMgrOpt.pUplinks;
  1176.          while (pUplink)
  1177.          {
  1178.             sItem = (SHORT) WinSendDlgItemMsg(hwnd, IDD_EMS_UPLINKS+1, LM_INSERTITEM,
  1179.                                               MPFROMSHORT(LIT_END), pUplink->pchEchoMgrAddress);
  1180.             if (sItem != LIT_MEMERROR &&
  1181.                 sItem != LIT_ERROR)
  1182.                WinSendDlgItemMsg(hwnd, IDD_EMS_UPLINKS+1, LM_SETITEMHANDLE,
  1183.                                  MPFROMSHORT(sItem), pUplink);
  1184.  
  1185.             pUplink = pUplink->next;
  1186.          }
  1187.  
  1188.          if (EchoMgrOpt.pUplinks)
  1189.          {
  1190.             WinEnableControl(hwnd, IDD_EMS_UPLINKS+3, TRUE);
  1191.             WinEnableControl(hwnd, IDD_EMS_UPLINKS+4, TRUE);
  1192.          }
  1193.          break;
  1194.  
  1195.       case WM_DESTROY:
  1196.          break;
  1197.  
  1198.       case WM_COMMAND:
  1199.          switch(SHORT1FROMMP(mp1))
  1200.          {
  1201.             case IDD_EMS_UPLINKS+3: /* Change */
  1202.                sItem = (SHORT) WinSendDlgItemMsg(hwnd, IDD_EMS_UPLINKS+1, LM_QUERYSELECTION,
  1203.                                                  MPFROMSHORT(LIT_FIRST), NULL);
  1204.                if (sItem != LIT_NONE)
  1205.                   ChangeUplink(hwnd, sItem);
  1206.                break;
  1207.  
  1208.             case IDD_EMS_UPLINKS+4: /* Delete */
  1209.                sItem = (SHORT) WinSendDlgItemMsg(hwnd, IDD_EMS_UPLINKS+1, LM_QUERYSELECTION,
  1210.                                                  MPFROMSHORT(LIT_FIRST), NULL);
  1211.                if (sItem != LIT_NONE)
  1212.                   DeleteUplink(hwnd, sItem, pEManData->pEchoMgrData);
  1213.                if (!EchoMgrOpt.pUplinks)
  1214.                {
  1215.                   WinEnableControl(hwnd, IDD_EMS_UPLINKS+3, FALSE);
  1216.                   WinEnableControl(hwnd, IDD_EMS_UPLINKS+4, FALSE);
  1217.                }
  1218.                break;
  1219.  
  1220.             default:
  1221.                break;
  1222.          }
  1223.          return (MRESULT) FALSE;
  1224.  
  1225.       case WM_CONTROL:
  1226.          if (SHORT1FROMMP(mp1) == IDD_EMS_UPLINKS+1)
  1227.          {
  1228.             if (SHORT2FROMMP(mp1) == LN_ENTER)
  1229.             {
  1230.                sItem = (SHORT) SendMsg((HWND)mp2, LM_QUERYSELECTION, MPFROMSHORT(LIT_FIRST), NULL);
  1231.                if (sItem != LIT_NONE)
  1232.                   ChangeUplink(hwnd, sItem);
  1233.             }
  1234.          }
  1235.          break;
  1236.  
  1237.       case WM_CURRENTDEL:
  1238.          WinPostMsg(pEManData->hwndSettingsDlg, WM_CURRENTDEL, NULL, NULL);
  1239.          break;
  1240.  
  1241.       default:
  1242.          break;
  1243.    }
  1244.    return WinDefDlgProc(hwnd, msg, mp1, mp2);
  1245. }
  1246.  
  1247. /*---------------------------------------------------------------------------*/
  1248. /* Funktionsname: ChangeUplink                                               */
  1249. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  1250. /* Beschreibung: Oeffnet Dialog zur Einstellung eines Uplinks                */
  1251. /*                                                                           */
  1252. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  1253. /* Parameter: hwndDlg: Dialog-Window (Owner)                                 */
  1254. /*            sItem: Ausgewähltes Item in der Uplink-Liste                   */
  1255. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  1256. /* Rückgabewerte: 1  OK                                                      */
  1257. /*                0  Fehler                                                  */
  1258. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  1259. /* Sonstiges: -                                                              */
  1260. /*                                                                           */
  1261. /*---------------------------------------------------------------------------*/
  1262.  
  1263. static int ChangeUplink(HWND hwndDlg, SHORT sItem)
  1264. {
  1265.    UPLINKPARAM UplinkParam = {sizeof(UPLINKPARAM), NULL};
  1266.  
  1267.    UplinkParam.pUplink = WinSendDlgItemMsg(hwndDlg, IDD_EMS_UPLINKS+1, LM_QUERYITEMHANDLE,
  1268.                                            MPFROMSHORT(sItem), NULL);
  1269.    if (UplinkParam.pUplink)
  1270.    {
  1271.       if (WinDlgBox(HWND_DESKTOP, hwndDlg, UplinkProc, hmodLang, IDD_UPLINK,
  1272.                     &UplinkParam) == DID_OK)
  1273.          EchoMgrOpt.bDirty = TRUE;
  1274.  
  1275.       return 1;
  1276.    }
  1277.    else
  1278.       return 0;
  1279. }
  1280.  
  1281. /*---------------------------------------------------------------------------*/
  1282. /* Funktionsname: UplinkProc                                                 */
  1283. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  1284. /* Beschreibung: Window-Prozedur des Uplink-Settings-Dialogs                 */
  1285. /*                                                                           */
  1286. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  1287. /* Parameter: WINPROC                                                        */
  1288. /*                                                                           */
  1289. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  1290. /* Rückgabewerte: MRESULT                                                    */
  1291. /*                                                                           */
  1292. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  1293. /* Sonstiges: -                                                              */
  1294. /*                                                                           */
  1295. /*---------------------------------------------------------------------------*/
  1296.  
  1297. static MRESULT EXPENTRY UplinkProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
  1298. {
  1299.    PUPLINK pUplink = (PUPLINK) WinQueryWindowULong(hwnd , QWL_USER);
  1300.    extern HWND hwndhelp;
  1301.  
  1302.    switch(msg)
  1303.    {
  1304.       case WM_INITDLG:
  1305.          pUplink = ((PUPLINKPARAM)mp2)->pUplink;
  1306.          WinSetWindowULong(hwnd, QWL_USER, (ULONG) pUplink);
  1307.          WinSetWindowText(hwnd, pUplink->pchEchoMgrAddress);
  1308.  
  1309.          WinSendDlgItemMsg(hwnd, IDD_UPLINK+4, EM_SETTEXTLIMIT, MPFROMSHORT(LEN_USERNAME), NULL);
  1310.          WinSetDlgItemText(hwnd, IDD_UPLINK+4, pUplink->pchEchoMgrName);
  1311.          WinSendDlgItemMsg(hwnd, IDD_UPLINK+2, EM_SETTEXTLIMIT,
  1312.                            MPFROMSHORT(sizeof(pUplink->pchPassword)-1), NULL);
  1313.          WinSetDlgItemText(hwnd, IDD_UPLINK+2, pUplink->pchPassword);
  1314.          break;
  1315.  
  1316.       case WM_COMMAND:
  1317.          if (SHORT1FROMMP(mp1)==DID_OK)
  1318.          {
  1319.             WinQueryDlgItemText(hwnd, IDD_UPLINK+4, LEN_USERNAME+1, pUplink->pchEchoMgrName);
  1320.             WinQueryDlgItemText(hwnd, IDD_UPLINK+2, sizeof(pUplink->pchPassword), pUplink->pchPassword);
  1321.          }
  1322.          break;
  1323.  
  1324.       case WM_ACTIVATE:
  1325.          if (mp1)
  1326.             WinAssociateHelpInstance(hwndhelp, hwnd);
  1327.          else
  1328.             WinAssociateHelpInstance(hwndhelp, NULLHANDLE);
  1329.          break;
  1330.  
  1331.       default:
  1332.          break;
  1333.    }
  1334.    return WinDefDlgProc(hwnd, msg, mp1, mp2);
  1335. }
  1336.  
  1337. /*---------------------------------------------------------------------------*/
  1338. /* Funktionsname: DeleteUplink                                               */
  1339. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  1340. /* Beschreibung: Loescht einen Uplink aus der Liste                          */
  1341. /*                                                                           */
  1342. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  1343. /* Parameter: hwndDlg: Dialog-Window (Owner)                                 */
  1344. /*            sItem: Ausgewähltes Item in der Uplink-Liste                   */
  1345. /*            pEchoMgrData: Echo-Manager-Instanzdaten                        */
  1346. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  1347. /* Rückgabewerte: 1  OK                                                      */
  1348. /*                0  Fehler                                                  */
  1349. /*                2  Abgebrochen                                             */
  1350. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  1351. /* Sonstiges: -                                                              */
  1352. /*                                                                           */
  1353. /*---------------------------------------------------------------------------*/
  1354.  
  1355. static int DeleteUplink(HWND hwndDlg, SHORT sItem, PECHOMGRDATA pEchoMgrData)
  1356. {
  1357.    PUPLINK pUplink;
  1358.  
  1359.    pUplink = WinSendDlgItemMsg(hwndDlg, IDD_EMS_UPLINKS+1, LM_QUERYITEMHANDLE,
  1360.                                MPFROMSHORT(sItem), NULL);
  1361.    if (pUplink)
  1362.    {
  1363.       int iUplink=0;
  1364.  
  1365.       /* Sicherheitsabfrage */
  1366.       if (MessageBox(hwndDlg, IDST_MSG_DELUPLINK, IDST_TITLE_DELUPLINK, IDD_DELUPLINK,
  1367.                      MB_QUERY | MB_YESNO) != MBID_YES)
  1368.          return 2;
  1369.  
  1370.       /* Im Menue suchen */
  1371.       while (iUplink < pEchoMgrData->ulCountUplinks)
  1372.       {
  1373.          if (pEchoMgrData->pMenuTable[iUplink].pUplink == pUplink)
  1374.             break;
  1375.          iUplink++;
  1376.       }
  1377.       if (iUplink < pEchoMgrData->ulCountUplinks)
  1378.       {
  1379.          /* Menue entfernen */
  1380.          SendMsg(pEchoMgrData->hwndFolderPopup, MM_REMOVEITEM,
  1381.                  MPFROM2SHORT(pEchoMgrData->pMenuTable[iUplink].usID, TRUE),
  1382.                  NULL);
  1383.  
  1384.          /* Tabelle updaten */
  1385.          if ((pEchoMgrData->ulCountUplinks - iUplink -1) > 0)
  1386.             memmove(&pEchoMgrData->pMenuTable[iUplink], &pEchoMgrData->pMenuTable[iUplink+1],
  1387.                     (pEchoMgrData->ulCountUplinks - iUplink -1) * sizeof(MENUTABLE));
  1388.          pEchoMgrData->ulCountUplinks--;
  1389.       }
  1390.  
  1391.       /* Aus Listbox entfernen */
  1392.       WinSendDlgItemMsg(hwndDlg, IDD_EMS_UPLINKS+1, LM_DELETEITEM,
  1393.                         MPFROMSHORT(sItem), NULL);
  1394.  
  1395.       /* Aus Liste aushaengen */
  1396.       if (pUplink->prev)
  1397.          pUplink->prev->next = pUplink->next;
  1398.       if (pUplink->next)
  1399.          pUplink->next->prev = pUplink->prev;
  1400.       if (EchoMgrOpt.pUplinks == pUplink)
  1401.          EchoMgrOpt.pUplinks = pUplink->next;
  1402.       if (EchoMgrOpt.pUplinksLast == pUplink)
  1403.          EchoMgrOpt.pUplinksLast = pUplink->prev;
  1404.       EchoMgrOpt.bDirty = TRUE;
  1405.  
  1406.       /* Element entfernen */
  1407.       if (pUplink->pchUplinkAreas)
  1408.          free(pUplink->pchUplinkAreas);
  1409.       free(pUplink);
  1410.  
  1411.       /* aktuellen Uplink geloescht? */
  1412.       if (pUplink == pEchoMgrData->pUplink)
  1413.          WinPostMsg(hwndDlg, WM_CURRENTDEL, NULL, NULL);
  1414.  
  1415.       return 1;
  1416.    }
  1417.    else
  1418.       return 0;
  1419. }
  1420.  
  1421.  
  1422. /*---------------------------------------------------------------------------*/
  1423. /* Funktionsname: DllSettings                                                */
  1424. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  1425. /* Beschreibung: Notebook-Seite "Erweiterungs-DLL"                           */
  1426. /*                                                                           */
  1427. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  1428. /* Parameter: WINPROC                                                        */
  1429. /*                                                                           */
  1430. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  1431. /* Rückgabewerte: MRESULT                                                    */
  1432. /*                                                                           */
  1433. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  1434. /* Sonstiges: -                                                              */
  1435. /*                                                                           */
  1436. /*---------------------------------------------------------------------------*/
  1437.  
  1438. static MRESULT EXPENTRY DllSettings(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
  1439. {
  1440.    switch(msg)
  1441.    {
  1442.       case WM_INITDLG:
  1443.          WinSendDlgItemMsg(hwnd, IDD_EMS_EXTDLL+2, EM_SETTEXTLIMIT,
  1444.                            MPFROMSHORT(LEN_PATHNAME), NULL);
  1445.          WinSetDlgItemText(hwnd, IDD_EMS_EXTDLL+2, EchoMgrOpt.pchDllName);
  1446.          if (EchoMgrOpt.pchDllName[0])
  1447.             WinEnableControl(hwnd, IDD_EMS_EXTDLL+4, TRUE);
  1448.          break;
  1449.  
  1450.       case WM_DESTROY:
  1451.          {
  1452.             char pchTemp[LEN_PATHNAME+1];
  1453.  
  1454.             WinQueryDlgItemText(hwnd, IDD_EMS_EXTDLL+2, sizeof(pchTemp), pchTemp);
  1455.             if (strcmp(EchoMgrOpt.pchDllName, pchTemp))
  1456.             {
  1457.                strcpy(EchoMgrOpt.pchDllName, pchTemp);
  1458.                EchoMgrOpt.bDirty = TRUE;
  1459.             }
  1460.          }
  1461.          break;
  1462.  
  1463.       case WM_CONTROL:
  1464.          if (SHORT1FROMMP(mp1) == IDD_EMS_EXTDLL+2)
  1465.             if (WinQueryDlgItemTextLength(hwnd, IDD_EMS_EXTDLL+2))
  1466.                WinEnableControl(hwnd, IDD_EMS_EXTDLL+4, TRUE);
  1467.             else
  1468.                WinEnableControl(hwnd, IDD_EMS_EXTDLL+4, FALSE);
  1469.          break;
  1470.  
  1471.       case WM_COMMAND:
  1472.          switch(SHORT1FROMMP(mp1))
  1473.          {
  1474.             case IDD_EMS_EXTDLL+3: /* Locate */
  1475.                {
  1476.                   char pchTemp[LEN_PATHNAME+1];
  1477.  
  1478.                   WinQueryDlgItemText(hwnd, IDD_EMS_EXTDLL+2, sizeof(pchTemp), pchTemp);
  1479.                   if (GetPathname(hwnd, pchTemp) == DID_OK)
  1480.                   {
  1481.                      WinSetDlgItemText(hwnd, IDD_EMS_EXTDLL+2, pchTemp);
  1482.                      strcpy(EchoMgrOpt.pchDllName, pchTemp);
  1483.  
  1484.                      EchoMgrOpt.bDirty=TRUE;
  1485.                   }
  1486.                }
  1487.                break;
  1488.  
  1489.             case IDD_EMS_EXTDLL+4: /* Configure */
  1490.                {
  1491.                   char pchTemp[LEN_PATHNAME+1];
  1492.                   FUNCTABLE FuncTable;
  1493.  
  1494.                   WinQueryDlgItemText(hwnd, IDD_EMS_EXTDLL+2, sizeof(pchTemp), pchTemp);
  1495.                   switch(LoadExtensionDLL(pchTemp, &FuncTable))
  1496.                   {
  1497.                      case LOADDLL_OK:
  1498.                         ConfigureDLL(hwnd, &FuncTable);
  1499.                         DosFreeModule(FuncTable.hModule);
  1500.                         break;
  1501.  
  1502.                      case LOADDLL_CANTLOAD:
  1503.                         MessageBox(hwnd, IDST_MSG_EM_DLLLOAD, 0, IDD_EM_DLLLOAD, MB_ERROR | MB_OK);
  1504.                         break;
  1505.  
  1506.                      case LOADDLL_VERSION:
  1507.                         MessageBox(hwnd, IDST_MSG_EM_DLLVER, 0, IDD_EM_DLLVER, MB_ERROR | MB_OK);
  1508.                         break;
  1509.  
  1510.                      case LOADDLL_FUNCMISSING:
  1511.                         MessageBox(hwnd, IDST_MSG_EM_DLLFUNC, 0, IDD_EM_DLLFUNC, MB_ERROR | MB_OK);
  1512.                         break;
  1513.                   }
  1514.                }
  1515.                break;
  1516.  
  1517.             default:
  1518.                break;
  1519.          }
  1520.          return (MRESULT) FALSE;
  1521.  
  1522.       default:
  1523.          break;
  1524.    }
  1525.    return WinDefDlgProc(hwnd, msg, mp1, mp2);
  1526. }
  1527.  
  1528. /*---------------------------------------------------------------------------*/
  1529. /* Funktionsname: ConfigureDLL                                               */
  1530. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  1531. /* Beschreibung: Ruft die Konfigurations-Funktion der DLL auf                */
  1532. /*                                                                           */
  1533. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  1534. /* Parameter: hwndDlg: Dialog-Window (Owner)                                 */
  1535. /*            pFuncTable: Funktionspointer-Tabelle der DLL                   */
  1536. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  1537. /* Rückgabewerte: -                                                          */
  1538. /*                                                                           */
  1539. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  1540. /* Sonstiges: -                                                              */
  1541. /*                                                                           */
  1542. /*---------------------------------------------------------------------------*/
  1543.  
  1544. static void ConfigureDLL(HWND hwndDlg, PFUNCTABLE pFuncTable)
  1545. {
  1546.    extern ECHOMGROPT EchoMgrOpt;
  1547.    ULONG ulSize=0;
  1548.  
  1549.    if (!EchoMgrOpt.pDllParams)
  1550.    {
  1551.       /* noch kein Parameter-Block, neu anfordern */
  1552.       ulSize = pFuncTable->QueryParamBlockSize();
  1553.       if (ulSize < MIN_PARAM_SIZE)
  1554.       {
  1555.          /* interner Fehler der DLL */
  1556.          MessageBox(hwndDlg, IDST_MSG_EM_DLLINT, 0, IDD_EM_DLLINT, MB_ERROR | MB_OK);
  1557.          return;
  1558.       }
  1559.       EchoMgrOpt.pDllParams = calloc(1, ulSize);
  1560.       EchoMgrOpt.ulParamLen = ulSize;
  1561.       EchoMgrOpt.bDirty = TRUE;
  1562.    }
  1563.  
  1564.    /* Setup aufrufen */
  1565.    switch(pFuncTable->SetupParams(EchoMgrOpt.pDllParams, EchoMgrOpt.ulParamLen, hwndDlg, anchor, pFuncTable->hModule))
  1566.    {
  1567.       case ECHOMAN_OK:
  1568.          EchoMgrOpt.bDirty = TRUE;
  1569.          return;
  1570.  
  1571.       case ECHOMAN_CANCEL:
  1572.          return;
  1573.  
  1574.       case ECHOMAN_PARAMSIZE:
  1575.       case ECHOMAN_FORMAT:
  1576.          /* nochmal versuchen, s.u. */
  1577.          break;
  1578.  
  1579.       default:
  1580.          /* interner Fehler der DLL */
  1581.          MessageBox(hwndDlg, IDST_MSG_EM_DLLINT, 0, IDD_EM_DLLINT, MB_ERROR | MB_OK);
  1582.          return;
  1583.    }
  1584.  
  1585.    /* falscher Parameter-Block, neu allokieren und nochmal probieren */
  1586.    ulSize = pFuncTable->QueryParamBlockSize();
  1587.    if (ulSize < MIN_PARAM_SIZE)
  1588.    {
  1589.       /* interner Fehler der DLL */
  1590.       MessageBox(hwndDlg, IDST_MSG_EM_DLLINT, 0, IDD_EM_DLLINT, MB_ERROR | MB_OK);
  1591.       return;
  1592.    }
  1593.    free(EchoMgrOpt.pDllParams);
  1594.    EchoMgrOpt.pDllParams = calloc(1, ulSize);
  1595.    EchoMgrOpt.ulParamLen = ulSize;
  1596.    EchoMgrOpt.bDirty = TRUE;
  1597.  
  1598.    /* Setup aufrufen */
  1599.    switch(pFuncTable->SetupParams(EchoMgrOpt.pDllParams, EchoMgrOpt.ulParamLen, hwndDlg, anchor, pFuncTable->hModule))
  1600.    {
  1601.       case ECHOMAN_OK:
  1602.          EchoMgrOpt.bDirty = TRUE;
  1603.          return;
  1604.  
  1605.       case ECHOMAN_CANCEL:
  1606.          return;
  1607.  
  1608.       default:
  1609.          /* interner Fehler der DLL */
  1610.          MessageBox(hwndDlg, IDST_MSG_EM_DLLINT, 0, IDD_EM_DLLINT, MB_ERROR | MB_OK);
  1611.          return;
  1612.    }
  1613. }
  1614.  
  1615. /*---------------------------------------------------------------------------*/
  1616. /* Funktionsname: ExtractAreasFromMessage                                    */
  1617. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  1618. /* Beschreibung: Holt eine Area-Liste aus dem Messagetext                    */
  1619. /*                                                                           */
  1620. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  1621. /* Parameter: pchMessageText: Text mit Area-Liste                            */
  1622. /*                                                                           */
  1623. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  1624. /* Rückgabewerte: Zeiger auf den Area-String                                 */
  1625. /*                                                                           */
  1626. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  1627. /* Sonstiges: Area-String hat die Form "AREA1 AREA2 AREA3\0"                 */
  1628. /*                                                                           */
  1629. /*---------------------------------------------------------------------------*/
  1630.  
  1631. static char *ExtractAreasFromMessage(char *pchMessageText, char *pchOldAreas)
  1632. {
  1633.    PSTRINGLIST pList=NULL, pLast=NULL;
  1634.    char *pchLine;
  1635.    char pchAreaTag[LEN_AREATAG+1];
  1636.    int iCopied=0;
  1637.    int i;
  1638.    ULONG ulReqLen=0;
  1639.    char *pchAreas=NULL;
  1640.  
  1641.    if (!pchMessageText)
  1642.       return NULL;
  1643.  
  1644.    pchLine = pchMessageText;
  1645.  
  1646.    while (*pchLine)
  1647.    {
  1648.       /* Zeilenenden übergehen */
  1649.       while (*pchLine == '\n')
  1650.          pchLine++;
  1651.  
  1652.       /* Whitespace übergehen */
  1653.       while (*pchLine == ' ' || *pchLine == '*' || *pchLine == '+')
  1654.          pchLine++;
  1655.  
  1656.       /* erstes Wort kopieren */
  1657.       iCopied=0;
  1658.       while (iCopied < LEN_AREATAG && *pchLine != '\n' && *pchLine != ' ')
  1659.          pchAreaTag[iCopied++]= *pchLine++;
  1660.       pchAreaTag[iCopied]=0;
  1661.  
  1662.       /* Ist das ein Area-Tag? */
  1663.       if (pchAreaTag[0])
  1664.       {
  1665.          i=0;
  1666.          while (pchAreaTag[i])
  1667.             if (isalnum(pchAreaTag[i]) ||
  1668.                 pchAreaTag[i] == '.' ||
  1669.                 pchAreaTag[i] == '-' ||
  1670.                 pchAreaTag[i] == '_')
  1671.                i++;
  1672.             else
  1673.                break;
  1674.          if (!pchAreaTag[i] && strlen(pchAreaTag)>=3 )
  1675.          {
  1676.             strupr(pchAreaTag);
  1677. #if 0
  1678.             i=0;
  1679.             while (pchAreaTag[i])
  1680.             {
  1681.                if (isalpha(pchAreaTag[i]))
  1682.                {
  1683. #endif
  1684.                   if (!HaveArea(pList, pchAreaTag) &&
  1685.                       !AreaInAreaSet(pchOldAreas, pchAreaTag) )
  1686.                   {
  1687.                      /* Area-Tag gefunden */
  1688.                      if (pList)
  1689.                      {
  1690.                         pLast->next = malloc(sizeof(STRINGLIST));
  1691.                         pLast = pLast->next;
  1692.                      }
  1693.                      else
  1694.                         pList = pLast = malloc(sizeof(STRINGLIST));
  1695.  
  1696.                      pLast->next = NULL;
  1697.                      pLast->pchString = strdup(pchAreaTag);
  1698.                      ulReqLen += strlen(pchAreaTag)+1;
  1699.                   }
  1700.  
  1701. #if 0
  1702.                   break;
  1703.                }
  1704.                i++;
  1705.             }
  1706. #endif
  1707.          }
  1708.       }
  1709.  
  1710.       /* Zeilenende suchen */
  1711.       while (*pchLine && *pchLine != '\n')
  1712.          pchLine++;
  1713.    }
  1714.  
  1715.    if (ulReqLen)
  1716.    {
  1717.       pchAreas = malloc(ulReqLen);
  1718.       pchAreas[0]=0;
  1719.  
  1720.       while (pList)
  1721.       {
  1722.          if (pchAreas[0])
  1723.             strcat(pchAreas, " ");
  1724.          strcat(pchAreas, pList->pchString);
  1725.  
  1726.          free(pList->pchString);
  1727.          pLast = pList;
  1728.          pList = pList->next;
  1729.          free(pLast);
  1730.       }
  1731.       return pchAreas;
  1732.    }
  1733.    else
  1734.       return NULL;
  1735. }
  1736.  
  1737. static BOOL HaveArea(PSTRINGLIST pList, char *pchTag)
  1738. {
  1739.    while (pList)
  1740.       if (!stricmp(pList->pchString, pchTag))
  1741.          return TRUE;
  1742.       else
  1743.          pList = pList->next;
  1744.  
  1745.    return FALSE;
  1746. }
  1747.  
  1748. /*---------------------------------------------------------------------------*/
  1749. /* Funktionsname: CreateMessageText                                          */
  1750. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  1751. /* Beschreibung: Erzeugt Text mit Anweisungen aus den Echomanager-Kommandos  */
  1752. /*                                                                           */
  1753. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  1754. /* Parameter: hwndCnr: Container-Window                                      */
  1755. /*            pEchoMgrData: Instanzdaten                                     */
  1756. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  1757. /* Rückgabewerte: Zeiger auf neuen Messagetext                               */
  1758. /*                                                                           */
  1759. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  1760. /* Sonstiges: -                                                              */
  1761. /*                                                                           */
  1762. /*---------------------------------------------------------------------------*/
  1763.  
  1764. static char *CreateMessageText(HWND hwndCnr, PECHOMGRDATA pEchoMgrData)
  1765. {
  1766.    char *pchText=NULL, *pchTemp=NULL;
  1767.    char pchLine[100];
  1768.    ULONG ulAlloc=0;
  1769.    PECHOMGRRECORD pRecord=NULL;
  1770.  
  1771.    while (pRecord = SendMsg(hwndCnr, CM_QUERYRECORD, pRecord,
  1772.                                MPFROM2SHORT(pRecord?CMA_NEXT:CMA_FIRST, CMA_ITEMORDER)))
  1773.    {
  1774.       if (pRecord->ulAction)
  1775.       {
  1776.          switch(pRecord->ulAction)
  1777.          {
  1778.             case ACTION_LINK:
  1779.                sprintf(pchLine, CMD_LINK, pRecord->pchEchoName);
  1780.                break;
  1781.  
  1782.             case ACTION_UNLINK:
  1783.                sprintf(pchLine, CMD_UNLINK, pRecord->pchEchoName);
  1784.                break;
  1785.  
  1786.             case ACTION_RESCAN:
  1787.                sprintf(pchLine, CMD_RESCAN, pRecord->pchEchoName);
  1788.                break;
  1789.  
  1790.             case ACTION_LNKRESC:
  1791.                sprintf(pchLine, CMD_LNKRESC, pRecord->pchEchoName, pRecord->pchEchoName);
  1792.                break;
  1793.  
  1794.             default:
  1795.                pchLine[0]=0;
  1796.                break;
  1797.          }
  1798.          if (!pchText)
  1799.          {
  1800.             pchText = malloc(TEXTBLOCKSIZE);
  1801.             strcpy(pchText, pchLine);
  1802.             ulAlloc = TEXTBLOCKSIZE;
  1803.          }
  1804.          else
  1805.          {
  1806.             if (strlen(pchText)+strlen(pchLine) > ulAlloc)
  1807.             {
  1808.                pchTemp = pchText;
  1809.                ulAlloc += TEXTBLOCKSIZE;
  1810.                pchText = malloc(ulAlloc);
  1811.                strcpy(pchText, pchTemp);
  1812.                free(pchTemp);
  1813.             }
  1814.             strcat(pchText, pchLine);
  1815.          }
  1816.       }
  1817.    }
  1818.  
  1819.    if (pEchoMgrData->ulAction)
  1820.    {
  1821.       switch(pEchoMgrData->ulAction)
  1822.       {
  1823.          case ACTION_REFRESH:
  1824.             strcpy(pchLine, CMD_REFRESH);
  1825.             break;
  1826.  
  1827.          case ACTION_PAUSE:
  1828.             strcpy(pchLine, CMD_PAUSE);
  1829.             break;
  1830.  
  1831.          case ACTION_RESUME:
  1832.             strcpy(pchLine, CMD_RESUME);
  1833.             break;
  1834.  
  1835.          default:
  1836.             pchLine[0]=0;
  1837.             break;
  1838.       }
  1839.  
  1840.       if (!pchText)
  1841.       {
  1842.          pchText = malloc(TEXTBLOCKSIZE);
  1843.          strcpy(pchText, pchLine);
  1844.          ulAlloc = TEXTBLOCKSIZE;
  1845.       }
  1846.       else
  1847.       {
  1848.          if (strlen(pchText)+strlen(pchLine) > ulAlloc)
  1849.          {
  1850.             pchTemp = pchText;
  1851.             ulAlloc += TEXTBLOCKSIZE;
  1852.             pchText = malloc(ulAlloc);
  1853.             strcpy(pchText, pchTemp);
  1854.             free(pchTemp);
  1855.          }
  1856.          strcat(pchText, pchLine);
  1857.       }
  1858.    }
  1859.  
  1860.    return pchText;
  1861. }
  1862.  
  1863. /*---------------------------------------------------------------------------*/
  1864. /* Funktionsname: CreateActionList                                           */
  1865. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  1866. /* Beschreibung: Erzeugt eine Liste von Aktionen, die durch die Erweiterungs-*/
  1867. /*               DLL verarbeitet werden sollen                               */
  1868. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  1869. /* Parameter: hwndCnr: Container-Window                                      */
  1870. /*                                                                           */
  1871. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  1872. /* Rückgabewerte: Zeiger auf Kopf der Liste                                  */
  1873. /*                                                                           */
  1874. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  1875. /* Sonstiges: -                                                              */
  1876. /*                                                                           */
  1877. /*---------------------------------------------------------------------------*/
  1878.  
  1879. static PACTIONLIST CreateActionList(HWND hwndCnr)
  1880. {
  1881.    PECHOMGRRECORD pRecord=NULL;
  1882.    PACTIONLIST pList=NULL, pLast=NULL;
  1883.  
  1884.    while (pRecord = SendMsg(hwndCnr, CM_QUERYRECORD, pRecord,
  1885.                                MPFROM2SHORT(pRecord?CMA_NEXT:CMA_FIRST, CMA_ITEMORDER)))
  1886.    {
  1887.       if (pRecord->ulAction == ACTION_LINK ||
  1888.           pRecord->ulAction == ACTION_LNKRESC ||
  1889.           pRecord->ulAction == ACTION_UNLINK)
  1890.       {
  1891.          if (!pList)
  1892.             pList = pLast = malloc(sizeof(ACTIONLIST));
  1893.          else
  1894.          {
  1895.             pLast->next = malloc(sizeof(ACTIONLIST));
  1896.             pLast = pLast->next;
  1897.          }
  1898.  
  1899.          pLast->next = NULL;
  1900.          pLast->ulAction = pRecord->ulAction;
  1901.          strcpy(pLast->pchAreaTag, pRecord->pchEchoName);
  1902.       }
  1903.    }
  1904.    return pList;
  1905. }
  1906.  
  1907. /*---------------------------------------------------------------------------*/
  1908. /* Funktionsname: CreateMessage                                              */
  1909. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  1910. /* Beschreibung: Erzeugt eine Message an den Uplink                          */
  1911. /*                                                                           */
  1912. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  1913. /* Parameter: hwndCnr: Container-Window                                      */
  1914. /*            pEchoMgrData: Instanzdaten                                     */
  1915. /*            pMessage: Erzeugte Message                                     */
  1916. /*            pHeader: Erzeugter Header                                      */
  1917. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  1918. /* Rückgabewerte:  0   OK                                                    */
  1919. /*                 1   keine Aktion                                          */
  1920. /*                 2   Passwort o. Name fehlt                                */
  1921. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  1922. /* Sonstiges: -                                                              */
  1923. /*                                                                           */
  1924. /*---------------------------------------------------------------------------*/
  1925.  
  1926. static int CreateMessage(HWND hwndCnr, PECHOMGRDATA pEchoMgrData, PFTNMESSAGE pMessage, PMSGHEADER pHeader)
  1927. {
  1928.    extern ECHOMGROPT EchoMgrOpt;
  1929.    extern char CurrentName[LEN_USERNAME+1];
  1930.    extern char CurrentArea[LEN_AREATAG+1];
  1931.    extern AREALIST arealiste;
  1932.    char *pchText;
  1933.    LONG lDummy;
  1934.  
  1935.    pchText = CreateMessageText(hwndCnr, pEchoMgrData);
  1936.  
  1937.    if (pchText)
  1938.    {
  1939.       if (pEchoMgrData->pUplink->pchEchoMgrName[0] &&
  1940.           pEchoMgrData->pUplink->pchEchoMgrAddress[0] &&
  1941.           pEchoMgrData->pUplink->pchPassword[0])
  1942.       {
  1943.          /* Header vorbereiten */
  1944.          MSG_NewMessage(pMessage, pHeader, &arealiste, CurrentArea, CurrentName, pEchoMgrData->pUplink->pchMyAddress, &lDummy);
  1945.          if (pMessage->pchMessageText)
  1946.             free(pMessage->pchMessageText);
  1947.          pMessage->pchMessageText = pchText;
  1948.          strcpy(pHeader->pchToName, pEchoMgrData->pUplink->pchEchoMgrName);
  1949.          strcpy(pHeader->pchSubject, pEchoMgrData->pUplink->pchPassword);
  1950.          StringToNetAddr(pEchoMgrData->pUplink->pchEchoMgrAddress, &pHeader->ToAddress, NULL);
  1951.          pHeader->ulAttrib |= ATTRIB_KILLSENT | ATTRIB_PRIVATE;
  1952.  
  1953.          return 0;
  1954.       }
  1955.       else
  1956.       {
  1957.          free(pchText);
  1958.          return 2;
  1959.       }
  1960.    }
  1961.    else
  1962.       return 1;
  1963. }
  1964.  
  1965. /*---------------------------------------------------------------------------*/
  1966. /* Funktionsname: MessageSaveThread                                          */
  1967. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  1968. /* Beschreibung: Sichert die Uplink-Message in der Messagebase               */
  1969. /*                                                                           */
  1970. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  1971. /* Parameter: pParam: Datenblock (SAVEPARAM)                                 */
  1972. /*                                                                           */
  1973. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  1974. /* Rückgabewerte: -                                                          */
  1975. /*                                                                           */
  1976. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  1977. /* Sonstiges: -                                                              */
  1978. /*                                                                           */
  1979. /*---------------------------------------------------------------------------*/
  1980.  
  1981. static void _Optlink MessageSaveThread(PVOID pParam)
  1982. {
  1983.    extern USERDATAOPT userdaten;
  1984.    extern GENERALOPT generaloptions;
  1985.    extern AREALIST arealiste;
  1986.    extern DRIVEREMAP driveremap;
  1987.    extern TEMPLATELIST templatelist;
  1988.    extern char CurrentArea[LEN_AREATAG+1];
  1989.    extern BOOL MailEntered[3];
  1990.    AREADEFLIST *pAreaDef;
  1991.    HAB hab;
  1992.    HMQ hmq;
  1993.  
  1994.    PSAVEPARAM pSaveParam = (PSAVEPARAM) pParam;
  1995.    ULONG ulRet=0;
  1996.  
  1997.    INSTALLEXPT("MsgSave");
  1998.  
  1999.    hab = WinInitialize(0);
  2000.    hmq=WinCreateMsgQueue(hab, 0);
  2001.    WinCancelShutdown(hmq, TRUE);
  2002.  
  2003.    if (pAreaDef = AM_FindArea(&arealiste, CurrentArea))
  2004.    {
  2005.       ulRet = MSG_AddMessage(&pSaveParam->Message, &pSaveParam->Header,
  2006.                              &arealiste, CurrentArea, &userdaten, &generaloptions,
  2007.                              &driveremap, generaloptions.lMaxMsgLen * 1024,
  2008.                              &templatelist, 0, SendAddMessage);
  2009.       MailEntered[pAreaDef->areadata.areatype]=TRUE;
  2010.       pAreaDef->mailentered = TRUE;
  2011.    }
  2012.  
  2013.    MSG_ClearMessage(&pSaveParam->Header, &pSaveParam->Message);
  2014.  
  2015.    WinPostMsg(pSaveParam->hwndDlg, WM_SAVEDONE, MPFROMLONG(ulRet), pSaveParam);
  2016.  
  2017.    WinDestroyMsgQueue(hmq);
  2018.    WinTerminate(hab);
  2019.  
  2020.    DEINSTALLEXPT;
  2021.  
  2022.    return;
  2023. }
  2024.  
  2025. /*---------------------------------------------------------------------------*/
  2026. /* Funktionsname: CfgChangeThread                                            */
  2027. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  2028. /* Beschreibung: Ruft die Erweiterungs-DLL auf, um die Config-Dateien zu     */
  2029. /*               aendern                                                     */
  2030. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  2031. /* Parameter: pParam: Thread-Parameter (CHANGEPARAM)                         */
  2032. /*                                                                           */
  2033. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  2034. /* Rückgabewerte: -                                                          */
  2035. /*                                                                           */
  2036. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  2037. /* Sonstiges: -                                                              */
  2038. /*                                                                           */
  2039. /*---------------------------------------------------------------------------*/
  2040.  
  2041. static void _Optlink CfgChangeThread(PVOID pParam)
  2042. {
  2043.    extern ECHOMGROPT EchoMgrOpt;
  2044.    extern PATHNAMES pathnames;
  2045.    extern char CurrentAddress[LEN_5DADDRESS+1];
  2046.    PACTIONLIST pActionList = ((PCHANGEPARAM) pParam)->pActionList;
  2047.    PUPLINK pUplink = ((PCHANGEPARAM) pParam)->pUplink;
  2048.    PACTIONLIST pTemp;
  2049.    ULONG ulRet=0;
  2050.    FUNCTABLE FuncTable;
  2051.  
  2052.    INSTALLEXPT("CfgChange");
  2053.  
  2054.    switch(ulRet = LoadExtensionDLL(EchoMgrOpt.pchDllName, &FuncTable))
  2055.    {
  2056.       case LOADDLL_OK:
  2057.          while(pActionList)
  2058.          {
  2059.             if (pActionList->ulAction == ACTION_LINK ||
  2060.                 pActionList->ulAction == ACTION_LNKRESC)
  2061.                ulRet = FuncTable.AddEcho(EchoMgrOpt.pDllParams, EchoMgrOpt.ulParamLen,
  2062.                                          pathnames.squishcfg, pUplink->pchMyAddress,
  2063.                                          pUplink->pchEchoMgrAddress,
  2064.                                          pActionList->pchAreaTag, 0);
  2065.             else
  2066.                ulRet = FuncTable.RemoveEcho(EchoMgrOpt.pDllParams, EchoMgrOpt.ulParamLen,
  2067.                                             pathnames.squishcfg, pUplink->pchMyAddress,
  2068.                                             pUplink->pchEchoMgrAddress,
  2069.                                             pActionList->pchAreaTag, 0);
  2070.  
  2071.             if (ulRet)
  2072.                break;
  2073.             else
  2074.             {
  2075.                pTemp = pActionList;
  2076.                pActionList = pActionList->next;
  2077.                free(pTemp);
  2078.             }
  2079.          }
  2080.          /* restliche Aktionen loeschen */
  2081.          while(pActionList)
  2082.          {
  2083.             pTemp = pActionList;
  2084.             pActionList = pActionList->next;
  2085.             free(pTemp);
  2086.          }
  2087.          DosFreeModule(FuncTable.hModule);
  2088.          break;
  2089.  
  2090.       default:
  2091.          WinPostMsg(((PCHANGEPARAM) pParam)->hwndDlg, WM_CHANGEDONE, MPFROMLONG(ulRet), NULL);
  2092.          free(pParam);
  2093.          DEINSTALLEXPT;
  2094.          return;
  2095.    }
  2096.  
  2097.    WinPostMsg(((PCHANGEPARAM) pParam)->hwndDlg, WM_CHANGEDONE, NULL, MPFROMLONG(ulRet));
  2098.    free(pParam);
  2099.  
  2100.    DEINSTALLEXPT;
  2101.  
  2102.    return;
  2103. }
  2104.  
  2105. /*---------------------------------------------------------------------------*/
  2106. /* Funktionsname: LoadExtensionDLL                                           */
  2107. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  2108. /* Beschreibung: Laedt die Erweiterungs-DLL, holt alle Funktionspointer      */
  2109. /*                                                                           */
  2110. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  2111. /* Parameter: pchDllName: Dateiname der DLL                                  */
  2112. /*            pFuncTable: Funktionspointer-Tabelle                           */
  2113. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  2114. /* Rückgabewerte: LOADDLL_OK:   DLL geladen                                  */
  2115. /*                LOADDLL_CANTLOAD: Kann DLL nicht laden                     */
  2116. /*                LOADDLL_FUNCMISSING: Funktion in der DLL fehlt             */
  2117. /*                LOADDLL_VERSION: Version der DLL stimmt nicht              */
  2118. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  2119. /* Sonstiges: -                                                              */
  2120. /*                                                                           */
  2121. /*---------------------------------------------------------------------------*/
  2122.  
  2123. static int LoadExtensionDLL(char *pchDllName, PFUNCTABLE pFuncTable)
  2124. {
  2125.    HMODULE hmod;
  2126.    char pchError[20];
  2127.    int iRet = LOADDLL_OK;
  2128.  
  2129.    if (DosLoadModule(pchError, sizeof(pchError), pchDllName, &hmod))
  2130.       return LOADDLL_CANTLOAD;
  2131.  
  2132.    pFuncTable->hModule = hmod;
  2133.  
  2134.    if (DosQueryProcAddr(hmod, 0, "QueryVersion", (PFN*) &pFuncTable->QueryVersion))
  2135.       iRet = LOADDLL_FUNCMISSING;
  2136.    else
  2137.       if (pFuncTable->QueryVersion() != DLL_VERSION)
  2138.          iRet = LOADDLL_VERSION;
  2139.       else
  2140.          if (DosQueryProcAddr(hmod, 0, "QueryParamBlockSize", (PFN*) &pFuncTable->QueryParamBlockSize))
  2141.             iRet = LOADDLL_FUNCMISSING;
  2142.          else
  2143.             if (DosQueryProcAddr(hmod, 0, "SetupParams", (PFN*) &pFuncTable->SetupParams))
  2144.                iRet = LOADDLL_FUNCMISSING;
  2145.             else
  2146.                if (DosQueryProcAddr(hmod, 0, "AddEcho", (PFN*) &pFuncTable->AddEcho))
  2147.                   iRet = LOADDLL_FUNCMISSING;
  2148.                else
  2149.                   if (DosQueryProcAddr(hmod, 0, "RemoveEcho", (PFN*) &pFuncTable->RemoveEcho))
  2150.                      iRet = LOADDLL_FUNCMISSING;
  2151.  
  2152.    if (iRet)
  2153.       DosFreeModule(hmod);
  2154.  
  2155.    return iRet;
  2156. }
  2157.  
  2158. /*---------------------------------------------------------------------------*/
  2159. /* Funktionsname: FindUplink                                                 */
  2160. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  2161. /* Beschreibung: Sucht in der Liste der Uplinks den Eintrag mit der          */
  2162. /*               angegebenen Uplink-Adresse                                  */
  2163. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  2164. /* Parameter: pEchoMgrOpt: Uplink-Liste                                      */
  2165. /*            pchUplinkAddress: FTN-Adresse des ges. Uplinks                 */
  2166. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  2167. /* Rückgabewerte: NULL    nicht gefunden                                     */
  2168. /*                sonst   Pointer auf Uplink-Eintrag                         */
  2169. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  2170. /* Sonstiges: -                                                              */
  2171. /*                                                                           */
  2172. /*---------------------------------------------------------------------------*/
  2173.  
  2174. static PUPLINK FindUplink(PECHOMGROPT pEchoMgrOpt, char *pchUplinkAddress)
  2175. {
  2176.    PUPLINK pTemp = pEchoMgrOpt->pUplinks;
  2177.  
  2178.    while (pTemp && stricmp(pTemp->pchEchoMgrAddress, pchUplinkAddress))
  2179.       pTemp = pTemp->next;
  2180.  
  2181.    return pTemp;
  2182. }
  2183.  
  2184. /*---------------------------------------------------------------------------*/
  2185. /* Funktionsname: FindMatchingUplink                                         */
  2186. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  2187. /* Beschreibung: Sucht in der Liste der Uplinks den Eintrag, der zu der      */
  2188. /*               angegebenen aktuellen Adresse passt.                        */
  2189. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  2190. /* Parameter: pEchoMgrOpt: Uplink-Liste                                      */
  2191. /*            pchMyAddress: aktuelle Adresse                                 */
  2192. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  2193. /* Rückgabewerte: NULL    nicht gefunden                                     */
  2194. /*                sonst   Pointer auf Uplink-Eintrag                         */
  2195. /*                                                                           */
  2196. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  2197. /* Sonstiges: -                                                              */
  2198. /*                                                                           */
  2199. /*---------------------------------------------------------------------------*/
  2200.  
  2201. static PUPLINK FindMatchingUplink(PECHOMGROPT pEchoMgrOpt, char *pchMyAddress)
  2202. {
  2203.    PUPLINK pTemp = pEchoMgrOpt->pUplinks;
  2204.  
  2205.    while (pTemp && stricmp(pTemp->pchMyAddress, pchMyAddress))
  2206.       pTemp = pTemp->next;
  2207.  
  2208.    return pTemp;
  2209. }
  2210.  
  2211. /*---------------------------------------------------------------------------*/
  2212. /* Funktionsname: ExtractUplinkFromMessage                                   */
  2213. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  2214. /* Beschreibung: Erzeugt einen neuen Uplink aus der aktuellen Message        */
  2215. /*                                                                           */
  2216. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  2217. /* Parameter: pHeader: Message-Header                                        */
  2218. /*            pMessage: aktuelle Message                                     */
  2219. /*            pEchoMgrOpt: Uplink-Liste                                      */
  2220. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  2221. /* Rückgabewerte: 1   OK                                                     */
  2222. /*                0   keine Areas in der Message                             */
  2223. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  2224. /* Sonstiges: -                                                              */
  2225. /*                                                                           */
  2226. /*---------------------------------------------------------------------------*/
  2227.  
  2228. int ExtractUplinkFromMessage(HWND hwndClient, PMSGHEADER pHeader, PFTNMESSAGE pMessage, PECHOMGROPT pEchoMgrOpt)
  2229. {
  2230.    PUPLINK pNewUplink;
  2231.    char pchAddress[LEN_5DADDRESS];
  2232.    char *pchAreas=NULL;
  2233.    char *pchSave=NULL;
  2234.    ULONG ulResponse;
  2235.  
  2236.    /* Suchen, ob schon vorhanden */
  2237.    NetAddrToString(pchAddress, &pHeader->FromAddress);
  2238.    pNewUplink = FindUplink(pEchoMgrOpt, pchAddress);
  2239.  
  2240.    if (pNewUplink)
  2241.       /* Schon vorhanden, Abfrage ob anhaengen */
  2242.       switch(ulResponse = MessageBox(hwndClient, IDST_MSG_APPENDAREAS, IDST_TITLE_DOEXTRACT,
  2243.                                      IDD_EM_APPENDAREAS, MB_YESNOCANCEL | MB_QUERY))
  2244.       {
  2245.          case MBID_YES:
  2246.             break;
  2247.  
  2248.          case MBID_NO:
  2249.             /* Areas ersetzen */
  2250.             if (pNewUplink->pchUplinkAreas)
  2251.                free(pNewUplink->pchUplinkAreas);
  2252.             pNewUplink->pchUplinkAreas = NULL;
  2253.             break;
  2254.  
  2255.          case MBID_CANCEL:
  2256.             return 1;
  2257.       }
  2258.  
  2259.    /* Text extrahieren */
  2260.    pchAreas = ExtractAreasFromMessage(pMessage->pchMessageText,
  2261.                                       pNewUplink?pNewUplink->pchUplinkAreas:NULL);
  2262.  
  2263.    if (!pchAreas)
  2264.       return 0;
  2265.  
  2266.    if (!pNewUplink)
  2267.    {
  2268.       /* Neuen Uplink */
  2269.       pNewUplink = calloc(1, sizeof(UPLINK));
  2270.       if (pEchoMgrOpt->pUplinks)
  2271.          pEchoMgrOpt->pUplinksLast->next = pNewUplink;
  2272.       else
  2273.          pEchoMgrOpt->pUplinks = pNewUplink;
  2274.       pNewUplink->prev = pEchoMgrOpt->pUplinksLast;
  2275.       pEchoMgrOpt->pUplinksLast = pNewUplink;
  2276.  
  2277.       /* Default-Daten */
  2278.       memcpy(pNewUplink->pchEchoMgrName, pHeader->pchFromName, LEN_USERNAME);
  2279.       memcpy(pNewUplink->pchEchoMgrAddress, pchAddress, LEN_5DADDRESS);
  2280.       NetAddrToString(pNewUplink->pchMyAddress, &pHeader->ToAddress);
  2281.       pNewUplink->pchUplinkAreas = pchAreas;
  2282.    }
  2283.    else
  2284.    {
  2285.       switch(ulResponse) /* von Abfrage Anhaengen */
  2286.       {
  2287.          case MBID_YES:
  2288.             pchSave = pNewUplink->pchUplinkAreas;
  2289.             if (pchSave)
  2290.             {
  2291.                pNewUplink->pchUplinkAreas = malloc(strlen(pchSave) + strlen(pchAreas) + 1);
  2292.                strcpy(pNewUplink->pchUplinkAreas, pchSave);
  2293.                strcat(pNewUplink->pchUplinkAreas, " ");
  2294.                strcat(pNewUplink->pchUplinkAreas, pchAreas);
  2295.                free(pchAreas);
  2296.             }
  2297.             else
  2298.                pNewUplink->pchUplinkAreas = pchAreas;
  2299.             break;
  2300.  
  2301.          case MBID_NO:
  2302.             /* Areas ersetzen */
  2303.             pNewUplink->pchUplinkAreas = pchAreas;
  2304.             NetAddrToString(pNewUplink->pchMyAddress, &pHeader->ToAddress);
  2305.             break;
  2306.       }
  2307.    }
  2308.  
  2309.    pEchoMgrOpt->bDirty = TRUE;
  2310.  
  2311.    return 1;
  2312. }
  2313.  
  2314. /*-----------------------------------------------------------------------------
  2315.  | Funktionsname: RemoveEchoFromUplink
  2316.  |- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  2317.  | Beschreibung: Entfernt ein Echo aus der Echoliste eines Uplinks
  2318.  |
  2319.  |- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  2320.  | Parameter: hwndDlg: Dialog-Window
  2321.  |            pEchoMgrData: Instanzdaten
  2322.  |- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  2323.  | Rückgabewerte: 0  OK
  2324.  |                1  Fehler (Echo nicht gefunden)
  2325.  |- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  2326.  | Sonstiges: Das Echo wird durch pPopupRecord in den Instanzdaten bestimmt.
  2327.  |
  2328.  +---------------------------------------------------------------------------*/
  2329.  
  2330. static int RemoveEchoFromUplink(HWND hwndDlg, PECHOMGRDATA pEchoMgrData)
  2331. {
  2332.    if (pEchoMgrData->pUplink)
  2333.    {
  2334.       PCHAR pchEchos, pchNext;
  2335.  
  2336.       /* Popup-Echo ermitteln */
  2337.       pchEchos = pEchoMgrData->pUplink->pchUplinkAreas;
  2338.  
  2339.       while (pchEchos)
  2340.       {
  2341.          pchEchos = strstr(pchEchos, pEchoMgrData->pPopupRecord->pchEchoName);
  2342.          if (pchEchos)
  2343.          {
  2344.             int len = strlen(pEchoMgrData->pPopupRecord->pchEchoName);
  2345.  
  2346.             if (*(pchEchos+len) == ' ' || /* danach ein Trenner */
  2347.                 *(pchEchos+len) == 0)     /* oder Ende */
  2348.             {
  2349.                /* gefunden */
  2350.                break;
  2351.             }
  2352.             else
  2353.                pchEchos += len;
  2354.          }
  2355.       }
  2356.  
  2357.       if (pchEchos)
  2358.       {
  2359.          /* Anfang des naechsten Echos suchen */
  2360.          pchNext = pchEchos;
  2361.          while (*pchNext && *pchNext != ' ')
  2362.             pchNext++;
  2363.          if (*pchNext)
  2364.          {
  2365.             pchNext++;
  2366.             if (pchEchos == pEchoMgrData->pUplink->pchUplinkAreas)
  2367.             {
  2368.                /* Erstes Echo */
  2369.                pchEchos = pEchoMgrData->pUplink->pchUplinkAreas;
  2370.                while (*pchNext)
  2371.                   *pchEchos++ = *pchNext++;
  2372.                *pchEchos = 0;
  2373.             }
  2374.             else
  2375.             {
  2376.                /* nach vorne kopieren */
  2377.                while (*pchNext)
  2378.                   *pchEchos++ = *pchNext++;
  2379.                *pchEchos = *pchNext;
  2380.             }
  2381.          }
  2382.          else
  2383.          {
  2384.             /* letztes Echo, abschneiden */
  2385.             if (pchEchos > pEchoMgrData->pUplink->pchUplinkAreas)
  2386.                pchEchos--;
  2387.             *pchEchos = 0;
  2388.          }
  2389.  
  2390.          /* Flags setzen */
  2391.          EchoMgrOpt.bDirty = TRUE;
  2392.  
  2393.          /* Record aus Container entfernen */
  2394.          free(pEchoMgrData->pPopupRecord->pchEchoName);
  2395.          WinSendDlgItemMsg(hwndDlg, IDD_ECHOMANAGER+1, CM_REMOVERECORD,
  2396.                            &pEchoMgrData->pPopupRecord,
  2397.                            MPFROM2SHORT(1, CMA_FREE | CMA_INVALIDATE));
  2398.  
  2399.          return 0;
  2400.       }
  2401.  
  2402.       /* nicht gefunden */
  2403.       return 1;
  2404.    }
  2405.    else
  2406.       /* kein Uplink !? */
  2407.       return 1;
  2408. }
  2409.  
  2410. /*-------------------------------- Modulende --------------------------------*/
  2411.  
  2412.