source: trunk/dll/dirsize.c@ 350

Last change on this file since 350 was 350, checked in by root, 19 years ago

Use Runtime_Error

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