source: trunk/dll/objcnr.c @ 731

Last change on this file since 731 was 731, checked in by Steven Levine, 13 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.