source: trunk/dll/dirsize.c@ 551

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

Indentation cleanup

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