source: trunk/dll/objcnr.c@ 1211

Last change on this file since 1211 was 1211, checked in by John Small, 17 years ago

Ticket 187: Move data declarations/definitions out of fm3dll.h

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