source: trunk/dll/dirsize.c @ 751

Last change on this file since 751 was 751, checked in by Steven Levine, 13 years ago

Sync rest of code with CNRITEM mods
Sync code with ARCITEM mods
Get compare dialog working
Still some issues with status display
Still some issues with directory sizes tree display
Heap check diagnostic code mostly enabled

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 25.9 KB
Line 
1
2/***********************************************************************
3
4  $Id: dirsize.c 751 2007-08-02 23:05:48Z stevenhl $
5
6  Directory sizes
7
8  Copyright (c) 1993-98 M. Kimes
9  Copyright (c) 2001, 2007 Steven H. Levine
10
11  16 Oct 02 SHL Handle large partitions
12  12 Feb 03 SHL Use CBLIST_TO_EASIZE
13  21 Nov 03 SHL Avoid VAC \ after // bug (wierd)
14  21 Nov 03 SHL Correct minor typos
15  21 Nov 03 SHL Total drives >4GB better
16  24 May 05 SHL Rework for CNRITEM.szSubject
17  25 May 05 SHL Use ULONGLONG and CommaFmtULL
18  26 May 05 SHL More large file formatting updates
19  06 Jun 05 SHL Drop obsoletes
20  19 Jun 05 SHL More 64-bit math fixes
21  08 Aug 05 SHL Avoid Expand/Collapse hangs while working
22  17 Jul 06 SHL Use Runtime_Error
23  19 Oct 06 SHL Correct . and .. detect
24  18 Feb 07 GKY Add new drive type icons
25  22 Mar 07 GKY Use QWL_USER
26  23 Jul 07 SHL Sync with naming standards
27
28***********************************************************************/
29
30#define INCL_DOS
31#define INCL_WIN
32#define INCL_GPI
33#define INCL_LONGLONG
34#include <os2.h>
35
36#include <stdio.h>
37#include <stdlib.h>
38#include <string.h>
39#include <ctype.h>
40#include <process.h>                    // _beginthread
41
42#include "fm3dll.h"
43#include "fm3dlg.h"
44#include "fm3str.h"
45
46typedef struct
47{
48  CHAR *pszFileName;
49  HWND hwndCnr;
50  CHAR *pchStopFlag;
51  DIRCNRDATA *pDCD;
52} DIRSIZE;
53
54typedef struct
55{
56  CHAR szDirName[CCHMAXPATH];
57  CHAR chStopFlag;
58  BOOL dying;
59  BOOL working;
60  HPOINTER hptr;
61} tState;
62
63static PSZ pszSrcFile = __FILE__;
64
65#pragma alloc_text(DIRSIZE,ProcessDir,FillCnrThread,DirSizeProc)
66#pragma alloc_text(DIRSIZE2,PrintToFile,FillInRecSizes,SortSizeCnr)
67
68static SHORT APIENTRY SortSizeCnr(PMINIRECORDCORE p1, PMINIRECORDCORE p2,
69                                  PVOID SortFlags)
70{
71  ULONGLONG size1;
72  ULONGLONG size2;
73
74  size1 = ((PCNRITEM) p1)->cbFile + ((PCNRITEM) p1)->easize;
75  size2 = ((PCNRITEM) p2)->cbFile + ((PCNRITEM) p2)->easize;
76  return (size1 < size2) ? 1 : (size1 == size2) ? 0 : -1;
77}
78
79static BOOL ProcessDir(HWND hwndCnr,
80                       CHAR *pszFileName,
81                       PCNRITEM pciParent,
82                       CHAR *pchStopFlag,
83                       BOOL top,
84                       PULONGLONG pullTotalBytes)
85{
86  CHAR maskstr[CCHMAXPATH];
87  CHAR szBuf[CCHMAXPATH];
88  CHAR *pEndMask;
89  register char *p;
90  register char *sp;
91  register char *pp;
92  ULONG nm;
93  ULONGLONG ullCurDirBytes = 0;
94  ULONGLONG ullSubDirBytes = 0;
95  ULONGLONG ull;
96  HDIR hdir;
97  FILEFINDBUF4 *pffb;
98  APIRET rc;
99  RECORDINSERT ri;
100  PCNRITEM pci;
101
102  // fixme to report errors
103  *pullTotalBytes = 0;                  // In case we fail
104
105  pffb = xmalloc(sizeof(FILEFINDBUF4), pszSrcFile, __LINE__);
106  if (!pffb)
107    return FALSE;
108  strcpy(maskstr, pszFileName);
109  if (maskstr[strlen(maskstr) - 1] != '\\')
110    strcat(maskstr, "\\");
111  pEndMask = &maskstr[strlen(maskstr)]; // Point after last backslash
112  strcat(maskstr, "*");
113  //printf("%s\n",maskstr);
114
115  hdir = HDIR_CREATE;
116  nm = 1;
117  memset(pffb, 0, sizeof(FILEFINDBUF4));
118  DosError(FERR_DISABLEHARDERR);
119  //printf("FIND1\n");
120  rc = DosFindFirst(pszFileName, &hdir,
121                    FILE_NORMAL | FILE_READONLY | FILE_ARCHIVED |
122                    FILE_SYSTEM | FILE_HIDDEN | MUST_HAVE_DIRECTORY,
123                    pffb, sizeof(FILEFINDBUF4), &nm, FIL_QUERYEASIZE);
124
125  if (!rc)
126    DosFindClose(hdir);
127
128  /*
129   * the "|| strlen(pszFileName) < 4 below works around an OS/2 bug
130   * that prevents FAT root directories from being found when
131   * requesting EASIZE.  sheesh.
132   */
133  if ((!rc && (pffb->attrFile & FILE_DIRECTORY)) || strlen(pszFileName) < 4) {
134    if (*pchStopFlag) {
135      free(pffb);
136      return FALSE;
137    }
138    pci = WinSendMsg(hwndCnr, CM_ALLOCRECORD, MPFROMLONG(EXTRA_RECORD_BYTES),
139                     MPFROMLONG(1));
140    if (!pci) {
141      free(pffb);
142      return FALSE;
143    }
144    if (!rc) {
145      ullCurDirBytes = pffb->cbFile;
146      ullCurDirBytes += CBLIST_TO_EASIZE(pffb->cbList);
147    }
148    else
149      DosError(FERR_DISABLEHARDERR);
150    pci->rc.hptrIcon = hptrDir;
151    pci->attrFile = 0;
152    pci->pszDispAttr = NullStr;
153    pci->pszSubject = NullStr;
154  }
155  else {
156    free(pffb);
157    Dos_Error(MB_ENTER,
158              rc,
159              HWND_DESKTOP,
160              pszSrcFile,
161              __LINE__, GetPString(IDS_CANTFINDDIRTEXT), pszFileName);
162    return FALSE;
163  }
164
165  if (strlen(pszFileName) < 4 || top)
166    pci->pszFileName = xstrdup(pszFileName, pszSrcFile, __LINE__);
167  else {
168    p = strrchr(pszFileName, '\\');
169    if (!p)
170      p = pszFileName;
171    else
172      p++;                              // After last backslash
173    // Handle quoted names
174    // fixme to understand this - why lose path prefix?
175    sp = strchr(pszFileName, ' ') != NULL ? "\"" : NullStr;
176    pp = szBuf;
177    if (*sp)
178      *pp++ = *sp;                      // Need quotes
179    strcpy(pp, p);
180    if (*sp)
181      strcat(pp, sp);
182    pci->pszFileName = xstrdup(szBuf, pszSrcFile, __LINE__);
183  }
184  // fixme to know why - it appears to be indirectly saving length, but why?
185  pci->pszDisplayName = pci->pszFileName + strlen(pci->pszFileName);
186  pci->pszLongname = pci->pszFileName;          // fixme to be sure?
187  pci->rc.pszIcon = pci->pszFileName;
188  pci->rc.flRecordAttr |= CRA_RECORDREADONLY;
189  if (fForceUpper)
190    strupr(pci->pszFileName);
191  else if (fForceLower)
192    strlwr(pci->pszFileName);
193  pci->pszDisplayName = pci->pszFileName + strlen(pci->pszFileName);
194  memset(&ri, 0, sizeof(RECORDINSERT));
195  ri.cb = sizeof(RECORDINSERT);
196  ri.pRecordOrder = (PRECORDCORE) CMA_END;
197  ri.pRecordParent = (PRECORDCORE) pciParent;
198  ri.zOrder = (USHORT) CMA_TOP;
199  ri.cRecordsInsert = 1;
200  ri.fInvalidateRecord = TRUE;
201  if (!WinSendMsg(hwndCnr, CM_INSERTRECORD, MPFROMP(pci), MPFROMP(&ri))) {
202    free(pffb);
203    return FALSE;
204  }
205  hdir = HDIR_CREATE;
206  nm = 1;
207  rc = DosFindFirst(maskstr, &hdir,
208                    FILE_NORMAL | FILE_READONLY | FILE_ARCHIVED |
209                    FILE_SYSTEM | FILE_HIDDEN | FILE_DIRECTORY,
210                    pffb, sizeof(FILEFINDBUF4), &nm, FIL_QUERYEASIZE);
211  if (!rc) {
212    register PBYTE fb = (PBYTE) pffb;
213    FILEFINDBUF4 *pffbFile;
214    ULONG x;
215
216    while (!rc) {
217      priority_normal();
218      //printf("Found %lu\n",nm);
219      for (x = 0; x < nm; x++) {
220        pffbFile = (FILEFINDBUF4 *) fb;
221        //printf("%s\n",pffbFile->achName);
222        //fflush(stdout);
223        // Total size skipping . and ..
224        if ((~pffbFile->attrFile & FILE_DIRECTORY) ||
225            (pffbFile->achName[0] != '.' ||
226             (pffbFile->achName[1] &&
227              (pffbFile->achName[1] != '.' || pffbFile->achName[2])))) {
228          ullCurDirBytes += pffbFile->cbFile;
229          ullCurDirBytes += CBLIST_TO_EASIZE(pffbFile->cbList) & 0x3ff;
230
231          if (!(pffbFile->attrFile & FILE_DIRECTORY))
232            pci->attrFile++;            // Bump file count
233          if (*pchStopFlag)
234            break;
235          if (pffbFile->attrFile & FILE_DIRECTORY) {
236            // Recurse into subdir
237            strcpy(pEndMask, pffbFile->achName);        // Append dirname to base dirname
238            if (!*pchStopFlag) {
239              ProcessDir(hwndCnr, maskstr, pci, pchStopFlag, FALSE, &ull);
240              ullSubDirBytes += ull;
241            }
242          }
243        }
244        if (!pffbFile->oNextEntryOffset)
245          break;
246        fb += pffbFile->oNextEntryOffset;
247      }                                 // for matches
248      if (*pchStopFlag)
249        break;
250      DosSleep(1);
251      nm = 1;                           /* FilesToGet */
252      rc = DosFindNext(hdir, pffb, sizeof(FILEFINDBUF4), &nm);
253    }                                   // while more found
254    DosFindClose(hdir);
255    priority_normal();
256  }
257
258  free(pffb);
259
260  pci->cbFile = ullCurDirBytes;
261  pci->easize = ullSubDirBytes;         // hack cough
262  WinSendMsg(hwndCnr, CM_INVALIDATERECORD, MPFROMP(&pci),
263             MPFROM2SHORT(1, CMA_ERASE | CMA_TEXTCHANGED));
264
265  *pullTotalBytes = ullCurDirBytes + ullSubDirBytes;
266  return TRUE;
267}
268
269static VOID FillInRecSizes(HWND hwndCnr, PCNRITEM pciParent,
270                           ULONGLONG ullTotalBytes, CHAR * pchStopFlag,
271                           BOOL isroot)
272{
273  PCNRITEM pci = pciParent;
274  SHORT attrib = CMA_FIRSTCHILD;
275
276  if (pci) {
277
278    float fltPct = 0.0;
279    USHORT c;
280    CHAR szCurDir[80];
281    CHAR szSubDir[80];
282    CHAR szAllDir[80];
283    CHAR szBar[80];
284
285    // cbFile = currect directory usage in bytes
286    // easize = subdirectory usage in bytes
287    CommaFmtULL(szCurDir, sizeof(szCurDir), pci->cbFile, 'K');
288    *szBar = 0;
289
290    if (ullTotalBytes) {
291      register UINT cBar;
292
293      if (isroot) {
294        FSALLOCATE fsa;
295        APIRET rc;
296
297        memset(&fsa, 0, sizeof(fsa));
298        rc = DosQueryFSInfo(toupper(*pci->pszFileName) - '@', FSIL_ALLOC, &fsa,
299                            sizeof(FSALLOCATE));
300        if (!rc) {
301          fltPct = (ullTotalBytes * 100.0) /
302            ((float)fsa.cUnit * (fsa.cSectorUnit * fsa.cbSector));
303        }
304        // Need unique buffer 23 Jul 07 SHL
305        pci->pszLongname = xmalloc(2, pszSrcFile, __LINE__);
306        pci->pszLongname[0] = 0;                // Make null string
307        pci->pszLongname[1] = 1;                // Flag root - hack cough
308      }
309      else
310        fltPct = (((float)pci->cbFile + pci->easize) * 100.0) / ullTotalBytes;
311
312      cBar = (UINT) fltPct / 2;
313      if (cBar)
314        memset(szBar, '#', cBar);
315      if (cBar * 2 != (UINT) fltPct) {
316        szBar[cBar] = '=';
317        cBar++;
318      }
319      if (cBar < 50)
320        memset(szBar + cBar, ' ', 50 - cBar);
321      szBar[50] = 0;
322    }
323
324    pci->flags = (ULONG) fltPct;
325    CommaFmtULL(szSubDir, sizeof(szSubDir), pci->easize, 'K');
326    CommaFmtULL(szAllDir, sizeof(szAllDir), pci->cbFile + pci->easize, 'K');
327    c = pci->pszDisplayName - pci->pszFileName;
328    pci->pszFileName = xrealloc(pci->pszFileName,
329                                CCHMAXPATH,
330                                pszSrcFile,
331                                __LINE__);      // 23 Jul 07 SHL
332    sprintf(pci->pszFileName + c,
333            "  %s + %s = %s (%.02lf%%%s)\r%s",
334            szCurDir,
335            szSubDir,
336            szAllDir,
337            fltPct,
338            isroot ? GetPString(IDS_OFDRIVETEXT) : NullStr,
339            szBar);
340    pci->pszFileName = xrealloc(pci->pszFileName,
341                                strlen(pci->pszFileName) + 1,
342                                pszSrcFile,
343                                __LINE__);      // 23 Jul 07 SHL
344    pci->pszDisplayName = pci->pszFileName + c;
345    WinSendMsg(hwndCnr,
346               CM_INVALIDATERECORD, MPFROMP(&pci), MPFROM2SHORT(1, 0));
347    isroot = FALSE;
348  }
349  else
350    attrib = CMA_FIRST;
351  pci = (PCNRITEM) WinSendMsg(hwndCnr, CM_QUERYRECORD, MPFROMP(pci),
352                              MPFROM2SHORT(attrib, CMA_ITEMORDER));
353  while (pci && (INT) pci != -1) {
354    if (*pchStopFlag)
355      break;
356    FillInRecSizes(hwndCnr, pci, ullTotalBytes, pchStopFlag, isroot);
357    isroot = FALSE;
358    pci = (PCNRITEM) WinSendMsg(hwndCnr, CM_QUERYRECORD, MPFROMP(pci),
359                                MPFROM2SHORT(CMA_NEXT, CMA_ITEMORDER));
360  }
361}
362
363static VOID PrintToFile(HWND hwndCnr, ULONG indent, PCNRITEM pciParent,
364                        FILE * fp)
365{
366  PCNRITEM pci;
367  CHAR *p;
368
369  if (!pciParent) {
370    pciParent = WinSendMsg(hwndCnr, CM_QUERYRECORD, MPFROMP(NULL),
371                           MPFROM2SHORT(CMA_FIRST, CMA_ITEMORDER));
372    indent = 0;
373  }
374  if (pciParent) {
375    p = strchr(pciParent->pszFileName, '\r');
376    if (p)
377      *p = 0;
378    fprintf(fp, "%*.*s%s %lu %s%s\n",
379            indent * 2, indent * 2, " ",
380            pciParent->pszFileName,
381            pciParent->attrFile,
382            GetPString(IDS_FILETEXT), &"s"[pciParent->attrFile == 1]);
383    if (p)
384      *p = '\r';
385    if (pciParent->rc.flRecordAttr & CRA_EXPANDED) {
386      pci = (PCNRITEM) WinSendMsg(hwndCnr, CM_QUERYRECORD, MPFROMP(pciParent),
387                                  MPFROM2SHORT(CMA_FIRSTCHILD,
388                                               CMA_ITEMORDER));
389      while (pci && (INT) pci != -1) {
390        DosSleep(1);
391        PrintToFile(hwndCnr, indent + 1, pci, fp);
392        pci = (PCNRITEM) WinSendMsg(hwndCnr, CM_QUERYRECORD, MPFROMP(pci),
393                                    MPFROM2SHORT(CMA_NEXT, CMA_ITEMORDER));
394      }
395    }
396  }
397}
398
399static VOID FillCnrThread(VOID * args)
400{
401  HAB hab;
402  HMQ hmq;
403  DIRSIZE *dirsize = (DIRSIZE *) args;
404  HWND hwndCnr;
405  ULONGLONG ull;
406
407  if (!dirsize)
408    return;
409  hwndCnr = dirsize->hwndCnr;
410
411  DosError(FERR_DISABLEHARDERR);
412
413  // priority_normal();
414  hab = WinInitialize(0);
415  if (hab) {
416    hmq = WinCreateMsgQueue(hab, 0);
417    if (hmq) {
418      WinCancelShutdown(hmq, TRUE);
419      ProcessDir(hwndCnr, dirsize->pszFileName,
420                 (PCNRITEM) NULL, dirsize->pchStopFlag, TRUE, &ull);
421      DosPostEventSem(CompactSem);
422      WinEnableWindowUpdate(hwndCnr, FALSE);
423      FillInRecSizes(hwndCnr, NULL, ull, dirsize->pchStopFlag, TRUE);
424      WinEnableWindowUpdate(hwndCnr, TRUE);
425      WinSendMsg(hwndCnr, CM_INVALIDATERECORD, MPVOID,
426                 MPFROM2SHORT(0, CMA_ERASE | CMA_TEXTCHANGED));
427      WinDestroyMsgQueue(hmq);
428    }
429    WinTerminate(hab);
430  }
431  PostMsg(WinQueryWindow(hwndCnr, QW_PARENT),
432          UM_CONTAINER_FILLED, MPVOID, MPVOID);
433  free(dirsize);
434}
435
436MRESULT EXPENTRY DirSizeProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
437{
438  tState *pState;
439  PCNRITEM pci;
440  CHAR szBytes[44];
441  CHAR sz[66];
442
443  switch (msg) {
444  case WM_INITDLG:
445    if (!mp2) {
446      WinDismissDlg(hwnd, 0);
447      break;
448    }
449    pState = xmallocz(sizeof(tState), pszSrcFile, __LINE__);
450    if (!pState) {
451      WinDismissDlg(hwnd, 0);
452      break;
453    }
454    strcpy(pState->szDirName, (CHAR *) mp2);
455    WinSetWindowPtr(hwnd, QWL_USER, (PVOID) pState);
456    pState->hptr = WinLoadPointer(HWND_DESKTOP, FM3ModHandle, DIRSIZE_ICON);
457    WinDefDlgProc(hwnd, WM_SETICON, MPFROMLONG(pState->hptr), MPVOID);
458    {
459      CHAR s[CCHMAXPATH + 81];
460
461      sprintf(s, GetPString(IDS_DIRSIZETITLETEXT), pState->szDirName);
462      WinSetWindowText(hwnd, s);
463    }
464    {
465      DIRSIZE *dirsize;
466
467      dirsize = xmalloc(sizeof(DIRSIZE), pszSrcFile, __LINE__);
468      if (!dirsize) {
469        WinDismissDlg(hwnd, 0);
470        break;
471      }
472      dirsize->pchStopFlag = (CHAR *) & pState->chStopFlag;
473      dirsize->pszFileName = pState->szDirName;
474      dirsize->hwndCnr = WinWindowFromID(hwnd, DSZ_CNR);
475      if (_beginthread(FillCnrThread, NULL, 122880L * 5, (PVOID)dirsize) ==
476          -1) {
477        Runtime_Error(pszSrcFile, __LINE__,
478                      GetPString(IDS_COULDNTSTARTTHREADTEXT));
479        free(dirsize);
480        WinDismissDlg(hwnd, 0);
481        break;
482      }
483      pState->working = TRUE;
484      WinEnableWindow(WinWindowFromID(hwnd, DSZ_COLLAPSE), FALSE);
485      WinEnableWindow(WinWindowFromID(hwnd, DSZ_EXPAND), FALSE);
486      WinEnableWindow(WinWindowFromID(hwnd, DSZ_PRINT), FALSE);
487    }
488    PostMsg(hwnd, UM_SETUP, MPVOID, MPVOID);
489    break;
490
491  case UM_SETUP:
492    {
493      CNRINFO cnri;
494      FSALLOCATE fsa;
495      APIRET rc;
496
497      memset(&cnri, 0, sizeof(CNRINFO));
498      cnri.cb = sizeof(CNRINFO);
499      WinSendDlgItemMsg(hwnd, DSZ_CNR, CM_QUERYCNRINFO,
500                        MPFROMP(&cnri), MPFROMLONG(sizeof(CNRINFO)));
501      cnri.cyLineSpacing = 0;
502      cnri.cxTreeIndent = 12;
503      cnri.flWindowAttr = CV_TREE | CV_FLOW | CA_TREELINE | CA_OWNERDRAW;
504      WinSendDlgItemMsg(hwnd, DSZ_CNR, CM_SETCNRINFO, MPFROMP(&cnri),
505                        MPFROMLONG(CMA_FLWINDOWATTR | CMA_TREEICON |
506                                   CMA_LINESPACING | CMA_CXTREEINDENT));
507      pState = INSTDATA(hwnd);
508      if (pState && isalpha(*pState->szDirName)) {
509        memset(&fsa, 0, sizeof(fsa));
510        rc =
511          DosQueryFSInfo(toupper(*pState->szDirName) - '@', FSIL_ALLOC, &fsa,
512                         sizeof(FSALLOCATE));
513        if (!rc) {
514
515          CHAR s[132], tf[80], tb[80], tu[80];
516
517          CommaFmtULL(tf, sizeof(tf),
518                      (ULONGLONG) fsa.cUnitAvail *
519                      (fsa.cSectorUnit * fsa.cbSector), 'M');
520          CommaFmtULL(tb, sizeof(tb),
521                      (ULONGLONG) fsa.cUnit *
522                      (fsa.cSectorUnit * fsa.cbSector), 'M');
523          CommaFmtULL(tu, sizeof(tu),
524                      (ULONGLONG) (fsa.cUnit - fsa.cUnitAvail) *
525                      (fsa.cSectorUnit * fsa.cbSector), 'M');
526          sprintf(s, GetPString(IDS_FREESPACETEXT), tf, tb, tu);
527          WinSetDlgItemText(hwnd, DSZ_FREESPACE, s);
528        }
529        else
530          WinSetDlgItemText(hwnd,
531                            DSZ_FREESPACE, GetPString(IDS_FREESPACEUTEXT));
532      }
533    }
534    return 0;
535
536  case UM_CONTAINER_FILLED:
537    pState = INSTDATA(hwnd);
538    if (!pState || pState->dying) {
539      if (pState)
540        pState->working = FALSE;
541      WinDismissDlg(hwnd, 0);
542      return 0;
543    }
544    pState->working = FALSE;
545    WinEnableWindow(WinWindowFromID(hwnd, DSZ_COLLAPSE), TRUE);
546    WinEnableWindow(WinWindowFromID(hwnd, DSZ_EXPAND), TRUE);
547    WinEnableWindow(WinWindowFromID(hwnd, DSZ_PRINT), TRUE);
548
549    pci = WinSendDlgItemMsg(hwnd, DSZ_CNR, CM_QUERYRECORD, MPVOID,
550                            MPFROM2SHORT(CMA_FIRST, CMA_ITEMORDER));
551    if (pci && (INT) pci != -1)
552      WinSendDlgItemMsg(hwnd, DSZ_CNR, CM_EXPANDTREE, MPFROMP(pci), MPVOID);
553    *sz = 0;
554    pci = WinSendDlgItemMsg(hwnd, DSZ_CNR, CM_QUERYRECORDEMPHASIS,
555                            MPFROMLONG(CMA_FIRST), MPFROMSHORT(CRA_CURSORED));
556    if (pci && (INT) pci != -1) {
557      commafmt(szBytes, sizeof(szBytes), pci->attrFile);
558      sprintf(sz,
559              "%s %s%s",
560              szBytes, GetPString(IDS_FILETEXT), &"s"[pci->attrFile == 1]);
561    }
562    WinSetDlgItemText(hwnd, DSZ_NUMFILES, sz);
563
564    WinSendDlgItemMsg(hwnd, DSZ_CNR, CM_SORTRECORD, MPFROMP(SortSizeCnr),
565                      MPVOID);
566    DosBeep(500, 25);                   // Wake up user
567    return 0;
568
569  case WM_ADJUSTWINDOWPOS:
570    PostMsg(hwnd, UM_STRETCH, MPVOID, MPVOID);
571    break;
572
573  case UM_STRETCH:
574    {
575      SWP swpC, swp;
576
577      WinQueryWindowPos(hwnd, &swp);
578      if (!(swp.fl & (SWP_HIDE | SWP_MINIMIZE))) {
579        WinQueryWindowPos(WinWindowFromID(hwnd, DSZ_CNR), &swpC);
580        WinSetWindowPos(WinWindowFromID(hwnd, DSZ_CNR), HWND_TOP,
581                        SysVal(SV_CXSIZEBORDER),
582                        swpC.y,
583                        swp.cx - (SysVal(SV_CXSIZEBORDER) * 2),
584                        (swp.cy - swpC.y) - (SysVal(SV_CYTITLEBAR) +
585                                             SysVal(SV_CYSIZEBORDER)),
586                        SWP_MOVE | SWP_SIZE);
587      }
588    }
589    return 0;
590
591  case WM_DRAWITEM:
592    if (mp2) {
593
594      OWNERITEM *oi = mp2;
595      CNRDRAWITEMINFO *cnd;
596      PCNRITEM pci;
597
598      if (oi->idItem == CMA_TEXT) {
599        cnd = (CNRDRAWITEMINFO *) oi->hItem;
600        if (cnd) {
601          pci = (PCNRITEM) cnd->pRecord;
602          if (pci) {
603
604            POINTL aptl[TXTBOX_COUNT], ptl;
605            CHAR *p;
606            LONG clr, x;
607
608            p = strchr(pci->pszFileName, '\r');
609            if (p) {
610              /* draw text */
611              if (!pci->cbFile)         /* no size */
612                GpiSetColor(oi->hps, CLR_DARKGRAY);
613              else if (!pci->easize)    /* no size below */
614                GpiSetColor(oi->hps, CLR_DARKBLUE);
615              else
616                GpiSetColor(oi->hps, CLR_BLACK);
617              GpiSetBackMix(oi->hps, BM_LEAVEALONE);
618              GpiSetMix(oi->hps, FM_OVERPAINT);
619              *p = 0;
620              GpiQueryTextBox(oi->hps, strlen(pci->pszFileName),
621                              pci->pszFileName, TXTBOX_COUNT, aptl);
622              ptl.x = oi->rclItem.xLeft;
623              ptl.y = (oi->rclItem.yTop - aptl[TXTBOX_TOPRIGHT].y);
624              GpiMove(oi->hps, &ptl);
625              GpiCharString(oi->hps, strlen(pci->pszFileName),
626                            pci->pszFileName);
627              *p = '\r';
628
629              /* draw the graph box */
630              GpiQueryTextBox(oi->hps, 1, "#", TXTBOX_COUNT, aptl);
631              /* draw black outline */
632              GpiSetColor(oi->hps, CLR_BLACK);
633              ptl.x = oi->rclItem.xLeft;
634              ptl.y = oi->rclItem.yBottom + 2;
635              GpiMove(oi->hps, &ptl);
636              ptl.x = oi->rclItem.xLeft + 101;
637              ptl.y = (oi->rclItem.yBottom + aptl[TXTBOX_TOPRIGHT].y);
638              GpiBox(oi->hps, DRO_OUTLINE, &ptl, 0, 0);
639              /* fill with gray */
640              GpiSetColor(oi->hps, CLR_PALEGRAY);
641              ptl.x = oi->rclItem.xLeft + 1;
642              ptl.y = oi->rclItem.yBottom + 3;
643              GpiMove(oi->hps, &ptl);
644              ptl.x = oi->rclItem.xLeft + 100;
645              ptl.y = (oi->rclItem.yBottom + aptl[TXTBOX_TOPRIGHT].y) - 1;
646              GpiBox(oi->hps, DRO_OUTLINEFILL, &ptl, 0, 0);
647
648              /* draw shadow at bottom & right sides */
649              GpiSetColor(oi->hps, CLR_DARKGRAY);
650              ptl.x = oi->rclItem.xLeft + 1;
651              ptl.y = oi->rclItem.yBottom + 3;
652              GpiMove(oi->hps, &ptl);
653              ptl.x = oi->rclItem.xLeft + 100;
654              GpiLine(oi->hps, &ptl);
655              ptl.y = (oi->rclItem.yBottom + aptl[TXTBOX_TOPRIGHT].y) - 1;
656              GpiLine(oi->hps, &ptl);
657
658              /* draw highlight at top and left sides */
659              GpiSetColor(oi->hps, CLR_WHITE);
660              ptl.x = oi->rclItem.xLeft + 1;
661              GpiLine(oi->hps, &ptl);
662              ptl.y = oi->rclItem.yBottom + 3;
663              GpiLine(oi->hps, &ptl);
664
665              /* draw shadow of box */
666              GpiSetColor(oi->hps, CLR_DARKGRAY);
667              ptl.x = oi->rclItem.xLeft + 2;
668              ptl.y = oi->rclItem.yBottom;
669              GpiMove(oi->hps, &ptl);
670              ptl.x = oi->rclItem.xLeft + 103;
671              GpiLine(oi->hps, &ptl);
672              ptl.y = (oi->rclItem.yBottom + aptl[TXTBOX_TOPRIGHT].y) - 2;
673              GpiLine(oi->hps, &ptl);
674              ptl.x--;
675              GpiMove(oi->hps, &ptl);
676              ptl.y = oi->rclItem.yBottom + 1;
677              GpiLine(oi->hps, &ptl);
678              ptl.x = oi->rclItem.xLeft + 2;
679              GpiLine(oi->hps, &ptl);
680
681              /* fill box with graph bar, flags is integer % */
682              if (pci->flags) {
683                if (*(pci->pszLongname + 1) == 1)       /* is root record */
684                  GpiSetColor(oi->hps, CLR_DARKGREEN);
685                else
686                  GpiSetColor(oi->hps, CLR_RED);
687                ptl.x = oi->rclItem.xLeft + 1;
688                ptl.y = oi->rclItem.yBottom + 3;
689                GpiMove(oi->hps, &ptl);
690                ptl.x = oi->rclItem.xLeft + pci->flags;
691                ptl.y = (oi->rclItem.yBottom + aptl[TXTBOX_TOPRIGHT].y) - 1;
692                GpiBox(oi->hps, DRO_OUTLINEFILL, &ptl, 0, 0);
693
694                /* draw highlights and shadows on graph */
695                if (*(pci->pszLongname + 1) == 1)
696                  GpiSetColor(oi->hps, CLR_GREEN);
697                else
698                  GpiSetColor(oi->hps, CLR_PALEGRAY);
699                if (pci->flags > 5) {
700                  ptl.x = oi->rclItem.xLeft + 1;
701                  ptl.y = oi->rclItem.yBottom + 3;
702                  GpiMove(oi->hps, &ptl);
703                  ptl.y = (oi->rclItem.yBottom + aptl[TXTBOX_TOPRIGHT].y) - 1;
704                  GpiLine(oi->hps, &ptl);
705                }
706                else {
707                  ptl.y = (oi->rclItem.yBottom + aptl[TXTBOX_TOPRIGHT].y) - 1;
708                  GpiMove(oi->hps, &ptl);
709                }
710                ptl.x = oi->rclItem.xLeft + pci->flags;
711                GpiLine(oi->hps, &ptl);
712                if (*(pci->pszLongname + 1) != 1) {
713                  GpiSetColor(oi->hps, CLR_DARKRED);
714                  ptl.x = oi->rclItem.xLeft + 2;
715                  ptl.y = oi->rclItem.yBottom + 3;
716                  GpiMove(oi->hps, &ptl);
717                  ptl.x = oi->rclItem.xLeft + pci->flags;
718                  GpiLine(oi->hps, &ptl);
719                }
720              }
721
722              /* draw hash marks in box */
723              GpiSetColor(oi->hps, CLR_WHITE);
724              clr = CLR_WHITE;
725              for (x = 1; x < 10; x++) {
726                if (clr == CLR_WHITE && x * 10 > pci->flags) {
727                  clr = CLR_BLACK;
728                  GpiSetColor(oi->hps, CLR_BLACK);
729                }
730                ptl.x = (oi->rclItem.xLeft + 1) + (x * 10);
731                ptl.y = oi->rclItem.yBottom + aptl[TXTBOX_TOPRIGHT].y - 1;
732                GpiMove(oi->hps, &ptl);
733                switch (x) {
734                case 1:
735                case 3:
736                case 7:
737                case 9:
738                  ptl.y -= 1;
739                  break;
740                case 5:
741                  ptl.y -= 4;
742                  break;
743                case 2:
744                case 4:
745                case 6:
746                case 8:
747                  ptl.y -= 2;
748                  break;
749                }
750                GpiLine(oi->hps, &ptl);
751              }
752              return MRFROMLONG(TRUE);
753            }
754          }
755        }
756      }
757    }
758    return FALSE;
759
760  case WM_CONTROL:
761    switch (SHORT2FROMMP(mp1)) {
762    case CN_ENTER:
763      if (mp2) {
764        PCNRITEM pci = (PCNRITEM)((PNOTIFYRECORDENTER)mp2)->pRecord;
765        CHAR szFileName[CCHMAXPATH];    // 23 Jul 07 SHL
766        CHAR szTemp[CCHMAXPATH];
767
768        if (pci) {
769          *szFileName = 0;
770          while (pci && (INT) pci != -1) {
771            memset(szTemp, 0, sizeof(szTemp));
772            strncpy(szTemp, pci->pszFileName,
773                    pci->pszDisplayName - pci->pszFileName);
774            strrev(szTemp);
775            if (*szFileName && *szTemp != '\\')
776              strcat(szFileName, "\\");
777            strcat(szFileName, szTemp);
778            pci = WinSendDlgItemMsg(hwnd, DSZ_CNR, CM_QUERYRECORD,
779                                    MPFROMP(pci),
780                                    MPFROM2SHORT(CMA_PARENT, CMA_ITEMORDER));
781          }
782          strrev(szFileName);
783          if (!fVTreeOpensWPS)
784            OpenDirCnr((HWND)0,
785                       hwndMain ? hwndMain : HWND_DESKTOP,
786                       hwnd,
787                       FALSE,
788                       szFileName);
789          else {
790
791            ULONG size = sizeof(ULONG);
792            ULONG flWindowAttr = CV_ICON;
793            CHAR s[33];
794
795            strcpy(s, "ICON");
796            PrfQueryProfileData(fmprof, appname, "DirflWindowAttr",
797                                (PVOID) & flWindowAttr, &size);
798            if (flWindowAttr & CV_DETAIL) {
799              if (IsRoot(szFileName))
800                strcpy(s, "TREE");
801              else
802                strcpy(s, "DETAILS");
803            }
804            OpenObject(szFileName, s, hwnd);
805          }
806        }
807      }
808      break;
809    case CN_EMPHASIS:
810      pState = INSTDATA(hwnd);
811      if (pState && !pState->working && mp2) {
812
813        PNOTIFYRECORDEMPHASIS pre = mp2;
814
815        pci = (PCNRITEM) ((pre) ? pre->pRecord : NULL);
816        if (pci && (pre->fEmphasisMask & CRA_SELECTED) &&
817            (pci->rc.flRecordAttr & CRA_SELECTED)) {
818          commafmt(szBytes, sizeof(szBytes), pci->attrFile);
819          sprintf(sz,
820                  "%s %s%s",
821                  szBytes,
822                  GetPString(IDS_FILETEXT), &"s"[pci->attrFile == 1]);
823          WinSetDlgItemText(hwnd, DSZ_NUMFILES, sz);
824        }
825      }
826      break;
827    }
828    return 0;
829
830  case WM_COMMAND:
831    switch (SHORT1FROMMP(mp1)) {
832    case IDM_HELP:
833      if (hwndHelp)
834        WinSendMsg(hwndHelp, HM_DISPLAY_HELP,
835                   MPFROM2SHORT(HELP_DIRSIZE, 0), MPFROMSHORT(HM_RESOURCEID));
836      break;
837
838    case DSZ_PRINT:
839      // Save button
840      pState = INSTDATA(hwnd);
841      if (!pState)
842        Runtime_Error2(pszSrcFile, __LINE__, IDS_NODATATEXT);
843      else {
844
845        CHAR szFileName[CCHMAXPATH];
846        FILE *fp;
847
848        save_dir2(szFileName);
849        sprintf(&szFileName[strlen(szFileName)], "\\%csizes.Rpt",
850                (pState) ? toupper(*pState->szDirName) : '+');
851        if (export_filename(hwnd, szFileName, FALSE) && *szFileName) {
852          if (stricmp(szFileName, "PRN") &&
853              strnicmp(szFileName, "\\DEV\\LPT", 8) &&
854              !strchr(szFileName, '.'))
855            strcat(szFileName, ".RPT");
856          fp = fopen(szFileName, "a+");
857          if (!fp) {
858            saymsg(MB_CANCEL,
859                   hwnd,
860                   GetPString(IDS_ERRORTEXT),
861                   GetPString(IDS_COMPCANTOPENTEXT), szFileName);
862          }
863          else {
864            WinSetPointer(HWND_DESKTOP, hptrBusy);
865            PrintToFile(WinWindowFromID(hwnd, DSZ_CNR), 0, NULL, fp);
866            fclose(fp);
867            WinSetPointer(HWND_DESKTOP, hptrArrow);
868          }
869        }
870      }
871      break;
872
873    case DSZ_EXPAND:
874    case DSZ_COLLAPSE:
875      pState = INSTDATA(hwnd);
876      if (pState) {
877        pci = (PCNRITEM) WinSendDlgItemMsg(hwnd, DSZ_CNR,
878                                           CM_QUERYRECORDEMPHASIS,
879                                           MPFROMLONG(CMA_FIRST),
880                                           MPFROMSHORT(CRA_CURSORED));
881        if (pci) {
882          WinEnableWindow(WinWindowFromID(hwnd, DID_OK), FALSE);
883          WinEnableWindow(WinWindowFromID(hwnd, IDM_HELP), FALSE);
884          WinEnableWindow(WinWindowFromID(hwnd, DSZ_COLLAPSE), FALSE);
885          WinEnableWindow(WinWindowFromID(hwnd, DSZ_EXPAND), FALSE);
886          WinEnableWindow(WinWindowFromID(hwnd, DSZ_PRINT), FALSE);
887          WinEnableWindow(WinWindowFromID(hwnd, DID_CANCEL), FALSE);
888          // fixme to use thread - too slow on large trees
889          ExpandAll(WinWindowFromID(hwnd, DSZ_CNR),
890                    (SHORT1FROMMP(mp1) == DSZ_EXPAND), pci);
891          WinEnableWindow(WinWindowFromID(hwnd, DID_OK), TRUE);
892          WinEnableWindow(WinWindowFromID(hwnd, IDM_HELP), TRUE);
893          WinEnableWindow(WinWindowFromID(hwnd, DSZ_COLLAPSE), TRUE);
894          WinEnableWindow(WinWindowFromID(hwnd, DSZ_EXPAND), TRUE);
895          WinEnableWindow(WinWindowFromID(hwnd, DSZ_PRINT), TRUE);
896          WinEnableWindow(WinWindowFromID(hwnd, DID_CANCEL), TRUE);
897        }
898      }
899      break;
900
901    case DID_OK:
902    case DID_CANCEL:
903      pState = INSTDATA(hwnd);
904      if (!pState)
905        Runtime_Error2(pszSrcFile, __LINE__, IDS_NODATATEXT);
906      else {
907        if (pState->working) {
908          pState->dying = TRUE;
909          pState->chStopFlag = (BYTE)0xff;
910          DosBeep(1000, 100);           // Complain?
911        }
912        else
913          WinDismissDlg(hwnd, 0);
914      }
915      break;
916    }                                   // switch mp1
917    return 0;
918
919  case WM_CLOSE:
920    pState = INSTDATA(hwnd);
921    if (pState)
922      pState->chStopFlag = (BYTE)0xff;
923    DosSleep(1);
924    break;
925
926  case WM_DESTROY:
927    pState = INSTDATA(hwnd);
928    if (pState) {
929      pState->chStopFlag = (BYTE)0xff;
930      if (pState->hptr)
931        WinDestroyPointer(pState->hptr);
932      DosSleep(33);
933      free(pState);                     // Let's hope no one is still looking
934    }
935    DosPostEventSem(CompactSem);
936    break;
937  }
938  return WinDefDlgProc(hwnd, msg, mp1, mp2);
939}
Note: See TracBrowser for help on using the repository browser.