source: trunk/dll/objcnr.c@ 1871

Last change on this file since 1871 was 1871, checked in by Gregg Young, 10 years ago

Create CollapseAll and modify ExpandAll to reduce code overhead both to try and speed drive expansion. Change ExpandAll to allow it to loop in UM_EXPAND until until drive is completely expanded. Changes were need to work with Flesh, Stubby and UnFlesh being moved to a thread. Add code for Flesh to skip the directory entry added by Stubby (eliminate use of NULL/Nullstr pszFileNames by Stubby). Add code in Stubby to insert a complete container item. Add a flag to indicate when a directory needed to be Fleshed. Get expand and switch code to work with Flesh, UnFlesh and Stubby running on a thread. Loop and idle ExpandAll; Move tree expand to a thread; Have ShowTreeRec wait for the Flesh thread. Add a correction factor so directories don't get placed above the top of the tree container when a large drive has been expanded. Debug is mostly still in but all turned off.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 12.3 KB
RevLine 
[159]1
2/***********************************************************************
3
4 $Id: objcnr.c 1871 2015-09-20 22:57:02Z gyoung $
5
6 Object containers
7
8 Copyright (c) 1993-98 M. Kimes
[1871]9 Copyright (c) 2005, 2015 Steven H. Levine
[159]10
11 24 May 05 SHL Rework for CNRITEM.szSubject
[349]12 13 Jul 06 SHL Use Runtime_Error
[488]13 01 Sep 06 SHL Do not complain for normal cancel
[517]14 19 Oct 06 SHL Correct . and .. detect
[531]15 03 Nov 06 SHL Renames
[574]16 22 Mar 07 GKY Use QWL_USER
[751]17 01 Aug 07 SHL Rework to sync with CNRITEM mods
[756]18 03 Aug 07 GKY Enlarged and made setable everywhere Findbuf (speed file loading)
[775]19 06 Aug 07 GKY Reduce DosSleep times (ticket 148)
[783]20 13 Aug 07 SHL Avoid realloc - not needed; sanitize code
21 13 Aug 07 SHL Move #pragma alloc_text to end for OpenWatcom compat
[787]22 14 Aug 07 SHL Revert ProcessDir DosSleep to 0
[985]23 29 Feb 08 GKY Use xfree where appropriate
[1335]24 10 Dec 08 SHL Integrate exception handler support
[1402]25 08 Mar 09 GKY Additional strings move to PCSZs
[1438]26 28 Jun 09 GKY Added AddBackslashToPath() to remove repeatative code.
[1871]27 20 Sep 15 GKY Update for modified ExpandAll
[159]28
29***********************************************************************/
30
[907]31#include <stdlib.h>
32#include <string.h>
33#include <ctype.h>
[1335]34// #include <process.h> // _beginthread
[907]35
[2]36#define INCL_DOS
37#define INCL_WIN
[783]38#define INCL_DOSERRORS
[841]39#define INCL_LONGLONG
[2]40
[1188]41#include "fm3dll.h"
[1225]42#include "fm3dll2.h" // #define's for UM_*, control id's, etc.
[1211]43#include "draglist.h" // Data declaration(s)
44#include "info.h" // Data declaration(s)
45#include "init.h" // Data declaration(s)
46#include "notebook.h" // Data declaration(s)
47#include "newview.h" // Data declarations
[2]48#include "fm3dlg.h"
49#include "fm3str.h"
[1163]50#include "errutil.h" // Dos_Error...
51#include "strutil.h" // GetPString
52#include "objcnr.h"
[1188]53#include "notify.h" // Notify
54#include "wrappers.h" // xDosFindNext
[1163]55#include "select.h" // ExpandAll
[1188]56#include "valid.h" // IsRoot
57#include "misc.h" // PostMsg
[1017]58#include "fortify.h"
[1335]59#include "excputil.h" // xbeginthread
[1438]60#include "pathutil.h" // AddBackslashToPath
[1017]61
[551]62typedef struct
63{
[2]64 CHAR *filename;
[551]65 HWND hwndCnr;
[2]66 CHAR *stopflag;
[551]67}
68DIRSIZE;
[2]69
[551]70typedef struct
71{
[2]72 CHAR *dirname;
[551]73 CHAR stopflag;
74 BOOL dying;
75 BOOL working;
76}
77TEMP;
[2]78
[349]79#pragma data_seg(DATA1)
[2]80
[349]81static PSZ pszSrcFile = __FILE__;
[2]82
[349]83static HWND objcnrwnd;
[2]84
[783]85static VOID ProcessDir(HWND hwndCnr,
[1335]86 CHAR *filename,
87 PCNRITEM pciParent,
88 CHAR *stopflag)
[349]89{
[551]90 CHAR maskstr[CCHMAXPATH], *endpath, *p;
[783]91 ULONG ulFindCnt, ulFindMax;
92 ULONG ulBufBytes;
[551]93 HDIR hdir;
[841]94 PFILEFINDBUF3L pffbArray;
[551]95 APIRET rc;
96 RECORDINSERT ri;
97 PCNRITEM pciP;
[783]98 HPOINTER hptr;
[2]99
[841]100 ulBufBytes = sizeof(FILEFINDBUF3L) * FilesToGet;
[783]101 pffbArray = xmalloc(ulBufBytes, pszSrcFile, __LINE__);
102 if (!pffbArray)
[1163]103 return; // Error already reported
[551]104 strcpy(maskstr, filename);
[1438]105 AddBackslashToPath(maskstr);
106 //if (maskstr[strlen(maskstr) - 1] != '\\')
107 // strcat(maskstr, "\\");
[2]108 endpath = &maskstr[strlen(maskstr)];
[551]109 strcat(maskstr, "*");
[2]110 hdir = HDIR_CREATE;
[783]111 ulFindCnt = 1;
[838]112 rc = xDosFindFirst(filename, &hdir,
[1335]113 FILE_NORMAL | FILE_READONLY | FILE_ARCHIVED |
114 FILE_SYSTEM | FILE_HIDDEN | MUST_HAVE_DIRECTORY,
115 pffbArray, ulBufBytes, &ulFindCnt, FIL_STANDARDL);
[551]116 if (!rc)
[2]117 DosFindClose(hdir);
[783]118 // work around furshluginer FAT root bug
119 else if (IsRoot(filename))
120 rc = 0;
[2]121
[783]122 if ((!rc && (pffbArray->attrFile & FILE_DIRECTORY))) {
[731]123 pciP = WinSendMsg(hwndCnr,
[1335]124 CM_ALLOCRECORD,
125 MPFROMLONG(EXTRA_RECORD_BYTES),
126 MPFROMLONG(1));
[551]127 if (!pciP) {
[1402]128 Win_Error(hwndCnr, HWND_DESKTOP, pszSrcFile, __LINE__, PCSZ_CM_ALLOCRECORD);
[1039]129 free(pffbArray);
[2]130 return;
131 }
[730]132 pciP->pszFileName = xstrdup(filename, pszSrcFile, __LINE__);
[751]133 pciP->pszDispAttr = NullStr;
134 pciP->pszSubject = NullStr;
[762]135 pciP->pszLongName = NullStr;
[551]136 if (strlen(filename) < 4)
[751]137 pciP->pszDisplayName = pciP->pszFileName;
[2]138 else {
[730]139 p = strrchr(pciP->pszFileName, '\\');
[551]140 if (!p)
[1335]141 pciP->pszDisplayName = pciP->pszFileName;
[551]142 else if (*(p + 1))
[1335]143 p++;
[751]144 pciP->pszDisplayName = p;
[2]145 }
[751]146 pciP->rc.pszIcon = pciP->pszDisplayName;
[551]147 if (fForceUpper)
[730]148 strupr(pciP->pszFileName);
[551]149 else if (fForceLower)
[730]150 strlwr(pciP->pszFileName);
[2]151 pciP->rc.flRecordAttr |= CRA_RECORDREADONLY;
152 }
153 else {
[1039]154 free(pffbArray);
[783]155 Dos_Error(MB_ENTER, rc, HWND_DESKTOP, pszSrcFile, __LINE__,
[1335]156 GetPString(IDS_CANTFINDDIRTEXT), filename);
[2]157 return;
158 }
159
[783]160 hptr = WinLoadFileIcon(pciP->pszFileName, FALSE);
161 if (hptr)
162 pciP->rc.hptrIcon = hptr;
163
[1673]164 if (!pciP->rc.hptrIcon || pciP->rc.hptrIcon == hptrFile) // OS/2 bug bug bug bug
[2]165 pciP->rc.hptrIcon = hptrDir;
[783]166
[551]167 memset(&ri, 0, sizeof(RECORDINSERT));
168 ri.cb = sizeof(RECORDINSERT);
169 ri.pRecordOrder = (PRECORDCORE) CMA_END;
170 ri.pRecordParent = (PRECORDCORE) pciParent;
171 ri.zOrder = (USHORT) CMA_TOP;
[771]172 ri.cRecordsInsert = 1;
[551]173 ri.fInvalidateRecord = TRUE;
174 if (!WinSendMsg(hwndCnr, CM_INSERTRECORD, MPFROMP(pciP), MPFROMP(&ri))) {
[1039]175 free(pffbArray);
[2]176 return;
177 }
178 hdir = HDIR_CREATE;
[551]179 if (!isalpha(*maskstr) || maskstr[1] != ':' || maskstr[2] != '\\' ||
180 ((driveflags[toupper(*maskstr) - 'A'] & DRIVE_REMOTE) && fRemoteBug))
[783]181 ulFindMax = 1;
[2]182 else
[783]183 ulFindMax = FilesToGet;
184 ulFindCnt = ulFindMax;
[838]185 rc = xDosFindFirst(maskstr, &hdir,
[1335]186 FILE_NORMAL | FILE_READONLY | FILE_ARCHIVED |
187 FILE_SYSTEM | FILE_HIDDEN | MUST_HAVE_DIRECTORY,
188 pffbArray, ulBufBytes, &ulFindCnt, FIL_STANDARDL);
[551]189 if (!rc) {
[841]190 PFILEFINDBUF3L pffbFile;
[551]191 ULONG x;
[2]192
[551]193 while (!rc) {
[783]194 pffbFile = pffbArray;
195 for (x = 0; x < ulFindCnt; x++) {
[1335]196 if (*stopflag)
197 break;
198 if ((pffbFile->attrFile & FILE_DIRECTORY) &&
199 // Skip . and ..
200 (pffbFile->achName[0] != '.' ||
201 (pffbFile->achName[1] &&
202 (pffbFile->achName[1] != '.' || pffbFile->achName[2])))) {
203 strcpy(endpath, pffbFile->achName);
204 ProcessDir(hwndCnr, maskstr, pciP, stopflag);
205 }
206 if (!pffbFile->oNextEntryOffset)
207 break;
208 pffbFile = (PFILEFINDBUF3L)((PBYTE)pffbFile + pffbFile->oNextEntryOffset);
[783]209 } // for
[1163]210 DosSleep(0); // Let's others at same priority get some work done
[551]211 if (*stopflag)
[1335]212 break;
[783]213 ulFindCnt = ulFindMax;
[850]214 rc = xDosFindNext(hdir, pffbArray, ulBufBytes, &ulFindCnt, FIL_STANDARDL);
[783]215 } // while
[2]216 DosFindClose(hdir);
217 }
[783]218
219 if (rc && rc != ERROR_NO_MORE_FILES) {
220 Dos_Error(MB_ENTER, rc, HWND_DESKTOP, pszSrcFile, __LINE__,
[1335]221 GetPString(IDS_CANTFINDDIRTEXT), filename);
[783]222 }
223
[1039]224 free(pffbArray);
[551]225 WinSendMsg(hwndCnr, CM_INVALIDATERECORD, MPFROMP(&pciP),
[1335]226 MPFROM2SHORT(1, 0));
[2]227}
228
[551]229static VOID FillCnrsThread(VOID * args)
[349]230{
[551]231 HAB hab;
232 HMQ hmq;
[783]233 DIRSIZE *dirsize = (DIRSIZE *)args;
[2]234
[1038]235# ifdef FORTIFY
236 Fortify_EnterScope();
[1063]237# endif
[783]238 if (!dirsize) {
[1398]239 Runtime_Error(pszSrcFile, __LINE__, NULL);
[2]240 return;
[783]241 }
[2]242
243 DosError(FERR_DISABLEHARDERR);
244
245 hab = WinInitialize(0);
[551]246 if (hab) {
247 hmq = WinCreateMsgQueue(hab, 0);
248 if (hmq) {
249 WinCancelShutdown(hmq, TRUE);
250 ProcessDir(dirsize->hwndCnr, dirsize->filename, (PCNRITEM) NULL,
[1335]251 dirsize->stopflag);
[2]252 DosPostEventSem(CompactSem);
253 WinDestroyMsgQueue(hmq);
254 }
255 WinTerminate(hab);
256 }
[551]257 PostMsg(WinQueryWindow(dirsize->hwndCnr, QW_PARENT), UM_CONTAINER_FILLED,
[1335]258 MPVOID, MPVOID);
[1039]259 free(dirsize);
[1017]260# ifdef FORTIFY
261 Fortify_LeaveScope();
[1063]262# endif
[2]263}
264
[551]265MRESULT EXPENTRY ObjCnrDlgProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
[349]266{
[2]267 TEMP *data;
268
[551]269 switch (msg) {
270 case WM_INITDLG:
271 if (objcnrwnd) {
272 Runtime_Error(pszSrcFile, __LINE__, "objcnrwnd set");
273 WinSetWindowPos(objcnrwnd, HWND_TOP, 0, 0, 0, 0,
[1335]274 SWP_RESTORE | SWP_SHOW | SWP_ACTIVATE | SWP_ZORDER);
[551]275 WinDismissDlg(hwnd, 0);
276 break;
277 }
278 if (!mp2) {
279 Runtime_Error(pszSrcFile, __LINE__, "mp2 NULL");
280 WinDismissDlg(hwnd, 0);
281 break;
282 }
283 objcnrwnd = hwnd;
284 data = xmallocz(sizeof(TEMP), pszSrcFile, __LINE__);
285 if (!data) {
286 WinDismissDlg(hwnd, 0);
287 break;
288 }
[1009]289 data->dirname = (CHAR *)mp2;
[574]290 WinSetWindowPtr(hwnd, QWL_USER, (PVOID) data);
[551]291 if (*data->dirname)
292 WinSetDlgItemText(hwnd, OBJCNR_DIR, data->dirname);
293 {
294 DIRSIZE *dirsize;
[1063]295# ifdef FORTIFY
296 Fortify_EnterScope();
297# endif
[551]298 dirsize = xmalloc(sizeof(DIRSIZE), pszSrcFile, __LINE__);
299 if (!dirsize) {
[1335]300 WinDismissDlg(hwnd, 0);
301 break;
[2]302 }
[1009]303 dirsize->stopflag = (CHAR *)&data->stopflag;
[551]304 dirsize->filename = data->dirname;
305 dirsize->hwndCnr = WinWindowFromID(hwnd, OBJCNR_CNR);
[1335]306 if (xbeginthread(FillCnrsThread,
307 65536 * 8,
308 dirsize,
309 pszSrcFile,
310 __LINE__) == -1)
311 {
312 free(dirsize);
[1063]313# ifdef FORTIFY
[1335]314 Fortify_LeaveScope();
[1063]315# endif
[1335]316 WinDismissDlg(hwnd, 0);
317 break;
[349]318 }
[551]319 else
[1335]320 data->working = TRUE;
[551]321 }
322 PostMsg(hwnd, UM_SETUP, MPVOID, MPVOID);
323 break;
[2]324
[551]325 case UM_SETUP:
326 // WinEnableWindowUpdate(WinWindowFromID(hwnd,OBJCNR_CNR),FALSE);
327 {
328 CNRINFO cnri;
[2]329
[551]330 memset(&cnri, 0, sizeof(CNRINFO));
331 cnri.cb = sizeof(CNRINFO);
332 WinSendDlgItemMsg(hwnd, OBJCNR_CNR, CM_QUERYCNRINFO,
[1335]333 MPFROMP(&cnri), MPFROMLONG(sizeof(CNRINFO)));
[551]334 cnri.cyLineSpacing = 0;
335 cnri.cxTreeIndent = 12L;
[1394]336 cnri.pszCnrTitle = (PSZ)GetPString(IDS_WORKINGTEXT);
[551]337 cnri.flWindowAttr = CV_TREE | CV_FLOW |
[1335]338 CA_CONTAINERTITLE | CA_TITLESEPARATOR | CA_TREELINE;
[551]339 if (WinQueryWindowUShort(hwnd, QWS_ID) == QTREE_FRAME)
[1335]340 cnri.flWindowAttr |= CV_MINI;
[551]341 WinSendDlgItemMsg(hwnd, OBJCNR_CNR, CM_SETCNRINFO, MPFROMP(&cnri),
[1335]342 MPFROMLONG(CMA_FLWINDOWATTR | CMA_LINESPACING |
343 CMA_CXTREEINDENT));
[551]344 }
345 return 0;
[2]346
[551]347 case UM_CONTAINER_FILLED:
348 WinSetDlgItemText(hwnd, OBJCNR_NOTE, NullStr);
[2]349// WinEnableWindowUpdate(WinWindowFromID(hwnd,OBJCNR_CNR),TRUE);
[551]350 WinSendDlgItemMsg(hwnd, OBJCNR_CNR, CM_INVALIDATERECORD, MPVOID,
[1335]351 MPFROM2SHORT(0, CMA_ERASE | CMA_INVALIDATE));
[551]352 data = INSTDATA(hwnd);
353 if (data) {
354 data->working = FALSE;
355 if (data->dying)
[1335]356 WinDismissDlg(hwnd, 0);
[551]357 {
[1335]358 PCNRITEM pci;
359 USHORT id;
[2]360
[1335]361 id = WinQueryWindowUShort(hwnd, QWS_ID);
362 pci = (PCNRITEM) WinSendDlgItemMsg(hwnd, OBJCNR_CNR,
363 CM_QUERYRECORD,
364 MPVOID,
365 MPFROM2SHORT(CMA_FIRST,
366 CMA_ITEMORDER));
367 if (pci && (INT) pci != -1) {
[1871]368 ExpandAll(WinWindowFromID(hwnd, OBJCNR_CNR), 0, pci);
[1335]369 if (id == QTREE_FRAME)
370 pci = (PCNRITEM) WinSendDlgItemMsg(hwnd, OBJCNR_CNR,
371 CM_QUERYRECORD,
372 MPFROMP(pci),
373 MPFROM2SHORT(CMA_FIRSTCHILD,
374 CMA_ITEMORDER));
375 }
376 if ((!pci || (INT) pci == -1) && id == QTREE_FRAME) {
377 Notify(GetPString(IDS_NODIRSUNDERTEXT));
378 WinDismissDlg(hwnd, 0);
379 break;
380 }
[2]381 }
[551]382 }
383 return 0;
[2]384
[551]385 case WM_CONTROL:
386 switch (SHORT1FROMMP(mp1)) {
387 case OBJCNR_CNR:
388 if (SHORT2FROMMP(mp1) == CN_ENTER) {
[2]389
[1335]390 PCNRITEM pci = (PCNRITEM) ((PNOTIFYRECORDENTER) mp2)->pRecord;
[2]391
[1335]392 if (pci && (INT) pci != -1)
393 WinSendDlgItemMsg(hwnd, DID_OK, BM_CLICK, MPVOID, MPVOID);
[2]394 }
[551]395 break;
396 }
397 return 0;
[2]398
[551]399 case WM_COMMAND:
400 switch (SHORT1FROMMP(mp1)) {
401 case IDM_HELP:
402 if (hwndHelp) {
[2]403
[1335]404 USHORT id;
[2]405
[1335]406 id = WinQueryWindowUShort(hwnd, QWS_ID);
[2]407
[1335]408 if (id == QTREE_FRAME)
409 WinSendMsg(hwndHelp, HM_DISPLAY_HELP,
410 MPFROM2SHORT(HELP_QUICKTREE, 0),
411 MPFROMSHORT(HM_RESOURCEID));
412 else
413 WinSendMsg(hwndHelp, HM_DISPLAY_HELP,
414 MPFROM2SHORT(HELP_OBJECTPATH, 0),
415 MPFROMSHORT(HM_RESOURCEID));
[551]416 }
417 break;
[2]418
[551]419 case OBJCNR_DESKTOP:
420 case DID_OK:
421 data = INSTDATA(hwnd);
422 if (data) {
[2]423
[1335]424 PCNRITEM pci;
[2]425
[1335]426 if (data->working) {
427 Runtime_Error(pszSrcFile, __LINE__, "working unexpected");
428 break;
429 }
430 if (SHORT1FROMMP(mp1) == OBJCNR_DESKTOP) {
431 WinDismissDlg(hwnd, 2);
432 break;
433 }
434 pci = (PCNRITEM) WinSendDlgItemMsg(hwnd, OBJCNR_CNR,
435 CM_QUERYRECORDEMPHASIS,
436 MPFROMLONG(CMA_FIRST),
437 MPFROMSHORT(CRA_CURSORED));
438 if (pci && (INT) pci != -1)
439 strcpy(data->dirname, pci->pszFileName);
440 WinDismissDlg(hwnd, 1);
[2]441 }
[551]442 break;
[2]443
[551]444 case DID_CANCEL:
[2]445 data = INSTDATA(hwnd);
[551]446 if (data) {
[1335]447 if (data->working) {
448 data->dying = (CHAR)TRUE;
449 data->stopflag = (CHAR)0xff;
450 break;
451 }
452 WinDismissDlg(hwnd, 0);
[551]453 }
[2]454 break;
[551]455 }
456 return 0;
457
458 case WM_DESTROY:
459 objcnrwnd = (HWND) 0;
460 data = INSTDATA(hwnd);
[1009]461 xfree(data, pszSrcFile, __LINE__);
[551]462 break;
[2]463 }
[551]464 return WinDefDlgProc(hwnd, msg, mp1, mp2);
[2]465}
[783]466
467#pragma alloc_text(OBJCNR,ProcessDir,FillCnrsThread,ObjCnrDlgProc)
Note: See TracBrowser for help on using the repository browser.