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
RevLine 
[159]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
[574]9 Copyright (c) 2005, 2007 Steven H. Levine
[159]10
11 24 May 05 SHL Rework for CNRITEM.szSubject
[349]12 13 Jul 06 SHL Use Runtime_Error
[488]13 01 Sep 06 SHL Do not complain for normal cancel
[517]14 19 Oct 06 SHL Correct . and .. detect
[531]15 03 Nov 06 SHL Renames
[574]16 22 Mar 07 GKY Use QWL_USER
[751]17 01 Aug 07 SHL Rework to sync with CNRITEM mods
[756]18 03 Aug 07 GKY Enlarged and made setable everywhere Findbuf (speed file loading)
[775]19 06 Aug 07 GKY Reduce DosSleep times (ticket 148)
[783]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
[787]22 14 Aug 07 SHL Revert ProcessDir DosSleep to 0
[985]23 29 Feb 08 GKY Use xfree where appropriate
[159]24
25***********************************************************************/
26
[907]27#include <stdlib.h>
28#include <string.h>
29#include <ctype.h>
[1163]30#include <process.h> // _beginthread
[907]31
[2]32#define INCL_DOS
33#define INCL_WIN
[783]34#define INCL_DOSERRORS
[841]35#define INCL_LONGLONG
[2]36
[1188]37#include "fm3dll.h"
[1225]38#include "fm3dll2.h" // #define's for UM_*, control id's, etc.
[1211]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
[2]44#include "fm3dlg.h"
45#include "fm3str.h"
[1163]46#include "errutil.h" // Dos_Error...
47#include "strutil.h" // GetPString
48#include "objcnr.h"
[1188]49#include "notify.h" // Notify
50#include "wrappers.h" // xDosFindNext
[1163]51#include "select.h" // ExpandAll
[1188]52#include "valid.h" // IsRoot
53#include "misc.h" // PostMsg
[1017]54#include "fortify.h"
55
[551]56typedef struct
57{
[2]58 CHAR *filename;
[551]59 HWND hwndCnr;
[2]60 CHAR *stopflag;
[551]61}
62DIRSIZE;
[2]63
[551]64typedef struct
65{
[2]66 CHAR *dirname;
[551]67 CHAR stopflag;
68 BOOL dying;
69 BOOL working;
70}
71TEMP;
[2]72
[349]73#pragma data_seg(DATA1)
[2]74
[349]75static PSZ pszSrcFile = __FILE__;
[2]76
[349]77static HWND objcnrwnd;
[2]78
[783]79static VOID ProcessDir(HWND hwndCnr,
[1163]80 CHAR *filename,
81 PCNRITEM pciParent,
82 CHAR *stopflag)
[349]83{
[551]84 CHAR maskstr[CCHMAXPATH], *endpath, *p;
[783]85 ULONG ulFindCnt, ulFindMax;
86 ULONG ulBufBytes;
[551]87 HDIR hdir;
[841]88 PFILEFINDBUF3L pffbArray;
[551]89 APIRET rc;
90 RECORDINSERT ri;
91 PCNRITEM pciP;
[783]92 HPOINTER hptr;
[2]93
[841]94 ulBufBytes = sizeof(FILEFINDBUF3L) * FilesToGet;
[783]95 pffbArray = xmalloc(ulBufBytes, pszSrcFile, __LINE__);
96 if (!pffbArray)
[1163]97 return; // Error already reported
[551]98 strcpy(maskstr, filename);
99 if (maskstr[strlen(maskstr) - 1] != '\\')
100 strcat(maskstr, "\\");
[2]101 endpath = &maskstr[strlen(maskstr)];
[551]102 strcat(maskstr, "*");
[2]103 hdir = HDIR_CREATE;
[783]104 ulFindCnt = 1;
[838]105 rc = xDosFindFirst(filename, &hdir,
[1163]106 FILE_NORMAL | FILE_READONLY | FILE_ARCHIVED |
107 FILE_SYSTEM | FILE_HIDDEN | MUST_HAVE_DIRECTORY,
108 pffbArray, ulBufBytes, &ulFindCnt, FIL_STANDARDL);
[551]109 if (!rc)
[2]110 DosFindClose(hdir);
[783]111 // work around furshluginer FAT root bug
112 else if (IsRoot(filename))
113 rc = 0;
[2]114
[783]115 if ((!rc && (pffbArray->attrFile & FILE_DIRECTORY))) {
[731]116 pciP = WinSendMsg(hwndCnr,
[1163]117 CM_ALLOCRECORD,
118 MPFROMLONG(EXTRA_RECORD_BYTES),
119 MPFROMLONG(1));
[551]120 if (!pciP) {
[783]121 Win_Error(hwndCnr, HWND_DESKTOP, pszSrcFile, __LINE__, "CM_ALLOCRECORD");
[1039]122 free(pffbArray);
[2]123 return;
124 }
[730]125 pciP->pszFileName = xstrdup(filename, pszSrcFile, __LINE__);
[751]126 pciP->pszDispAttr = NullStr;
127 pciP->pszSubject = NullStr;
[762]128 pciP->pszLongName = NullStr;
[551]129 if (strlen(filename) < 4)
[751]130 pciP->pszDisplayName = pciP->pszFileName;
[2]131 else {
[730]132 p = strrchr(pciP->pszFileName, '\\');
[551]133 if (!p)
[1163]134 pciP->pszDisplayName = pciP->pszFileName;
[551]135 else if (*(p + 1))
[1163]136 p++;
[751]137 pciP->pszDisplayName = p;
[2]138 }
[751]139 pciP->rc.pszIcon = pciP->pszDisplayName;
[551]140 if (fForceUpper)
[730]141 strupr(pciP->pszFileName);
[551]142 else if (fForceLower)
[730]143 strlwr(pciP->pszFileName);
[2]144 pciP->rc.flRecordAttr |= CRA_RECORDREADONLY;
145 }
146 else {
[1039]147 free(pffbArray);
[783]148 Dos_Error(MB_ENTER, rc, HWND_DESKTOP, pszSrcFile, __LINE__,
[1163]149 GetPString(IDS_CANTFINDDIRTEXT), filename);
[2]150 return;
151 }
152
[783]153 hptr = WinLoadFileIcon(pciP->pszFileName, FALSE);
154 if (hptr)
155 pciP->rc.hptrIcon = hptr;
156
[1163]157 if (!pciP->rc.hptrIcon || pciP->rc.hptrIcon == hptrFile) /* OS/2 bug bug bug bug */
[2]158 pciP->rc.hptrIcon = hptrDir;
[783]159
[551]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;
[771]165 ri.cRecordsInsert = 1;
[551]166 ri.fInvalidateRecord = TRUE;
167 if (!WinSendMsg(hwndCnr, CM_INSERTRECORD, MPFROMP(pciP), MPFROMP(&ri))) {
[1039]168 free(pffbArray);
[2]169 return;
170 }
171 hdir = HDIR_CREATE;
[551]172 if (!isalpha(*maskstr) || maskstr[1] != ':' || maskstr[2] != '\\' ||
173 ((driveflags[toupper(*maskstr) - 'A'] & DRIVE_REMOTE) && fRemoteBug))
[783]174 ulFindMax = 1;
[2]175 else
[783]176 ulFindMax = FilesToGet;
177 ulFindCnt = ulFindMax;
[838]178 rc = xDosFindFirst(maskstr, &hdir,
[1163]179 FILE_NORMAL | FILE_READONLY | FILE_ARCHIVED |
180 FILE_SYSTEM | FILE_HIDDEN | MUST_HAVE_DIRECTORY,
181 pffbArray, ulBufBytes, &ulFindCnt, FIL_STANDARDL);
[551]182 if (!rc) {
[841]183 PFILEFINDBUF3L pffbFile;
[551]184 ULONG x;
[2]185
[551]186 while (!rc) {
[783]187 pffbFile = pffbArray;
188 for (x = 0; x < ulFindCnt; x++) {
[1163]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);
[783]202 } // for
[1163]203 DosSleep(0); // Let's others at same priority get some work done
[551]204 if (*stopflag)
[1163]205 break;
[783]206 ulFindCnt = ulFindMax;
[850]207 rc = xDosFindNext(hdir, pffbArray, ulBufBytes, &ulFindCnt, FIL_STANDARDL);
[783]208 } // while
[2]209 DosFindClose(hdir);
210 }
[783]211
212 if (rc && rc != ERROR_NO_MORE_FILES) {
213 Dos_Error(MB_ENTER, rc, HWND_DESKTOP, pszSrcFile, __LINE__,
[1163]214 GetPString(IDS_CANTFINDDIRTEXT), filename);
[783]215 }
216
[1039]217 free(pffbArray);
[551]218 WinSendMsg(hwndCnr, CM_INVALIDATERECORD, MPFROMP(&pciP),
[1163]219 MPFROM2SHORT(1, 0));
[2]220}
221
[551]222static VOID FillCnrsThread(VOID * args)
[349]223{
[551]224 HAB hab;
225 HMQ hmq;
[783]226 DIRSIZE *dirsize = (DIRSIZE *)args;
[2]227
[1038]228# ifdef FORTIFY
229 Fortify_EnterScope();
[1063]230# endif
[783]231 if (!dirsize) {
232 Runtime_Error(pszSrcFile, __LINE__, "no data");
[2]233 return;
[783]234 }
[2]235
236 DosError(FERR_DISABLEHARDERR);
237
238 hab = WinInitialize(0);
[551]239 if (hab) {
240 hmq = WinCreateMsgQueue(hab, 0);
241 if (hmq) {
242 WinCancelShutdown(hmq, TRUE);
243 ProcessDir(dirsize->hwndCnr, dirsize->filename, (PCNRITEM) NULL,
[1163]244 dirsize->stopflag);
[2]245 DosPostEventSem(CompactSem);
246 WinDestroyMsgQueue(hmq);
247 }
248 WinTerminate(hab);
249 }
[551]250 PostMsg(WinQueryWindow(dirsize->hwndCnr, QW_PARENT), UM_CONTAINER_FILLED,
[1163]251 MPVOID, MPVOID);
[1039]252 free(dirsize);
[1017]253# ifdef FORTIFY
254 Fortify_LeaveScope();
[1063]255# endif
[2]256}
257
[551]258MRESULT EXPENTRY ObjCnrDlgProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
[349]259{
[2]260 TEMP *data;
261
[551]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,
[1163]267 SWP_RESTORE | SWP_SHOW | SWP_ACTIVATE | SWP_ZORDER);
[551]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 }
[1009]282 data->dirname = (CHAR *)mp2;
[574]283 WinSetWindowPtr(hwnd, QWL_USER, (PVOID) data);
[551]284 if (*data->dirname)
285 WinSetDlgItemText(hwnd, OBJCNR_DIR, data->dirname);
286 {
287 DIRSIZE *dirsize;
[1063]288# ifdef FORTIFY
289 Fortify_EnterScope();
290# endif
[551]291 dirsize = xmalloc(sizeof(DIRSIZE), pszSrcFile, __LINE__);
292 if (!dirsize) {
[1163]293 WinDismissDlg(hwnd, 0);
294 break;
[2]295 }
[1009]296 dirsize->stopflag = (CHAR *)&data->stopflag;
[551]297 dirsize->filename = data->dirname;
298 dirsize->hwndCnr = WinWindowFromID(hwnd, OBJCNR_CNR);
299 if (_beginthread(FillCnrsThread, NULL, 65536 * 8, (PVOID) dirsize) ==
[1163]300 -1) {
301 Runtime_Error(pszSrcFile, __LINE__,
302 GetPString(IDS_COULDNTSTARTTHREADTEXT));
[1039]303 free(dirsize);
[1063]304# ifdef FORTIFY
305 Fortify_LeaveScope();
306# endif
[1163]307 WinDismissDlg(hwnd, 0);
308 break;
[349]309 }
[551]310 else
[1163]311 data->working = TRUE;
[551]312 }
313 PostMsg(hwnd, UM_SETUP, MPVOID, MPVOID);
314 break;
[2]315
[551]316 case UM_SETUP:
317 // WinEnableWindowUpdate(WinWindowFromID(hwnd,OBJCNR_CNR),FALSE);
318 {
319 CNRINFO cnri;
[2]320
[551]321 memset(&cnri, 0, sizeof(CNRINFO));
322 cnri.cb = sizeof(CNRINFO);
323 WinSendDlgItemMsg(hwnd, OBJCNR_CNR, CM_QUERYCNRINFO,
[1163]324 MPFROMP(&cnri), MPFROMLONG(sizeof(CNRINFO)));
[551]325 cnri.cyLineSpacing = 0;
326 cnri.cxTreeIndent = 12L;
327 cnri.pszCnrTitle = GetPString(IDS_WORKINGTEXT);
328 cnri.flWindowAttr = CV_TREE | CV_FLOW |
[1163]329 CA_CONTAINERTITLE | CA_TITLESEPARATOR | CA_TREELINE;
[551]330 if (WinQueryWindowUShort(hwnd, QWS_ID) == QTREE_FRAME)
[1163]331 cnri.flWindowAttr |= CV_MINI;
[551]332 WinSendDlgItemMsg(hwnd, OBJCNR_CNR, CM_SETCNRINFO, MPFROMP(&cnri),
[1163]333 MPFROMLONG(CMA_FLWINDOWATTR | CMA_LINESPACING |
334 CMA_CXTREEINDENT));
[551]335 }
336 return 0;
[2]337
[551]338 case UM_CONTAINER_FILLED:
339 WinSetDlgItemText(hwnd, OBJCNR_NOTE, NullStr);
[2]340// WinEnableWindowUpdate(WinWindowFromID(hwnd,OBJCNR_CNR),TRUE);
[551]341 WinSendDlgItemMsg(hwnd, OBJCNR_CNR, CM_INVALIDATERECORD, MPVOID,
[1163]342 MPFROM2SHORT(0, CMA_ERASE | CMA_INVALIDATE));
[551]343 data = INSTDATA(hwnd);
344 if (data) {
345 data->working = FALSE;
346 if (data->dying)
[1163]347 WinDismissDlg(hwnd, 0);
[551]348 {
[1163]349 PCNRITEM pci;
350 USHORT id;
[2]351
[1163]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 }
[2]372 }
[551]373 }
374 return 0;
[2]375
[551]376 case WM_CONTROL:
377 switch (SHORT1FROMMP(mp1)) {
378 case OBJCNR_CNR:
379 if (SHORT2FROMMP(mp1) == CN_ENTER) {
[2]380
[1163]381 PCNRITEM pci = (PCNRITEM) ((PNOTIFYRECORDENTER) mp2)->pRecord;
[2]382
[1163]383 if (pci && (INT) pci != -1)
384 WinSendDlgItemMsg(hwnd, DID_OK, BM_CLICK, MPVOID, MPVOID);
[2]385 }
[551]386 break;
387 }
388 return 0;
[2]389
[551]390 case WM_COMMAND:
391 switch (SHORT1FROMMP(mp1)) {
392 case IDM_HELP:
393 if (hwndHelp) {
[2]394
[1163]395 USHORT id;
[2]396
[1163]397 id = WinQueryWindowUShort(hwnd, QWS_ID);
[2]398
[1163]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));
[551]407 }
408 break;
[2]409
[551]410 case OBJCNR_DESKTOP:
411 case DID_OK:
412 data = INSTDATA(hwnd);
413 if (data) {
[2]414
[1163]415 PCNRITEM pci;
[2]416
[1163]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);
[2]432 }
[551]433 break;
[2]434
[551]435 case DID_CANCEL:
[2]436 data = INSTDATA(hwnd);
[551]437 if (data) {
[1163]438 if (data->working) {
439 data->dying = (CHAR)TRUE;
440 data->stopflag = (CHAR)0xff;
441 break;
442 }
443 WinDismissDlg(hwnd, 0);
[551]444 }
[2]445 break;
[551]446 }
447 return 0;
448
449 case WM_DESTROY:
450 objcnrwnd = (HWND) 0;
451 data = INSTDATA(hwnd);
[1009]452 xfree(data, pszSrcFile, __LINE__);
[551]453 break;
[2]454 }
[551]455 return WinDefDlgProc(hwnd, msg, mp1, mp2);
[2]456}
[783]457
458#pragma alloc_text(OBJCNR,ProcessDir,FillCnrsThread,ObjCnrDlgProc)
Note: See TracBrowser for help on using the repository browser.