source: trunk/dll/objcnr.c@ 985

Last change on this file since 985 was 985, checked in by Gregg Young, 17 years ago

Update sizes dialog (ticket 44); Make max command line length user settable (ticket 199); use xfree for free in most cases (ticket 212); initial code to check for valid ini file (ticket 102); Some additional refactoring and structure rework; Some documentation updates;

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