source: trunk/dll/objcnr.c@ 838

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

Remainder of changes for xDosFindFirst/Next wrapper performance test

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