source: trunk/dll/dirsize.c@ 730

Last change on this file since 730 was 730, checked in by Gregg Young, 18 years ago

Preliminary work on variable sized container buffers. Removes szFileName etc. Builds fine but traps.

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