source: trunk/dll/dirsize.c@ 574

Last change on this file since 574 was 574, checked in by Gregg Young, 18 years ago

Use QWL_USER; Replace doesn't move the command and Okay on cmd dialog removed error on unchanged command

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