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
Line 
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
9 Copyright (c) 2005, 2015 Steven H. Levine
10
11 24 May 05 SHL Rework for CNRITEM.szSubject
12 13 Jul 06 SHL Use Runtime_Error
13 01 Sep 06 SHL Do not complain for normal cancel
14 19 Oct 06 SHL Correct . and .. detect
15 03 Nov 06 SHL Renames
16 22 Mar 07 GKY Use QWL_USER
17 01 Aug 07 SHL Rework to sync with CNRITEM mods
18 03 Aug 07 GKY Enlarged and made setable everywhere Findbuf (speed file loading)
19 06 Aug 07 GKY Reduce DosSleep times (ticket 148)
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
22 14 Aug 07 SHL Revert ProcessDir DosSleep to 0
23 29 Feb 08 GKY Use xfree where appropriate
24 10 Dec 08 SHL Integrate exception handler support
25 08 Mar 09 GKY Additional strings move to PCSZs
26 28 Jun 09 GKY Added AddBackslashToPath() to remove repeatative code.
27 20 Sep 15 GKY Update for modified ExpandAll
28
29***********************************************************************/
30
31#include <stdlib.h>
32#include <string.h>
33#include <ctype.h>
34// #include <process.h> // _beginthread
35
36#define INCL_DOS
37#define INCL_WIN
38#define INCL_DOSERRORS
39#define INCL_LONGLONG
40
41#include "fm3dll.h"
42#include "fm3dll2.h" // #define's for UM_*, control id's, etc.
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
48#include "fm3dlg.h"
49#include "fm3str.h"
50#include "errutil.h" // Dos_Error...
51#include "strutil.h" // GetPString
52#include "objcnr.h"
53#include "notify.h" // Notify
54#include "wrappers.h" // xDosFindNext
55#include "select.h" // ExpandAll
56#include "valid.h" // IsRoot
57#include "misc.h" // PostMsg
58#include "fortify.h"
59#include "excputil.h" // xbeginthread
60#include "pathutil.h" // AddBackslashToPath
61
62typedef struct
63{
64 CHAR *filename;
65 HWND hwndCnr;
66 CHAR *stopflag;
67}
68DIRSIZE;
69
70typedef struct
71{
72 CHAR *dirname;
73 CHAR stopflag;
74 BOOL dying;
75 BOOL working;
76}
77TEMP;
78
79#pragma data_seg(DATA1)
80
81static PSZ pszSrcFile = __FILE__;
82
83static HWND objcnrwnd;
84
85static VOID ProcessDir(HWND hwndCnr,
86 CHAR *filename,
87 PCNRITEM pciParent,
88 CHAR *stopflag)
89{
90 CHAR maskstr[CCHMAXPATH], *endpath, *p;
91 ULONG ulFindCnt, ulFindMax;
92 ULONG ulBufBytes;
93 HDIR hdir;
94 PFILEFINDBUF3L pffbArray;
95 APIRET rc;
96 RECORDINSERT ri;
97 PCNRITEM pciP;
98 HPOINTER hptr;
99
100 ulBufBytes = sizeof(FILEFINDBUF3L) * FilesToGet;
101 pffbArray = xmalloc(ulBufBytes, pszSrcFile, __LINE__);
102 if (!pffbArray)
103 return; // Error already reported
104 strcpy(maskstr, filename);
105 AddBackslashToPath(maskstr);
106 //if (maskstr[strlen(maskstr) - 1] != '\\')
107 // strcat(maskstr, "\\");
108 endpath = &maskstr[strlen(maskstr)];
109 strcat(maskstr, "*");
110 hdir = HDIR_CREATE;
111 ulFindCnt = 1;
112 rc = xDosFindFirst(filename, &hdir,
113 FILE_NORMAL | FILE_READONLY | FILE_ARCHIVED |
114 FILE_SYSTEM | FILE_HIDDEN | MUST_HAVE_DIRECTORY,
115 pffbArray, ulBufBytes, &ulFindCnt, FIL_STANDARDL);
116 if (!rc)
117 DosFindClose(hdir);
118 // work around furshluginer FAT root bug
119 else if (IsRoot(filename))
120 rc = 0;
121
122 if ((!rc && (pffbArray->attrFile & FILE_DIRECTORY))) {
123 pciP = WinSendMsg(hwndCnr,
124 CM_ALLOCRECORD,
125 MPFROMLONG(EXTRA_RECORD_BYTES),
126 MPFROMLONG(1));
127 if (!pciP) {
128 Win_Error(hwndCnr, HWND_DESKTOP, pszSrcFile, __LINE__, PCSZ_CM_ALLOCRECORD);
129 free(pffbArray);
130 return;
131 }
132 pciP->pszFileName = xstrdup(filename, pszSrcFile, __LINE__);
133 pciP->pszDispAttr = NullStr;
134 pciP->pszSubject = NullStr;
135 pciP->pszLongName = NullStr;
136 if (strlen(filename) < 4)
137 pciP->pszDisplayName = pciP->pszFileName;
138 else {
139 p = strrchr(pciP->pszFileName, '\\');
140 if (!p)
141 pciP->pszDisplayName = pciP->pszFileName;
142 else if (*(p + 1))
143 p++;
144 pciP->pszDisplayName = p;
145 }
146 pciP->rc.pszIcon = pciP->pszDisplayName;
147 if (fForceUpper)
148 strupr(pciP->pszFileName);
149 else if (fForceLower)
150 strlwr(pciP->pszFileName);
151 pciP->rc.flRecordAttr |= CRA_RECORDREADONLY;
152 }
153 else {
154 free(pffbArray);
155 Dos_Error(MB_ENTER, rc, HWND_DESKTOP, pszSrcFile, __LINE__,
156 GetPString(IDS_CANTFINDDIRTEXT), filename);
157 return;
158 }
159
160 hptr = WinLoadFileIcon(pciP->pszFileName, FALSE);
161 if (hptr)
162 pciP->rc.hptrIcon = hptr;
163
164 if (!pciP->rc.hptrIcon || pciP->rc.hptrIcon == hptrFile) // OS/2 bug bug bug bug
165 pciP->rc.hptrIcon = hptrDir;
166
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;
172 ri.cRecordsInsert = 1;
173 ri.fInvalidateRecord = TRUE;
174 if (!WinSendMsg(hwndCnr, CM_INSERTRECORD, MPFROMP(pciP), MPFROMP(&ri))) {
175 free(pffbArray);
176 return;
177 }
178 hdir = HDIR_CREATE;
179 if (!isalpha(*maskstr) || maskstr[1] != ':' || maskstr[2] != '\\' ||
180 ((driveflags[toupper(*maskstr) - 'A'] & DRIVE_REMOTE) && fRemoteBug))
181 ulFindMax = 1;
182 else
183 ulFindMax = FilesToGet;
184 ulFindCnt = ulFindMax;
185 rc = xDosFindFirst(maskstr, &hdir,
186 FILE_NORMAL | FILE_READONLY | FILE_ARCHIVED |
187 FILE_SYSTEM | FILE_HIDDEN | MUST_HAVE_DIRECTORY,
188 pffbArray, ulBufBytes, &ulFindCnt, FIL_STANDARDL);
189 if (!rc) {
190 PFILEFINDBUF3L pffbFile;
191 ULONG x;
192
193 while (!rc) {
194 pffbFile = pffbArray;
195 for (x = 0; x < ulFindCnt; x++) {
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);
209 } // for
210 DosSleep(0); // Let's others at same priority get some work done
211 if (*stopflag)
212 break;
213 ulFindCnt = ulFindMax;
214 rc = xDosFindNext(hdir, pffbArray, ulBufBytes, &ulFindCnt, FIL_STANDARDL);
215 } // while
216 DosFindClose(hdir);
217 }
218
219 if (rc && rc != ERROR_NO_MORE_FILES) {
220 Dos_Error(MB_ENTER, rc, HWND_DESKTOP, pszSrcFile, __LINE__,
221 GetPString(IDS_CANTFINDDIRTEXT), filename);
222 }
223
224 free(pffbArray);
225 WinSendMsg(hwndCnr, CM_INVALIDATERECORD, MPFROMP(&pciP),
226 MPFROM2SHORT(1, 0));
227}
228
229static VOID FillCnrsThread(VOID * args)
230{
231 HAB hab;
232 HMQ hmq;
233 DIRSIZE *dirsize = (DIRSIZE *)args;
234
235# ifdef FORTIFY
236 Fortify_EnterScope();
237# endif
238 if (!dirsize) {
239 Runtime_Error(pszSrcFile, __LINE__, NULL);
240 return;
241 }
242
243 DosError(FERR_DISABLEHARDERR);
244
245 hab = WinInitialize(0);
246 if (hab) {
247 hmq = WinCreateMsgQueue(hab, 0);
248 if (hmq) {
249 WinCancelShutdown(hmq, TRUE);
250 ProcessDir(dirsize->hwndCnr, dirsize->filename, (PCNRITEM) NULL,
251 dirsize->stopflag);
252 DosPostEventSem(CompactSem);
253 WinDestroyMsgQueue(hmq);
254 }
255 WinTerminate(hab);
256 }
257 PostMsg(WinQueryWindow(dirsize->hwndCnr, QW_PARENT), UM_CONTAINER_FILLED,
258 MPVOID, MPVOID);
259 free(dirsize);
260# ifdef FORTIFY
261 Fortify_LeaveScope();
262# endif
263}
264
265MRESULT EXPENTRY ObjCnrDlgProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
266{
267 TEMP *data;
268
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,
274 SWP_RESTORE | SWP_SHOW | SWP_ACTIVATE | SWP_ZORDER);
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 }
289 data->dirname = (CHAR *)mp2;
290 WinSetWindowPtr(hwnd, QWL_USER, (PVOID) data);
291 if (*data->dirname)
292 WinSetDlgItemText(hwnd, OBJCNR_DIR, data->dirname);
293 {
294 DIRSIZE *dirsize;
295# ifdef FORTIFY
296 Fortify_EnterScope();
297# endif
298 dirsize = xmalloc(sizeof(DIRSIZE), pszSrcFile, __LINE__);
299 if (!dirsize) {
300 WinDismissDlg(hwnd, 0);
301 break;
302 }
303 dirsize->stopflag = (CHAR *)&data->stopflag;
304 dirsize->filename = data->dirname;
305 dirsize->hwndCnr = WinWindowFromID(hwnd, OBJCNR_CNR);
306 if (xbeginthread(FillCnrsThread,
307 65536 * 8,
308 dirsize,
309 pszSrcFile,
310 __LINE__) == -1)
311 {
312 free(dirsize);
313# ifdef FORTIFY
314 Fortify_LeaveScope();
315# endif
316 WinDismissDlg(hwnd, 0);
317 break;
318 }
319 else
320 data->working = TRUE;
321 }
322 PostMsg(hwnd, UM_SETUP, MPVOID, MPVOID);
323 break;
324
325 case UM_SETUP:
326 // WinEnableWindowUpdate(WinWindowFromID(hwnd,OBJCNR_CNR),FALSE);
327 {
328 CNRINFO cnri;
329
330 memset(&cnri, 0, sizeof(CNRINFO));
331 cnri.cb = sizeof(CNRINFO);
332 WinSendDlgItemMsg(hwnd, OBJCNR_CNR, CM_QUERYCNRINFO,
333 MPFROMP(&cnri), MPFROMLONG(sizeof(CNRINFO)));
334 cnri.cyLineSpacing = 0;
335 cnri.cxTreeIndent = 12L;
336 cnri.pszCnrTitle = (PSZ)GetPString(IDS_WORKINGTEXT);
337 cnri.flWindowAttr = CV_TREE | CV_FLOW |
338 CA_CONTAINERTITLE | CA_TITLESEPARATOR | CA_TREELINE;
339 if (WinQueryWindowUShort(hwnd, QWS_ID) == QTREE_FRAME)
340 cnri.flWindowAttr |= CV_MINI;
341 WinSendDlgItemMsg(hwnd, OBJCNR_CNR, CM_SETCNRINFO, MPFROMP(&cnri),
342 MPFROMLONG(CMA_FLWINDOWATTR | CMA_LINESPACING |
343 CMA_CXTREEINDENT));
344 }
345 return 0;
346
347 case UM_CONTAINER_FILLED:
348 WinSetDlgItemText(hwnd, OBJCNR_NOTE, NullStr);
349// WinEnableWindowUpdate(WinWindowFromID(hwnd,OBJCNR_CNR),TRUE);
350 WinSendDlgItemMsg(hwnd, OBJCNR_CNR, CM_INVALIDATERECORD, MPVOID,
351 MPFROM2SHORT(0, CMA_ERASE | CMA_INVALIDATE));
352 data = INSTDATA(hwnd);
353 if (data) {
354 data->working = FALSE;
355 if (data->dying)
356 WinDismissDlg(hwnd, 0);
357 {
358 PCNRITEM pci;
359 USHORT id;
360
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) {
368 ExpandAll(WinWindowFromID(hwnd, OBJCNR_CNR), 0, pci);
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 }
381 }
382 }
383 return 0;
384
385 case WM_CONTROL:
386 switch (SHORT1FROMMP(mp1)) {
387 case OBJCNR_CNR:
388 if (SHORT2FROMMP(mp1) == CN_ENTER) {
389
390 PCNRITEM pci = (PCNRITEM) ((PNOTIFYRECORDENTER) mp2)->pRecord;
391
392 if (pci && (INT) pci != -1)
393 WinSendDlgItemMsg(hwnd, DID_OK, BM_CLICK, MPVOID, MPVOID);
394 }
395 break;
396 }
397 return 0;
398
399 case WM_COMMAND:
400 switch (SHORT1FROMMP(mp1)) {
401 case IDM_HELP:
402 if (hwndHelp) {
403
404 USHORT id;
405
406 id = WinQueryWindowUShort(hwnd, QWS_ID);
407
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));
416 }
417 break;
418
419 case OBJCNR_DESKTOP:
420 case DID_OK:
421 data = INSTDATA(hwnd);
422 if (data) {
423
424 PCNRITEM pci;
425
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);
441 }
442 break;
443
444 case DID_CANCEL:
445 data = INSTDATA(hwnd);
446 if (data) {
447 if (data->working) {
448 data->dying = (CHAR)TRUE;
449 data->stopflag = (CHAR)0xff;
450 break;
451 }
452 WinDismissDlg(hwnd, 0);
453 }
454 break;
455 }
456 return 0;
457
458 case WM_DESTROY:
459 objcnrwnd = (HWND) 0;
460 data = INSTDATA(hwnd);
461 xfree(data, pszSrcFile, __LINE__);
462 break;
463 }
464 return WinDefDlgProc(hwnd, msg, mp1, mp2);
465}
466
467#pragma alloc_text(OBJCNR,ProcessDir,FillCnrsThread,ObjCnrDlgProc)
Note: See TracBrowser for help on using the repository browser.