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

  1. /*---------------------------------------------------------------------------+
  2.  | Titel:  MSGLIST.C                                                         |
  3.  +-----------------------------------------+---------------------------------+
  4.  | Erstellt von: Michael Hohner            | Am: 27.07.93                    |
  5.  +-----------------------------------------+---------------------------------+
  6.  | System: OS/2 2.x PM                                                       |
  7.  +---------------------------------------------------------------------------+
  8.  | Beschreibung:                                                             |
  9.  |                                                                           |
  10.  |     Messageliste von Fleet Street                                         |
  11.  |                                                                           |
  12.  |                                                                           |
  13.  +---------------------------------------------------------------------------+
  14.  | Bemerkungen:                                                              |
  15.  +---------------------------------------------------------------------------*/
  16.  
  17. /*----------------------------- Header-Dateien ------------------------------*/
  18. #pragma strings(readonly)
  19.  
  20. #define INCL_GPILOGCOLORTABLE
  21. #define INCL_BASE
  22. #define INCL_PM
  23. #define INCL_SPLDOSPRINT
  24. #include <os2.h>
  25. #include <string.h>
  26. #include <stdlib.h>
  27. #include <stdio.h>
  28.  
  29. #include "main.h"
  30. #include "resids.h"
  31. #include "messages.h"
  32. #include "structs.h"
  33. #include "msgheader.h"
  34. #include "areaman\areaman.h"
  35. #include "dialogids.h"
  36. #include "handlemsg\handlemsg.h"
  37. #include "handlemsg\kludgeapi.h"
  38. #include "msglist.h"
  39. #include "utility.h"
  40. #include "areadlg.h"
  41. #include "savemsg.h"
  42. #include "controls\mlist.h"
  43. #include "controls\clrsel.h"
  44. #include "printsetup.h"
  45. #include "printmsg\printmsg.h"
  46. #include "dump\expt.h"
  47.  
  48. /*--------------------------------- Defines ---------------------------------*/
  49.  
  50.  
  51. typedef struct _MSGLISTDATA {
  52.              ULONG         popupRecord;
  53.              HWND          hwndpopup;
  54.              HWND          hwndpopupsmall;
  55.              HPOINTER      icon;
  56.              char          pchCurrentArea[LEN_AREATAG+1];
  57.              HSWITCH       hSwitch;       /* Switch-Entry-Handle        */
  58.              ULONG         ulEnableCount; /* Enable-Counter             */
  59.              BOOL          bKeyboard;     /* Kontextmenue per Tastatur? */
  60.              BOOL          bNotifications;
  61.              BOOL          bForeground;
  62.           } MSGLISTDATA, *PMSGLISTDATA;
  63.  
  64. #define TAB_FONT    "8.Helv"
  65. #define RGB_GREY    0x00cccccc
  66.  
  67. /*---------------------------- Globale Variablen ----------------------------*/
  68.  
  69. extern HAB anchor;
  70. extern HMODULE hmodLang;
  71. extern char CurrentArea[LEN_AREATAG+1];
  72. extern AREALIST arealiste;
  73. extern BOOL MailEntered[3];
  74. extern HWND client;
  75. extern BOOL bDoingWork;
  76. extern BOOL bStopWork;
  77. extern MSGLISTOPTIONS msglistoptions;
  78. extern DRIVEREMAP driveremap;
  79.  
  80. /*--------------------------- Funktionsprototypen ---------------------------*/
  81. static void CleanupMsgList(HWND hwndContainer);
  82. static int InsertHeaders(HWND hwndContainer);
  83. static BOOL LoadItem(HWND hwnd, PMLISTRECORD pRecord);
  84. static PULONG CollectMsgIDs(HWND hwndCnr, ULONG ulSelectedID, PULONG pulRecordsCollected);
  85. static void ListAddMessage(HWND hwndCnr, PMESSAGEID pMsgID, MSGHEADER *pHeader);
  86. static void ListDeleteMessage(HWND hwndCnr, PMESSAGEID pMsgID);
  87. static void ListMarkReadMessage(HWND hwndCnr, PMESSAGEID pMsgID);
  88. static void ListMarkAllRead(HWND hwndCnr, PMESSAGEID pMsgID);
  89. static void ListChangeMessage(HWND hwndCnr, PMESSAGEID pMsgID, MSGHEADER *pHeader);
  90. static MRESULT EXPENTRY MListSettingsProc(HWND hwnd, ULONG message, MPARAM mp1, MPARAM mp2);
  91. static void InsertMListSettingsPages(HWND notebook);
  92. static MRESULT EXPENTRY MListSettColProc(HWND hwnd, ULONG message, MPARAM mp1, MPARAM mp2);
  93.  
  94. /*---------------------------------------------------------------------------*/
  95. /* Funktionsname: MsgListProc                                                */
  96. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  97. /* Beschreibung: Dialog-Prozedur der Messageliste                            */
  98. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  99. /* Parameter: (Window-Procedure )                                            */
  100. /*                                                                           */
  101. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  102. /* Rückgabewerte: MRESULT                                                    */
  103. /*                                                                           */
  104. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  105. /* Sonstiges:                                                                */
  106. /*                                                                           */
  107. /*---------------------------------------------------------------------------*/
  108.  
  109. MRESULT EXPENTRY MsgListProc(HWND parent, ULONG message, MPARAM mp1, MPARAM mp2)
  110. {
  111.    extern HWND hwndhelp, frame;
  112.    extern GENERALOPT generaloptions;
  113.    extern PATHNAMES pathnames;
  114.    extern int tidWorker;
  115.    MRESULT resultbuf=0;
  116.    SWP swp;
  117.    PMSGLISTDATA pMsgListData;
  118.    int iCurrent;
  119.    MLISTCOLUMNS MCol;
  120.    MLISTCOLORS  MColors;
  121.  
  122.    pMsgListData=(PMSGLISTDATA) WinQueryWindowULong(parent, QWL_USER);
  123.  
  124.    switch(message)
  125.    {
  126.       case WM_INITDLG:
  127.          pMsgListData=malloc(sizeof(MSGLISTDATA));
  128.          memset(pMsgListData, 0, sizeof(MSGLISTDATA));
  129.          WinSetWindowULong(parent, QWL_USER, (ULONG) pMsgListData);
  130.  
  131.          pMsgListData->hSwitch=AddToWindowList(parent);
  132.  
  133.          pMsgListData->hwndpopup=WinLoadMenu(HWND_DESKTOP,
  134.                                              hmodLang, IDM_MSGLISTPOPUP);
  135.          pMsgListData->hwndpopupsmall=WinLoadMenu(WinWindowFromID(parent, IDD_MSGLIST+1),
  136.                                              hmodLang, IDM_SMLISTPOPUP);
  137.          if (pMsgListData->hwndpopupsmall)
  138.             ReplaceSysMenu(parent, pMsgListData->hwndpopupsmall, 1);
  139.  
  140.          if (msglistoptions.ulFlags & SCRIPTS_FOREGROUND)
  141.          {
  142.             pMsgListData->bForeground = TRUE;
  143.             WinCheckMenuItem(pMsgListData->hwndpopupsmall, IDM_SMP_FGROUND, TRUE);
  144.             WinSetOwner(parent, client);
  145.          }
  146.          else
  147.          {
  148.             pMsgListData->bForeground = FALSE;
  149.             WinCheckMenuItem(pMsgListData->hwndpopupsmall, IDM_SMP_FGROUND, FALSE);
  150.             WinSetOwner(parent, HWND_DESKTOP);
  151.          }
  152.  
  153.          RestoreWinPos(parent, &msglistoptions.ListPos, TRUE, FALSE);
  154.  
  155.          SetForeground(WinWindowFromID(parent,IDD_MSGLIST+1),
  156.                        &msglistoptions.lForeClr);
  157.          SetBackground(WinWindowFromID(parent,IDD_MSGLIST+1),
  158.                        &msglistoptions.lBackClr);
  159.          MColors.lUnreadClr = msglistoptions.lUnreadClr;
  160.          MColors.lFromClr   = msglistoptions.lFromClr;
  161.          MColors.lToClr     = msglistoptions.lToClr;
  162.          WinSendDlgItemMsg(parent, IDD_MSGLIST+1, MLIM_SETCOLORS, &MColors, NULL);
  163.  
  164.          SetFont(WinWindowFromID(parent,IDD_MSGLIST+1),
  165.                  msglistoptions.mlistfont);
  166.  
  167.          MCol.ulNrPercent   = msglistoptions.ulNrPercent;
  168.          MCol.ulFromPercent = msglistoptions.ulFromPercent;
  169.          MCol.ulToPercent   = msglistoptions.ulToPercent;
  170.          MCol.ulSubjPercent = msglistoptions.ulSubjPercent;
  171.          MCol.ulStampWrittenPercent = msglistoptions.ulStampWrittenPercent;
  172.          MCol.ulStampArrivedPercent = msglistoptions.ulStampArrivedPercent;
  173.  
  174.          WinSendDlgItemMsg(parent, IDD_MSGLIST+1, MLIM_SETCOLUMNS,
  175.                            &MCol, NULL);
  176.  
  177.  
  178.          pMsgListData->icon=LoadIcon(IDB_MSGLIST);
  179.          SendMsg(parent, WM_SETICON, (MPARAM) pMsgListData->icon, (MPARAM) 0);
  180.  
  181.          SendMsg(parent, TM_REREADTHREADS, NULL, NULL);
  182.          SetInitialAccel(parent);
  183.          WinShowWindow(parent, TRUE);
  184.          pMsgListData->bNotifications = TRUE;
  185.          break;
  186.  
  187.       case TM_REREADTHREADS:
  188.          CleanupMsgList(WinWindowFromID(parent, IDD_MSGLIST+1));
  189.          strcpy(pMsgListData->pchCurrentArea, CurrentArea);
  190.  
  191.          /* Header-Infos einfuegen */
  192.          WinEnableWindowUpdate(WinWindowFromID(parent, IDD_MSGLIST+1), FALSE);
  193.          iCurrent = InsertHeaders(WinWindowFromID(parent, IDD_MSGLIST+1));
  194.  
  195.          if (iCurrent)
  196.          {
  197.             /* Aktuelle Message anfahren */
  198.  
  199.             WinSendDlgItemMsg(parent, IDD_MSGLIST+1, MLIM_SCROLLTO,
  200.                               MPFROMLONG(iCurrent), NULL);
  201.          }
  202.          WinEnableWindowUpdate(WinWindowFromID(parent, IDD_MSGLIST+1), TRUE);
  203.          break;
  204.  
  205.       case WM_QUERYTRACKINFO:
  206.          WinQueryWindowPos(parent, &swp);
  207.          if (swp.fl & SWP_MINIMIZE)
  208.             break;
  209.  
  210.          /* Default-Werte aus Original-Prozedur holen */
  211.          resultbuf=WinDefDlgProc(parent,message,mp1,mp2);
  212.  
  213.          /* Minimale Fenstergroesse einstellen */
  214.          ((PTRACKINFO)mp2)->ptlMinTrackSize.x=290;
  215.          ((PTRACKINFO)mp2)->ptlMinTrackSize.y=160;
  216.          return resultbuf;
  217.  
  218.       case WM_ADJUSTWINDOWPOS:
  219.          if (((PSWP)mp1)->fl & SWP_MINIMIZE)
  220.             WinShowWindow(WinWindowFromID(parent, IDD_MSGLIST+1), FALSE);
  221.          if (((PSWP)mp1)->fl & (SWP_MAXIMIZE|SWP_RESTORE))
  222.             WinShowWindow(WinWindowFromID(parent, IDD_MSGLIST+1), TRUE);
  223.          break;
  224.  
  225.       case WM_ADJUSTFRAMEPOS:
  226.          SizeToClient(anchor, (PSWP) mp1, parent, IDD_MSGLIST+1);
  227.          break;
  228.  
  229.       case WM_WINDOWPOSCHANGED:
  230.          if (pMsgListData && pMsgListData->bNotifications)
  231.          {
  232.             extern DIRTYFLAGS dirtyflags;
  233.  
  234.             SaveWinPos(parent, (PSWP) mp1, &msglistoptions.ListPos, &dirtyflags.mlsettingsdirty);
  235.          }
  236.          break;
  237.  
  238.       case WM_ACTIVATE:
  239.          if (mp1)
  240.             WinAssociateHelpInstance(hwndhelp, parent);
  241.          else
  242.             WinAssociateHelpInstance(hwndhelp, frame);
  243.          break;
  244.  
  245.       case WM_DESTROY:
  246.          /* Fenster aufraeumen */
  247.          RemoveFromWindowList(pMsgListData->hSwitch);
  248.          WinDestroyPointer(pMsgListData->icon);
  249.          WinDestroyWindow(pMsgListData->hwndpopup);
  250.          WinDestroyWindow(pMsgListData->hwndpopupsmall);
  251.          CleanupMsgList(WinWindowFromID(parent, IDD_MSGLIST+1));
  252.  
  253.          if (pMsgListData->bForeground)
  254.          {
  255.             if (!(msglistoptions.ulFlags & MLISTFLAG_FOREGROUND))
  256.             {
  257.                extern DIRTYFLAGS dirtyflags;
  258.  
  259.                msglistoptions.ulFlags |= MLISTFLAG_FOREGROUND;
  260.                dirtyflags.mlsettingsdirty = TRUE;
  261.             }
  262.          }
  263.          else
  264.          {
  265.             if (msglistoptions.ulFlags & MLISTFLAG_FOREGROUND)
  266.             {
  267.                extern DIRTYFLAGS dirtyflags;
  268.  
  269.                msglistoptions.ulFlags &= ~MLISTFLAG_FOREGROUND;
  270.                dirtyflags.mlsettingsdirty = TRUE;
  271.             }
  272.          }
  273.          free(pMsgListData);
  274.          break;
  275.  
  276.       case WM_CLOSE:
  277.          WinPostMsg(client, MSGLM_CLOSE, NULL, NULL);
  278.          break;
  279.  
  280.       case WM_COMMAND:
  281.          if (SHORT1FROMMP(mp2)==CMDSRC_MENU)
  282.          {
  283.             if (bDoingWork || pMsgListData->ulEnableCount)
  284.             {
  285.                WinAlarm(HWND_DESKTOP, WA_WARNING);
  286.                return (MRESULT) FALSE;
  287.             }
  288.             if (SHORT1FROMMP(mp1)==IDM_MP_DELETE)
  289.             {
  290.                PWORKDATA pWorkData;
  291.  
  292.                if (generaloptions.safety & SAFETY_DELMSG)
  293.                {
  294.                   if (MessageBox(parent, IDST_MSG_DELETE, IDST_TITLE_DELETE,
  295.                                  IDD_DELETE, MB_YESNO | MB_ICONEXCLAMATION)!=MBID_YES)
  296.                   {
  297.                      if (SHORT2FROMMP(mp2)==FALSE)
  298.                         SendMsg(parent, WM_MENUEND, NULL,
  299.                                    (MPARAM) pMsgListData->hwndpopup);
  300.                      return (MRESULT) FALSE;
  301.                   }
  302.                }
  303.                pWorkData=malloc(sizeof(WORKDATA));
  304.                pWorkData->next=NULL;
  305.                pWorkData->MsgIDArray=CollectMsgIDs(WinWindowFromID(parent, IDD_MSGLIST+1),
  306.                                                    pMsgListData->popupRecord, &pWorkData->ulArraySize);
  307.                pWorkData->flWorkToDo=WORK_DELETE;
  308.                pWorkData->pPrintDest = NULL;
  309.                strcpy(pWorkData->pchDestArea, pMsgListData->pchCurrentArea);
  310.                bDoingWork=TRUE;
  311.                tidWorker = _beginthread(WorkerThread, NULL, 32768, pWorkData);
  312.             }
  313.             if (SHORT1FROMMP(mp1)==IDM_MP_EXPORT)
  314.             {
  315.                /* Messages exportieren */
  316.                PWORKDATA pWorkData;
  317.                extern ULONG ulExportOptions;
  318.  
  319.                pWorkData=malloc(sizeof(WORKDATA));
  320.                pWorkData->next=NULL;
  321.                strcpy(pWorkData->pchDestFile, pathnames.lastexport);
  322.  
  323.                /* Filenamen holen */
  324.                if (GetExportName(parent, pWorkData->pchDestFile, &ulExportOptions))
  325.                {
  326.                   strcpy(pathnames.lastexport, pWorkData->pchDestFile);
  327.  
  328.                   pWorkData->MsgIDArray=CollectMsgIDs(WinWindowFromID(parent, IDD_MSGLIST+1),
  329.                                 pMsgListData->popupRecord, &pWorkData->ulArraySize);
  330.                   pWorkData->flWorkToDo=WORK_EXPORT;
  331.                   pWorkData->pPrintDest = NULL;
  332.                   pWorkData->ulExportOptions = ulExportOptions;
  333.                   strcpy(pWorkData->pchSrcArea, pMsgListData->pchCurrentArea);
  334.                   bDoingWork=TRUE;
  335.                   tidWorker = _beginthread(WorkerThread, NULL, 32768, pWorkData);
  336.                }
  337.                else
  338.                {
  339.                   free(pWorkData);
  340.                   return (MRESULT) FALSE;
  341.                }
  342.             }
  343.             if (SHORT1FROMMP(mp1)==IDM_MP_PRINT)
  344.             {
  345.                PWORKDATA pWorkData;
  346.  
  347.                pWorkData=malloc(sizeof(WORKDATA));
  348.                pWorkData->next=NULL;
  349.  
  350.                pWorkData->MsgIDArray=CollectMsgIDs(WinWindowFromID(parent, IDD_MSGLIST+1),
  351.                              pMsgListData->popupRecord, &pWorkData->ulArraySize);
  352.                pWorkData->flWorkToDo=WORK_PRINT;
  353.                pWorkData->pPrintDest = NULL;
  354.                strcpy(pWorkData->pchSrcArea, pMsgListData->pchCurrentArea);
  355.                bDoingWork=TRUE;
  356.                tidWorker = _beginthread(WorkerThread, NULL, 32768, pWorkData);
  357.             }
  358.             if (SHORT1FROMMP(mp1)==IDM_MP_COPY)
  359.             {
  360.                PWORKDATA pWorkData;
  361.                AREALISTPAR AreaListPar;
  362.  
  363.                /* ZielArea holen */
  364.                AreaListPar.cb=sizeof(AREALISTPAR);
  365.                if (generaloptions.LastCopyArea[0])
  366.                   AreaListPar.pchString=strdup(generaloptions.LastCopyArea);
  367.                else
  368.                   AreaListPar.pchString=strdup(CurrentArea);
  369.                AreaListPar.idTitle = IDST_TITLE_AL_COPY;
  370.                AreaListPar.ulIncludeTypes = INCLUDE_ALL;
  371.                AreaListPar.bExtendedSel = FALSE;
  372.                AreaListPar.bChange      = FALSE;
  373.  
  374.                if (WinDlgBox(HWND_DESKTOP, parent,
  375.                              AreaListProc, hmodLang,
  376.                              IDD_AREALIST, &AreaListPar)==DID_OK && AreaListPar.pchString)
  377.                {
  378.                   AREADEFLIST *pArea;
  379.  
  380.                   pWorkData=malloc(sizeof(WORKDATA));
  381.                   pWorkData->next=NULL;
  382.                   pWorkData->ulCopyMove = 0;
  383.  
  384.                   pArea = AM_FindArea(&arealiste, AreaListPar.pchString);
  385.                   if (pArea && pArea->areadata.areatype != AREATYPE_LOCAL)
  386.                      switch(MessageBox(parent, IDST_MSG_RESEND, IDST_TITLE_RESEND,
  387.                                        IDD_RESEND, MB_YESNO | MB_ICONQUESTION | MB_DEFBUTTON2))
  388.                      {
  389.                         case MBID_YES:
  390.                            pWorkData->ulCopyMove = COPYMOVE_RESEND;
  391.                            break;
  392.  
  393.                         default:
  394.                            break;
  395.                      }
  396.  
  397.                   pWorkData->MsgIDArray=CollectMsgIDs(WinWindowFromID(parent, IDD_MSGLIST+1),
  398.                                 pMsgListData->popupRecord, &pWorkData->ulArraySize);
  399.                   pWorkData->flWorkToDo=WORK_COPY;
  400.                   pWorkData->pPrintDest = NULL;
  401.                   strcpy(pWorkData->pchSrcArea, pMsgListData->pchCurrentArea);
  402.                   strcpy(pWorkData->pchDestArea, AreaListPar.pchString);
  403.                   bDoingWork=TRUE;
  404.                   tidWorker = _beginthread(WorkerThread, NULL, 32768, pWorkData);
  405.                   free(AreaListPar.pchString);
  406.                }
  407.                else
  408.                   return (MRESULT) FALSE;
  409.             }
  410.             if (SHORT1FROMMP(mp1)==IDM_MP_MOVE)
  411.             {
  412.                PWORKDATA pWorkData;
  413.                AREALISTPAR AreaListPar;
  414.  
  415.                /* ZielArea holen */
  416.                AreaListPar.cb=sizeof(AREALISTPAR);
  417.                if (generaloptions.LastMoveArea[0])
  418.                   AreaListPar.pchString=strdup(generaloptions.LastMoveArea);
  419.                else
  420.                   AreaListPar.pchString=strdup(CurrentArea);
  421.                AreaListPar.idTitle = IDST_TITLE_AL_MOVE;
  422.                AreaListPar.ulIncludeTypes = INCLUDE_ALL;
  423.                AreaListPar.bExtendedSel = FALSE;
  424.                AreaListPar.bChange      = FALSE;
  425.  
  426.                if (WinDlgBox(HWND_DESKTOP, parent,
  427.                              AreaListProc, hmodLang,
  428.                              IDD_AREALIST, &AreaListPar)==DID_OK && AreaListPar.pchString)
  429.                {
  430.                   AREADEFLIST *pArea;
  431.  
  432.                   pWorkData=malloc(sizeof(WORKDATA));
  433.                   pWorkData->next=NULL;
  434.                   pWorkData->ulCopyMove = 0;
  435.  
  436.                   pArea = AM_FindArea(&arealiste, AreaListPar.pchString);
  437.                   if (pArea && pArea->areadata.areatype != AREATYPE_LOCAL)
  438.                      switch(MessageBox(parent, IDST_MSG_RESEND, IDST_TITLE_RESEND,
  439.                                        IDD_RESEND, MB_YESNO | MB_ICONQUESTION | MB_DEFBUTTON2))
  440.                      {
  441.                         case MBID_YES:
  442.                            pWorkData->ulCopyMove = COPYMOVE_RESEND;
  443.                            break;
  444.  
  445.                         default:
  446.                            break;
  447.                      }
  448.  
  449.                   pWorkData->MsgIDArray=CollectMsgIDs(WinWindowFromID(parent, IDD_MSGLIST+1),
  450.                                 pMsgListData->popupRecord, &pWorkData->ulArraySize);
  451.                   pWorkData->flWorkToDo=WORK_MOVE;
  452.                   pWorkData->pPrintDest = NULL;
  453.                   strcpy(pWorkData->pchSrcArea, pMsgListData->pchCurrentArea);
  454.                   strcpy(pWorkData->pchDestArea, AreaListPar.pchString);
  455.                   bDoingWork=TRUE;
  456.                   tidWorker = _beginthread(WorkerThread, NULL, 32768, pWorkData);
  457.                   free(AreaListPar.pchString);
  458.                }
  459.                else
  460.                   return (MRESULT) FALSE;
  461.             }
  462.             if (SHORT1FROMMP(mp1)==IDM_MP_SELECTALL)
  463.             {
  464.                WinSendDlgItemMsg(parent, IDD_MSGLIST+1, MLIM_SELECTALL, NULL, NULL);
  465.             }
  466.             if (SHORT1FROMMP(mp1)==IDM_MP_SELECTNONE)
  467.             {
  468.                WinSendDlgItemMsg(parent, IDD_MSGLIST+1, MLIM_SELECTNONE, NULL, NULL);
  469.             }
  470.             if (SHORT1FROMMP(mp1)==IDM_SMP_SETTINGS)
  471.             {
  472.                extern DIRTYFLAGS dirtyflags;
  473.  
  474.                /* Settings-Notebook aufmachen */
  475.                WinDlgBox(HWND_DESKTOP, parent, MListSettingsProc,
  476.                          hmodLang, IDD_MLISTSETTINGS, NULL);
  477.                if (dirtyflags.mlsettingsdirty)
  478.                {
  479.                   WinEnableWindowUpdate(WinWindowFromID(parent, IDD_AREALIST+1), FALSE);
  480.                   pMsgListData->bNotifications=FALSE;
  481.                   SetForeground(WinWindowFromID(parent,IDD_MSGLIST+1),
  482.                                 &msglistoptions.lForeClr);
  483.                   SetBackground(WinWindowFromID(parent,IDD_MSGLIST+1),
  484.                                 &msglistoptions.lBackClr);
  485.                   MColors.lUnreadClr = msglistoptions.lUnreadClr;
  486.                   MColors.lFromClr   = msglistoptions.lFromClr;
  487.                   MColors.lToClr     = msglistoptions.lToClr;
  488.                   WinSendDlgItemMsg(parent, IDD_MSGLIST+1, MLIM_SETCOLORS, &MColors,
  489.                                     NULL);
  490.                   pMsgListData->bNotifications=TRUE;
  491.  
  492.                   WinEnableWindowUpdate(WinWindowFromID(parent, IDD_AREALIST+1), TRUE);
  493.                }
  494.             }
  495.             if (SHORT1FROMMP(mp1)==IDM_SMP_FGROUND)
  496.             {
  497.                if (pMsgListData->bForeground)
  498.                {
  499.                   pMsgListData->bForeground = FALSE;
  500.                   WinCheckMenuItem(pMsgListData->hwndpopupsmall, IDM_SMP_FGROUND, FALSE);
  501.                   WinSetOwner(parent, HWND_DESKTOP);
  502.                }
  503.                else
  504.                {
  505.                   pMsgListData->bForeground = TRUE;
  506.                   WinCheckMenuItem(pMsgListData->hwndpopupsmall, IDM_SMP_FGROUND, TRUE);
  507.                   WinSetOwner(parent, client);
  508.                }
  509.             }
  510.             return (MRESULT) FALSE;
  511.          }
  512.          if (SHORT1FROMMP(mp2)==CMDSRC_ACCELERATOR)
  513.          {
  514.             switch(SHORT1FROMMP(mp1))
  515.             {
  516.                case IDA_DELMSG:
  517.                   {
  518.                      /* Delete-Key abfangen */
  519.                      LONG lItem;
  520.                      MLISTRECORD MRecord;
  521.  
  522.                      if (bDoingWork || pMsgListData->ulEnableCount)
  523.                         return (MRESULT) FALSE;
  524.  
  525.                      lItem = (LONG) WinSendDlgItemMsg(parent, IDD_MSGLIST+1,
  526.                                                       MLIM_QUERYCRSITEM, NULL, NULL);
  527.  
  528.                      if (lItem == MLIT_NONE)
  529.                         return (MRESULT) FALSE;
  530.  
  531.                      WinSendDlgItemMsg(parent, IDD_MSGLIST+1, MLIM_QUERYITEM,
  532.                                        MPFROMLONG(lItem), &MRecord);
  533.  
  534.                      pMsgListData->popupRecord= MRecord.ulMsgID;
  535.  
  536.                      if (!pMsgListData->popupRecord)
  537.                         return (MRESULT) FALSE;
  538.  
  539.                      WinSendDlgItemMsg(parent, IDD_MSGLIST+1, MLIM_EMPHASIZEITEM,
  540.                                        MPFROMLONG(lItem), NULL);
  541.  
  542.                      SendMsg(parent, WM_COMMAND, MPFROMSHORT(IDM_MP_DELETE),
  543.                                 MPFROM2SHORT(CMDSRC_MENU, FALSE));
  544.  
  545.                   }
  546.                   return (MRESULT) TRUE;
  547.  
  548.                default:
  549.                   return RedirectCommand(mp1, mp2);
  550.             }
  551.          }
  552.  
  553.          WinPostMsg(client, MSGLM_CLOSE, NULL, NULL);
  554.          break;
  555.  
  556.       case WM_CONTROL:
  557.          if (SHORT1FROMMP(mp1)==IDD_MSGLIST+1)
  558.          {
  559.             switch(SHORT2FROMMP(mp1))
  560.             {
  561.                PMLCONTEXT pContext;
  562.  
  563.                case MLIN_ENTER:
  564.                   if (pMsgListData->ulEnableCount == 0)
  565.                   {
  566.                      MLISTRECORD MRecord;
  567.                      if (WinSendDlgItemMsg(parent, IDD_MSGLIST+1, MLIM_QUERYITEM,
  568.                                        mp2, &MRecord))
  569.                      {
  570.                         SendMsg(client, TM_JUMPTOMESSAGE,
  571.                                    MPFROMLONG(MRecord.ulMsgID), (MRESULT) TRUE);
  572.                         SetFocusControl(client, IDML_MAINEDIT);
  573.                      }
  574.                   }
  575.                   break;
  576.  
  577.                case MLIN_CONTEXTMENU:
  578.                   if (bDoingWork || pMsgListData->ulEnableCount)
  579.                   {
  580.                      WinAlarm(HWND_DESKTOP, WA_WARNING);
  581.                      break;
  582.                   }
  583.                   else
  584.                   {
  585.                      MLISTRECORD MRecord;
  586.  
  587.                      pContext = (PMLCONTEXT) mp2;
  588.  
  589.                      if (pContext->lItem == MLIT_NONE)
  590.                      {
  591.                         pMsgListData->popupRecord = 0;
  592.                         WinPopupMenu(HWND_DESKTOP, parent, pMsgListData->hwndpopupsmall,
  593.                                      pContext->xContext,
  594.                                      pContext->yContext,
  595.                                      0, PU_HCONSTRAIN | PU_VCONSTRAIN | PU_KEYBOARD | PU_MOUSEBUTTON1);
  596.                      }
  597.                      else
  598.                      {
  599.                         WinSendDlgItemMsg(parent, IDD_MSGLIST+1, MLIM_QUERYITEM,
  600.                                           MPFROMLONG(pContext->lItem), &MRecord);
  601.                         pMsgListData->popupRecord = MRecord.ulMsgID;
  602.  
  603.                         WinSendDlgItemMsg(parent, IDD_MSGLIST+1, MLIM_EMPHASIZEITEM,
  604.                                           MPFROMLONG(pContext->lItem), NULL);
  605.  
  606.                         WinPopupMenu(HWND_DESKTOP, parent, pMsgListData->hwndpopup,
  607.                                      pContext->xContext,
  608.                                      pContext->yContext,
  609.                                      0, PU_HCONSTRAIN | PU_VCONSTRAIN | PU_KEYBOARD | PU_MOUSEBUTTON1);
  610.                      }
  611.                   }
  612.                   break;
  613.  
  614.                case MLIN_LOADITEM:
  615.                   return (MRESULT) LoadItem(parent, (PMLISTRECORD) mp2);
  616.  
  617.                case MLIN_PPARAMCHANGED:
  618.                   if (pMsgListData && pMsgListData->bNotifications)
  619.                   {
  620.                      extern DIRTYFLAGS dirtyflags;
  621.  
  622.                      QueryForeground(WinWindowFromID(parent,IDD_MSGLIST+1),
  623.                                      &msglistoptions.lForeClr);
  624.                      QueryBackground(WinWindowFromID(parent,IDD_MSGLIST+1),
  625.                                      &msglistoptions.lBackClr);
  626.                      QueryFont(WinWindowFromID(parent,IDD_MSGLIST+1),
  627.                                msglistoptions.mlistfont);
  628.  
  629.                      dirtyflags.mlsettingsdirty = TRUE;
  630.                   }
  631.                   break;
  632.  
  633.                case MLIN_SEPACHANGED:
  634.                   {
  635.                      MLISTCOLUMNS MCol;
  636.                      extern DIRTYFLAGS dirtyflags;
  637.  
  638.                      WinSendDlgItemMsg(parent, IDD_MSGLIST+1, MLIM_QUERYCOLUMNS,
  639.                                        &MCol, NULL);
  640.  
  641.                      msglistoptions.ulNrPercent   = MCol.ulNrPercent;
  642.                      msglistoptions.ulFromPercent = MCol.ulFromPercent;
  643.                      msglistoptions.ulToPercent   = MCol.ulToPercent;
  644.                      msglistoptions.ulSubjPercent = MCol.ulSubjPercent;
  645.                      msglistoptions.ulStampWrittenPercent = MCol.ulStampWrittenPercent;
  646.                      msglistoptions.ulStampArrivedPercent = MCol.ulStampArrivedPercent;
  647.  
  648.                      dirtyflags.mlsettingsdirty = TRUE;
  649.                   }
  650.                   break;
  651.  
  652.                default:
  653.                   break;
  654.             }
  655.          }
  656.          break;
  657.  
  658.       case WM_CONTEXTMENU:
  659.          if (!SHORT1FROMMP(mp1) &&
  660.              WinQueryFocus(HWND_DESKTOP)==WinWindowFromID(parent, IDD_MSGLIST+1))
  661.          {
  662.             pMsgListData->bKeyboard=TRUE;
  663.             WinSendDlgItemMsg(parent, IDD_MSGLIST+1, WM_CONTEXTMENU,
  664.                               mp1, mp2);
  665.          }
  666.          break;
  667.  
  668.       case WM_MENUEND:
  669.          if ((HWND) mp2 == pMsgListData->hwndpopup)
  670.          {
  671.             pMsgListData->bKeyboard=FALSE;
  672.             WinSendDlgItemMsg(parent, IDD_MSGLIST+1, MLIM_EMPHASIZEITEM,
  673.                               MPFROMLONG(MLIT_NONE), NULL);
  674.          }
  675.          if ((HWND) mp2 == pMsgListData->hwndpopupsmall)
  676.             ResetMenuStyle(pMsgListData->hwndpopupsmall, parent);
  677.          break;
  678.  
  679.       case WORKM_DELETED:
  680.          if (stricmp(pMsgListData->pchCurrentArea, ((PMESSAGEID) mp1)->pchAreaTag))
  681.             break;
  682.          ListDeleteMessage(WinWindowFromID(parent, IDD_MSGLIST+1),
  683.                            (PMESSAGEID) mp1);
  684.          break;
  685.  
  686.       case WORKM_ADDED:
  687.          if (stricmp(pMsgListData->pchCurrentArea, ((PMESSAGEID) mp1)->pchAreaTag))
  688.             break;
  689.          ListAddMessage(WinWindowFromID(parent, IDD_MSGLIST+1),
  690.                         (PMESSAGEID) mp1, (PMSGHEADER) mp2);
  691.          break;
  692.  
  693.       case WORKM_END:
  694.          break;
  695.  
  696.       case WORKM_DISABLEVIEWS:
  697.          pMsgListData->ulEnableCount++;
  698.          break;
  699.  
  700.       case WORKM_ENABLEVIEWS:
  701.          if (pMsgListData->ulEnableCount)
  702.             pMsgListData->ulEnableCount--;
  703.          break;
  704.  
  705.       case WORKM_READ:
  706.          if (stricmp(pMsgListData->pchCurrentArea, ((PMESSAGEID) mp1)->pchAreaTag))
  707.             break;
  708.          ListMarkReadMessage(WinWindowFromID(parent, IDD_MSGLIST+1),
  709.                              (PMESSAGEID) mp1);
  710.          break;
  711.  
  712.       case WORKM_CHANGED:
  713.          if (stricmp(pMsgListData->pchCurrentArea, ((PMESSAGEID) mp1)->pchAreaTag))
  714.             break;
  715.          ListChangeMessage(WinWindowFromID(parent, IDD_MSGLIST+1),
  716.                            (PMESSAGEID) mp1, (PMSGHEADER) mp2);
  717.          break;
  718.  
  719.       case WORKM_MARKEND:
  720.          if (stricmp(pMsgListData->pchCurrentArea, ((PMESSAGEID) mp1)->pchAreaTag))
  721.             break;
  722.          ListMarkAllRead(WinWindowFromID(parent, IDD_MSGLIST+1), (PMESSAGEID) mp1);
  723.          break;
  724.  
  725.       case WORKM_TRACKMSG:
  726.          if (!stricmp(pMsgListData->pchCurrentArea, MESSAGEIDFROMP(mp1)->pchAreaTag))
  727.          {
  728.             LONG lTracked;
  729.  
  730.             lTracked = (LONG) WinSendDlgItemMsg(parent, IDD_MSGLIST+1, MLIM_FINDUMSGID,
  731.                                                 MPFROMLONG(MESSAGEIDFROMP(mp1)->ulMsgID), NULL);
  732.  
  733.             if (lTracked != MLIT_NONE)
  734.                WinSendDlgItemMsg(parent, IDD_MSGLIST+1, MLIM_SHIFTINTOVIEW,
  735.                                  MPFROMLONG(lTracked), NULL);
  736.          }
  737.          break;
  738.  
  739.       case WORKM_SWITCHACCELS:
  740.          SwitchAccels(parent, (ULONG) mp1);
  741.          break;
  742.  
  743.       default:
  744.          break;
  745.    }
  746.    return WinDefDlgProc(parent, message, mp1, mp2);
  747. }
  748.  
  749. /*---------------------------------------------------------------------------*/
  750. /* Funktionsname: LoadItem                                                   */
  751. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  752. /* Beschreibung: Laedt ein Item zur Anzeige in der Liste                     */
  753. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  754. /* Parameter: hwnd: Window-Handle der Liste                                  */
  755. /*            pRecord: Zeiger auf den Item-Record in der Liste               */
  756. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  757. /* Rückgabewerte: TRUE  Erfolg                                               */
  758. /*                FALSE Fehler                                               */
  759. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  760. /* Sonstiges: -                                                              */
  761. /*                                                                           */
  762. /*---------------------------------------------------------------------------*/
  763.  
  764. static BOOL LoadItem(HWND hwnd, PMLISTRECORD pRecord)
  765. {
  766.    extern USERDATAOPT userdaten;
  767.    int msgnum, i;
  768.    MSGHEADER Header;
  769.  
  770.    hwnd = hwnd;
  771.  
  772.    msgnum=MSG_UidToMsgn(&arealiste, CurrentArea, pRecord->ulMsgID, TRUE);
  773.    if (!msgnum ||
  774.        MSG_ReadHeader(&Header, &arealiste, CurrentArea, msgnum))
  775.    {
  776.       return FALSE;
  777.    }
  778.    else
  779.    {
  780.       /* Strings kopieren */
  781.       strncpy(pRecord->pchFrom, Header.pchFromName, LEN_USERNAME);
  782.       pRecord->pchFrom[LEN_USERNAME]=0;
  783.       strncpy(pRecord->pchTo, Header.pchToName, LEN_USERNAME);
  784.       pRecord->pchTo[LEN_USERNAME]=0;
  785.       strncpy(pRecord->pchSubject, Header.pchSubject, LEN_SUBJECT);
  786.       pRecord->pchSubject[LEN_SUBJECT]=0;
  787.       pRecord->StampWritten = Header.StampWritten;
  788.       pRecord->StampArrived = Header.StampArrived;
  789.  
  790.       /* Read-Flag */
  791.       if (Header.ulAttrib & ATTRIB_READ)
  792.          pRecord->flRecFlags |= LISTFLAG_READ;
  793.       else
  794.          pRecord->flRecFlags &= ~LISTFLAG_READ;
  795.  
  796.       /* From pruefen */
  797.       i=0;
  798.       while (i<MAX_USERNAMES && stricmp(userdaten.username[i], Header.pchFromName))
  799.          i++;
  800.       if (i<MAX_USERNAMES)
  801.          pRecord->flRecFlags |= LISTFLAG_FROMME;
  802.       else
  803.          pRecord->flRecFlags &= ~LISTFLAG_FROMME;
  804.  
  805.       /* To pruefen */
  806.       i=0;
  807.       while (i<MAX_USERNAMES && stricmp(userdaten.username[i], Header.pchToName))
  808.          i++;
  809.       if (i<MAX_USERNAMES)
  810.          pRecord->flRecFlags |= LISTFLAG_TOME;
  811.       else
  812.          pRecord->flRecFlags &= ~LISTFLAG_TOME;
  813.  
  814.       return TRUE;
  815.    }
  816. }
  817.  
  818. /*---------------------------------------------------------------------------*/
  819. /* Funktionsname: InsertHeaders                                              */
  820. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  821. /* Beschreibung: Fuegt alle Header in die Liste ein                          */
  822. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  823. /* Parameter: hwndContainer: Window-Handle der Liste                         */
  824. /*                                                                           */
  825. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  826. /* Rückgabewerte: Nummer der aktuellen Message                               */
  827. /*                                                                           */
  828. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  829. /* Sonstiges:                                                                */
  830. /*                                                                           */
  831. /*---------------------------------------------------------------------------*/
  832.  
  833. static int InsertHeaders(HWND hwndContainer)
  834. {
  835.    extern char CurrentArea[LEN_AREATAG+1];
  836.    AREADEFLIST *zeiger;
  837.    PMLISTRECORD pRecords=NULL;
  838.    int i;
  839.  
  840.    zeiger=AM_FindArea(&arealiste, CurrentArea);
  841.  
  842.    if (!zeiger)
  843.       return MLIT_NONE;
  844.  
  845.    if (zeiger->maxmessages==0)
  846.       return MLIT_NONE;
  847.  
  848.    pRecords= malloc(zeiger->maxmessages * sizeof(MLISTRECORD));
  849.  
  850.    for (i=1; i<=zeiger->maxmessages; i++)
  851.    {
  852.       pRecords[i-1].ulMsgID=MSG_MsgnToUid(&arealiste, CurrentArea, i);
  853.       pRecords[i-1].flRecFlags = 0;
  854.    }
  855.  
  856.    SendMsg(hwndContainer, MLIM_ADDITEMARRAY, pRecords,
  857.               MPFROMLONG(zeiger->maxmessages));
  858.  
  859.    free (pRecords);
  860.  
  861.    return zeiger->currentmessage - 1;
  862. }
  863.  
  864. /*---------------------------------------------------------------------------*/
  865. /* Funktionsname: CleanupMsgList                                             */
  866. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  867. /* Beschreibung: Loescht alle Eintraege in der Liste                         */
  868. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  869. /* Parameter: hwndContainer: Window-Handle der Liste                         */
  870. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  871. /* Rückgabewerte: -                                                          */
  872. /*                                                                           */
  873. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  874. /* Sonstiges:                                                                */
  875. /*                                                                           */
  876. /*---------------------------------------------------------------------------*/
  877.  
  878. static void CleanupMsgList(HWND hwndContainer)
  879. {
  880.    SendMsg(hwndContainer, MLIM_CLEARLIST, NULL, NULL);
  881.  
  882.    return;
  883. }
  884.  
  885. /*---------------------------------------------------------------------------*/
  886. /* Funktionsname: CollectMsgIDs                                              */
  887. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  888. /* Beschreibung: Sucht aus der Messageliste alle MSGIDs, fuer die eine       */
  889. /*               Operation durchgefuehrt werden soll                         */
  890. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  891. /* Parameter: hwndCnr: Container-Window                                      */
  892. /*            ulSelectedID: Record, fuer den das Contextmenue                */
  893. /*                          geoeffnet wurde                                  */
  894. /*            pulRecordsCollected: Zeiger auf Anzahl der ausgesuchten Records*/
  895. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  896. /* Rückgabewerte: Zeiger auf das erzeugte Array                              */
  897. /*                                                                           */
  898. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  899. /* Sonstiges: Das erzeugte Array muss ausserhalb freigegeben werden          */
  900. /*                                                                           */
  901. /*---------------------------------------------------------------------------*/
  902.  
  903. static PULONG CollectMsgIDs(HWND hwndCnr, ULONG ulSelectedID, PULONG pulRecordsCollected)
  904. {
  905.    PULONG pSelArray=NULL;
  906.    PULONG pSaveArray=NULL;
  907.    MLISTRECORD MRecord;
  908.    ULONG ulCountRecords=0;
  909.    LONG lItem;
  910.  
  911.    lItem = (LONG) SendMsg(hwndCnr, MLIM_FINDUMSGID, MPFROMLONG(ulSelectedID),
  912.                              NULL);
  913.  
  914.    if (lItem == MLIT_NONE)
  915.    {
  916.       *pulRecordsCollected = 0;
  917.       return NULL;
  918.    }
  919.  
  920.    SendMsg(hwndCnr, MLIM_QUERYITEM, MPFROMLONG(lItem), &MRecord);
  921.  
  922.    if (MRecord.flRecFlags & LISTFLAG_SELECTED)
  923.    {
  924.       /* Alle selected Records auswählen */
  925.       lItem = (LONG) SendMsg(hwndCnr, MLIM_QUERYFSELECT, NULL, NULL);
  926.  
  927.       while (lItem != MLIT_NONE)
  928.       {
  929.          if (SendMsg(hwndCnr, MLIM_QUERYITEM, MPFROMLONG(lItem), &MRecord))
  930.          {
  931.             /* MSGID in Array aufnehmen */
  932.             ulCountRecords++;
  933.             pSaveArray=pSelArray;
  934.             pSelArray=realloc(pSelArray, sizeof(ULONG)* ulCountRecords);
  935.             if (pSelArray)
  936.                pSelArray[ulCountRecords-1]=MRecord.ulMsgID;
  937.             else
  938.             {
  939.                /* realloc schiefgelaufen, neu anlegen */
  940.                pSelArray=malloc(sizeof(ULONG)* ulCountRecords);
  941.                if (pSaveArray)
  942.                {
  943.                   memcpy(pSelArray, pSaveArray, sizeof(ULONG)* (ulCountRecords-1));
  944.                   free(pSaveArray);
  945.                }
  946.                pSelArray[ulCountRecords-1]=MRecord.ulMsgID;
  947.             }
  948.          }
  949.          lItem = (LONG) SendMsg(hwndCnr, MLIM_QUERYNSELECT,
  950.                                    MPFROMLONG(lItem), NULL);
  951.       }
  952.       *pulRecordsCollected=ulCountRecords;
  953.    }
  954.    else
  955.    {
  956.       /* nur aktuellen Record auswaehlen */
  957.       pSelArray=malloc(sizeof(ULONG));
  958.       pSelArray[0]=MRecord.ulMsgID;
  959.       *pulRecordsCollected=1;
  960.    }
  961.    return pSelArray;
  962. }
  963.  
  964. /*---------------------------------------------------------------------------*/
  965. /* Funktionsname: WorkerThread                                               */
  966. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  967. /* Beschreibung: Arbeitsthread fuer die Messageliste                         */
  968. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  969. /* Parameter: pThreadData: Zeiger auf WORKDATA-Struktur                      */
  970. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  971. /* Rückgabewerte: -                                                          */
  972. /*                                                                           */
  973. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  974. /* Sonstiges:                                                                */
  975. /*                                                                           */
  976. /*---------------------------------------------------------------------------*/
  977.  
  978. void _Optlink WorkerThread(PVOID pThreadData)
  979. {
  980.    PWORKDATA pWorkData=(PWORKDATA)pThreadData;
  981.    PWORKDATA pWorkData2;
  982.    ULONG ulMsgNum=0;
  983.    ULONG ulProgress;     /* 0-100 */
  984.    ULONG ulNewProgress;
  985.    int i;
  986.    BOOL bStop=FALSE;
  987.    FTNMESSAGE Message;
  988.    MESSAGEID SMessageID, DMessageID;
  989.    MSGHEADER Header;
  990.    HMQ hmq = NULLHANDLE;
  991.    HAB hab;
  992.    HDC hdc;
  993.    HPS hps;
  994.    AREADEFLIST *pAreaDef;
  995.    ULONG ulExportOptions=0;
  996.  
  997.    extern MISCOPTIONS miscoptions;
  998.    extern HWND client;
  999.    extern DRIVEREMAP driveremap;
  1000.    extern USERDATAOPT userdaten;
  1001.    extern PRINTSETUP PrintSetup;
  1002.    extern GENERALOPT generaloptions;
  1003.  
  1004.    INSTALLEXPT("Worker");
  1005.  
  1006.    memset(&Message, 0, sizeof(Message));
  1007.    memset(&Header, 0, sizeof(Header));
  1008.    bStopWork = FALSE;
  1009.  
  1010.    hab = WinInitialize(0);
  1011.    hmq=WinCreateMsgQueue(hab, 0);
  1012.    WinCancelShutdown(hmq, TRUE);
  1013.  
  1014.    /* Export-Optionen der ersten Area übernehmen */
  1015.    if (pWorkData)
  1016.       ulExportOptions = pWorkData->ulExportOptions;
  1017.  
  1018.    while (pWorkData)
  1019.    {
  1020.       /* Arbeit verrichten */
  1021.       switch(pWorkData->flWorkToDo)
  1022.       {
  1023.          case WORK_DELETE:
  1024.  
  1025.             MSG_OpenArea(&arealiste, pWorkData->pchDestArea, miscoptions.lastreadoffset, &driveremap);
  1026.             SendMsg(client, WORKM_STARTWORKAREA, pWorkData->pchDestArea, NULL);
  1027.             i=pWorkData->ulArraySize-1;
  1028.             bStop = FALSE;
  1029.             ulProgress=0;
  1030.             while(!bStop && i >=0 && !bStopWork)
  1031.             {
  1032.                ulNewProgress= (100*(pWorkData->ulArraySize-i)) / pWorkData->ulArraySize;
  1033.                if (ulNewProgress != ulProgress)
  1034.                {
  1035.                   ulProgress= ulNewProgress;
  1036.                   SendMsg(client, WORKM_PROGRESS, MPFROMLONG(ulProgress), NULL);
  1037.                }
  1038.  
  1039.                ulMsgNum=MSG_UidToMsgn(&arealiste, pWorkData->pchDestArea, pWorkData->MsgIDArray[i], TRUE);
  1040.                if (ulMsgNum && !MSG_KillMessage(&arealiste, pWorkData->pchDestArea, ulMsgNum, &driveremap, SendKillMessage))
  1041.                {
  1042.                   i--;
  1043.                }
  1044.                else
  1045.                   switch((ULONG) SendMsg(client, WORKM_ERROR, NULL, NULL))
  1046.                   {
  1047.                      case WORK_ERROR_IGNORE:  /* ignore error */
  1048.  
  1049.                         i--;                  /* next message */
  1050.                         break;
  1051.  
  1052.                      case WORK_ERROR_RETRY:   /* retry operation, don't inc index */
  1053.  
  1054.                         break;
  1055.  
  1056.                      case WORK_ERROR_ABORT:   /* abort, set Stop flag */
  1057.  
  1058.                         bStop=TRUE;
  1059.                         break;
  1060.  
  1061.                      default:
  1062.  
  1063.                         i--;
  1064.                         break;
  1065.                   }
  1066.             }
  1067.             MSG_CloseArea(&arealiste, pWorkData->pchDestArea, TRUE, miscoptions.lastreadoffset, &driveremap);
  1068.             break;
  1069.  
  1070.          case WORK_EXPORT:
  1071.             MSG_OpenArea(&arealiste, pWorkData->pchSrcArea, miscoptions.lastreadoffset, &driveremap);
  1072.             strcpy(SMessageID.pchAreaTag, pWorkData->pchSrcArea);
  1073.             SendMsg(client, WORKM_STARTWORKAREA, pWorkData->pchSrcArea, NULL);
  1074.             i=0;
  1075.             bStop = FALSE;
  1076.             ulProgress=0;
  1077.             while(!bStop && i < pWorkData->ulArraySize && !bStopWork)
  1078.             {
  1079.                ulNewProgress= (100*i) / pWorkData->ulArraySize;
  1080.                if (ulNewProgress != ulProgress)
  1081.                {
  1082.                   ulProgress= ulNewProgress;
  1083.                   SendMsg(client, WORKM_PROGRESS, MPFROMLONG(ulProgress), NULL);
  1084.                }
  1085.  
  1086.                ulMsgNum=MSG_UidToMsgn(&arealiste, pWorkData->pchSrcArea, pWorkData->MsgIDArray[i], TRUE);
  1087.                if (ulMsgNum && !MSG_ReadNum(&Message, &Header, &arealiste, pWorkData->pchSrcArea, ulMsgNum) &&
  1088.                    !WriteMessage(pWorkData->pchDestFile, &Message,
  1089.                                  &Header, pWorkData->pchSrcArea,
  1090.                                  ulExportOptions))
  1091.                {
  1092.  
  1093.                   SMessageID.ulMsgID = pWorkData->MsgIDArray[i];
  1094.                   SendMsg(client, WORKM_EXPORTED, &SMessageID, NULL);
  1095.                   i++;
  1096.                   ulExportOptions |= EXPORT_APPEND;
  1097.                }
  1098.                else
  1099.                   switch((ULONG)SendMsg(client, WORKM_ERROR, NULL, NULL))
  1100.                   {
  1101.                      case WORK_ERROR_IGNORE:  /* ignore error */
  1102.  
  1103.                         i++;                  /* next message */
  1104.                         ulExportOptions |= EXPORT_APPEND;
  1105.                         break;
  1106.  
  1107.                      case WORK_ERROR_RETRY:   /* retry operation, don't inc index */
  1108.  
  1109.                         break;
  1110.  
  1111.                      case WORK_ERROR_ABORT:   /* abort, set Stop flag */
  1112.  
  1113.                         bStop=TRUE;
  1114.                         break;
  1115.  
  1116.                      default:
  1117.  
  1118.                         i++;
  1119.                         ulExportOptions |= EXPORT_APPEND;
  1120.                         break;
  1121.                   }
  1122.             }
  1123.             MSG_CloseArea(&arealiste, pWorkData->pchSrcArea, TRUE, miscoptions.lastreadoffset, &driveremap);
  1124.             break;
  1125.  
  1126.          case WORK_PRINT:
  1127.  
  1128.             MSG_OpenArea(&arealiste, pWorkData->pchSrcArea, miscoptions.lastreadoffset, &driveremap);
  1129.             strcpy(SMessageID.pchAreaTag, pWorkData->pchSrcArea);
  1130.             SendMsg(client, WORKM_STARTWORKAREA, SMessageID.pchAreaTag, NULL);
  1131.             i=0;
  1132.             bStop = FALSE;
  1133.             ulProgress=0;
  1134.  
  1135.             if (pWorkData->pPrintDest)
  1136.                OpenPrinterDM(anchor, &hdc, &hps, pWorkData->pPrintDest);
  1137.             else
  1138.                OpenPrinter(&PrintSetup, &hdc, &hps);
  1139.  
  1140.             if (pWorkData->pPrintDest)
  1141.                free (pWorkData->pPrintDest);
  1142.  
  1143.             while(!bStop && i < pWorkData->ulArraySize && !bStopWork)
  1144.             {
  1145.                int rc;
  1146.  
  1147.                ulNewProgress= (100*i) / pWorkData->ulArraySize;
  1148.                if (ulNewProgress != ulProgress)
  1149.                {
  1150.                   ulProgress= ulNewProgress;
  1151.                   SendMsg(client, WORKM_PROGRESS, MPFROMLONG(ulProgress), NULL);
  1152.                }
  1153.  
  1154.  
  1155.                ulMsgNum=MSG_UidToMsgn(&arealiste, pWorkData->pchSrcArea, pWorkData->MsgIDArray[i], TRUE);
  1156.                if (ulMsgNum && !MSG_ReadNum(&Message, &Header, &arealiste, pWorkData->pchSrcArea, ulMsgNum))
  1157.                {
  1158.                   rc = PrintMessage(hdc, hps, &Header, &Message,
  1159.                                     pWorkData->pchSrcArea, ulMsgNum, &arealiste,
  1160.                                     hmodLang, &PrintSetup);
  1161.  
  1162.                   if (!rc)
  1163.                   {
  1164.  
  1165.                      SMessageID.ulMsgID = pWorkData->MsgIDArray[i];
  1166.                      SendMsg(client, WORKM_PRINTED, &SMessageID, NULL);
  1167.                      i++;
  1168.                   }
  1169.                   else
  1170.                      switch((ULONG)SendMsg(client, WORKM_ERROR, NULL, NULL))
  1171.                      {
  1172.                         case WORK_ERROR_IGNORE:  /* ignore error */
  1173.  
  1174.                            i++;                  /* next message */
  1175.                            break;
  1176.  
  1177.                         case WORK_ERROR_RETRY:   /* retry operation, don't inc index */
  1178.  
  1179.                            break;
  1180.  
  1181.                         case WORK_ERROR_ABORT:   /* abort, set Stop flag */
  1182.  
  1183.                            bStop=TRUE;
  1184.                            break;
  1185.  
  1186.                         default:
  1187.  
  1188.                            i++;
  1189.                            break;
  1190.                      }
  1191.                }
  1192.             }
  1193.             ClosePrinter(hdc, hps);
  1194.  
  1195.             MSG_CloseArea(&arealiste, pWorkData->pchSrcArea, TRUE, miscoptions.lastreadoffset, &driveremap);
  1196.             break;
  1197.  
  1198.          case WORK_COPY:
  1199.  
  1200.             MSG_OpenArea(&arealiste, pWorkData->pchDestArea, miscoptions.lastreadoffset, &driveremap);
  1201.             MSG_OpenArea(&arealiste, pWorkData->pchSrcArea, miscoptions.lastreadoffset, &driveremap);
  1202.             SendMsg(client, WORKM_STARTWORKAREA, pWorkData->pchSrcArea, NULL);
  1203.             i=0;
  1204.             bStop=FALSE;
  1205.             ulProgress=0;
  1206.             while (!bStop && i < pWorkData->ulArraySize && !bStopWork)
  1207.             {
  1208.                BOOL bError=FALSE;
  1209.  
  1210.                ulNewProgress= (100*i) / pWorkData->ulArraySize;
  1211.                if (ulNewProgress != ulProgress)
  1212.                {
  1213.                   ulProgress= ulNewProgress;
  1214.                   SendMsg(client, WORKM_PROGRESS, MPFROMLONG(ulProgress), NULL);
  1215.                }
  1216.  
  1217.  
  1218.                ulMsgNum=MSG_UidToMsgn(&arealiste, pWorkData->pchSrcArea, pWorkData->MsgIDArray[i], TRUE);
  1219.                if (!ulMsgNum)
  1220.                   bError=TRUE;
  1221.                else
  1222.                   if (MSG_ReadNum(&Message, &Header, &arealiste, pWorkData->pchSrcArea, ulMsgNum))
  1223.                      bError=TRUE;
  1224.                   else
  1225.                      if (MSG_CopyMessage(&Message, &Header, &arealiste, pWorkData->pchDestArea,
  1226.                                          &driveremap, &userdaten, &generaloptions, SendAddMessage,
  1227.                                          pWorkData->ulCopyMove))
  1228.                         bError=TRUE;
  1229.  
  1230.                if (!bError)
  1231.                {
  1232.  
  1233.                   i++;
  1234.                }
  1235.                else
  1236.                   switch((ULONG)SendMsg(client, WORKM_ERROR, NULL, NULL))
  1237.                   {
  1238.                      case WORK_ERROR_IGNORE:  /* ignore error */
  1239.  
  1240.                         i++;                  /* next message */
  1241.                         break;
  1242.  
  1243.                      case WORK_ERROR_RETRY:   /* retry operation, don't inc index */
  1244.  
  1245.                         break;
  1246.  
  1247.                      case WORK_ERROR_ABORT:   /* abort, set Stop flag */
  1248.  
  1249.                         bStop=TRUE;
  1250.                         break;
  1251.  
  1252.                      default:
  1253.  
  1254.                         i++;
  1255.                         break;
  1256.                   }
  1257.             }
  1258.             MSG_CloseArea(&arealiste, pWorkData->pchSrcArea, TRUE, miscoptions.lastreadoffset, &driveremap);
  1259.             MSG_CloseArea(&arealiste, pWorkData->pchDestArea, TRUE, miscoptions.lastreadoffset, &driveremap);
  1260.  
  1261.             AM_FindArea(&arealiste, pWorkData->pchDestArea)->mailentered=TRUE;
  1262.             MailEntered[AM_FindArea(&arealiste, pWorkData->pchDestArea)->areadata.areatype]=TRUE;
  1263.             break;
  1264.  
  1265.          case WORK_MOVE:
  1266.  
  1267.             if (!stricmp(pWorkData->pchDestArea, pWorkData->pchSrcArea))
  1268.                break;
  1269.             MSG_OpenArea(&arealiste, pWorkData->pchDestArea, miscoptions.lastreadoffset, &driveremap);
  1270.             MSG_OpenArea(&arealiste, pWorkData->pchSrcArea, miscoptions.lastreadoffset, &driveremap);
  1271.             strcpy(SMessageID.pchAreaTag, pWorkData->pchSrcArea);
  1272.             SendMsg(client, WORKM_STARTWORKAREA, pWorkData->pchSrcArea, NULL);
  1273.             i=0;
  1274.             bStop=FALSE;
  1275.             ulProgress=0;
  1276.             while (!bStop && i < pWorkData->ulArraySize && !bStopWork)
  1277.             {
  1278.                BOOL bError=FALSE;
  1279.  
  1280.                ulNewProgress= (100*i) / pWorkData->ulArraySize;
  1281.                if (ulNewProgress != ulProgress)
  1282.                {
  1283.                   ulProgress= ulNewProgress;
  1284.                   SendMsg(client, WORKM_PROGRESS, MPFROMLONG(ulProgress), NULL);
  1285.                }
  1286.  
  1287.                ulMsgNum=MSG_UidToMsgn(&arealiste, pWorkData->pchSrcArea, pWorkData->MsgIDArray[i], TRUE);
  1288.  
  1289.                if (!ulMsgNum)
  1290.                   bError=TRUE;
  1291.                else
  1292.                   if (MSG_ReadNum(&Message, &Header, &arealiste, pWorkData->pchSrcArea, ulMsgNum))
  1293.                      bError=TRUE;
  1294.                   else
  1295.                      if (MSG_MoveMessage(&Message, &Header, &arealiste, pWorkData->pchSrcArea,
  1296.                                          pWorkData->pchDestArea, ulMsgNum,
  1297.                                          &driveremap, &userdaten, &generaloptions, SendAddMessage,
  1298.                                          SendKillMessage, pWorkData->ulCopyMove))
  1299.                         bError=TRUE;
  1300.  
  1301.                if (!bError)
  1302.                {
  1303.  
  1304.                   i++;
  1305.                }
  1306.                else
  1307.                   switch((ULONG)SendMsg(client, WORKM_ERROR, NULL, NULL))
  1308.                   {
  1309.                      case WORK_ERROR_IGNORE:  /* ignore error */
  1310.  
  1311.                         i++;                  /* next message */
  1312.                         break;
  1313.  
  1314.                      case WORK_ERROR_RETRY:   /* retry operation, don't inc index */
  1315.  
  1316.                         break;
  1317.  
  1318.                      case WORK_ERROR_ABORT:   /* abort, set Stop flag */
  1319.  
  1320.                         bStop=TRUE;
  1321.                         break;
  1322.  
  1323.                      default:
  1324.  
  1325.                         i++;
  1326.                         break;
  1327.                   }
  1328.             }
  1329.             MSG_CloseArea(&arealiste, pWorkData->pchSrcArea, TRUE, miscoptions.lastreadoffset, &driveremap);
  1330.             MSG_CloseArea(&arealiste, pWorkData->pchDestArea, TRUE, miscoptions.lastreadoffset, &driveremap);
  1331.  
  1332.             AM_FindArea(&arealiste, pWorkData->pchDestArea)->mailentered=TRUE;
  1333.             MailEntered[AM_FindArea(&arealiste, pWorkData->pchDestArea)->areadata.areatype]=TRUE;
  1334.             break;
  1335.  
  1336.          case WORK_MARK:
  1337.  
  1338.             MSG_OpenArea(&arealiste, pWorkData->pchSrcArea, miscoptions.lastreadoffset, &driveremap);
  1339.             strcpy(DMessageID.pchAreaTag, pWorkData->pchSrcArea);
  1340.             SendMsg(client, WORKM_STARTWORKAREA, pWorkData->pchSrcArea, NULL);
  1341.             i=0;
  1342.             bStop = FALSE;
  1343.             ulProgress=0;
  1344.             while(!bStop && i < pWorkData->ulArraySize && !bStopWork)
  1345.             {
  1346.                ulNewProgress= (100*i) / pWorkData->ulArraySize;
  1347.                if (ulNewProgress != ulProgress)
  1348.                {
  1349.                   ulProgress= ulNewProgress;
  1350.                   SendMsg(client, WORKM_PROGRESS, MPFROMLONG(ulProgress), NULL);
  1351.                }
  1352.  
  1353.  
  1354.                DMessageID.ulMsgID = pWorkData->MsgIDArray[i];
  1355.                ulMsgNum=MSG_UidToMsgn(&arealiste, pWorkData->pchSrcArea, pWorkData->MsgIDArray[i], TRUE);
  1356.                if (ulMsgNum && !MSG_MarkRead(&arealiste, pWorkData->pchSrcArea, ulMsgNum, "", &driveremap))
  1357.                {
  1358.  
  1359.                   SendMsg(client, WORKM_READ, &DMessageID, NULL);
  1360.                   i++;
  1361.                }
  1362.                else
  1363.                   switch((ULONG) SendMsg(client, WORKM_ERROR, NULL, NULL))
  1364.                   {
  1365.                      case WORK_ERROR_IGNORE:  /* ignore error */
  1366.  
  1367.                         i++;                  /* next message */
  1368.                         break;
  1369.  
  1370.                      case WORK_ERROR_RETRY:   /* retry operation, don't inc index */
  1371.  
  1372.                         break;
  1373.  
  1374.                      case WORK_ERROR_ABORT:   /* abort, set Stop flag */
  1375.  
  1376.                         bStop=TRUE;
  1377.                         break;
  1378.  
  1379.                      default:
  1380.  
  1381.                         i++;
  1382.                         break;
  1383.                   }
  1384.             }
  1385.             MSG_CloseArea(&arealiste, pWorkData->pchSrcArea, TRUE, miscoptions.lastreadoffset, &driveremap);
  1386.             break;
  1387.  
  1388.          case WORK_MARKALL:
  1389.  
  1390.             MSG_OpenArea(&arealiste, pWorkData->pchSrcArea, miscoptions.lastreadoffset, &driveremap);
  1391.             SendMsg(client, WORKM_STARTWORKAREA, pWorkData->pchSrcArea, NULL);
  1392.             pAreaDef = AM_FindArea(&arealiste, pWorkData->pchSrcArea);
  1393.             strcpy(DMessageID.pchAreaTag, pWorkData->pchSrcArea);
  1394.             pAreaDef->currentmessage = pAreaDef->maxmessages;
  1395.             SendMsg(client, WORKM_REREAD, pWorkData->pchSrcArea, NULL);
  1396.             i=1;
  1397.             bStop = FALSE;
  1398.             ulProgress=0;
  1399.             while(!bStop && i <= pAreaDef->maxmessages  && !bStopWork)
  1400.             {
  1401.                ulNewProgress= (100*i) / pAreaDef->maxmessages;
  1402.                if (ulNewProgress != ulProgress)
  1403.                {
  1404.                   ulProgress= ulNewProgress;
  1405.                   SendMsg(client, WORKM_PROGRESS, MPFROMLONG(ulProgress), NULL);
  1406.                }
  1407.  
  1408.  
  1409.                DMessageID.ulMsgID = MSG_MsgnToUid(&arealiste, pWorkData->pchSrcArea, i);
  1410.                if (!MSG_MarkRead(&arealiste, pWorkData->pchSrcArea, i, pAreaDef->areadata.username, &driveremap))
  1411.                {
  1412.  
  1413.                   i++;
  1414.                }
  1415.                else
  1416.                   switch((ULONG) SendMsg(client, WORKM_ERROR, NULL, NULL))
  1417.                   {
  1418.                      case WORK_ERROR_IGNORE:  /* ignore error */
  1419.  
  1420.                         i++;                  /* next message */
  1421.                         break;
  1422.  
  1423.                      case WORK_ERROR_RETRY:   /* retry operation, don't inc index */
  1424.  
  1425.                         break;
  1426.  
  1427.                      case WORK_ERROR_ABORT:   /* abort, set Stop flag */
  1428.  
  1429.                         bStop=TRUE;
  1430.                         break;
  1431.  
  1432.                      default:
  1433.  
  1434.                         i++;
  1435.                         break;
  1436.                   }
  1437.             }
  1438.             if (i>=pAreaDef->maxmessages)
  1439.                DMessageID.ulMsgID = MSG_MsgnToUid(&arealiste, pWorkData->pchSrcArea, pAreaDef->maxmessages);
  1440.             else
  1441.                DMessageID.ulMsgID = MSG_MsgnToUid(&arealiste, pWorkData->pchSrcArea, i);
  1442.             SendMsg(client, WORKM_MARKEND, &DMessageID, NULL);
  1443.             MSG_CloseArea(&arealiste, pWorkData->pchSrcArea, TRUE, miscoptions.lastreadoffset, &driveremap);
  1444.             break;
  1445.  
  1446.          default:
  1447.             break;
  1448.       }
  1449.       free (pWorkData->MsgIDArray);
  1450.       pWorkData2 = pWorkData;
  1451.       pWorkData = pWorkData->next;
  1452.       free(pWorkData2);
  1453.    }
  1454.  
  1455.    MSG_ClearMessage(&Header, &Message);
  1456.  
  1457.    WinPostMsg(client, WORKM_END, NULL, NULL);
  1458.  
  1459.    WinDestroyMsgQueue(hmq);
  1460.    WinTerminate(hab);
  1461.  
  1462.  
  1463.    DEINSTALLEXPT;
  1464.  
  1465.    return;
  1466. }
  1467.  
  1468. void MarkAllMessages(char *pchAreaTag)
  1469. {
  1470.    extern int tidWorker;
  1471.    PWORKDATA pWorkData=malloc(sizeof(WORKDATA));
  1472.  
  1473.    pWorkData->next=NULL;
  1474.    pWorkData->MsgIDArray=NULL;
  1475.    pWorkData->flWorkToDo=WORK_MARKALL;
  1476.    pWorkData->pPrintDest = NULL;
  1477.    strcpy(pWorkData->pchSrcArea, pchAreaTag);
  1478.    strcpy(pWorkData->pchDestArea, pchAreaTag);
  1479.    bDoingWork=TRUE;
  1480.    tidWorker = _beginthread(WorkerThread, NULL, 32768, pWorkData);
  1481.  
  1482.    return;
  1483. }
  1484.  
  1485. /*---------------------------------------------------------------------------*/
  1486. /* Funktionsname: ListAddMessage                                             */
  1487. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  1488. /* Beschreibung: Fuegt eine neue Message in die Messageliste ein             */
  1489. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  1490. /* Parameter: hwndCnr: Window-Handle des Containers                          */
  1491. /*            pMsgID:  Message-ID-Struktur                                   */
  1492. /*            pHeader: Neuer Header                                          */
  1493. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  1494. /* Rückgabewerte: -                                                          */
  1495. /*                                                                           */
  1496. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  1497. /* Sonstiges:                                                                */
  1498. /*                                                                           */
  1499. /*---------------------------------------------------------------------------*/
  1500.  
  1501. static void ListAddMessage(HWND hwndCnr, PMESSAGEID pMsgID, MSGHEADER *pHeader)
  1502. {
  1503.    extern USERDATAOPT userdaten;
  1504.    extern char CurrentArea[LEN_AREATAG+1];
  1505.    MLISTRECORD MRecord;
  1506.    int i;
  1507.  
  1508.    /* Neue Daten setzen */
  1509.    /* Strings kopieren */
  1510.    strncpy(MRecord.pchFrom, pHeader->pchFromName, LEN_USERNAME);
  1511.    MRecord.pchFrom[LEN_USERNAME]=0;
  1512.    strncpy(MRecord.pchTo, pHeader->pchToName, LEN_USERNAME);
  1513.    MRecord.pchTo[LEN_USERNAME]=0;
  1514.    strncpy(MRecord.pchSubject, pHeader->pchSubject, LEN_SUBJECT);
  1515.    MRecord.pchSubject[LEN_SUBJECT]=0;
  1516.    MRecord.StampWritten = pHeader->StampWritten;
  1517.    MRecord.StampArrived = pHeader->StampArrived;
  1518.  
  1519.    MRecord.ulMsgID = pMsgID->ulMsgID;
  1520.  
  1521.    /* Read-Flag */
  1522.    MRecord.flRecFlags =0;
  1523.    if (pHeader->ulAttrib & ATTRIB_READ)
  1524.       MRecord.flRecFlags |= LISTFLAG_READ;
  1525.    else
  1526.       MRecord.flRecFlags &= ~LISTFLAG_READ;
  1527.  
  1528.    /* From pruefen */
  1529.    i=0;
  1530.    while (i<MAX_USERNAMES && stricmp(userdaten.username[i], pHeader->pchFromName))
  1531.       i++;
  1532.    if (i<MAX_USERNAMES)
  1533.       MRecord.flRecFlags |= LISTFLAG_FROMME;
  1534.    else
  1535.       MRecord.flRecFlags &= ~LISTFLAG_FROMME;
  1536.  
  1537.    /* To pruefen */
  1538.    i=0;
  1539.    while (i<MAX_USERNAMES && stricmp(userdaten.username[i], pHeader->pchToName))
  1540.       i++;
  1541.    if (i<MAX_USERNAMES)
  1542.       MRecord.flRecFlags |= LISTFLAG_TOME;
  1543.    else
  1544.       MRecord.flRecFlags &= ~LISTFLAG_TOME;
  1545.  
  1546.    /* Item anhaengen */
  1547.    SendMsg(hwndCnr, MLIM_ADDITEM, &MRecord, NULL);
  1548.  
  1549.    /* erstes Item pruefen */
  1550.    if (SendMsg(hwndCnr, MLIM_QUERYITEM, MPFROMLONG(MLIT_FIRST),
  1551.                   &MRecord))
  1552.    {
  1553.       if (MSG_UidToMsgn(&arealiste, CurrentArea, MRecord.ulMsgID, TRUE) == 0)
  1554.       {
  1555.          /* erster Record nicht mehr vorhanden, loeschen */
  1556.          SendMsg(hwndCnr, MLIM_DELITEM, MPFROMLONG(MLIT_FIRST), NULL);
  1557.       }
  1558.    }
  1559.  
  1560.    return;
  1561. }
  1562.  
  1563. /*---------------------------------------------------------------------------*/
  1564. /* Funktionsname: ListChangeMessage                                          */
  1565. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  1566. /* Beschreibung: Aendert eine vorhandene Message ab                          */
  1567. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  1568. /* Parameter: hwndCnr: Window-Handle des Containers                          */
  1569. /*            pMsgID:  Message-ID-Struktur                                   */
  1570. /*            pHeader: Neuer Header                                          */
  1571. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  1572. /* Rückgabewerte: -                                                          */
  1573. /*                                                                           */
  1574. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  1575. /* Sonstiges:                                                                */
  1576. /*                                                                           */
  1577. /*---------------------------------------------------------------------------*/
  1578.  
  1579. static void ListChangeMessage(HWND hwndCnr, PMESSAGEID pMsgID, MSGHEADER *pHeader)
  1580. {
  1581.    extern USERDATAOPT userdaten;
  1582.    LONG lItem;
  1583.    MLISTRECORD MRecord;
  1584.    int i;
  1585.  
  1586.    lItem = (LONG) SendMsg(hwndCnr, MLIM_FINDUMSGID,
  1587.                              MPFROMLONG(pMsgID->ulMsgID), NULL);
  1588.  
  1589.    if (lItem != MLIT_NONE)
  1590.    {
  1591.       if (SendMsg(hwndCnr, MLIM_QUERYITEM, MPFROMLONG(lItem),
  1592.                      &MRecord))
  1593.       {
  1594.          /* Neue Daten setzen */
  1595.          /* Strings kopieren */
  1596.          strncpy(MRecord.pchFrom, pHeader->pchFromName, LEN_USERNAME);
  1597.          MRecord.pchFrom[LEN_USERNAME]=0;
  1598.          strncpy(MRecord.pchTo, pHeader->pchToName, LEN_USERNAME);
  1599.          MRecord.pchTo[LEN_USERNAME]=0;
  1600.          strncpy(MRecord.pchSubject, pHeader->pchSubject, LEN_SUBJECT);
  1601.          MRecord.pchSubject[LEN_SUBJECT]=0;
  1602.          MRecord.StampWritten = pHeader->StampWritten;
  1603.          MRecord.StampArrived = pHeader->StampArrived;
  1604.  
  1605.          /* Read-Flag */
  1606.          if (pHeader->ulAttrib & ATTRIB_READ)
  1607.             MRecord.flRecFlags |= LISTFLAG_READ;
  1608.          else
  1609.             MRecord.flRecFlags &= ~LISTFLAG_READ;
  1610.  
  1611.          /* From pruefen */
  1612.          i=0;
  1613.          while (i<MAX_USERNAMES && stricmp(userdaten.username[i], pHeader->pchFromName))
  1614.             i++;
  1615.          if (i<MAX_USERNAMES)
  1616.             MRecord.flRecFlags |= LISTFLAG_FROMME;
  1617.          else
  1618.             MRecord.flRecFlags &= ~LISTFLAG_FROMME;
  1619.  
  1620.          /* To pruefen */
  1621.          i=0;
  1622.          while (i<MAX_USERNAMES && stricmp(userdaten.username[i], pHeader->pchToName))
  1623.             i++;
  1624.          if (i<MAX_USERNAMES)
  1625.             MRecord.flRecFlags |= LISTFLAG_TOME;
  1626.          else
  1627.             MRecord.flRecFlags &= ~LISTFLAG_TOME;
  1628.  
  1629.          SendMsg(hwndCnr, MLIM_UPDATEITEM, &MRecord, MPFROMLONG(lItem));
  1630.       }
  1631.    }
  1632.    return;
  1633. }
  1634.  
  1635. /*---------------------------------------------------------------------------*/
  1636. /* Funktionsname: ListDeleteMessage                                          */
  1637. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  1638. /* Beschreibung: Loescht eine vorhandene Message                             */
  1639. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  1640. /* Parameter: hwndCnr: Window-Handle der Liste                               */
  1641. /*            pMsgID:  Message-ID-Struktur                                   */
  1642. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  1643. /* Rückgabewerte: -                                                          */
  1644. /*                                                                           */
  1645. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  1646. /* Sonstiges:                                                                */
  1647. /*                                                                           */
  1648. /*---------------------------------------------------------------------------*/
  1649.  
  1650. static void ListDeleteMessage(HWND hwndCnr, PMESSAGEID pMsgID)
  1651. {
  1652.    LONG lItem;
  1653.  
  1654.    lItem = (LONG) SendMsg(hwndCnr, MLIM_FINDUMSGID,
  1655.                              MPFROMLONG(pMsgID->ulMsgID), NULL);
  1656.  
  1657.    if (lItem != MLIT_NONE)
  1658.       SendMsg(hwndCnr, MLIM_DELITEM, MPFROMLONG(lItem), NULL);
  1659.  
  1660.    return;
  1661. }
  1662.  
  1663. /*---------------------------------------------------------------------------*/
  1664. /* Funktionsname: ListMarkReadMessage                                        */
  1665. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  1666. /* Beschreibung: Markiert eine Message als gelesen                           */
  1667. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  1668. /* Parameter: hwndCnr: Window-Handle der Liste                               */
  1669. /*            pMsgID:  Message-ID-Struktur                                   */
  1670. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  1671. /* Rückgabewerte: -                                                          */
  1672. /*                                                                           */
  1673. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  1674. /* Sonstiges:                                                                */
  1675. /*                                                                           */
  1676. /*---------------------------------------------------------------------------*/
  1677.  
  1678. static void ListMarkReadMessage(HWND hwndCnr, PMESSAGEID pMsgID)
  1679. {
  1680.    LONG lItem;
  1681.    MLISTRECORD MRecord;
  1682.  
  1683.    lItem = (LONG) SendMsg(hwndCnr, MLIM_FINDUMSGID,
  1684.                              MPFROMLONG(pMsgID->ulMsgID), NULL);
  1685.  
  1686.    if (lItem != MLIT_NONE)
  1687.    {
  1688.       if (SendMsg(hwndCnr, MLIM_QUERYITEM, MPFROMLONG(lItem),
  1689.                      &MRecord))
  1690.       {
  1691.          MRecord.flRecFlags |= LISTFLAG_READ;
  1692.          SendMsg(hwndCnr, MLIM_UPDATEITEM, &MRecord, MPFROMLONG(lItem));
  1693.       }
  1694.    }
  1695.    return;
  1696. }
  1697.  
  1698. /*---------------------------------------------------------------------------*/
  1699. /* Funktionsname: ListMarkAllRead                                            */
  1700. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  1701. /* Beschreibung: Markiert alle Messages als gelesen                          */
  1702. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  1703. /* Parameter: hwndCnr: Window-Handle der Liste                               */
  1704. /*            pMsgID:  Message-ID-Struktur                                   */
  1705. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  1706. /* Rückgabewerte: -                                                          */
  1707. /*                                                                           */
  1708. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  1709. /* Sonstiges:                                                                */
  1710. /*                                                                           */
  1711. /*---------------------------------------------------------------------------*/
  1712.  
  1713. static void ListMarkAllRead(HWND hwndCnr, PMESSAGEID pMsgID)
  1714. {
  1715.    LONG lItem;
  1716.    MLISTRECORD MRecord;
  1717.    LONG lCount;
  1718.  
  1719.    lCount = (LONG) SendMsg(hwndCnr, MLIM_QUERYITEMCOUNT, NULL, NULL);
  1720.  
  1721.    for (lItem=0; lItem < lCount; lItem++)
  1722.    {
  1723.       if (SendMsg(hwndCnr, MLIM_QUERYITEM, MPFROMLONG(lItem),
  1724.                      &MRecord))
  1725.       {
  1726.          if (MRecord.ulMsgID > pMsgID->ulMsgID)
  1727.             break;
  1728.  
  1729.          if (!(MRecord.flRecFlags & LISTFLAG_READ))
  1730.          {
  1731.             MRecord.flRecFlags |= LISTFLAG_READ;
  1732.             SendMsg(hwndCnr, MLIM_UPDATEITEM, &MRecord, MPFROMLONG(lItem));
  1733.          }
  1734.       }
  1735.    }
  1736.    return;
  1737. }
  1738.  
  1739. /*---------------------------------------------------------------------------*/
  1740. /* Funktionsname: MListSettingsProc                                          */
  1741. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  1742. /* Beschreibung: Window-Procedure f. Msg-List-Settings                       */
  1743. /*                                                                           */
  1744. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  1745. /* Parameter: WinProc                                                        */
  1746. /*                                                                           */
  1747. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  1748. /* Rückgabewerte: MRESULT                                                    */
  1749. /*                                                                           */
  1750. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  1751. /* Sonstiges:                                                                */
  1752. /*                                                                           */
  1753. /*---------------------------------------------------------------------------*/
  1754.  
  1755. static MRESULT EXPENTRY MListSettingsProc(HWND hwnd, ULONG message, MPARAM mp1, MPARAM mp2)
  1756. {
  1757.    extern WINDOWPOSITIONS windowpositions;
  1758.    extern HWND hwndhelp;
  1759.    HWND notebook=NULLHANDLE;
  1760.  
  1761.    switch(message)
  1762.    {
  1763.       MRESULT resultbuf;
  1764.  
  1765.       case WM_INITDLG:
  1766.          notebook=WinWindowFromID(hwnd, IDD_MLISTSETTINGS+1);
  1767.          InsertMListSettingsPages(notebook);
  1768.          RestoreWinPos(hwnd, &windowpositions.mlistsettingspos, TRUE, TRUE);
  1769.          break;
  1770.  
  1771.       case WM_ADJUSTFRAMEPOS:
  1772.          SizeToClient(anchor, (PSWP) mp1, hwnd, IDD_MLISTSETTINGS+1);
  1773.          break;
  1774.  
  1775.       case WM_QUERYTRACKINFO:
  1776.          /* Default-Werte aus Original-Prozedur holen */
  1777.          resultbuf=WinDefDlgProc(hwnd, message, mp1, mp2);
  1778.  
  1779.          /* Minimale Fenstergroesse einstellen */
  1780.          ((PTRACKINFO)mp2)->ptlMinTrackSize.x=255;
  1781.          ((PTRACKINFO)mp2)->ptlMinTrackSize.y=190;
  1782.  
  1783.          return resultbuf;
  1784.  
  1785.       case WM_DESTROY:
  1786.          QueryWinPos(hwnd, &(windowpositions.mlistsettingspos));
  1787.          break;
  1788.  
  1789.       case WM_ACTIVATE:
  1790.          if (mp1)
  1791.             WinAssociateHelpInstance(hwndhelp, hwnd);
  1792.          else
  1793.             WinAssociateHelpInstance(hwndhelp, NULLHANDLE);
  1794.          break;
  1795.  
  1796.       default:
  1797.          break;
  1798.    }
  1799.    return WinDefDlgProc(hwnd, message, mp1, mp2);
  1800. }
  1801.  
  1802. /*---------------------------------------------------------------------------*/
  1803. /* Funktionsname: InsertMListSettingsPages                                   */
  1804. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  1805. /* Beschreibung: Fuegt die Settings-Pages in das Notebook fuer die           */
  1806. /*               Arealisten-Settings ein.                                    */
  1807. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  1808. /* Parameter: notebook: Window-handle des Notebooks                          */
  1809. /*                                                                           */
  1810. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  1811. /* Rückgabewerte: -                                                          */
  1812. /*                                                                           */
  1813. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  1814. /* Sonstiges:                                                                */
  1815. /*                                                                           */
  1816. /*---------------------------------------------------------------------------*/
  1817.  
  1818. static void InsertMListSettingsPages(HWND notebook)
  1819. {
  1820.    SetNotebookParams(notebook, 80);
  1821.  
  1822.    InsertOnePage(notebook, IDD_ML_SETTINGS_COLORS, IDST_TAB_AL_COLORS, MListSettColProc, NULL);
  1823.  
  1824.    return;
  1825. }
  1826.  
  1827. /*---------------------------------------------------------------------------*/
  1828. /* Funktionsname: MListSettColProc                                           */
  1829. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  1830. /* Beschreibung: Window-Procedure f. Msg-List-Color-Settings                 */
  1831. /*                                                                           */
  1832. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  1833. /* Parameter: WinProc                                                        */
  1834. /*                                                                           */
  1835. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  1836. /* Rückgabewerte: MRESULT                                                    */
  1837. /*                                                                           */
  1838. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  1839. /* Sonstiges:                                                                */
  1840. /*                                                                           */
  1841. /*---------------------------------------------------------------------------*/
  1842.  
  1843. static MRESULT EXPENTRY MListSettColProc(HWND hwnd, ULONG message, MPARAM mp1, MPARAM mp2)
  1844. {
  1845.    extern DIRTYFLAGS dirtyflags;
  1846.  
  1847.    switch (message)
  1848.    {
  1849.       case WM_INITDLG:
  1850.          /* Farben im Value-Set initialisieren */
  1851.          WinSendDlgItemMsg(hwnd, IDD_ML_SETTINGS_COLORS+4, VM_SETITEM,
  1852.                            MPFROM2SHORT(1, 1),
  1853.                            MPFROMLONG(msglistoptions.lBackClr));
  1854.          WinSendDlgItemMsg(hwnd, IDD_ML_SETTINGS_COLORS+4, VM_SETITEM,
  1855.                            MPFROM2SHORT(2, 1),
  1856.                            MPFROMLONG(msglistoptions.lForeClr));
  1857.          WinSendDlgItemMsg(hwnd, IDD_ML_SETTINGS_COLORS+4, VM_SETITEM,
  1858.                            MPFROM2SHORT(3, 1),
  1859.                            MPFROMLONG(msglistoptions.lUnreadClr));
  1860.          WinSendDlgItemMsg(hwnd, IDD_ML_SETTINGS_COLORS+4, VM_SETITEM,
  1861.                            MPFROM2SHORT(4, 1),
  1862.                            MPFROMLONG(msglistoptions.lFromClr));
  1863.          WinSendDlgItemMsg(hwnd, IDD_ML_SETTINGS_COLORS+4, VM_SETITEM,
  1864.                            MPFROM2SHORT(5, 1),
  1865.                            MPFROMLONG(msglistoptions.lToClr));
  1866.  
  1867.          /* Erstes Element im VS auswaehlen */
  1868.          WinSendDlgItemMsg(hwnd, IDD_ML_SETTINGS_COLORS+4, VM_SELECTITEM,
  1869.                            MPFROM2SHORT(1, 1), NULL);
  1870.  
  1871.          /* Fadenkreuz im Color-Wheel entsprechend setzen */
  1872.          WinSendDlgItemMsg(hwnd, IDD_ML_SETTINGS_COLORS+3, CLSM_SETRGB,
  1873.                            &msglistoptions.lBackClr,
  1874.                            NULL);
  1875.          break;
  1876.  
  1877.       case WM_CONTROL:
  1878.          switch(SHORT1FROMMP(mp1))
  1879.          {
  1880.             case IDD_ML_SETTINGS_COLORS+3:  /* Color-Wheel */
  1881.                if (SHORT2FROMMP(mp1) == CLSN_RGB)
  1882.                {
  1883.                   MRESULT selected;
  1884.  
  1885.                   /* selektiertes Item im Value-Set abfragen */
  1886.                   selected=WinSendDlgItemMsg(hwnd, IDD_ML_SETTINGS_COLORS+4, VM_QUERYSELECTEDITEM,
  1887.                                              NULL, NULL);
  1888.  
  1889.                   /* Farbe updaten */
  1890.                   WinSendDlgItemMsg(hwnd, IDD_ML_SETTINGS_COLORS+4, VM_SETITEM,
  1891.                                     selected, mp2);
  1892.  
  1893.                   /* Farbe in Settings eintragen */
  1894.                   switch(SHORT1FROMMR(selected))
  1895.                   {
  1896.                      case 1:
  1897.                         msglistoptions.lBackClr = (LONG) mp2;
  1898.                         break;
  1899.  
  1900.                      case 2:
  1901.                         msglistoptions.lForeClr = (LONG) mp2;
  1902.                         break;
  1903.  
  1904.                      case 3:
  1905.                         msglistoptions.lUnreadClr = (LONG) mp2;
  1906.                         break;
  1907.  
  1908.                      case 4:
  1909.                         msglistoptions.lFromClr = (LONG) mp2;
  1910.                         break;
  1911.  
  1912.                      case 5:
  1913.                         msglistoptions.lToClr = (LONG) mp2;
  1914.                         break;
  1915.  
  1916.                      default:
  1917.                         break;
  1918.                   }
  1919.  
  1920.                   /* Dirty-Flag setzen */
  1921.                   dirtyflags.mlsettingsdirty=TRUE;
  1922.                }
  1923.                break;
  1924.  
  1925.             case IDD_ML_SETTINGS_COLORS+4:  /* Value-Set */
  1926.                if (SHORT2FROMMP(mp1) == VN_SELECT)
  1927.                {
  1928.                   ULONG ulColor;
  1929.  
  1930.                   /* neue Selektion abfragen */
  1931.                   ulColor=(ULONG)WinSendDlgItemMsg(hwnd, IDD_ML_SETTINGS_COLORS+4,
  1932.                                                    VM_QUERYITEM, mp2, NULL);
  1933.  
  1934.                   /* Fadenkreuz setzen */
  1935.                   WinSendDlgItemMsg(hwnd, IDD_ML_SETTINGS_COLORS+3,
  1936.                                     CLSM_SETRGB, &ulColor, NULL);
  1937.                }
  1938.                break;
  1939.  
  1940.             default:
  1941.                break;
  1942.          }
  1943.          break;
  1944.  
  1945.       case WM_COMMAND:
  1946.          return (MRESULT) FALSE;
  1947.  
  1948.       case WM_DESTROY:
  1949.          break;
  1950.  
  1951.       default:
  1952.          break;
  1953.    }
  1954.    return WinDefDlgProc(hwnd, message, mp1, mp2);
  1955. }
  1956.  
  1957. /*-------------------------------- Modulende --------------------------------*/
  1958.  
  1959.