source: trunk/dll/dirsize.c@ 517

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

Correct . and .. detect

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