source: trunk/dll/dirsize.c@ 239

Last change on this file since 239 was 239, checked in by root, 20 years ago

Avoid Expand/Collapse hangs while working

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