source: trunk/dll/objcnr.c@ 1394

Last change on this file since 1394 was 1394, checked in by Steven Levine, 17 years ago

Ticket 340: Convert GetPString to use STRINGTABLE.

Drop fm3dll.str and mkstr.exe from makefiles and wpi builders

Convert many functions to expect PCSZ arguments.
Correct walk, compare and dirsizes dialog setups to ignore saved dialog size
Drop copyright.c logic from makefile

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