source: trunk/dll/dirsize.c@ 739

Last change on this file since 739 was 739, checked in by Steven Levine, 18 years ago

More ticket #24 updates

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