source: trunk/dll/dirsize.c@ 689

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

Commit OpenWatcom compatibility updates

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