source: trunk/dll/objcnr.c@ 752

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

Changes to findbuf (10240 default setting) to speed container fills. Max is 102400 min 2048. Also reduced DosSleep time in filldirs to speed container fills.Ticket 138.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 10.4 KB
Line 
1
2/***********************************************************************
3
4 $Id: objcnr.c 752 2007-08-03 02:36:29Z gyoung $
5
6 Object containers
7
8 Copyright (c) 1993-98 M. Kimes
9 Copyright (c) 2005, 2007 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
19***********************************************************************/
20
21#define INCL_DOS
22#define INCL_WIN
23#include <os2.h>
24
25#include <stdio.h>
26#include <stdlib.h>
27#include <string.h>
28#include <ctype.h>
29#include <process.h> // _beginthread
30
31#include "fm3dll.h"
32#include "fm3dlg.h"
33#include "fm3str.h"
34
35typedef struct
36{
37 CHAR *filename;
38 HWND hwndCnr;
39 CHAR *stopflag;
40}
41DIRSIZE;
42
43typedef struct
44{
45 CHAR *dirname;
46 CHAR stopflag;
47 BOOL dying;
48 BOOL working;
49}
50TEMP;
51
52#pragma data_seg(DATA1)
53
54static PSZ pszSrcFile = __FILE__;
55
56static HWND objcnrwnd;
57
58#pragma alloc_text(OBJCNR,ProcessDir,FillCnrsThread,ObjCnrDlgProc)
59
60static VOID ProcessDir(HWND hwndCnr, CHAR * filename, PCNRITEM pciParent,
61 CHAR * stopflag)
62{
63 CHAR maskstr[CCHMAXPATH], *endpath, *p;
64 ULONG nm, ulM;
65 HDIR hdir;
66 FILEFINDBUF3 *ffb, *fft;
67 APIRET rc;
68 RECORDINSERT ri;
69 PCNRITEM pciP;
70
71 ffb = xmalloc(sizeof(FILEFINDBUF3), pszSrcFile, __LINE__);
72 if (!ffb)
73 return;
74 strcpy(maskstr, filename);
75 if (maskstr[strlen(maskstr) - 1] != '\\')
76 strcat(maskstr, "\\");
77 endpath = &maskstr[strlen(maskstr)];
78 strcat(maskstr, "*");
79 hdir = HDIR_CREATE;
80 nm = 1L;
81 rc = DosFindFirst(filename, &hdir,
82 FILE_NORMAL | FILE_READONLY | FILE_ARCHIVED |
83 FILE_SYSTEM | FILE_HIDDEN | MUST_HAVE_DIRECTORY,
84 ffb, sizeof(FILEFINDBUF3), &nm, FIL_STANDARD);
85 if (!rc)
86 DosFindClose(hdir);
87
88 if (rc) { /* work around furshluginer FAT bug... */
89 if (IsRoot(filename))
90 rc = 0;
91 }
92
93 if ((!rc && (ffb->attrFile & FILE_DIRECTORY))) {
94 pciP = WinSendMsg(hwndCnr,
95 CM_ALLOCRECORD,
96 MPFROMLONG(EXTRA_RECORD_BYTES),
97 MPFROMLONG(1L));
98 if (!pciP) {
99 free(ffb);
100 return;
101 }
102 pciP->pszFileName = xstrdup(filename, pszSrcFile, __LINE__);
103 pciP->pszDispAttr = NullStr;
104 pciP->pszSubject = NullStr;
105 pciP->pszLongname = NullStr;
106 if (strlen(filename) < 4)
107 pciP->pszDisplayName = pciP->pszFileName;
108 else {
109 p = strrchr(pciP->pszFileName, '\\');
110 if (!p)
111 pciP->pszFileName = pciP->pszFileName;
112 else if (*(p + 1))
113 p++;
114 pciP->pszDisplayName = p;
115 }
116 pciP->rc.pszIcon = pciP->pszDisplayName;
117 if (fForceUpper)
118 strupr(pciP->pszFileName);
119 else if (fForceLower)
120 strlwr(pciP->pszFileName);
121 pciP->rc.flRecordAttr |= CRA_RECORDREADONLY;
122 }
123 else {
124 free(ffb);
125 Dos_Error(MB_ENTER,
126 rc,
127 HWND_DESKTOP,
128 pszSrcFile,
129 __LINE__, GetPString(IDS_CANTFINDDIRTEXT), filename);
130 return;
131 }
132 {
133 HPOINTER hptr;
134
135 hptr = WinLoadFileIcon(pciP->pszFileName, FALSE);
136 if (hptr)
137 pciP->rc.hptrIcon = hptr;
138 }
139 if (!pciP->rc.hptrIcon || pciP->rc.hptrIcon == hptrFile) /* OS/2 bug bug bug bug */
140 pciP->rc.hptrIcon = hptrDir;
141 memset(&ri, 0, sizeof(RECORDINSERT));
142 ri.cb = sizeof(RECORDINSERT);
143 ri.pRecordOrder = (PRECORDCORE) CMA_END;
144 ri.pRecordParent = (PRECORDCORE) pciParent;
145 ri.zOrder = (USHORT) CMA_TOP;
146 ri.cRecordsInsert = 1L;
147 ri.fInvalidateRecord = TRUE;
148 if (!WinSendMsg(hwndCnr, CM_INSERTRECORD, MPFROMP(pciP), MPFROMP(&ri))) {
149 free(ffb);
150 return;
151 }
152 hdir = HDIR_CREATE;
153 if (!isalpha(*maskstr) || maskstr[1] != ':' || maskstr[2] != '\\' ||
154 ((driveflags[toupper(*maskstr) - 'A'] & DRIVE_REMOTE) && fRemoteBug))
155 ulM = 1L;
156 else
157 ulM = FilesToGet;
158 if (ulM > 1L) {
159 fft = xrealloc(ffb, sizeof(FILEFINDBUF3) * ulM, pszSrcFile, __LINE__);
160 if (!fft)
161 ulM = 1L;
162 else
163 ffb = fft;
164 }
165 nm = ulM;
166 rc = DosFindFirst(maskstr, &hdir,
167 FILE_NORMAL | FILE_READONLY | FILE_ARCHIVED |
168 FILE_SYSTEM | FILE_HIDDEN | MUST_HAVE_DIRECTORY, ffb,
169 sizeof(FILEFINDBUF3) * ulM, &nm, FIL_STANDARD);
170 if (!rc) {
171
172 register PBYTE fb = (PBYTE) ffb;
173 FILEFINDBUF3 *pffbFile;
174 ULONG x;
175
176 while (!rc) {
177 for (x = 0L; x < nm; x++) {
178 pffbFile = (FILEFINDBUF3 *) fb;
179 if (*stopflag)
180 break;
181 if ((pffbFile->attrFile & FILE_DIRECTORY) &&
182 // Skip . and ..
183 (pffbFile->achName[0] != '.' ||
184 (pffbFile->achName[1] &&
185 (pffbFile->achName[1] != '.' || pffbFile->achName[2])))) {
186 strcpy(endpath, pffbFile->achName);
187 ProcessDir(hwndCnr, maskstr, pciP, stopflag);
188 }
189 if (!pffbFile->oNextEntryOffset)
190 break;
191 fb += pffbFile->oNextEntryOffset;
192 }
193 DosSleep(0L);
194 if (*stopflag)
195 break;
196 nm = ulM;
197 rc = DosFindNext(hdir, ffb, sizeof(FILEFINDBUF3) * ulM, &nm);
198 }
199 DosFindClose(hdir);
200 }
201 free(ffb);
202 WinSendMsg(hwndCnr, CM_INVALIDATERECORD, MPFROMP(&pciP),
203 MPFROM2SHORT(1, 0));
204}
205
206static VOID FillCnrsThread(VOID * args)
207{
208 HAB hab;
209 HMQ hmq;
210 DIRSIZE *dirsize = (DIRSIZE *) args;
211
212 if (!dirsize)
213 return;
214
215 DosError(FERR_DISABLEHARDERR);
216
217 hab = WinInitialize(0);
218 if (hab) {
219 hmq = WinCreateMsgQueue(hab, 0);
220 if (hmq) {
221 WinCancelShutdown(hmq, TRUE);
222 ProcessDir(dirsize->hwndCnr, dirsize->filename, (PCNRITEM) NULL,
223 dirsize->stopflag);
224 DosPostEventSem(CompactSem);
225 WinDestroyMsgQueue(hmq);
226 }
227 WinTerminate(hab);
228 }
229 PostMsg(WinQueryWindow(dirsize->hwndCnr, QW_PARENT), UM_CONTAINER_FILLED,
230 MPVOID, MPVOID);
231 free(dirsize);
232}
233
234MRESULT EXPENTRY ObjCnrDlgProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
235{
236 TEMP *data;
237
238 switch (msg) {
239 case WM_INITDLG:
240 if (objcnrwnd) {
241 Runtime_Error(pszSrcFile, __LINE__, "objcnrwnd set");
242 WinSetWindowPos(objcnrwnd, HWND_TOP, 0, 0, 0, 0,
243 SWP_RESTORE | SWP_SHOW | SWP_ACTIVATE | SWP_ZORDER);
244 WinDismissDlg(hwnd, 0);
245 break;
246 }
247 if (!mp2) {
248 Runtime_Error(pszSrcFile, __LINE__, "mp2 NULL");
249 WinDismissDlg(hwnd, 0);
250 break;
251 }
252 objcnrwnd = hwnd;
253 data = xmallocz(sizeof(TEMP), pszSrcFile, __LINE__);
254 if (!data) {
255 WinDismissDlg(hwnd, 0);
256 break;
257 }
258 data->dirname = (CHAR *) mp2;
259 WinSetWindowPtr(hwnd, QWL_USER, (PVOID) data);
260 if (*data->dirname)
261 WinSetDlgItemText(hwnd, OBJCNR_DIR, data->dirname);
262 {
263 DIRSIZE *dirsize;
264
265 dirsize = xmalloc(sizeof(DIRSIZE), pszSrcFile, __LINE__);
266 if (!dirsize) {
267 WinDismissDlg(hwnd, 0);
268 break;
269 }
270 dirsize->stopflag = (CHAR *) & data->stopflag;
271 dirsize->filename = data->dirname;
272 dirsize->hwndCnr = WinWindowFromID(hwnd, OBJCNR_CNR);
273 if (_beginthread(FillCnrsThread, NULL, 65536 * 8, (PVOID) dirsize) ==
274 -1) {
275 Runtime_Error(pszSrcFile, __LINE__,
276 GetPString(IDS_COULDNTSTARTTHREADTEXT));
277 free(dirsize);
278 WinDismissDlg(hwnd, 0);
279 break;
280 }
281 else
282 data->working = TRUE;
283 }
284 PostMsg(hwnd, UM_SETUP, MPVOID, MPVOID);
285 break;
286
287 case UM_SETUP:
288 // WinEnableWindowUpdate(WinWindowFromID(hwnd,OBJCNR_CNR),FALSE);
289 {
290 CNRINFO cnri;
291
292 memset(&cnri, 0, sizeof(CNRINFO));
293 cnri.cb = sizeof(CNRINFO);
294 WinSendDlgItemMsg(hwnd, OBJCNR_CNR, CM_QUERYCNRINFO,
295 MPFROMP(&cnri), MPFROMLONG(sizeof(CNRINFO)));
296 cnri.cyLineSpacing = 0;
297 cnri.cxTreeIndent = 12L;
298 cnri.pszCnrTitle = GetPString(IDS_WORKINGTEXT);
299 cnri.flWindowAttr = CV_TREE | CV_FLOW |
300 CA_CONTAINERTITLE | CA_TITLESEPARATOR | CA_TREELINE;
301 if (WinQueryWindowUShort(hwnd, QWS_ID) == QTREE_FRAME)
302 cnri.flWindowAttr |= CV_MINI;
303 WinSendDlgItemMsg(hwnd, OBJCNR_CNR, CM_SETCNRINFO, MPFROMP(&cnri),
304 MPFROMLONG(CMA_FLWINDOWATTR | CMA_LINESPACING |
305 CMA_CXTREEINDENT));
306 }
307 return 0;
308
309 case UM_CONTAINER_FILLED:
310 WinSetDlgItemText(hwnd, OBJCNR_NOTE, NullStr);
311// WinEnableWindowUpdate(WinWindowFromID(hwnd,OBJCNR_CNR),TRUE);
312 WinSendDlgItemMsg(hwnd, OBJCNR_CNR, CM_INVALIDATERECORD, MPVOID,
313 MPFROM2SHORT(0, CMA_ERASE | CMA_INVALIDATE));
314 data = INSTDATA(hwnd);
315 if (data) {
316 data->working = FALSE;
317 if (data->dying)
318 WinDismissDlg(hwnd, 0);
319 {
320 PCNRITEM pci;
321 USHORT id;
322
323 id = WinQueryWindowUShort(hwnd, QWS_ID);
324 pci = (PCNRITEM) WinSendDlgItemMsg(hwnd, OBJCNR_CNR,
325 CM_QUERYRECORD,
326 MPVOID,
327 MPFROM2SHORT(CMA_FIRST,
328 CMA_ITEMORDER));
329 if (pci && (INT) pci != -1) {
330 ExpandAll(WinWindowFromID(hwnd, OBJCNR_CNR), TRUE, pci);
331 if (id == QTREE_FRAME)
332 pci = (PCNRITEM) WinSendDlgItemMsg(hwnd, OBJCNR_CNR,
333 CM_QUERYRECORD,
334 MPFROMP(pci),
335 MPFROM2SHORT(CMA_FIRSTCHILD,
336 CMA_ITEMORDER));
337 }
338 if ((!pci || (INT) pci == -1) && id == QTREE_FRAME) {
339 Notify(GetPString(IDS_NODIRSUNDERTEXT));
340 WinDismissDlg(hwnd, 0);
341 break;
342 }
343 }
344 }
345 return 0;
346
347 case WM_CONTROL:
348 switch (SHORT1FROMMP(mp1)) {
349 case OBJCNR_CNR:
350 if (SHORT2FROMMP(mp1) == CN_ENTER) {
351
352 PCNRITEM pci = (PCNRITEM) ((PNOTIFYRECORDENTER) mp2)->pRecord;
353
354 if (pci && (INT) pci != -1)
355 WinSendDlgItemMsg(hwnd, DID_OK, BM_CLICK, MPVOID, MPVOID);
356 }
357 break;
358 }
359 return 0;
360
361 case WM_COMMAND:
362 switch (SHORT1FROMMP(mp1)) {
363 case IDM_HELP:
364 if (hwndHelp) {
365
366 USHORT id;
367
368 id = WinQueryWindowUShort(hwnd, QWS_ID);
369
370 if (id == QTREE_FRAME)
371 WinSendMsg(hwndHelp, HM_DISPLAY_HELP,
372 MPFROM2SHORT(HELP_QUICKTREE, 0),
373 MPFROMSHORT(HM_RESOURCEID));
374 else
375 WinSendMsg(hwndHelp, HM_DISPLAY_HELP,
376 MPFROM2SHORT(HELP_OBJECTPATH, 0),
377 MPFROMSHORT(HM_RESOURCEID));
378 }
379 break;
380
381 case OBJCNR_DESKTOP:
382 case DID_OK:
383 data = INSTDATA(hwnd);
384 if (data) {
385
386 PCNRITEM pci;
387
388 if (data->working) {
389 Runtime_Error(pszSrcFile, __LINE__, "working unexpected");
390 break;
391 }
392 if (SHORT1FROMMP(mp1) == OBJCNR_DESKTOP) {
393 WinDismissDlg(hwnd, 2);
394 break;
395 }
396 pci = (PCNRITEM) WinSendDlgItemMsg(hwnd, OBJCNR_CNR,
397 CM_QUERYRECORDEMPHASIS,
398 MPFROMLONG(CMA_FIRST),
399 MPFROMSHORT(CRA_CURSORED));
400 if (pci && (INT) pci != -1)
401 strcpy(data->dirname, pci->pszFileName);
402 WinDismissDlg(hwnd, 1);
403 }
404 break;
405
406 case DID_CANCEL:
407 data = INSTDATA(hwnd);
408 if (data) {
409 if (data->working) {
410 data->dying = (CHAR)TRUE;
411 data->stopflag = (CHAR)0xff;
412 break;
413 }
414 WinDismissDlg(hwnd, 0);
415 }
416 break;
417 }
418 return 0;
419
420 case WM_DESTROY:
421 objcnrwnd = (HWND) 0;
422 data = INSTDATA(hwnd);
423 if (data)
424 free(data);
425 break;
426 }
427 return WinDefDlgProc(hwnd, msg, mp1, mp2);
428}
Note: See TracBrowser for help on using the repository browser.