source: trunk/dll/objcnr.c@ 1211

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

Ticket 187: Move data declarations/definitions out of fm3dll.h

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