source: trunk/dll/objcnr.c@ 762

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

Use two pass logic to free CNRITEMs and ARCITEMs
Rename pszLongname to pszLongName
More compare directories rework
Make directory sizes item draw placement deterministic - how did it ever work?

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