source: trunk/dll/objcnr.c@ 731

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

Correct ticket 24 pointer errors for Gregg

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