source: trunk/dll/objcnr.c@ 785

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

Rework DosFindFirst/Next loops to optimize memory allocation and code paths
Adjust FilesToGet limits
Update configuration notebook scanning page
Start updating #pragma alloc_text positioning for OpenWatcom compatibility

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