source: trunk/dll/objcnr.c@ 1225

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

Ticket 187: Moved typedef's and some #define's from fm3dll.h

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