source: trunk/dll/dirsize.c@ 731

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

Correct ticket 24 pointer errors for Gregg

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