source: trunk/dll/objcnr.c@ 787

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

Rework UM_FILLSETUPLIST IDM_SAVEDIRCNRSTATE and ..._setups() logic for ticket# 109 and #31
Add GetMSecTimer()
Use GetMSecTimer in DbgMsg
Tweak notebook.ipf scanning page
Move more #pragma alloc_text statements to end of files for OpenWatcom
Delete obsoletes
Revert ExpandAll() ShowTreeRec() DosSleeps to 0 - DosSleep(1) was slowing down inner loops
Drop afFilesToGet - use FilesToGet directly
Optimze ShowTreeRec() collapse logic - was really slow

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 11.1 KB
RevLine 
[159]1
2/***********************************************************************
3
4 $Id: objcnr.c 787 2007-08-19 21:02:37Z 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
[787]22 14 Aug 07 SHL Revert ProcessDir DosSleep to 0
[159]23
24***********************************************************************/
25
[2]26#define INCL_DOS
27#define INCL_WIN
[783]28#define INCL_DOSERRORS
[349]29#include <os2.h>
[2]30
31#include <stdio.h>
32#include <stdlib.h>
33#include <string.h>
34#include <ctype.h>
[689]35#include <process.h> // _beginthread
[349]36
[2]37#include "fm3dll.h"
38#include "fm3dlg.h"
39#include "fm3str.h"
40
[551]41typedef struct
42{
[2]43 CHAR *filename;
[551]44 HWND hwndCnr;
[2]45 CHAR *stopflag;
[551]46}
47DIRSIZE;
[2]48
[551]49typedef struct
50{
[2]51 CHAR *dirname;
[551]52 CHAR stopflag;
53 BOOL dying;
54 BOOL working;
55}
56TEMP;
[2]57
[349]58#pragma data_seg(DATA1)
[2]59
[349]60static PSZ pszSrcFile = __FILE__;
[2]61
[349]62static HWND objcnrwnd;
[2]63
[783]64static VOID ProcessDir(HWND hwndCnr,
65 CHAR *filename,
66 PCNRITEM pciParent,
67 CHAR *stopflag)
[349]68{
[551]69 CHAR maskstr[CCHMAXPATH], *endpath, *p;
[783]70 ULONG ulFindCnt, ulFindMax;
71 ULONG ulBufBytes;
[551]72 HDIR hdir;
[783]73 PFILEFINDBUF3 pffbArray;
[551]74 APIRET rc;
75 RECORDINSERT ri;
76 PCNRITEM pciP;
[783]77 HPOINTER hptr;
[2]78
[783]79 ulBufBytes = sizeof(FILEFINDBUF3) * FilesToGet;
80 pffbArray = xmalloc(ulBufBytes, pszSrcFile, __LINE__);
81 if (!pffbArray)
82 return; // Error already reported
[551]83 strcpy(maskstr, filename);
84 if (maskstr[strlen(maskstr) - 1] != '\\')
85 strcat(maskstr, "\\");
[2]86 endpath = &maskstr[strlen(maskstr)];
[551]87 strcat(maskstr, "*");
[2]88 hdir = HDIR_CREATE;
[783]89 ulFindCnt = 1;
[2]90 rc = DosFindFirst(filename, &hdir,
[551]91 FILE_NORMAL | FILE_READONLY | FILE_ARCHIVED |
92 FILE_SYSTEM | FILE_HIDDEN | MUST_HAVE_DIRECTORY,
[783]93 pffbArray, ulBufBytes, &ulFindCnt, FIL_STANDARD);
[551]94 if (!rc)
[2]95 DosFindClose(hdir);
[783]96 // work around furshluginer FAT root bug
97 else if (IsRoot(filename))
98 rc = 0;
[2]99
[783]100 if ((!rc && (pffbArray->attrFile & FILE_DIRECTORY))) {
[731]101 pciP = WinSendMsg(hwndCnr,
102 CM_ALLOCRECORD,
[751]103 MPFROMLONG(EXTRA_RECORD_BYTES),
[761]104 MPFROMLONG(1));
[551]105 if (!pciP) {
[783]106 Win_Error(hwndCnr, HWND_DESKTOP, pszSrcFile, __LINE__, "CM_ALLOCRECORD");
107 free(pffbArray);
[2]108 return;
109 }
[730]110 pciP->pszFileName = xstrdup(filename, pszSrcFile, __LINE__);
[751]111 pciP->pszDispAttr = NullStr;
112 pciP->pszSubject = NullStr;
[762]113 pciP->pszLongName = NullStr;
[551]114 if (strlen(filename) < 4)
[751]115 pciP->pszDisplayName = pciP->pszFileName;
[2]116 else {
[730]117 p = strrchr(pciP->pszFileName, '\\');
[551]118 if (!p)
[756]119 pciP->pszDisplayName = pciP->pszFileName;
[551]120 else if (*(p + 1))
121 p++;
[751]122 pciP->pszDisplayName = p;
[2]123 }
[751]124 pciP->rc.pszIcon = pciP->pszDisplayName;
[551]125 if (fForceUpper)
[730]126 strupr(pciP->pszFileName);
[551]127 else if (fForceLower)
[730]128 strlwr(pciP->pszFileName);
[2]129 pciP->rc.flRecordAttr |= CRA_RECORDREADONLY;
130 }
131 else {
[783]132 free(pffbArray);
133 Dos_Error(MB_ENTER, rc, HWND_DESKTOP, pszSrcFile, __LINE__,
134 GetPString(IDS_CANTFINDDIRTEXT), filename);
[2]135 return;
136 }
137
[783]138 hptr = WinLoadFileIcon(pciP->pszFileName, FALSE);
139 if (hptr)
140 pciP->rc.hptrIcon = hptr;
141
[551]142 if (!pciP->rc.hptrIcon || pciP->rc.hptrIcon == hptrFile) /* OS/2 bug bug bug bug */
[2]143 pciP->rc.hptrIcon = hptrDir;
[783]144
[551]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;
[771]150 ri.cRecordsInsert = 1;
[551]151 ri.fInvalidateRecord = TRUE;
152 if (!WinSendMsg(hwndCnr, CM_INSERTRECORD, MPFROMP(pciP), MPFROMP(&ri))) {
[783]153 free(pffbArray);
[2]154 return;
155 }
156 hdir = HDIR_CREATE;
[551]157 if (!isalpha(*maskstr) || maskstr[1] != ':' || maskstr[2] != '\\' ||
158 ((driveflags[toupper(*maskstr) - 'A'] & DRIVE_REMOTE) && fRemoteBug))
[783]159 ulFindMax = 1;
[2]160 else
[783]161 ulFindMax = FilesToGet;
162 ulFindCnt = ulFindMax;
[2]163 rc = DosFindFirst(maskstr, &hdir,
[551]164 FILE_NORMAL | FILE_READONLY | FILE_ARCHIVED |
[783]165 FILE_SYSTEM | FILE_HIDDEN | MUST_HAVE_DIRECTORY,
166 pffbArray, ulBufBytes, &ulFindCnt, FIL_STANDARD);
[551]167 if (!rc) {
[783]168 PFILEFINDBUF3 pffbFile;
[551]169 ULONG x;
[2]170
[551]171 while (!rc) {
[783]172 pffbFile = pffbArray;
173 for (x = 0; x < ulFindCnt; x++) {
[551]174 if (*stopflag)
175 break;
176 if ((pffbFile->attrFile & FILE_DIRECTORY) &&
[517]177 // Skip . and ..
[551]178 (pffbFile->achName[0] != '.' ||
[517]179 (pffbFile->achName[1] &&
[551]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;
[783]186 pffbFile = (PFILEFINDBUF3)((PBYTE)pffbFile + pffbFile->oNextEntryOffset);
187 } // for
[787]188 DosSleep(0); // Let's others at same priority get some work done
[551]189 if (*stopflag)
190 break;
[783]191 ulFindCnt = ulFindMax;
192 rc = DosFindNext(hdir, pffbArray, ulBufBytes, &ulFindCnt);
193 } // while
[2]194 DosFindClose(hdir);
195 }
[783]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);
[551]203 WinSendMsg(hwndCnr, CM_INVALIDATERECORD, MPFROMP(&pciP),
204 MPFROM2SHORT(1, 0));
[2]205}
206
[551]207static VOID FillCnrsThread(VOID * args)
[349]208{
[551]209 HAB hab;
210 HMQ hmq;
[783]211 DIRSIZE *dirsize = (DIRSIZE *)args;
[2]212
[783]213 if (!dirsize) {
214 Runtime_Error(pszSrcFile, __LINE__, "no data");
[2]215 return;
[783]216 }
[2]217
218 DosError(FERR_DISABLEHARDERR);
219
220 hab = WinInitialize(0);
[551]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);
[2]227 DosPostEventSem(CompactSem);
228 WinDestroyMsgQueue(hmq);
229 }
230 WinTerminate(hab);
231 }
[551]232 PostMsg(WinQueryWindow(dirsize->hwndCnr, QW_PARENT), UM_CONTAINER_FILLED,
233 MPVOID, MPVOID);
[2]234 free(dirsize);
235}
236
[551]237MRESULT EXPENTRY ObjCnrDlgProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
[349]238{
[2]239 TEMP *data;
240
[551]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;
[574]262 WinSetWindowPtr(hwnd, QWL_USER, (PVOID) data);
[551]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;
[2]272 }
[551]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;
[349]283 }
[551]284 else
285 data->working = TRUE;
286 }
287 PostMsg(hwnd, UM_SETUP, MPVOID, MPVOID);
288 break;
[2]289
[551]290 case UM_SETUP:
291 // WinEnableWindowUpdate(WinWindowFromID(hwnd,OBJCNR_CNR),FALSE);
292 {
293 CNRINFO cnri;
[2]294
[551]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;
[2]311
[551]312 case UM_CONTAINER_FILLED:
313 WinSetDlgItemText(hwnd, OBJCNR_NOTE, NullStr);
[2]314// WinEnableWindowUpdate(WinWindowFromID(hwnd,OBJCNR_CNR),TRUE);
[551]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;
[2]325
[551]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 }
[2]346 }
[551]347 }
348 return 0;
[2]349
[551]350 case WM_CONTROL:
351 switch (SHORT1FROMMP(mp1)) {
352 case OBJCNR_CNR:
353 if (SHORT2FROMMP(mp1) == CN_ENTER) {
[2]354
[551]355 PCNRITEM pci = (PCNRITEM) ((PNOTIFYRECORDENTER) mp2)->pRecord;
[2]356
[551]357 if (pci && (INT) pci != -1)
358 WinSendDlgItemMsg(hwnd, DID_OK, BM_CLICK, MPVOID, MPVOID);
[2]359 }
[551]360 break;
361 }
362 return 0;
[2]363
[551]364 case WM_COMMAND:
365 switch (SHORT1FROMMP(mp1)) {
366 case IDM_HELP:
367 if (hwndHelp) {
[2]368
[551]369 USHORT id;
[2]370
[551]371 id = WinQueryWindowUShort(hwnd, QWS_ID);
[2]372
[551]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;
[2]383
[551]384 case OBJCNR_DESKTOP:
385 case DID_OK:
386 data = INSTDATA(hwnd);
387 if (data) {
[2]388
[551]389 PCNRITEM pci;
[2]390
[551]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)
[730]404 strcpy(data->dirname, pci->pszFileName);
[551]405 WinDismissDlg(hwnd, 1);
[2]406 }
[551]407 break;
[2]408
[551]409 case DID_CANCEL:
[2]410 data = INSTDATA(hwnd);
[551]411 if (data) {
412 if (data->working) {
[689]413 data->dying = (CHAR)TRUE;
414 data->stopflag = (CHAR)0xff;
[551]415 break;
416 }
417 WinDismissDlg(hwnd, 0);
418 }
[2]419 break;
[551]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;
[2]429 }
[551]430 return WinDefDlgProc(hwnd, msg, mp1, mp2);
[2]431}
[783]432
433#pragma alloc_text(OBJCNR,ProcessDir,FillCnrsThread,ObjCnrDlgProc)
Note: See TracBrowser for help on using the repository browser.