source: trunk/dll/dirsize.c@ 751

Last change on this file since 751 was 751, checked in by Steven Levine, 18 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.