home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / dos2ib.zip / dos2ibm.c next >
Text File  |  1993-11-01  |  21KB  |  665 lines

  1. #define INCL_PM
  2. #define INCL_DOS
  3.  
  4. #include <os2.h>
  5. #include <stdio.h>
  6. #include <memory.h>
  7. #include <stddef.h>
  8. #include <errno.h>
  9. #include <malloc.h>
  10. #include <string.h>
  11. #include <process.h>
  12.  
  13. #include "dos2pm.h"
  14.  
  15. #define DEFAULT_VIEW        ID_VIEW_TREE
  16. #define FINDBUFF_ENTRIES    10
  17. #define CNRREC_SIZE         (sizeof(CNRREC)-sizeof(MINIRECORDCORE))
  18.  
  19. typedef struct _CNRREC
  20. {
  21.     MINIRECORDCORE  mrc;
  22.     char            szFileName[CCHMAXPATH];
  23.     ULONG           ulSize;
  24.     CDATE           Date;
  25.     CTIME           Time;
  26.     ULONG           ulAttr;
  27. }CNRREC;
  28.  
  29. typedef struct _GLOBALDATA
  30. {
  31.     HAB         hab;
  32.     HMQ         hmq;
  33.     HWND        hFrame, hClient, hMenu, hContainer;
  34.     RECTL       rclUpdate;
  35.     char        *pszText[MAXLINES];
  36.     short       sLineCount, sCharHeight, sTopLine;
  37.     char        szFileName[CCHMAXPATH];
  38.     short       sCloseFile;
  39.     char        szCurrDir[CCHMAXPATH];
  40.     USHORT      usView;
  41. }GLOBALDATA;
  42.  
  43. int     main(int, char **);
  44. static  HWND    CreateWindow(GLOBALDATA *);
  45. static  MRESULT EXPENTRY    ClientWndProc(HWND, ULONG, MPARAM, MPARAM);
  46. static  MRESULT ClientWndInit(HWND, GLOBALDATA *);
  47. static  void    FileOpen(HWND, GLOBALDATA *, char *);
  48. static  void    FileClose(HWND, GLOBALDATA *);
  49. static  void    ReadFileThread(void *);
  50. static  void    FillContainerThread(void *);
  51. static  void    CalcLinePosition(HWND, GLOBALDATA *, short, RECTL *);
  52. static  HWND    CreateContainer(HWND, GLOBALDATA *);
  53. static  ULONG   FillContainer(HWND, CNRREC *, char *);
  54. static  void    SetView(HWND, GLOBALDATA *, USHORT);
  55.  
  56. static HWND CreateWindow(GLOBALDATA *pGlobalData)
  57. {
  58.     FRAMECDATA  fcdata;
  59.     HWND        hFrame, hClient;
  60.     SWP         swp;
  61.  
  62.     WinQueryTaskSizePos(pGlobalData->hab, 0 ,&swp);
  63.  
  64.     memset(&fcdata, 0, sizeof(fcdata));
  65.  
  66.     fcdata.cb = sizeof(fcdata);
  67.     fcdata.idResources = ID_FRAME;
  68.     fcdata.flCreateFlags=FCF_SIZEBORDER | FCF_SYSMENU | FCF_MENU | FCF_MINMAX | FCF_TITLEBAR | FCF_TASKLIST;
  69.  
  70.     hFrame = WinCreateWindow(HWND_DESKTOP, WC_FRAME, NULL, FS_TASKLIST | FS_SIZEBORDER,
  71.                                 0, 0, 0, 0, HWND_DESKTOP, HWND_TOP, ID_FRAME, &fcdata, NULL);
  72.  
  73.     pGlobalData->hFrame = hFrame;
  74.     pGlobalData->hMenu = WinWindowFromID(hFrame, FID_MENU);
  75.  
  76.     hClient=WinCreateWindow(hFrame, CLASSNAME, NULL, 0, 0, 0, 0, 0, hFrame, HWND_BOTTOM, FID_CLIENT, pGlobalData, NULL);
  77.  
  78.     pGlobalData->hClient = hClient;
  79.  
  80.     WinSetWindowPos(hFrame, HWND_TOP, swp.x, swp.y, swp.cx, swp.cy, SWP_SIZE | SWP_MOVE | SWP_SHOW | SWP_ACTIVATE | SWP_ZORDER);
  81.  
  82.     return (hFrame);
  83. }
  84.  
  85. static MRESULT EXPENTRY ClientWndProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
  86. {
  87.     int                 i;
  88.     short               sError;
  89.     char                *psz, szErrBuff[128];
  90.     GLOBALDATA          *pGlobalData;
  91.     HPS                 hps;
  92.     RECTL               rcl, rclText;
  93.     MRESULT             mr;
  94.     USHORT              id;
  95.     CNRREC              *pcr;
  96.     CNRINFO             cnri;
  97.     NOTIFYRECORDENTER   *pnre;
  98.     switch (msg) {
  99.  
  100.     case WM_CREATE:
  101.        pGlobalData = (GLOBALDATA *)PVOIDFROMMP(mp1);
  102.        return (ClientWndInit(hwnd, pGlobalData));
  103.  
  104.     case WM_CLOSE:
  105.        pGlobalData = (GLOBALDATA *)WinQueryWindowPtr(hwnd, 0);
  106.        mr=WinSendMsg(WinWindowFromID(pGlobalData->hFrame, FID_MENU), MM_QUERYITEMATTR,
  107.         MPFROM2SHORT(ID_FILE_CLOSE, TRUE), MPFROMSHORT(MIA_DISABLED));
  108.        if (LONGFROMMR(mr) != MIA_DISABLED) {
  109.           if (WinMessageBox(HWND_DESKTOP, hwnd, "Close file and exit?", "File is open", 0, MB_YESNO | MB_ICONQUESTION) == MBID_YES) {
  110.              FileClose(hwnd, pGlobalData);
  111.            } else {
  112.               return (MRFROMSHORT(0));
  113.           } /* endif (WinMessageBox(... */
  114.        } /* endif (LONGFROMMR(mr) != MIA_DISABLED) */
  115.        WinPostMsg(hwnd, WM_QUIT, 0l, 0l);
  116.        return (MRFROMSHORT(0));
  117.  
  118.     case WM_PAINT:
  119.        pGlobalData = (GLOBALDATA *)WinQueryWindowPtr(hwnd, 0);
  120.        hps = WinBeginPaint(hwnd, NULLHANDLE, &rcl);
  121.        WinFillRect(hps, &rcl, SYSCLR_WINDOW);
  122.        CalcLinePosition(hwnd, pGlobalData, pGlobalData->sTopLine, &rclText);
  123.  
  124.        for (i=pGlobalData->sTopLine; i<pGlobalData->sLineCount; i++) {
  125.           WinDrawText(hps,  -1, pGlobalData->pszText[i], &rclText, SYSCLR_WINDOWTEXT, SYSCLR_WINDOW, DT_LEFT);
  126.           rclText.yBottom -= pGlobalData->sCharHeight;
  127.           rclText.yTop -= pGlobalData->sCharHeight;
  128.        } /* endfor (i=pGlobalData->sTopLine; i<pGlobalData->sLineCount; i++) */
  129.  
  130.        pGlobalData->rclUpdate = rclText;
  131.        pGlobalData->rclUpdate.yTop = pGlobalData->sCharHeight;
  132.        pGlobalData->rclUpdate.yBottom = 0;
  133.        WinEndPaint(hps);
  134.        return (MRFROMSHORT(0));
  135.  
  136.     case WM_SIZE:
  137.        pGlobalData = (GLOBALDATA *)WinQueryWindowPtr(hwnd, 0);
  138.  
  139.        if (pGlobalData->hContainer)
  140.           WinSetWindowPos(pGlobalData->hContainer, NULLHANDLE, 0, 0, SHORT1FROMMP(mp2), SHORT2FROMMP(mp2), SWP_MOVE | SWP_SIZE);
  141.  
  142.        break;
  143.  
  144.     case UM_LINEOFTEXT:
  145.        pGlobalData = (GLOBALDATA *)WinQueryWindowPtr(hwnd, 0);
  146.  
  147.        if (pGlobalData->sLineCount < MAXLINES) {
  148.           pGlobalData->sLineCount++;
  149.        } else {
  150.           free(pGlobalData->pszText[0]);
  151.  
  152.           for ( i=0; i<pGlobalData->sLineCount-1 ; i++) {
  153.              pGlobalData->pszText[i]=pGlobalData->pszText[i+1];
  154.           } /* endfor */
  155.  
  156.        } /* endif */
  157.  
  158.        pGlobalData->pszText[pGlobalData->sLineCount-1]=(char *)PVOIDFROMMP(mp1);
  159.        CalcLinePosition(hwnd, pGlobalData, pGlobalData->sLineCount-1, &rclText);
  160.  
  161.        if (rclText.yBottom <= 0) {
  162.  
  163.           if (pGlobalData->sLineCount < MAXLINES) {
  164.              pGlobalData->sTopLine++;
  165.           } /* endif */
  166.  
  167.           WinScrollWindow(hwnd, 0, pGlobalData->sCharHeight, NULL, NULL, NULLHANDLE, NULL, 0);
  168.           pGlobalData->rclUpdate.yTop += pGlobalData->sCharHeight;
  169.        } else {
  170.           pGlobalData->rclUpdate = rclText;
  171.        } /* endif */
  172.  
  173.        WinInvalidateRect(hwnd, &pGlobalData->rclUpdate, FALSE);
  174.        return (MRFROMSHORT(0));
  175.  
  176.     case UM_ENDOFFILE:
  177.        pGlobalData = (GLOBALDATA *)WinQueryWindowPtr(hwnd, 0);
  178.        sError = SHORT1FROMMP(mp1);
  179.  
  180.        if (sError) {
  181.           sprintf(szErrBuff, "Error %d accessing %s.", sError, pGlobalData->szFileName);
  182.           WinMessageBox(HWND_DESKTOP, hwnd, szErrBuff, "ERROR!", 0, MB_OK | MB_ICONEXCLAMATION);
  183.           FileClose(hwnd, pGlobalData);
  184.        } /* endif */
  185.  
  186.        return (MRFROMSHORT(0));
  187.  
  188.    case UM_CNRFILLDONE:
  189.        if (mp1) {
  190.           pGlobalData = (GLOBALDATA *)WinQueryWindowPtr(hwnd, 0);
  191.           SetView(pGlobalData->hContainer, pGlobalData, DEFAULT_VIEW);
  192.           WinSendMsg(pGlobalData->hMenu, MM_SETITEMATTR, MPFROM2SHORT(ID_VIEW, TRUE),MPFROM2SHORT(MIA_DISABLED, FALSE));
  193.           WinShowWindow(pGlobalData->hContainer, TRUE);
  194.           WinSetFocus(HWND_DESKTOP, pGlobalData->hContainer);
  195.        } /* endif */
  196.  
  197.        return (MRFROMSHORT(0));
  198.  
  199.     case WM_CONTROL:
  200.        pGlobalData = (GLOBALDATA *)WinQueryWindowPtr(hwnd, 0);
  201.        switch (SHORT1FROMMP(mp1)) {
  202.  
  203.        case ID_CONTAINER:
  204.  
  205.           switch (SHORT2FROMMP(mp1)) {
  206.  
  207.           case CN_ENTER:
  208.              pnre = (NOTIFYRECORDENTER *)PVOIDFROMMP(mp2);
  209.              pcr = (CNRREC *)pnre->pRecord;
  210.  
  211.              if (!(pcr->ulAttr & FILE_DIRECTORY)) {
  212.                 FileOpen(hwnd, pGlobalData, pcr->szFileName);
  213.                 WinDestroyWindow(pGlobalData->hContainer);
  214.                 WinSendMsg(pGlobalData->hMenu, MM_SETITEMATTR, MPFROM2SHORT(ID_VIEW,TRUE),MPFROM2SHORT(MIA_DISABLED, MIA_DISABLED));
  215.                 pGlobalData->hContainer=NULLHANDLE;
  216.              } /* endif */
  217.  
  218.              break;
  219.  
  220.           default:
  221.             break;
  222.  
  223.           } /* endswitch (SHORT2FROMMP(mp1)) */
  224.  
  225.           break;
  226.  
  227.        default:
  228.          break;
  229.  
  230.        } /* endswitch (SHORT1FROMMP(mp1)) */
  231.  
  232.        break;
  233.  
  234.     case WM_COMMAND:
  235.        pGlobalData = (GLOBALDATA *)WinQueryWindowPtr(hwnd, 0);
  236.  
  237.        switch ((id = SHORT1FROMMP(mp1))) {
  238.  
  239.        case ID_FILE_OPEN:
  240.           FileOpen(hwnd, pGlobalData, NULL);
  241.           break;
  242.  
  243.        case ID_FILE_CLOSE:
  244.           FileClose(hwnd, pGlobalData);
  245.           break;
  246.  
  247.        case ID_FILE_EXIT:
  248.           WinPostMsg(hwnd, WM_CLOSE, 0l, 0l);
  249.           break;
  250.  
  251.        case ID_VIEW_TREE:
  252.        case ID_VIEW_DETAILS:
  253.        case ID_VIEW_ICON:
  254.        case ID_VIEW_NAME:
  255.        case ID_VIEW_TEXT:
  256.           SetView(pGlobalData->hContainer, pGlobalData, id);
  257.           break;
  258.  
  259.        } /* endswitch ((id = SHORT1FROMMP(mp1))) */
  260.  
  261.        return (MRFROMSHORT(0));
  262.  
  263.     default:
  264.       break;
  265.     } /* endswitch */
  266.  
  267.     return (WinDefWindowProc(hwnd, msg, mp1, mp2));
  268. }
  269.  
  270. static MRESULT ClientWndInit(HWND hwnd, GLOBALDATA *pGlobalData)
  271. {
  272.     FONTMETRICS fm;
  273.     WinSetWindowPtr(hwnd, 0, (void *)pGlobalData);
  274.     WinSendMsg(pGlobalData->hMenu, MM_SETITEMATTR, MPFROM2SHORT(ID_FILE_OPEN, TRUE), MPFROM2SHORT(MIA_DISABLED, FALSE));
  275.     WinSendMsg(pGlobalData->hMenu, MM_SETITEMATTR, MPFROM2SHORT(ID_FILE_CLOSE, TRUE), MPFROM2SHORT(MIA_DISABLED, FALSE));
  276.     GpiQueryFontMetrics(WinGetPS(hwnd), sizeof(fm), &fm);
  277.     pGlobalData->sCharHeight = (short)fm.lMaxBaselineExt;
  278.     pGlobalData->sTopLine=0;
  279.     pGlobalData->sLineCount=0;
  280.     memset(&pGlobalData->rclUpdate, 0, sizeof(pGlobalData->rclUpdate));
  281.     return (MRFROMSHORT(FALSE));
  282. }
  283.  
  284. static HWND CreateContainer(HWND hwnd, GLOBALDATA *pGlobalData)
  285. {
  286.    HWND              hContainer;
  287.    FIELDINFO         *pfi, *pfiRoot;
  288.    FIELDINFOINSERT   fii;
  289.    CNRINFO           cnri;
  290.    SWP               swp;
  291.    ULONG             ulLength;
  292.  
  293.    WinQueryWindowPos(hwnd, &swp);
  294.    hContainer = WinCreateWindow(hwnd, WC_CONTAINER, NULL, CCS_MINIRECORDCORE, 0, 0, swp.cx, swp.cy, hwnd, HWND_TOP, ID_CONTAINER, NULL, NULL);
  295.  
  296.    if (!hContainer) {
  297.       return (NULLHANDLE);
  298.    } /* endif */
  299.  
  300.    pfi = WinSendMsg(hContainer, CM_ALLOCDETAILFIELDINFO, MPFROMLONG(5), NULL);
  301.    pfiRoot = pfi;
  302.  
  303.  
  304. /* Icon column field */
  305.  
  306.    pfi->pTitleData   = "Icon";
  307.    pfi->flTitle      = CFA_CENTER | CFA_FITITLEREADONLY;
  308.    pfi->flData       = CFA_BITMAPORICON | CFA_CENTER | CFA_HORZSEPARATOR | CFA_SEPARATOR | CFA_FITITLEREADONLY;
  309.    pfi->offStruct    = FIELDOFFSET(CNRREC, mrc.hptrIcon);
  310.  
  311.  
  312. /* File column Field */   
  313.  
  314.    pfi               = pfi->pNextFieldInfo;
  315.    pfi->pTitleData   = "File Name";
  316.    pfi->flTitle      = CFA_CENTER | CFA_FITITLEREADONLY;
  317.    pfi->flData       = CFA_STRING | CFA_LEFT | CFA_HORZSEPARATOR;
  318.    pfi->offStruct    = FIELDOFFSET(CNRREC, mrc.pszIcon);
  319.    memset(&cnri, 0, sizeof(cnri));
  320.    cnri.cb           = sizeof(cnri);
  321.    cnri.pFieldInfoLast  = pfi;
  322.    cnri.xVertSplitbar   = 220;
  323.  
  324. /* file size column */
  325.  
  326.    pfi               = pfi->pNextFieldInfo;
  327.    pfi->pTitleData   = "Size";
  328.    pfi->flTitle      = CFA_CENTER | CFA_FITITLEREADONLY;
  329.    pfi->flData       = CFA_ULONG | CFA_RIGHT | CFA_HORZSEPARATOR | CFA_SEPARATOR;
  330.    pfi->offStruct    = FIELDOFFSET(CNRREC, ulSize);
  331.  
  332. /* file date column */
  333.  
  334.    pfi               = pfi->pNextFieldInfo;
  335.    pfi->pTitleData   = "Date";
  336.    pfi->flTitle      = CFA_CENTER | CFA_FITITLEREADONLY;
  337.    pfi->flData       = CFA_DATE | CFA_LEFT | CFA_HORZSEPARATOR | CFA_SEPARATOR;
  338.    pfi->offStruct    = FIELDOFFSET(CNRREC, Date);
  339.  
  340. /* file time column */
  341.  
  342.    pfi               = pfi->pNextFieldInfo;
  343.    pfi->pTitleData   = "Time";
  344.    pfi->flTitle      = CFA_CENTER | CFA_FITITLEREADONLY;
  345.    pfi->flData       = CFA_TIME | CFA_LEFT | CFA_HORZSEPARATOR;
  346.    pfi->offStruct    = FIELDOFFSET(CNRREC, Time);
  347.  
  348.    memset(&fii, 0, sizeof(fii));
  349.  
  350.    fii.cb               = sizeof(fii);
  351.    fii.pFieldInfoOrder  = (FIELDINFO *)CMA_FIRST;
  352.    fii.cFieldInfoInsert = 5;
  353.    fii.fInvalidateFieldInfo = TRUE;
  354.  
  355.    WinSendMsg(hContainer, CM_INSERTDETAILFIELDINFO, MPFROMP(pfiRoot), MPFROMP(&fii));
  356.  
  357.    WinSendMsg(hContainer, CM_SETCNRINFO, MPFROMP(&cnri), MPFROMLONG(CMA_PFIELDINFOLAST | CMA_XVERTSPLITBAR));
  358.  
  359.    ulLength = sizeof(pGlobalData->szCurrDir) - 1;
  360.    pGlobalData->szCurrDir[0] = '\\';
  361.    DosQCurDir(0, &pGlobalData->szCurrDir[1], &ulLength);
  362.  
  363. #ifdef __IBMC__
  364.    if (_beginthread(FillContainerThread, NULL, 4000, pGlobalData) == -1) {
  365. #endif
  366. #ifdef __BORLANDC__
  367.    if (_beginthread(FillContainerThread, 4000, pGlobalData) == -1) {
  368. #endif
  369.       WinMessageBox(HWND_DESKTOP, hwnd, "Can't start container fill thread.", "ERROR!", 0, MB_OK | MB_ICONEXCLAMATION);
  370.       WinDestroyWindow(hContainer);
  371.       hContainer = NULLHANDLE;
  372.    } /* endif */
  373.  
  374.    return (hContainer);
  375. }
  376.  
  377. static void FillContainerThread(void *pv)
  378. {
  379.    GLOBALDATA  *pGlobalData;
  380.    HAB         hab;
  381.    HMQ         hmq;
  382.    ULONG       ulFileCount;
  383.  
  384.    pGlobalData = (GLOBALDATA *)pv;
  385.  
  386.    ulFileCount = 0;
  387.  
  388.    if ((hab=WinInitialize(0))) {
  389.       if ((hmq = WinCreateMsgQueue(hab, 0))) {
  390.          ulFileCount = FillContainer(pGlobalData->hContainer, NULL, pGlobalData->szCurrDir);
  391.          WinDestroyMsgQueue(hmq);
  392.       } /* endif */
  393.       WinTerminate(hab);
  394.    } /* endif */
  395.    WinPostMsg(pGlobalData->hClient, UM_CNRFILLDONE, MPFROMLONG(ulFileCount), 0);
  396.    _endthread();
  397. }
  398.  
  399. static ULONG FillContainer(HWND hwnd, CNRREC *pcrRoot, char *pszDir)
  400. {
  401.    ULONG             i, ulMaxFiles, ulFindBuffSize, ulFileCount;
  402.    long              rc;
  403.    HDIR              hdir;
  404.    char              *pszFileSpec, *pszFullName;
  405.    CNRREC            *pcr, *pcrFirst;
  406.    FILEFINDBUF3      *pffb, *pffbFirst;
  407.    RECORDINSERT      ri;
  408.    HPOINTER          hptr;
  409.  
  410.    ulFileCount = 0;
  411.  
  412.    ulFindBuffSize = sizeof(*pffb) * FINDBUFF_ENTRIES;
  413.    if (!(pffbFirst = malloc(ulFindBuffSize))) {
  414.       return (0);
  415.    } /* endif */
  416.    if (!(pszFileSpec = malloc(CCHMAXPATH * 2))) {
  417.       free(pffbFirst);
  418.       return(0);
  419.    } /* endif */
  420.    pszFullName = pszFileSpec + CCHMAXPATH;
  421.  
  422.    strcpy(pszFileSpec, pszDir);
  423.    strcat(pszFileSpec, "\\*.*");
  424.  
  425.    hdir = HDIR_CREATE;
  426.    ulMaxFiles = FINDBUFF_ENTRIES;
  427.  
  428.    rc = DosFindFirst(pszFileSpec, &hdir, FILE_NORMAL | FILE_DIRECTORY, pffbFirst, ulFindBuffSize, &ulMaxFiles, FIL_STANDARD);
  429.  
  430.    while (!rc) {
  431.       pcrFirst = WinSendMsg(hwnd, CM_ALLOCRECORD, MPFROMLONG(CNRREC_SIZE), MPFROMLONG(ulMaxFiles));
  432.       if (!pcrFirst) {
  433.          break;
  434.       } /* endif */
  435.       for (i=0, pcr=pcrFirst, pffb=pffbFirst; i<ulMaxFiles; i++) {
  436.          strcpy(pszFullName, pszDir);
  437.          strcat(pszFullName, "\\");
  438.          strcat(pszFullName, pffb->achName);
  439.  
  440.          if (!(hptr = WinLoadFileIcon(pszFullName, FALSE))) {
  441.             hptr = WinQuerySysPointer(HWND_DESKTOP, SPTR_ICONERROR, FALSE);
  442.          } /* endif */
  443.  
  444.          strcpy(pcr->szFileName, pszFullName);
  445.          pcr->Date.day     = pffb->fdateLastWrite.day;
  446.          pcr->Date.month   = pffb->fdateLastWrite.month;
  447.          pcr->Date.year    = pffb->fdateLastWrite.year;
  448.          pcr->Time.seconds = pffb->ftimeLastWrite.twosecs;
  449.          pcr->Time.minutes = pffb->ftimeLastWrite.minutes;
  450.          pcr->Time.hours   = pffb->ftimeLastWrite.hours;
  451.            pcr->ulSize       = pffb->cbFile;
  452.          pcr->ulAttr       = pffb->attrFile;
  453.          pcr->mrc.pszIcon  = strrchr(pcr->szFileName, '\\') + 1;
  454.          pcr->mrc.hptrIcon = hptr;
  455.  
  456. #ifdef __IBMC__
  457.          (pffb) += pffb->oNextEntryOffset;
  458. #endif
  459. #ifdef __BORLANDC__
  460.          ((char *)pffb) += pffb->oNextEntryOffset;
  461. #endif
  462.          pcr = (CNRREC *)pcr->mrc.preccNextRecord;
  463.       } /* endfor */
  464.  
  465.       memset(&ri, 0, sizeof(ri));
  466.  
  467.       ri.cb                = sizeof(ri);
  468.       ri.pRecordOrder      = (PRECORDCORE)CMA_END;
  469.       ri.pRecordParent     = (PRECORDCORE)pcrRoot;
  470.       ri.zOrder            = (USHORT)CMA_TOP;
  471.       ri.cRecordsInsert    = ulMaxFiles;
  472.       ri.fInvalidateRecord = TRUE;
  473.  
  474.       if (WinSendMsg(hwnd, CM_INSERTRECORD, MPFROMP(pcrFirst), MPFROMP(&ri))) {
  475.          ulFileCount += ulMaxFiles;
  476.       } /* endif */
  477.  
  478.       for (i=0, pcr=pcrFirst, pffb=pffbFirst; i<ulMaxFiles; i++) {
  479.          if ((pffb->attrFile & FILE_DIRECTORY) && strcmp(pffb->achName, ".") && strcmp(pffb->achName, "..")) {
  480.             strcpy(pszFullName, pszDir);
  481.             strcat(pszFullName, "\\");
  482.             strcat(pszFullName, pffb->achName);
  483.  
  484.             ulFileCount += FillContainer(hwnd, pcr, pszFullName);
  485.          } /* endif */
  486.  
  487. #ifdef __IBMC__
  488.          (pffb) += pffb->oNextEntryOffset;
  489. #endif
  490. #ifdef __BORLANDC__
  491.          ((char *)pffb) += pffb->oNextEntryOffset;
  492. #endif
  493.          pcr = (CNRREC *)pcr->mrc.preccNextRecord;
  494.  
  495.       } /* endfor */
  496.  
  497.       ulMaxFiles = FINDBUFF_ENTRIES;
  498.       rc = DosFindNext(hdir, pffbFirst, ulFindBuffSize, &ulMaxFiles);
  499.  
  500.    } /* endwhile */
  501.  
  502.    DosFindClose(hdir);
  503.    free(pffbFirst);
  504.    free(pszFileSpec);
  505.  
  506.    return (ulFileCount);
  507.  }
  508.  
  509. static void SetView(HWND hwnd, GLOBALDATA *pGlobalData, USHORT usView)
  510. {
  511.    CNRINFO  cnri;
  512.  
  513.    memset(&cnri, 0, sizeof(cnri));
  514.  
  515.    cnri.cb           = sizeof(cnri);
  516.    cnri.flWindowAttr = CA_CONTAINERTITLE | CA_TITLESEPARATOR;
  517.    cnri.pszCnrTitle  = pGlobalData->szCurrDir;
  518.  
  519.    switch (usView) {
  520.     case ID_VIEW_TREE:
  521.        cnri.flWindowAttr |= CV_TREE | CV_ICON | CA_TREELINE;
  522.        break;
  523.     case ID_VIEW_ICON:
  524.        cnri.flWindowAttr |= CV_ICON | CV_FLOW;
  525.        break;
  526.     case ID_VIEW_NAME:
  527.        cnri.flWindowAttr |= CV_NAME | CV_FLOW;
  528.        break;
  529.     case ID_VIEW_DETAILS:
  530.        cnri.flWindowAttr |= CV_DETAIL | CA_DETAILSVIEWTITLES;
  531.        break;
  532.     case ID_VIEW_TEXT:
  533.        cnri.flWindowAttr |= CV_TEXT | CV_FLOW;
  534.        break;
  535.    } /* endswitch */
  536.  
  537.    if (WinSendMsg(hwnd, CM_SETCNRINFO, MPFROMP(&cnri), MPFROMLONG(CMA_FLWINDOWATTR | CMA_CNRTITLE))) {
  538.       if (cnri.flWindowAttr & CV_ICON) {
  539.          WinSendMsg(hwnd, CM_ARRANGE, NULL,NULL);
  540.       } /* endif */
  541.  
  542.       if (pGlobalData->usView) {
  543.          WinSendMsg(pGlobalData->hMenu, MM_SETITEMATTR, MPFROM2SHORT(pGlobalData->usView, TRUE), MPFROM2SHORT(MIA_CHECKED, FALSE));
  544.       } /* endif */
  545.  
  546.    WinSendMsg(pGlobalData->hMenu, MM_SETITEMATTR, MPFROM2SHORT(usView, TRUE), MPFROM2SHORT(MIA_CHECKED, MIA_CHECKED));
  547.    pGlobalData->usView = usView;
  548.    } /* endif */
  549.  
  550.    return;
  551. }
  552.  
  553. static void FileOpen (HWND hwnd, GLOBALDATA *pGlobalData, char *pszFileName)
  554. {
  555.    if (!pszFileName) {
  556.       pGlobalData->hContainer = CreateContainer(hwnd, pGlobalData);
  557.       return;
  558.    } /* endif */
  559.  
  560.    strcpy(pGlobalData->szFileName, pszFileName);
  561.    pGlobalData->sCloseFile=FALSE;
  562.  
  563. #ifdef __IBMC__
  564.    if (_beginthread(ReadFileThread, NULL, 4000, pGlobalData) == -1) {
  565. #endif
  566. #ifdef __BORLANDC__
  567.    if (_beginthread(ReadFileThread, 4000, pGlobalData) == -1) {
  568. #endif
  569.       WinMessageBox(HWND_DESKTOP, hwnd, "Can't start file input thread.", "ERROR!", 0 , MB_OK | MB_ICONEXCLAMATION);
  570.       return;
  571.    } /* endif */
  572.  
  573.    WinSendMsg(pGlobalData->hMenu, MM_SETITEMATTR, MPFROM2SHORT(ID_FILE_OPEN, TRUE), MPFROM2SHORT(MIA_DISABLED, MIA_DISABLED));
  574.    WinSendMsg(pGlobalData->hMenu, MM_SETITEMATTR, MPFROM2SHORT(ID_FILE_CLOSE, TRUE), MPFROM2SHORT(MIA_DISABLED, FALSE));
  575.    return;
  576. }
  577.  
  578. static void FileClose(HWND hwnd, GLOBALDATA *pGlobalData)
  579. {
  580.     int i;
  581.     pGlobalData->sCloseFile = TRUE;
  582.  
  583.     WinSendMsg(pGlobalData->hMenu, MM_SETITEMATTR, MPFROM2SHORT(ID_FILE_OPEN, TRUE), MPFROM2SHORT(MIA_DISABLED, FALSE));
  584.     WinSendMsg(pGlobalData->hMenu, MM_SETITEMATTR, MPFROM2SHORT(ID_FILE_CLOSE, TRUE), MPFROM2SHORT(MIA_DISABLED, MIA_DISABLED));
  585.  
  586.     for (i=0; i < pGlobalData->sLineCount; i++) {
  587.        free(pGlobalData->pszText[i]);
  588.     } /* endfor */
  589.  
  590.     pGlobalData->sTopLine=0;
  591.     pGlobalData->sLineCount=0;
  592.     memset(&pGlobalData->rclUpdate, 0, sizeof(pGlobalData->rclUpdate));
  593.  
  594.     WinInvalidateRect(hwnd, NULL, FALSE);
  595.  
  596.     return;
  597. }
  598.  
  599. static void CalcLinePosition(HWND hwnd, GLOBALDATA *pGlobalData, short sLineIndex, RECTL *prcl)
  600. {
  601.     WinQueryWindowRect(hwnd, prcl);
  602.  
  603.     prcl->yTop -= (sLineIndex - pGlobalData->sTopLine) * pGlobalData->sCharHeight;
  604.     prcl->yBottom = prcl->yTop - pGlobalData->sCharHeight;
  605.  
  606.     return;
  607. }
  608.  
  609. static void ReadFileThread(void *pv)
  610. {
  611.     GLOBALDATA  *pGlobalData;
  612.     FILE        *fp;
  613.     char        *psz, szBuff[256];
  614.  
  615.     pGlobalData = (GLOBALDATA *)pv;
  616.  
  617.     if (!(fp = fopen(pGlobalData->szFileName, "r"))) {
  618.        WinPostMsg(pGlobalData->hClient, UM_ENDOFFILE, MPFROMSHORT(errno), 0);
  619.        _endthread();
  620.     } /* endif */
  621.  
  622.     while (fgets(szBuff, sizeof(szBuff), fp)) {
  623.  
  624.        if (pGlobalData->sCloseFile) {
  625.           break;
  626.        } /* endif */
  627.  
  628.        if ((psz = strchr(szBuff, '\n'))) {
  629.           *psz = '\0';
  630.        } /* endif */
  631.  
  632.        psz = malloc(strlen(szBuff)+1);
  633.        strcpy(psz, szBuff);
  634.        WinPostMsg(pGlobalData->hClient, UM_LINEOFTEXT, MPFROMP(psz), 0);
  635.        DosSleep(0);
  636.     } /* endwhile */
  637.  
  638.     fclose(fp);
  639.     WinPostMsg(pGlobalData->hClient, UM_ENDOFFILE, MPFROMSHORT(errno), 0);
  640.     _endthread();
  641. }
  642.  
  643.  
  644. int main(int argc, char **argv)
  645. {
  646.     QMSG    qmsg;
  647.     GLOBALDATA GlobalData;
  648.     memset(&GlobalData, 0 , sizeof(GlobalData));
  649.  
  650.     GlobalData.hab = WinInitialize(0);
  651.     GlobalData.hmq = WinCreateMsgQueue(GlobalData.hab, 0);
  652.  
  653.     if (WinRegisterClass(GlobalData.hab, CLASSNAME, ClientWndProc, CS_SIZEREDRAW, sizeof(GLOBALDATA *))){
  654.           if (CreateWindow(&GlobalData)) {
  655.              while (WinGetMsg(GlobalData.hab, &qmsg, NULLHANDLE, 0 , 0)) {
  656.                 WinDispatchMsg(GlobalData.hab, &qmsg);
  657.              } /* endwhile */
  658.           } /* endif */
  659.     } /* endif */
  660.     WinDestroyMsgQueue(GlobalData.hmq);
  661.     WinTerminate(GlobalData.hab);
  662.     return(0);
  663. }
  664.  
  665.