source: trunk/dll/dirsize.c@ 552

Last change on this file since 552 was 552, checked in by Gregg Young, 19 years ago

font cleanup; new image and archiver masks; messages moved to string file; new drive flags including David's icons mostly working

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