source: trunk/dll/walkem.c@ 1844

Last change on this file since 1844 was 1673, checked in by Gregg Young, 13 years ago

Update to Doxygen comment style Ticket 55. Also some minor code cleanup.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 45.6 KB
Line 
1
2/***********************************************************************
3
4 $Id: walkem.c 1673 2012-12-30 18:51:01Z gyoung $
5
6 Misc persistent lists support
7
8 Copyright (c) 1993-98 M. Kimes
9 Copyright (c) 2005, 2009 Steven H. Levine
10
11 01 Aug 04 SHL Rework lstrip/rstrip usage
12 05 Jun 05 SHL Use QWL_USER
13 13 Aug 05 SHL Run through indent
14 13 Aug 05 SHL remove_udir - avoid corrupting last dirs list
15 17 Jul 06 SHL Use Runtime_Error
16 29 Jul 06 SHL Use xfgets
17 20 Oct 06 SHL Correct . .. check
18 06 Nov 06 SHL Oops - need to allow .. here
19 14 Nov 06 SHL Correct FillPathListBox regression
20 22 Mar 07 GKY Use QWL_USER
21 20 Apr 07 SHL Avoid spurious add_udir error reports
22 16 Aug 07 SHL Update add_setups for ticket# 109
23 19 Aug 07 SHL Correct load_setups error reporting
24 20 Aug 07 GKY Move #pragma alloc_text to end for OpenWatcom compat
25 25 Aug 07 SHL Correct #pragma alloc_text typos
26 11 Nov 07 GKY Cancel now directly closes dialog even if directory path text has changed
27 20 Jan 08 GKY Walk & walk2 dialogs now save and restore size and position
28 19 Feb 08 JBS Add "State at last FM/2 close" to the states combo box
29 29 Feb 08 GKY Use xfree where appropriate
30 29 Feb 08 GKY Refactor global command line variables to notebook.h
31 19 Jun 08 JBS Ticket 227: Allow temporary saving/deleting of the shutdown state of directory containers
32 22 Jun 08 GKY Add free_?dir for fortify testing
33 18 Jul 08 SHL More Fortify support
34 19 Jul 08 GKY Replace save_dir2(dir) with pFM2SaveDirectory and use BldFullPathName
35 24 Aug 08 GKY Warn full drive on save of .DAT file; prevent loss of existing file
36 28 Jun 09 GKY Added AddBackslashToPath() to remove repeatative code.
37 06 Oct 09 SHL Ctrl-select selects Walk Dialog listbox entry, but suppresses action
38 17 JAN 10 GKY Changes to get working with Watcom 1.9 Beta (1/16/10). Mostly cast CHAR CONSTANT * as CHAR *.
39 12 Aug 12 GKY Allow for selection of include subdirectories or a list file on initial startup of compare dirs
40
41***********************************************************************/
42
43#include <stdlib.h>
44#include <string.h>
45#include <ctype.h>
46#include <share.h>
47
48#define INCL_WIN
49#define INCL_DOS
50#define INCL_DOSERRORS
51#define INCL_SHLERRORS // PMERR_NOT_IN_IDX
52#define INCL_LONGLONG
53
54#include "fm3dll.h"
55#include "fm3dll2.h" // #define's for UM_*, control id's, etc.
56#include "arccnrs.h" // Data declaration(s)
57#include "info.h" // Data declaration(s)
58#include "init.h" // Data declaration(s)
59#include "mainwnd.h" // Data declaration(s)
60#include "fm3dlg.h"
61#include "fm3str.h"
62#include "errutil.h" // Dos_Error...
63#include "strutil.h" // GetPString
64#include "notebook.h" // targetdirectory
65#include "pathutil.h" // BldFullPathName
66#include "walkem.h"
67#include "valid.h" // MakeFullName
68#include "chklist.h" // PosOverOkay
69#include "mkdir.h" // SetDir
70#include "wrappers.h" // xfgets
71#include "strips.h" // bstrip
72#include "misc.h" // CheckDriveSpaceAvail
73#include "dirs.h" // save_dir2
74#include "fortify.h"
75
76typedef struct
77{
78 USHORT size;
79 USHORT changed;
80 BOOL nounwriteable;
81 CHAR szCurrentPath[CCHMAXPATH];
82 CHAR *szReturnPath;
83}
84WALKER;
85
86static MRESULT EXPENTRY WalkTwoDlgProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2);
87static VOID load_setups(VOID);
88static BOOL remove_ldir(PSZ path);
89
90// Data definitions
91#pragma data_seg(DATA1)
92
93static PSZ pszSrcFile = __FILE__;
94static CHAR WalkFont[CCHMAXPATH] = "";
95static ULONG WalkFontSize = sizeof(WalkFont);
96
97/**
98 * States names management
99 */
100
101static BOOL fSetupsLoaded;
102static LINKDIRS *pFirstSetup;
103static const PSZ pszLastSetups = "LastSetups";
104// 18 Aug 07 SHL fixme to stop supporting old style 1 year from now?
105static const ULONG ulOldSetupsBytes = 100 * 13; // Prior to 3.0.7
106
107#pragma data_seg(GLOBAL1)
108BOOL fUdirsChanged;
109BOOL loadedudirs;
110
111#pragma data_seg(GLOBAL2)
112LINKDIRS *ldirhead;
113LINKDIRS *udirhead;
114
115/**
116 * Fill States drop down list with known state names
117 */
118
119VOID fill_setups_list(VOID)
120{
121 WinSendMsg(hwndStatelist, LM_DELETEALL, MPVOID, MPVOID);
122 if (fUserComboBox) {
123 LINKDIRS *pld;
124 load_setups();
125 for (pld = pFirstSetup; pld; pld = pld->next) {
126 // DbgMsg(pszSrcFile, __LINE__, "Inserted %s", pld->path);
127 WinSendMsg(hwndStatelist,
128 LM_INSERTITEM,
129 MPFROM2SHORT(LIT_SORTASCENDING, 0),
130 MPFROMP(pld->path));
131 }
132 WinSetWindowText(hwndStatelist, (CHAR *) GetPString(IDS_STATETEXT));
133 }
134}
135
136/**
137 * Lookup setup and do requested action
138 * @param - action, Support old/new style storage method
139 * @return 1 if found and action OK, 0 if not found and action OK, -1 if error during action
140 */
141
142#define LS_FIND 0
143#define LS_ADD 1
144#define LS_DELETE 2
145
146static INT lookup_setup(PCSZ name, UINT action)
147{
148 LINKDIRS *pld;
149 LINKDIRS *pldLast = NULL;
150
151 if (!name || !*name) {
152 Runtime_Error(pszSrcFile, __LINE__, NULL);
153 return -1;
154 }
155
156 load_setups();
157
158 for (pld = pFirstSetup; pld; pld = pld->next) {
159 if (!stricmp(pld->path, name)) {
160 if (action == LS_DELETE) {
161 if (pldLast)
162 pldLast->next = pld->next;
163 else
164 pFirstSetup = pld->next;
165 xfree(pld->path, pszSrcFile, __LINE__);
166 free(pld);
167 }
168 return 1; // Found or added
169 }
170 pldLast = pld; // In case deleting
171 } // for
172
173 // Not found
174 if (action == LS_ADD) {
175 pld = xmalloc(sizeof(LINKDIRS), pszSrcFile, __LINE__);
176 if (!pld)
177 return -1;
178 pld->path = xstrdup(name, pszSrcFile, __LINE__);
179 if (!pld->path) {
180 free(pld);
181 return -1;
182 }
183 // Insert at front of list - drop down will sort
184 pld->next = pFirstSetup;
185 pFirstSetup = pld;
186 return 0;
187 }
188
189 return FALSE; // Not found
190}
191
192/**
193 * Load state names from ini
194 * Support old/new style storage method
195 */
196
197VOID load_setups(VOID)
198{
199 ULONG ulDataBytes;
200 ULONG l;
201 PSZ pszBuf;
202 PSZ psz;
203 LINKDIRS *pld;
204
205 if (fSetupsLoaded)
206 return;
207
208 if (!PrfQueryProfileSize(fmprof, FM3Str, pszLastSetups, &ulDataBytes)) {
209 // fixme to use generic hab
210 ERRORID eid = WinGetLastError((HAB)0);
211 if ((eid & 0xffff) != PMERR_NOT_IN_IDX) {
212 // Get error info back
213 PrfQueryProfileSize(fmprof, FM3Str, pszLastSetups, &ulDataBytes);
214 Win_Error(HWND_DESKTOP, HWND_DESKTOP, pszSrcFile, __LINE__, PCSZ_PRFQUERYPROFILESIZE);
215 }
216 else
217 fSetupsLoaded = TRUE; // Nothing saved
218 return;
219 }
220
221 if (ulDataBytes == 0) {
222 Runtime_Error(pszSrcFile, __LINE__, PCSZ_PRFQUERYPROFILESIZE);
223 return;
224 }
225
226 pszBuf = xmalloc(ulDataBytes + 1, pszSrcFile, __LINE__); // One extra for end marker
227 if (!pszBuf)
228 return;
229 l = ulDataBytes;
230 if (!PrfQueryProfileData(fmprof, FM3Str, pszLastSetups, pszBuf, &l)) {
231 Win_Error(HWND_DESKTOP, HWND_DESKTOP, pszSrcFile, __LINE__, PCSZ_PRFQUERYPROFILEDATA);
232 free(pszBuf);
233 return;
234 }
235
236 if (ulDataBytes != l) {
237 Runtime_Error(pszSrcFile, __LINE__, "PrfQueryProfileData reported %u expected %u", l, ulDataBytes);
238 free(pszBuf);
239 return;
240 }
241
242 *(pszBuf + ulDataBytes) = 0; // Insert end marker
243
244 psz = pszBuf;
245 if (!*psz && ulDataBytes == ulOldSetupsBytes)
246 psz += 13; // Rarely used 1st fixed width entry prior to 3.0.7
247
248 while (*psz) {
249 pld = xmalloc(sizeof(LINKDIRS), pszSrcFile, __LINE__);
250 if (!pld) {
251 free(pszBuf);
252 return;
253 }
254
255# ifdef FORTIFY
256 Fortify_SetOwner(pld, 1);
257 Fortify_SetScope(pld, 1);
258# endif
259
260 pld->path = xstrdup(psz, pszSrcFile, __LINE__);
261 if (!pld->path) {
262 free(pszBuf);
263 free(pld);
264 return;
265 }
266
267# ifdef FORTIFY
268 Fortify_SetOwner(pld->path, 1);
269 Fortify_SetScope(pld->path, 1);
270# endif
271
272 // Insert at front of list - drop down will sort
273 pld->next = pFirstSetup;
274 pFirstSetup = pld;
275 // DbgMsg(pszSrcFile, __LINE__, "Inserted %s", pld->path);
276
277 if (ulDataBytes == ulOldSetupsBytes)
278 psz += 13; // Buffers fixed width prior to 3.0.7
279 else
280 psz += strlen(psz) + 1;
281 } // while
282
283 free(pszBuf);
284
285 fSetupsLoaded = TRUE;
286}
287
288VOID save_setups(VOID)
289{
290 ULONG ulBufBytes;
291 ULONG ulFillBytes;
292 ULONG l;
293 PSZ pszBuf;
294 PSZ psz;
295 LINKDIRS *pld;
296
297 if (!fSetupsLoaded)
298 return;
299
300 ulBufBytes = 0;
301 for (pld = pFirstSetup; pld; pld = pld->next) {
302 ulBufBytes += strlen(pld->path) + 1;
303 } // for
304
305 if (!ulBufBytes)
306 pszBuf = NULL;
307 else {
308 // Ensure different than size prior to 3.0.7
309 ulFillBytes = ulBufBytes == ulOldSetupsBytes ? 1 : 0;
310 pszBuf = xmalloc(ulBufBytes + ulFillBytes, pszSrcFile, __LINE__);
311 if (!pszBuf)
312 return;
313
314 psz = pszBuf;
315 for (pld = pFirstSetup; pld; pld = pld->next) {
316 l = strlen(pld->path) + 1;
317 memcpy(psz, pld->path, l);
318 psz += l;
319 } // for
320 if (ulFillBytes)
321 *psz = 0;
322 }
323
324 if (!PrfWriteProfileData(fmprof,
325 FM3Str,
326 pszLastSetups, pszBuf, ulBufBytes)) {
327 ERRORID eid = WinGetLastError((HAB)0);
328 if ((eid & 0xffff) != PMERR_NOT_IN_IDX)
329 Runtime_Error(pszSrcFile, __LINE__, "PrfWriteProfileData returned %u", eid);
330 }
331
332 // Delete obsolete INI entry
333 PrfWriteProfileData(fmprof, FM3Str, "LastSetup", NULL, 0);
334}
335
336/**
337 * Add named state to setups list
338 * @return same as lookup_setup
339 */
340
341INT add_setup(PCSZ name)
342{
343 return lookup_setup(name, LS_ADD);
344}
345
346/**
347 * Delete named state from setups list
348 * @return same as lookup_setup
349 */
350
351INT remove_setup(PSZ name)
352{
353 return lookup_setup(name, LS_DELETE);
354}
355
356#ifdef FORTIFY
357
358VOID free_setups(VOID)
359{
360 LINKDIRS *pld = pFirstSetup;
361 while (pld) {
362 LINKDIRS *next = pld->next;
363 free(pld->path);
364 free(pld);
365 pld = next;
366 }
367 pFirstSetup = NULL;
368}
369
370#endif // FORTIFY
371
372VOID load_udirs(VOID)
373{
374 // load linked list of user directories from USERDIRS.DAT file
375
376 FILE *fp;
377 LINKDIRS *info;
378 LINKDIRS *last = NULL;
379 CHAR s[CCHMAXPATH + 24];
380 CHAR *moder = "r";
381
382 if (udirhead)
383 free_udirs();
384 loadedudirs = TRUE;
385 fUdirsChanged = FALSE;
386 BldFullPathName(s, pFM2SaveDirectory, PCSZ_USERDIRSDAT);
387 fp = xfsopen(s, moder, SH_DENYWR, pszSrcFile, __LINE__, TRUE);
388 if (fp) {
389 while (!feof(fp)) {
390 if (!xfgets(s, CCHMAXPATH + 24, fp, pszSrcFile, __LINE__))
391 break;
392 s[CCHMAXPATH] = 0;
393 bstripcr(s);
394 if (*s && *s != ';') {
395 info = xmalloc(sizeof(LINKDIRS), pszSrcFile, __LINE__);
396# ifdef FORTIFY
397 Fortify_SetOwner(info, 1);
398 Fortify_SetScope(info, 1);
399# endif
400 if (info) {
401 info->path = xstrdup(s, pszSrcFile, __LINE__);
402 if (!info->path)
403 free(info);
404 else {
405# ifdef FORTIFY
406 Fortify_SetOwner(info->path, 1);
407 Fortify_SetScope(info->path, 1);
408# endif
409 info->next = NULL;
410 if (!udirhead)
411 udirhead = info;
412 else
413 last->next = info;
414 last = info;
415 }
416 }
417 }
418 }
419 fclose(fp);
420 }
421}
422
423VOID save_udirs(VOID)
424{
425 FILE *fp;
426 LINKDIRS *info;
427 CHAR s[CCHMAXPATH + 14];
428 CHAR *modew = "w";
429
430 if (loadedudirs) {
431 fUdirsChanged = FALSE;
432 if (udirhead) {
433 BldFullPathName(s, pFM2SaveDirectory, PCSZ_USERDIRSDAT);
434 if (CheckDriveSpaceAvail(s, ullDATFileSpaceNeeded, 1) == 2)
435 return; //already gave error msg
436 fp = xfopen(s, modew, pszSrcFile, __LINE__, FALSE);
437 if (fp) {
438 fputs(GetPString(IDS_USERDEFDIRSTEXT), fp);
439 info = udirhead;
440 while (info) {
441 fprintf(fp, "%0.*s\n", CCHMAXPATH, info->path);
442 info = info->next;
443 }
444 fclose(fp);
445 }
446 }
447 }
448}
449
450/**
451 * Add path to user directory list or last used directory list.
452 * Callers need to check fUdirsChanged to know if user dirs change occured.
453 * Callers need to check return code to know if last dirs change occured.
454 * @param userdirs TRUE to process user directory list. Otherwise last used list.
455 * @return TRUE if added, FALSE if already in list or error.
456 */
457
458BOOL add_udir(BOOL userdirs, CHAR *inpath)
459{
460 CHAR path[CCHMAXPATH];
461 LINKDIRS *info;
462 LINKDIRS *last = NULL;
463 LINKDIRS *temp;
464
465 if (inpath && *inpath) {
466 if (DosQueryPathInfo(inpath, FIL_QUERYFULLNAME, path, sizeof(path)))
467 strcpy(path, inpath);
468 if (!userdirs && IsRoot(path))
469 return FALSE;
470 if (IsFullName(path)) {
471 if (!loadedudirs)
472 load_udirs();
473 // Search user dir list first unless doing last dirs
474 info = userdirs ? udirhead : ldirhead;
475 while (info) {
476 if (!stricmp(info->path, path))
477 return FALSE; // Already in list
478 last = info; // Remember append to location
479 info = info->next;
480 }
481 // Search last dir list unless doing just last dirs
482 if (!userdirs) {
483 info = udirhead;
484 while (info) {
485 if (!stricmp(info->path, path))
486 return FALSE;
487 info = info->next;
488 }
489 }
490 else {
491 // if adding manual directory, remove from auto list if present
492 info = ldirhead;
493 temp = NULL;
494 while (info) {
495 if (!stricmp(info->path, path)) {
496 if (temp)
497 temp->next = info->next;
498 else
499 ldirhead = info->next;
500 xfree(info->path, pszSrcFile, __LINE__);
501 free(info);
502 break;
503 }
504 temp = info;
505 info = info->next;
506 }
507 }
508 // Append entry to end of user dirs list
509 info = xmalloc(sizeof(LINKDIRS), pszSrcFile, __LINE__);
510 if (info) {
511# ifdef FORTIFY
512 Fortify_SetScope(info, 1);
513# endif
514 info->path = xstrdup(path, pszSrcFile, __LINE__);
515 if (!info->path)
516 free(info);
517 else {
518# ifdef FORTIFY
519 Fortify_SetScope(info->path, 1);
520# endif
521 info->next = NULL;
522 if (userdirs) {
523 fUdirsChanged = TRUE;
524 if (!udirhead)
525 udirhead = info;
526 else
527 last->next = info;
528 }
529 else {
530 if (!ldirhead)
531 ldirhead = info;
532 else
533 last->next = info;
534 }
535 return TRUE;
536 }
537 }
538 }
539 }
540 return FALSE;
541}
542
543//=== remove_udir - remove path from user dir list or last directory list ===
544
545BOOL remove_udir(CHAR * path)
546{
547 LINKDIRS *info;
548 LINKDIRS *last = NULL;
549
550 if (path && *path) {
551 if (!loadedudirs)
552 load_udirs();
553 info = udirhead;
554 while (info) {
555 if (!stricmp(info->path, path)) {
556 if (last)
557 last->next = info->next;
558 else
559 udirhead = info->next;
560 xfree(info->path, pszSrcFile, __LINE__);
561 free(info);
562 fUdirsChanged = TRUE;
563 return TRUE;
564 }
565 last = info;
566 info = info->next;
567 }
568
569 info = ldirhead;
570 last = NULL;
571 while (info) {
572 if (!stricmp(info->path, path)) {
573 if (last)
574 last->next = info->next;
575 else
576 ldirhead = info->next;
577 xfree(info->path, pszSrcFile, __LINE__);
578 free(info);
579 return TRUE;
580 }
581 last = info;
582 info = info->next;
583 }
584 }
585 return FALSE;
586}
587
588BOOL remove_ldir(CHAR * path)
589{
590 LINKDIRS *info;
591 LINKDIRS *last = NULL;
592
593 if (path && *path) {
594 info = ldirhead;
595 while (info) {
596 if (!stricmp(info->path, path)) {
597 if (last)
598 last->next = info->next;
599 else
600 ldirhead = info->next;
601 xfree(info->path, pszSrcFile, __LINE__);
602 free(info);
603 return TRUE;
604 }
605 last = info;
606 info = info->next;
607 }
608 }
609 return FALSE;
610}
611
612# ifdef FORTIFY
613
614VOID free_ldir(VOID)
615{
616 LINKDIRS *info, *next;
617
618 info = ldirhead;
619 while (info) {
620 next = info->next;
621 xfree(info->path, pszSrcFile, __LINE__);
622 free(info);
623 info = next;
624 }
625 ldirhead = NULL;
626}
627
628# endif
629
630VOID free_udirs(VOID)
631{
632 LINKDIRS *info, *next;
633
634 info = udirhead;
635 while (info) {
636 next = info->next;
637 xfree(info->path, pszSrcFile, __LINE__);
638 free(info);
639 info = next;
640 }
641 udirhead = NULL;
642}
643
644VOID FillPathListBox(HWND hwnd, HWND hwnddrive, HWND hwnddir, CHAR * pszPath,
645 BOOL nounwriteable)
646{
647 /**
648 * this function fills one or two list boxes with drive and directory
649 * information showing all available drives and all directories off of
650 * the directory represented by path. This works independently of the
651 * current directory.
652 */
653
654 CHAR szDrive[] = " :", szTemp[1032];
655 FILEFINDBUF3 findbuf;
656 HDIR hDir = HDIR_CREATE;
657 SHORT sDrive;
658 ULONG ulDriveNum, ulSearchCount = 1, ulDriveMap;
659
660 DosError(FERR_DISABLEHARDERR);
661 DosQCurDisk(&ulDriveNum, &ulDriveMap);
662 if (hwnddrive)
663 WinSendMsg(hwnddrive, LM_DELETEALL, MPVOID, MPVOID);
664 if (hwnddrive != hwnddir && hwnddir)
665 WinSendMsg(hwnddir, LM_DELETEALL, MPVOID, MPVOID);
666
667 if (hwnddrive) {
668 // Fill drive listbox
669 for (sDrive = 0; sDrive < 26; sDrive++) {
670 if (ulDriveMap & (1 << sDrive)) {
671 *szDrive = (CHAR) (sDrive + 'A');
672 if ((!nounwriteable || !(driveflags[sDrive] & DRIVE_NOTWRITEABLE)) &&
673 !(driveflags[sDrive] & (DRIVE_IGNORE | DRIVE_INVALID)))
674 WinSendMsg(hwnddrive, LM_INSERTITEM, MPFROM2SHORT(LIT_END, 0),
675 MPFROMP(szDrive));
676 }
677 }
678 if (hwnddrive != hwnddir && pszPath && isalpha(*pszPath)
679 && pszPath[1] == ':') {
680 *szDrive = toupper(*pszPath);
681 WinSetWindowText(hwnddrive, szDrive);
682 }
683 }
684
685 if (hwnddir) {
686 // Fill directory listbox
687 sprintf(szTemp,
688 "%s%s*",
689 pszPath, (pszPath[strlen(pszPath) - 1] == '\\') ? NullStr : PCSZ_BACKSLASH);
690 DosError(FERR_DISABLEHARDERR);
691 if (!DosFindFirst(szTemp,
692 &hDir,
693 FILE_DIRECTORY | MUST_HAVE_DIRECTORY |
694 FILE_READONLY | FILE_ARCHIVED | FILE_SYSTEM |
695 FILE_HIDDEN,
696 &findbuf,
697 sizeof(FILEFINDBUF3), &ulSearchCount, FIL_STANDARD)) {
698 do {
699 if (findbuf.attrFile & FILE_DIRECTORY) {
700 // Skip .. unless full path supplied
701 if (strcmp(findbuf.achName, "..") ||
702 strlen(pszPath) > 3 || pszPath[1] != ':') {
703 // Skip . allow ..
704 if (findbuf.achName[0] != '.' || findbuf.achName[1]) {
705 WinSendMsg(hwnddir,
706 LM_INSERTITEM,
707 MPFROM2SHORT(LIT_SORTASCENDING, 0),
708 MPFROMP(findbuf.achName));
709 }
710 }
711 }
712 ulSearchCount = 1;
713 } while (!DosFindNext(hDir,
714 &findbuf, sizeof(FILEFINDBUF3), &ulSearchCount));
715 DosFindClose(hDir);
716 }
717 DosError(FERR_DISABLEHARDERR);
718 }
719}
720
721MRESULT EXPENTRY TextSubProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
722{
723 PFNWP oldproc = (PFNWP) WinQueryWindowPtr(hwnd, QWL_USER);
724
725 switch (msg) {
726 case WM_CHAR:
727 if (SHORT1FROMMP(mp1) & KC_KEYUP) {
728 if ((SHORT1FROMMP(mp1) & KC_VIRTUALKEY) &&
729 (SHORT1FROMMP(mp2) & 255) == '\r')
730 PostMsg(WinQueryWindow(hwnd, QW_PARENT), WM_COMMAND,
731 MPFROM2SHORT(DID_OK, 0), MPVOID);
732 }
733 break;
734 }
735 return oldproc(hwnd, msg, mp1, mp2);
736}
737
738MRESULT EXPENTRY WalkDlgProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
739{
740 WALKER *wa;
741 CHAR szBuff[CCHMAXPATH + 1], szBuffer[CCHMAXPATH + 1], *p;
742 SHORT sSelect;
743 static BOOL okay; // avoid combobox selecting as filled
744 static CHAR lastdir[CCHMAXPATH + 1];
745
746 switch (msg) {
747 case UM_SETUP2:
748 case WM_INITDLG:
749 okay = FALSE;
750 *lastdir = 0;
751 if (!mp2) {
752 Runtime_Error(pszSrcFile, __LINE__, NULL);
753 WinDismissDlg(hwnd, 0);
754 break;
755 }
756 wa = xmallocz(sizeof(WALKER), pszSrcFile, __LINE__);
757 if (!wa) {
758 WinDismissDlg(hwnd, 0);
759 break;
760 }
761 wa->size = (USHORT) sizeof(WALKER);
762 WinSetWindowPtr(hwnd, QWL_USER, (PVOID) wa);
763 wa->szReturnPath = (CHAR *)mp2;
764 {
765 PFNWP oldproc;
766
767 oldproc = WinSubclassWindow(WinWindowFromID(hwnd, WALK_PATH),
768 (PFNWP) TextSubProc);
769 if (oldproc)
770 WinSetWindowPtr(WinWindowFromID(hwnd, WALK_PATH),
771 QWL_USER, (PVOID) oldproc);
772 WinSendDlgItemMsg(WinWindowFromID(hwnd, WALK_RECENT),
773 CBID_EDIT,
774 EM_SETTEXTLIMIT, MPFROM2SHORT(CCHMAXPATH, 0), MPVOID);
775 WinSendDlgItemMsg(WinWindowFromID(hwnd, WALK_RECENT),
776 CBID_EDIT,
777 EM_SETREADONLY, MPFROM2SHORT(TRUE, 0), MPVOID);
778 }
779 {
780 SWP swp;
781 ULONG size = sizeof(SWP);
782
783 PrfQueryProfileData(fmprof, FM3Str, "WalkDir.Position", (PVOID) &swp, &size);
784 swp.fl &= ~SWP_SIZE; // 04 Feb 09 SHL ignore saved size
785 WinSetWindowPos(hwnd,
786 HWND_TOP,
787 swp.x,
788 swp.y,
789 swp.cx,
790 swp.cy,
791 swp.fl);
792 }
793 PosOverOkay(hwnd);
794 if (msg == UM_SETUP2)
795 wa->nounwriteable = FALSE;
796 else
797 wa->nounwriteable = TRUE;
798 if (!*wa->szReturnPath)
799 strcpy(wa->szCurrentPath, pFM2SaveDirectory);
800 else {
801 strcpy(wa->szCurrentPath, wa->szReturnPath);
802 MakeFullName(wa->szCurrentPath);
803 }
804 if (wa->nounwriteable &&
805 (driveflags[toupper(*wa->szCurrentPath) - 'A'] &
806 DRIVE_NOTWRITEABLE)) {
807
808 ULONG bd;
809
810 strcpy(wa->szCurrentPath, "C:\\");
811 if (DosQuerySysInfo(QSV_BOOT_DRIVE,
812 QSV_BOOT_DRIVE,
813 (PVOID) & bd, (ULONG) sizeof(ULONG)))
814 bd = 3;
815 *wa->szCurrentPath = (CHAR) bd + '@';
816 }
817 WinSendDlgItemMsg(hwnd,
818 WALK_PATH,
819 EM_SETTEXTLIMIT, MPFROM2SHORT(CCHMAXPATH, 0), MPVOID);
820 WinSetDlgItemText(hwnd, WALK_PATH, wa->szCurrentPath);
821 if (!loadedudirs)
822 load_udirs();
823 { // fill user list box
824 ULONG ulDriveNum, ulDriveMap;
825 ULONG ulSearchCount;
826 FILEFINDBUF3 findbuf;
827 HDIR hDir;
828 APIRET rc;
829 LINKDIRS *info, *temp;
830
831 DosError(FERR_DISABLEHARDERR);
832 DosQCurDisk(&ulDriveNum, &ulDriveMap);
833 info = udirhead;
834 while (info) {
835 if (IsFullName(info->path) &&
836 !(driveflags[toupper(*info->path) - 'A'] &
837 (DRIVE_IGNORE | DRIVE_INVALID))) {
838 DosError(FERR_DISABLEHARDERR);
839 hDir = HDIR_CREATE;
840 ulSearchCount = 1;
841 if (!IsRoot(info->path))
842 rc = DosFindFirst(info->path, &hDir, FILE_DIRECTORY |
843 MUST_HAVE_DIRECTORY | FILE_READONLY |
844 FILE_ARCHIVED | FILE_SYSTEM | FILE_HIDDEN,
845 &findbuf, sizeof(FILEFINDBUF3),
846 &ulSearchCount, FIL_STANDARD);
847 else {
848 rc = 0;
849 findbuf.attrFile = FILE_DIRECTORY;
850 }
851 if (!rc) {
852 if (!IsRoot(info->path))
853 DosFindClose(hDir);
854 if (findbuf.attrFile & FILE_DIRECTORY)
855 WinSendDlgItemMsg(hwnd, WALK_USERLIST, LM_INSERTITEM,
856 MPFROM2SHORT(LIT_SORTASCENDING, 0),
857 MPFROMP(info->path));
858 else {
859 temp = info->next;
860 remove_udir(info->path);
861 info = temp;
862 continue;
863 }
864 }
865 else if (!(ulDriveMap & (1 << (toupper(*info->path) - 'A')))) {
866 temp = info->next;
867 remove_udir(info->path);
868 info = temp;
869 continue;
870 }
871 }
872 info = info->next;
873 }
874 info = ldirhead;
875 while (info) {
876 if (IsFullName(info->path) &&
877 !(driveflags[toupper(*info->path) - 'A'] &
878 (DRIVE_IGNORE | DRIVE_INVALID))) {
879 DosError(FERR_DISABLEHARDERR);
880 hDir = HDIR_CREATE;
881 ulSearchCount = 1;
882 if (!IsRoot(info->path))
883 rc = DosFindFirst(info->path, &hDir, FILE_DIRECTORY |
884 MUST_HAVE_DIRECTORY | FILE_READONLY |
885 FILE_ARCHIVED | FILE_SYSTEM | FILE_HIDDEN,
886 &findbuf, sizeof(FILEFINDBUF3),
887 &ulSearchCount, FIL_STANDARD);
888 else {
889 rc = 0;
890 findbuf.attrFile = FILE_DIRECTORY;
891 }
892 if (!rc) {
893 if (!IsRoot(info->path))
894 DosFindClose(hDir);
895 if (findbuf.attrFile & FILE_DIRECTORY)
896 WinSendDlgItemMsg(hwnd, WALK_RECENT, LM_INSERTITEM,
897 MPFROM2SHORT(LIT_SORTASCENDING, 0),
898 MPFROMP(info->path));
899 else {
900 temp = info->next;
901 remove_ldir(info->path);
902 info = temp;
903 continue;
904 }
905 WinSetDlgItemText(hwnd, WALK_RECENT,
906 (CHAR *) GetPString(IDS_WALKRECENTDIRSTEXT));
907 }
908 else if (!(ulDriveMap & (1 << (toupper(*info->path) - 'A')))) {
909 temp = info->next;
910 remove_ldir(info->path);
911 info = temp;
912 continue;
913 }
914 }
915 info = info->next;
916 }
917 }
918 FillPathListBox(hwnd,
919 WinWindowFromID(hwnd, WALK_DRIVELIST),
920 WinWindowFromID(hwnd, WALK_DIRLIST),
921 wa->szCurrentPath, wa->nounwriteable);
922 if (!PostMsg(hwnd, UM_SETUP4, MPVOID, MPVOID))
923 okay = TRUE;
924 {
925 MRESULT ret;
926
927 ret = WinDefDlgProc(hwnd, WM_INITDLG, mp1, mp2);
928 WinSendMsg(hwnd, UM_SETUP, MPVOID, MPVOID);
929 WinInvalidateRect(WinWindowFromID(hwnd, WALK_PATH), NULL, TRUE);
930 return ret;
931 }
932
933 case UM_SETUP4:
934 okay = TRUE;
935 return 0;
936
937 case WM_ADJUSTWINDOWPOS:
938 PostMsg(hwnd, UM_SETDIR, MPVOID, MPVOID);
939 break;
940
941 case UM_SETDIR:
942 PaintRecessedWindow(WinWindowFromID(hwnd, WALK_HELP), (HPS) 0, FALSE,
943 TRUE);
944 return 0;
945
946 case WM_PRESPARAMCHANGED:
947 {
948 ULONG AttrFound, AttrValue[64], cbRetLen;
949
950 cbRetLen = WinQueryPresParam(hwnd, (ULONG) mp1, 0, &AttrFound,
951 (ULONG) sizeof(AttrValue), &AttrValue, 0);
952 if (cbRetLen) {
953 switch (AttrFound) {
954 case PP_FONTNAMESIZE:
955 PrfWriteProfileData(fmprof,
956 appname,
957 "WalkFont", (PVOID) AttrValue, cbRetLen);
958 *WalkFont = 0;
959 WalkFontSize = sizeof(WalkFont);
960 WinInvalidateRect(WinWindowFromID(hwnd, WALK_PATH), NULL, TRUE);
961 break;
962 }
963 }
964 }
965 break;
966
967 case UM_SETUP3:
968 save_udirs();
969 if (hwndMain)
970 PostMsg(hwndMain, UM_FILLUSERLIST, MPVOID, MPVOID);
971 return 0;
972
973 case UM_SETUP:
974 {
975 INT x;
976 USHORT id[] = { WALK_PATH, WALK_DIRLIST, WALK_USERLIST,
977 WALK_RECENT, 0
978 };
979
980 if (*WalkFont ||
981 (PrfQueryProfileData(fmprof,
982 appname,
983 "WalkFont",
984 (PVOID) WalkFont,
985 &WalkFontSize) && WalkFontSize)) {
986 for (x = 0; id[x]; x++)
987 WinSetPresParam(WinWindowFromID(hwnd, id[x]),
988 PP_FONTNAMESIZE, WalkFontSize, (PVOID) WalkFont);
989 }
990 }
991 return 0;
992
993 case UM_CONTROL:
994 case WM_CONTROL:
995 wa = WinQueryWindowPtr(hwnd, QWL_USER);
996 if (SHORT1FROMMP(mp1) == WALK_DRIVELIST ||
997 SHORT1FROMMP(mp1) == WALK_DIRLIST ||
998 SHORT1FROMMP(mp1) == WALK_USERLIST ||
999 SHORT1FROMMP(mp1) == WALK_RECENT) {
1000 sSelect = (USHORT) WinSendDlgItemMsg(hwnd,
1001 SHORT1FROMMP(mp1),
1002 LM_QUERYSELECTION, MPVOID, MPVOID);
1003 *szBuffer = 0;
1004 if (sSelect >= 0)
1005 WinSendDlgItemMsg(hwnd, SHORT1FROMMP(mp1), LM_QUERYITEMTEXT,
1006 MPFROM2SHORT(sSelect, CCHMAXPATH),
1007 MPFROMP(szBuffer));
1008 }
1009 switch (SHORT1FROMMP(mp1)) {
1010 case WALK_PATH:
1011 if (SHORT2FROMMP(mp1) == EN_SETFOCUS)
1012 WinSetDlgItemText(hwnd, WALK_HELP, (CHAR *) GetPString(IDS_WALKCURRDIRTEXT));
1013 else if (SHORT2FROMMP(mp1) == EN_KILLFOCUS)
1014 WinSetDlgItemText(hwnd, WALK_HELP,
1015 (CHAR *) GetPString(IDS_WALKDEFAULTHELPTEXT));
1016 break;
1017
1018 case WALK_RECENT:
1019 if (okay && SHORT2FROMMP(mp1) == CBN_LBSELECT) {
1020
1021 ULONG ulSearchCount;
1022 FILEFINDBUF3 findbuf;
1023 HDIR hDir;
1024 APIRET rc;
1025
1026 // *szBuffer = 0;
1027 // WinQueryDlgItemText(hwnd,WALK_RECENT,CCHMAXPATH,szBuffer);
1028 if (!*szBuffer)
1029 break;
1030 DosError(FERR_DISABLEHARDERR);
1031 hDir = HDIR_CREATE;
1032 ulSearchCount = 1;
1033 if (!IsRoot(szBuffer)) {
1034 rc = DosFindFirst(szBuffer, &hDir, FILE_DIRECTORY |
1035 MUST_HAVE_DIRECTORY | FILE_READONLY |
1036 FILE_ARCHIVED | FILE_SYSTEM | FILE_HIDDEN,
1037 &findbuf, sizeof(FILEFINDBUF3),
1038 &ulSearchCount, FIL_STANDARD);
1039 if (!rc)
1040 DosFindClose(hDir);
1041 }
1042 else {
1043 findbuf.attrFile = FILE_DIRECTORY;
1044 rc = 0;
1045 }
1046 if (rc)
1047 Dos_Error(MB_CANCEL, rc, hwnd, pszSrcFile, __LINE__,
1048 "DosFindFirst");
1049 else if (~findbuf.attrFile & FILE_DIRECTORY)
1050 Runtime_Error(pszSrcFile, __LINE__, "not a directory");
1051 else {
1052 strcpy(wa->szCurrentPath, szBuffer);
1053 WinSetDlgItemText(hwnd, WALK_PATH, wa->szCurrentPath);
1054 WinSetDlgItemText(hwnd, WALK_RECENT, wa->szCurrentPath);
1055 FillPathListBox(hwnd,
1056 WinWindowFromID(hwnd, WALK_DRIVELIST),
1057 WinWindowFromID(hwnd, WALK_DIRLIST),
1058 wa->szCurrentPath, FALSE);
1059 }
1060 }
1061 else if (SHORT2FROMMP(mp1) == CBN_ENTER)
1062 PostMsg(hwnd, WM_COMMAND, MPFROM2SHORT(DID_OK, 0), MPVOID);
1063 else if (SHORT2FROMMP(mp1) == CBN_SHOWLIST)
1064 WinSetDlgItemText(hwnd, WALK_HELP,
1065 (CHAR *) GetPString(IDS_WALKRECENTDIRSHELPTEXT));
1066 break;
1067
1068 case WALK_USERLIST:
1069 if (okay && *szBuffer && SHORT2FROMMP(mp1) == LN_SELECT) {
1070
1071 ULONG ulSearchCount;
1072 FILEFINDBUF3 findbuf;
1073 HDIR hDir;
1074 APIRET rc;
1075
1076 // 06 Oct 09 SHL Ctrl-select selects, but suppresses action
1077 SetShiftState();
1078 if ((shiftstate & (KC_CTRL | KC_SHIFT | KC_ALT)) == KC_CTRL)
1079 break;
1080 DosError(FERR_DISABLEHARDERR);
1081 hDir = HDIR_CREATE;
1082 ulSearchCount = 1;
1083 if (!IsRoot(szBuffer)) {
1084 rc = DosFindFirst(szBuffer,
1085 &hDir,
1086 FILE_DIRECTORY |
1087 MUST_HAVE_DIRECTORY | FILE_READONLY |
1088 FILE_ARCHIVED | FILE_SYSTEM | FILE_HIDDEN,
1089 &findbuf,
1090 sizeof(FILEFINDBUF3),
1091 &ulSearchCount, FIL_STANDARD);
1092 if (!rc)
1093 DosFindClose(hDir);
1094 }
1095 else {
1096 findbuf.attrFile = FILE_DIRECTORY;
1097 rc = 0;
1098 }
1099 if (rc)
1100 Dos_Error(MB_CANCEL, rc, hwnd, pszSrcFile, __LINE__,
1101 "DosFindFirst");
1102 else if (~findbuf.attrFile & FILE_DIRECTORY)
1103 Runtime_Error(pszSrcFile, __LINE__, "not a directory");
1104 else {
1105 strcpy(wa->szCurrentPath, szBuffer);
1106 WinSetDlgItemText(hwnd, WALK_PATH, wa->szCurrentPath);
1107 FillPathListBox(hwnd,
1108 WinWindowFromID(hwnd, WALK_DRIVELIST),
1109 WinWindowFromID(hwnd, WALK_DIRLIST),
1110 wa->szCurrentPath, FALSE);
1111 }
1112 }
1113 else if (SHORT2FROMMP(mp1) == LN_ENTER)
1114 PostMsg(hwnd, WM_COMMAND, MPFROM2SHORT(DID_OK, 0), MPVOID);
1115 else if (SHORT2FROMMP(mp1) == LN_SETFOCUS)
1116 WinSetDlgItemText(hwnd,
1117 WALK_HELP, (CHAR *) GetPString(IDS_WALKUSERDIRSHELPTEXT));
1118 else if (SHORT2FROMMP(mp1) == LN_KILLFOCUS)
1119 WinSetDlgItemText(hwnd,
1120 WALK_HELP, (CHAR *) GetPString(IDS_WALKDEFAULTHELPTEXT));
1121 break;
1122
1123 case WALK_DRIVELIST:
1124 if (okay && *szBuffer && SHORT2FROMMP(mp1) == LN_ENTER) {
1125
1126 ULONG ulDirLen = CCHMAXPATH;
1127 APIRET rc;
1128
1129 rc = DosQCurDir(toupper(*szBuffer) - '@', (PBYTE)&szBuff[3], &ulDirLen);
1130 if (!rc) {
1131 strcpy(wa->szCurrentPath, "C:\\");
1132 *wa->szCurrentPath = toupper(*szBuffer);
1133 WinSetDlgItemText(hwnd, WALK_PATH, wa->szCurrentPath);
1134 FillPathListBox(hwnd,
1135 WinWindowFromID(hwnd, WALK_DRIVELIST),
1136 WinWindowFromID(hwnd, WALK_DIRLIST),
1137 wa->szCurrentPath, FALSE);
1138 }
1139 }
1140 else if (SHORT2FROMMP(mp1) == LN_SETFOCUS)
1141 WinSetDlgItemText(hwnd, WALK_HELP,
1142 (CHAR *) GetPString(IDS_WALKDRIVELISTHELPTEXT));
1143 else if (SHORT2FROMMP(mp1) == LN_KILLFOCUS)
1144 WinSetDlgItemText(hwnd, WALK_HELP,
1145 (CHAR *) GetPString(IDS_WALKDEFAULTHELPTEXT));
1146 break;
1147
1148 case WALK_DIRLIST:
1149 if (okay && SHORT2FROMMP(mp1) == LN_ENTER) {
1150
1151 ULONG ulSearchCount;
1152 FILEFINDBUF3 findbuf;
1153 HDIR hDir;
1154 APIRET rc;
1155
1156 bstrip(szBuffer);
1157 if (*szBuffer) {
1158 strcpy(szBuff, wa->szCurrentPath);
1159 AddBackslashToPath(szBuff);
1160 //if (szBuff[strlen(szBuff) - 1] != '\\')
1161 // strcat(szBuff, "\\");
1162 strcat(szBuff, szBuffer);
1163 MakeFullName(szBuff);
1164 DosError(FERR_DISABLEHARDERR);
1165 hDir = HDIR_CREATE;
1166 ulSearchCount = 1;
1167 if (!IsRoot(szBuff)) {
1168 rc = DosFindFirst(szBuff,
1169 &hDir,
1170 FILE_DIRECTORY |
1171 MUST_HAVE_DIRECTORY | FILE_READONLY |
1172 FILE_ARCHIVED | FILE_SYSTEM | FILE_HIDDEN,
1173 &findbuf,
1174 sizeof(FILEFINDBUF3),
1175 &ulSearchCount, FIL_STANDARD);
1176 if (!rc)
1177 DosFindClose(hDir);
1178 }
1179 else {
1180 findbuf.attrFile = FILE_DIRECTORY;
1181 rc = 0;
1182 }
1183 if (!rc && (findbuf.attrFile & FILE_DIRECTORY)) {
1184 strcpy(wa->szCurrentPath, szBuff);
1185 WinSetDlgItemText(hwnd, WALK_PATH, wa->szCurrentPath);
1186 FillPathListBox(hwnd,
1187 WinWindowFromID(hwnd, WALK_DRIVELIST),
1188 WinWindowFromID(hwnd, WALK_DIRLIST),
1189 wa->szCurrentPath, FALSE);
1190 }
1191 }
1192 }
1193 else if (SHORT2FROMMP(mp1) == LN_SETFOCUS)
1194 WinSetDlgItemText(hwnd, WALK_HELP,
1195 (CHAR *) GetPString(IDS_WALKDIRLISTHELPTEXT));
1196 else if (SHORT2FROMMP(mp1) == LN_KILLFOCUS)
1197 WinSetDlgItemText(hwnd, WALK_HELP,
1198 (CHAR *) GetPString(IDS_WALKDEFAULTHELPTEXT));
1199 break;
1200 }
1201 return 0;
1202
1203 case WM_COMMAND:
1204 wa = WinQueryWindowPtr(hwnd, QWL_USER);
1205 if (!wa)
1206 WinDismissDlg(hwnd, 0);
1207 *szBuff = 0;
1208 WinQueryDlgItemText(hwnd, WALK_PATH, CCHMAXPATH, szBuff);
1209 bstrip(szBuff);
1210 while ((p = strchr(szBuff, '/')) != NULL)
1211 *p = '\\';
1212 while (strlen(szBuff) > 3 && szBuff[strlen(szBuff) - 1] == '\\')
1213 szBuff[strlen(szBuff) - 1] = 0;
1214 MakeFullName(szBuff);
1215 if (*szBuff && stricmp(szBuff, wa->szCurrentPath) && SHORT1FROMMP(mp1) != DID_CANCEL) {
1216 if (!SetDir(WinQueryWindow(WinQueryWindow(hwnd, QW_PARENT),
1217 QW_OWNER), hwnd, szBuff, 0))
1218 strcpy(wa->szCurrentPath, szBuff);
1219 else
1220 return 0;
1221 }
1222 WinSetDlgItemText(hwnd, WALK_PATH, wa->szCurrentPath);
1223 switch (SHORT1FROMMP(mp1)) {
1224 case WALK_ADD:
1225 *szBuff = 0;
1226 WinQueryDlgItemText(hwnd, WALK_PATH, CCHMAXPATH, szBuff);
1227 bstrip(szBuff);
1228 while ((p = strchr(szBuff, '/')) != NULL)
1229 *p = '\\';
1230 if (*szBuff && !IsFile(szBuff)) {
1231 MakeFullName(szBuff);
1232 add_udir(TRUE, szBuff);
1233 if (fUdirsChanged) {
1234 WinSendDlgItemMsg(hwnd,
1235 WALK_USERLIST,
1236 LM_INSERTITEM,
1237 MPFROM2SHORT(LIT_SORTASCENDING, 0),
1238 MPFROMP(szBuff));
1239 wa->changed = 1;
1240 }
1241 }
1242 break;
1243
1244 case WALK_DELETE:
1245 // 07 Oct 09 SHL Delete current selection, like docs says
1246 sSelect = (SHORT)WinSendDlgItemMsg(hwnd,
1247 WALK_USERLIST,
1248 LM_QUERYSELECTION,
1249 MPFROMSHORT(LIT_FIRST), MPVOID);
1250 if (sSelect >= 0) {
1251 WinSendDlgItemMsg(hwnd,
1252 WALK_USERLIST,
1253 LM_DELETEITEM, MPFROM2SHORT(sSelect, 0), MPVOID);
1254 remove_udir(szBuff);
1255 wa->changed = 1;
1256 }
1257 break;
1258
1259 case DID_OK:
1260 if (*wa->szCurrentPath) {
1261 strcpy(wa->szReturnPath, wa->szCurrentPath);
1262 MakeValidDir(wa->szReturnPath);
1263 if (fAutoAddAllDirs)
1264 add_udir(FALSE, wa->szReturnPath);
1265 if (fChangeTarget) {
1266 strcpy(targetdir, wa->szReturnPath);
1267 PrfWriteProfileString(fmprof, appname, "Targetdir", targetdir);
1268 }
1269 }
1270 {
1271 SWP swp;
1272 ULONG size = sizeof(SWP);
1273 WinQueryWindowPos(hwnd, &swp);
1274 PrfWriteProfileData(fmprof, FM3Str, "WalkDir.Position", (PVOID) &swp,
1275 size);
1276 }
1277 if (wa->changed)
1278 WinSendMsg(hwnd, UM_SETUP3, MPVOID, MPVOID);
1279 WinDismissDlg(hwnd, 1);
1280 break;
1281
1282 case IDM_HELP:
1283 if (hwndHelp)
1284 WinSendMsg(hwndHelp,
1285 HM_DISPLAY_HELP,
1286 MPFROM2SHORT(HELP_WALKEM, 0), MPFROMSHORT(HM_RESOURCEID));
1287 break;
1288
1289 case DID_CANCEL:
1290 {
1291 SWP swp;
1292 ULONG size = sizeof(SWP);
1293
1294 WinQueryWindowPos(hwnd, &swp);
1295 PrfWriteProfileData(fmprof, FM3Str, "WalkDir.Position", (PVOID) &swp,
1296 size);
1297 }
1298 if (wa->changed)
1299 WinSendMsg(hwnd, UM_SETUP3, MPVOID, MPVOID);
1300 free(wa);
1301 WinDismissDlg(hwnd, 0);
1302 break;
1303 }
1304 return 0;
1305
1306 case WM_CLOSE:
1307 break;
1308 }
1309 return WinDefDlgProc(hwnd, msg, mp1, mp2);
1310}
1311
1312MRESULT EXPENTRY WalkAllDlgProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
1313{
1314 switch (msg) {
1315 case WM_INITDLG:
1316 return WalkDlgProc(hwnd, UM_SETUP2, mp1, mp2);
1317 }
1318 return WalkDlgProc(hwnd, msg, mp1, mp2);
1319}
1320
1321MRESULT EXPENTRY WalkCopyDlgProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
1322{
1323 switch (msg) {
1324 case WM_INITDLG:
1325 WinSetWindowText(hwnd, (CHAR *) GetPString(IDS_WALKCOPYDLGTEXT));
1326 return WalkDlgProc(hwnd, UM_SETUP2, mp1, mp2);
1327 }
1328 return WalkDlgProc(hwnd, msg, mp1, mp2);
1329}
1330
1331MRESULT EXPENTRY WalkMoveDlgProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
1332{
1333 switch (msg) {
1334 case WM_INITDLG:
1335 WinSetWindowText(hwnd, (CHAR *) GetPString(IDS_WALKMOVEDLGTEXT));
1336 return WalkDlgProc(hwnd, UM_SETUP2, mp1, mp2);
1337 }
1338 return WalkDlgProc(hwnd, msg, mp1, mp2);
1339}
1340
1341MRESULT EXPENTRY WalkExtractDlgProc(HWND hwnd, ULONG msg, MPARAM mp1,
1342 MPARAM mp2)
1343{
1344 switch (msg) {
1345 case WM_INITDLG:
1346 WinSetWindowText(hwnd, (CHAR *) GetPString(IDS_WALKEXTRACTDLGTEXT));
1347 return WalkDlgProc(hwnd, UM_SETUP2, mp1, mp2);
1348 }
1349 return WalkDlgProc(hwnd, msg, mp1, mp2);
1350}
1351
1352MRESULT EXPENTRY WalkTargetDlgProc(HWND hwnd, ULONG msg, MPARAM mp1,
1353 MPARAM mp2)
1354{
1355 switch (msg) {
1356 case WM_INITDLG:
1357 {
1358 char s[CCHMAXPATH + 32];
1359
1360 sprintf(s,
1361 GetPString(IDS_WALKTARGETDLGTEXT),
1362 (*targetdir) ?
1363 NullStr :
1364 " (",
1365 (*targetdir) ?
1366 NullStr : GetPString(IDS_NONE), (*targetdir) ? NullStr : ")");
1367 WinSetWindowText(hwnd, s);
1368 }
1369 return WalkDlgProc(hwnd, UM_SETUP2, mp1, mp2);
1370 }
1371 return WalkDlgProc(hwnd, msg, mp1, mp2);
1372}
1373
1374MRESULT EXPENTRY WalkTwoDlgProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
1375{
1376 WALK2 *wa;
1377 CHAR szBuff[CCHMAXPATH + 1], szBuffer[CCHMAXPATH + 1], *p;
1378 SHORT sSelect;
1379 static BOOL okay; // avoid combobox selecting as filled
1380
1381 switch (msg) {
1382 case UM_SETUP2:
1383 case WM_INITDLG:
1384 okay = FALSE;
1385 if (!mp2) {
1386 WinDismissDlg(hwnd, 0);
1387 break;
1388 }
1389 WinSetWindowPtr(hwnd, QWL_USER, mp2);
1390 wa = mp2;
1391 {
1392 PFNWP oldproc;
1393
1394 oldproc = WinSubclassWindow(WinWindowFromID(hwnd, WALK_PATH),
1395 (PFNWP) TextSubProc);
1396 if (oldproc)
1397 WinSetWindowPtr(WinWindowFromID(hwnd, WALK_PATH),
1398 QWL_USER, (PVOID) oldproc);
1399 oldproc = WinSubclassWindow(WinWindowFromID(hwnd, WALK2_PATH),
1400 (PFNWP) TextSubProc);
1401 if (oldproc)
1402 WinSetWindowPtr(WinWindowFromID(hwnd, WALK2_PATH),
1403 QWL_USER, (PVOID) oldproc);
1404 }
1405 {
1406 SWP swp;
1407 ULONG size = sizeof(SWP);
1408
1409 PrfQueryProfileData(fmprof, FM3Str, "WalkDir2.Position", (PVOID) &swp, &size);
1410 swp.fl &= ~SWP_SIZE; // 04 Feb 09 SHL ignore saved size
1411 WinSetWindowPos(hwnd,
1412 HWND_TOP,
1413 swp.x,
1414 swp.y,
1415 swp.cx,
1416 swp.cy,
1417 swp.fl);
1418 }
1419 if (!*wa->szCurrentPath1)
1420 strcpy(wa->szCurrentPath1, pFM2SaveDirectory);
1421 MakeFullName(wa->szCurrentPath1);
1422 if (!*wa->szCurrentPath2)
1423 strcpy(wa->szCurrentPath2, pFM2SaveDirectory);
1424 MakeFullName(wa->szCurrentPath2);
1425 WinSendDlgItemMsg(hwnd,
1426 WALK_PATH,
1427 EM_SETTEXTLIMIT, MPFROM2SHORT(CCHMAXPATH, 0), MPVOID);
1428 WinSetDlgItemText(hwnd, WALK_PATH, wa->szCurrentPath1);
1429 WinSendDlgItemMsg(hwnd, WALK2_PATH, EM_SETTEXTLIMIT,
1430 MPFROM2SHORT(CCHMAXPATH, 0), MPVOID);
1431 WinSetDlgItemText(hwnd, WALK2_PATH, wa->szCurrentPath2);
1432 FillPathListBox(hwnd,
1433 WinWindowFromID(hwnd, WALK_DRIVELIST),
1434 WinWindowFromID(hwnd, WALK_DIRLIST),
1435 wa->szCurrentPath1, FALSE);
1436 FillPathListBox(hwnd,
1437 WinWindowFromID(hwnd, WALK2_DRIVELIST),
1438 WinWindowFromID(hwnd, WALK2_DIRLIST),
1439 wa->szCurrentPath2, FALSE);
1440 WinEnableWindow(WinWindowFromID(hwnd, WALK2_INCLUDESUBDIRS), TRUE);
1441 WinEnableWindow(WinWindowFromID(hwnd, WALK2_LOADLISTFILE), TRUE);
1442 if (wa->includesubdirs)
1443 WinCheckButton(hwnd, WALK2_INCLUDESUBDIRS, TRUE);
1444 if (!PostMsg(hwnd, UM_SETUP4, MPVOID, MPVOID))
1445 okay = TRUE;
1446 {
1447 MRESULT ret;
1448
1449 ret = WinDefDlgProc(hwnd, WM_INITDLG, mp1, mp2);
1450 WinSendMsg(hwnd, UM_SETUP, MPVOID, MPVOID);
1451 WinInvalidateRect(WinWindowFromID(hwnd, WALK_PATH), NULL, TRUE);
1452 WinInvalidateRect(WinWindowFromID(hwnd, WALK2_PATH), NULL, TRUE);
1453 return ret;
1454 }
1455
1456 case UM_SETUP4:
1457 okay = TRUE;
1458 return 0;
1459
1460 case WM_PRESPARAMCHANGED:
1461 {
1462 ULONG AttrFound, AttrValue[64], cbRetLen;
1463
1464 cbRetLen = WinQueryPresParam(hwnd, (ULONG) mp1, 0, &AttrFound,
1465 (ULONG) sizeof(AttrValue), &AttrValue, 0);
1466 if (cbRetLen) {
1467 switch (AttrFound) {
1468 case PP_FONTNAMESIZE:
1469 PrfWriteProfileData(fmprof,
1470 appname,
1471 "WalkFont", (PVOID) AttrValue, cbRetLen);
1472 *WalkFont = 0;
1473 WalkFontSize = sizeof(WalkFont);
1474 WinInvalidateRect(WinWindowFromID(hwnd, WALK_PATH), NULL, TRUE);
1475 break;
1476 }
1477 }
1478 }
1479 break;
1480
1481 case UM_SETUP:
1482 {
1483 INT x;
1484 USHORT id[] = { WALK_PATH, WALK_DIRLIST,
1485 WALK2_PATH, WALK2_DIRLIST, 0
1486 };
1487
1488 if (*WalkFont ||
1489 (PrfQueryProfileData(fmprof,
1490 appname,
1491 "WalkFont",
1492 (PVOID) WalkFont,
1493 &WalkFontSize) && WalkFontSize)) {
1494 for (x = 0; id[x]; x++)
1495 WinSetPresParam(WinWindowFromID(hwnd, id[x]),
1496 PP_FONTNAMESIZE, WalkFontSize, (PVOID) WalkFont);
1497 }
1498 }
1499 return 0;
1500
1501 case UM_CONTROL:
1502 case WM_CONTROL:
1503 wa = WinQueryWindowPtr(hwnd, QWL_USER);
1504 if (SHORT1FROMMP(mp1) == WALK_DRIVELIST ||
1505 SHORT1FROMMP(mp1) == WALK_DIRLIST ||
1506 SHORT1FROMMP(mp1) == WALK2_DRIVELIST ||
1507 SHORT1FROMMP(mp1) == WALK2_DIRLIST) {
1508 sSelect = (USHORT) WinSendDlgItemMsg(hwnd,
1509 SHORT1FROMMP(mp1),
1510 LM_QUERYSELECTION, MPVOID, MPVOID);
1511 *szBuffer = 0;
1512 if (sSelect >= 0)
1513 WinSendDlgItemMsg(hwnd, SHORT1FROMMP(mp1), LM_QUERYITEMTEXT,
1514 MPFROM2SHORT(sSelect, CCHMAXPATH),
1515 MPFROMP(szBuffer));
1516 }
1517 switch (SHORT1FROMMP(mp1)) {
1518 case WALK_DRIVELIST:
1519 if (okay && *szBuffer && SHORT2FROMMP(mp1) == LN_ENTER) {
1520
1521 ULONG ulDirLen = CCHMAXPATH;
1522 APIRET rc;
1523
1524 rc = DosQCurDir(toupper(*szBuffer) - '@', (PBYTE)&szBuff[3], &ulDirLen);
1525 if (!rc) {
1526 strcpy(wa->szCurrentPath1, "C:\\");
1527 *wa->szCurrentPath1 = toupper(*szBuffer);
1528 WinSetDlgItemText(hwnd, WALK_PATH, wa->szCurrentPath1);
1529 FillPathListBox(hwnd,
1530 WinWindowFromID(hwnd, WALK_DRIVELIST),
1531 WinWindowFromID(hwnd, WALK_DIRLIST),
1532 wa->szCurrentPath1, FALSE);
1533 }
1534 }
1535 break;
1536
1537 case WALK_DIRLIST:
1538 if (okay && SHORT2FROMMP(mp1) == LN_ENTER) {
1539
1540 ULONG ulSearchCount;
1541 FILEFINDBUF3 findbuf;
1542 HDIR hDir;
1543 APIRET rc;
1544
1545 bstrip(szBuffer);
1546 if (*szBuffer) {
1547 strcpy(szBuff, wa->szCurrentPath1);
1548 AddBackslashToPath(szBuff);
1549 //if (szBuff[strlen(szBuff) - 1] != '\\')
1550 // strcat(szBuff, "\\");
1551 strcat(szBuff, szBuffer);
1552 MakeFullName(szBuff);
1553 DosError(FERR_DISABLEHARDERR);
1554 hDir = HDIR_CREATE;
1555 ulSearchCount = 1;
1556 if (!IsRoot(szBuff)) {
1557 rc = DosFindFirst(szBuff,
1558 &hDir,
1559 FILE_DIRECTORY |
1560 MUST_HAVE_DIRECTORY | FILE_READONLY |
1561 FILE_ARCHIVED | FILE_SYSTEM | FILE_HIDDEN,
1562 &findbuf,
1563 sizeof(FILEFINDBUF3),
1564 &ulSearchCount, FIL_STANDARD);
1565 if (!rc)
1566 DosFindClose(hDir);
1567 }
1568 else {
1569 findbuf.attrFile = FILE_DIRECTORY;
1570 rc = 0;
1571 }
1572 if (!rc && (findbuf.attrFile & FILE_DIRECTORY)) {
1573 strcpy(wa->szCurrentPath1, szBuff);
1574 WinSetDlgItemText(hwnd, WALK_PATH, wa->szCurrentPath1);
1575 FillPathListBox(hwnd,
1576 WinWindowFromID(hwnd, WALK_DRIVELIST),
1577 WinWindowFromID(hwnd, WALK_DIRLIST),
1578 wa->szCurrentPath1, FALSE);
1579 }
1580 }
1581 }
1582 break;
1583
1584 case WALK2_DRIVELIST:
1585 if (okay && *szBuffer && SHORT2FROMMP(mp1) == LN_ENTER) {
1586
1587 ULONG ulDirLen = CCHMAXPATH;
1588 APIRET rc;
1589
1590 rc = DosQCurDir(toupper(*szBuffer) - '@', (PBYTE)&szBuff[3], &ulDirLen);
1591 if (!rc) {
1592 strcpy(wa->szCurrentPath2, "C:\\");
1593 *wa->szCurrentPath2 = toupper(*szBuffer);
1594 WinSetDlgItemText(hwnd, WALK2_PATH, wa->szCurrentPath2);
1595 FillPathListBox(hwnd,
1596 WinWindowFromID(hwnd, WALK2_DRIVELIST),
1597 WinWindowFromID(hwnd, WALK2_DIRLIST),
1598 wa->szCurrentPath2, FALSE);
1599 }
1600 }
1601 break;
1602
1603 case WALK2_DIRLIST:
1604 if (okay && SHORT2FROMMP(mp1) == LN_ENTER) {
1605
1606 ULONG ulSearchCount;
1607 FILEFINDBUF3 findbuf;
1608 HDIR hDir;
1609 APIRET rc;
1610
1611 bstrip(szBuffer);
1612 if (*szBuffer) {
1613 strcpy(szBuff, wa->szCurrentPath2);
1614 AddBackslashToPath(szBuff);
1615 //if (szBuff[strlen(szBuff) - 1] != '\\')
1616 // strcat(szBuff, "\\");
1617 strcat(szBuff, szBuffer);
1618 MakeFullName(szBuff);
1619 DosError(FERR_DISABLEHARDERR);
1620 hDir = HDIR_CREATE;
1621 ulSearchCount = 1;
1622 if (!IsRoot(szBuff)) {
1623 rc = DosFindFirst(szBuff,
1624 &hDir,
1625 FILE_DIRECTORY |
1626 MUST_HAVE_DIRECTORY | FILE_READONLY |
1627 FILE_ARCHIVED | FILE_SYSTEM | FILE_HIDDEN,
1628 &findbuf,
1629 sizeof(FILEFINDBUF3),
1630 &ulSearchCount, FIL_STANDARD);
1631 if (!rc)
1632 DosFindClose(hDir);
1633 }
1634 else {
1635 findbuf.attrFile = FILE_DIRECTORY;
1636 rc = 0;
1637 }
1638 if (!rc && (findbuf.attrFile & FILE_DIRECTORY)) {
1639 strcpy(wa->szCurrentPath2, szBuff);
1640 WinSetDlgItemText(hwnd, WALK2_PATH, wa->szCurrentPath2);
1641 FillPathListBox(hwnd,
1642 WinWindowFromID(hwnd, WALK2_DRIVELIST),
1643 WinWindowFromID(hwnd, WALK2_DIRLIST),
1644 wa->szCurrentPath2, FALSE);
1645 }
1646 }
1647 }
1648 break;
1649 }
1650 return 0;
1651
1652 case WM_COMMAND:
1653 wa = WinQueryWindowPtr(hwnd, QWL_USER);
1654 if (!wa)
1655 WinDismissDlg(hwnd, 0);
1656 *szBuff = 0;
1657 WinQueryDlgItemText(hwnd, WALK_PATH, CCHMAXPATH, szBuff);
1658 bstrip(szBuff);
1659 while ((p = strchr(szBuff, '/')) != NULL)
1660 *p = '\\';
1661 while (strlen(szBuff) > 3 && szBuff[strlen(szBuff) - 1] == '\\')
1662 szBuff[strlen(szBuff) - 1] = 0;
1663 MakeFullName(szBuff);
1664 if (*szBuff && stricmp(szBuff, wa->szCurrentPath1) && SHORT1FROMMP(mp1) != DID_CANCEL) {
1665 if (!SetDir(WinQueryWindow(WinQueryWindow(hwnd, QW_PARENT),
1666 QW_OWNER), hwnd, szBuff, 0))
1667 strcpy(wa->szCurrentPath1, szBuff);
1668 else
1669 return 0;
1670 }
1671 WinSetDlgItemText(hwnd, WALK_PATH, wa->szCurrentPath1);
1672 *szBuff = 0;
1673 WinQueryDlgItemText(hwnd, WALK2_PATH, CCHMAXPATH, szBuff);
1674 bstrip(szBuff);
1675 while ((p = strchr(szBuff, '/')) != NULL)
1676 *p = '\\';
1677 while (strlen(szBuff) > 3 && szBuff[strlen(szBuff) - 1] == '\\')
1678 szBuff[strlen(szBuff) - 1] = 0;
1679 MakeFullName(szBuff);
1680 if (*szBuff && stricmp(szBuff, wa->szCurrentPath2) && SHORT1FROMMP(mp1) != DID_CANCEL) {
1681 if (!SetDir(WinQueryWindow(WinQueryWindow(hwnd, QW_PARENT),
1682 QW_OWNER), hwnd, szBuff, 0))
1683 strcpy(wa->szCurrentPath2, szBuff);
1684 else
1685 return 0;
1686 }
1687 WinSetDlgItemText(hwnd, WALK2_PATH, wa->szCurrentPath2);
1688 wa->includesubdirs = WinQueryButtonCheckstate(hwnd, WALK2_INCLUDESUBDIRS);
1689 wa->listfile = WinQueryButtonCheckstate(hwnd, WALK2_LOADLISTFILE);
1690 switch (SHORT1FROMMP(mp1)) {
1691 case DID_OK:
1692 {
1693 SWP swp;
1694 ULONG size = sizeof(SWP);
1695
1696 WinQueryWindowPos(hwnd, &swp);
1697 PrfWriteProfileData(fmprof, FM3Str, "WalkDir2.Position", (PVOID) &swp,
1698 size);
1699 }
1700 WinDismissDlg(hwnd, 1);
1701 break;
1702
1703 case IDM_HELP:
1704 if (hwndHelp)
1705 WinSendMsg(hwndHelp,
1706 HM_DISPLAY_HELP,
1707 MPFROM2SHORT(HELP_WALKEM2, 0), MPFROMSHORT(HM_RESOURCEID));
1708 break;
1709
1710 case DID_CANCEL:
1711 {
1712 SWP swp;
1713 ULONG size = sizeof(SWP);
1714
1715 WinQueryWindowPos(hwnd, &swp);
1716 PrfWriteProfileData(fmprof, FM3Str, "WalkDir2.Position", (PVOID) &swp,
1717 size);
1718 }
1719 WinDismissDlg(hwnd, 0);
1720 break;
1721 }
1722 return 0;
1723
1724 case WM_CLOSE:
1725 break;
1726 }
1727 return WinDefDlgProc(hwnd, msg, mp1, mp2);
1728}
1729
1730MRESULT EXPENTRY WalkTwoCmpDlgProc(HWND hwnd, ULONG msg, MPARAM mp1,
1731 MPARAM mp2)
1732{
1733 switch (msg) {
1734 case WM_INITDLG:
1735 WinSetWindowText(hwnd, (CHAR *) GetPString(IDS_WALKCOMPAREDLGTEXT));
1736 return WalkTwoDlgProc(hwnd, UM_SETUP2, mp1, mp2);
1737 }
1738 return WalkTwoDlgProc(hwnd, msg, mp1, mp2);
1739}
1740
1741MRESULT EXPENTRY WalkTwoSetDlgProc(HWND hwnd, ULONG msg, MPARAM mp1,
1742 MPARAM mp2)
1743{
1744 switch (msg) {
1745 case WM_INITDLG:
1746 WinSetWindowText(hwnd, (CHAR *) GetPString(IDS_WALKSETDIRSDLGTEXT));
1747 return WalkTwoDlgProc(hwnd, UM_SETUP2, mp1, mp2);
1748 }
1749 return WalkTwoDlgProc(hwnd, msg, mp1, mp2);
1750}
1751
1752#pragma alloc_text(WALKER,FillPathListBox,WalkDlgProc,TextSubProc)
1753#pragma alloc_text(WALKER,WalkAllDlgProc,WalkCopyDlgProc)
1754#pragma alloc_text(WALKER,WalkMoveDlgProc,WalkExtractDlgProc,WalkTargetDlgProc)
1755#pragma alloc_text(WALK2,WalkTwoDlgProc,WalkTwoCmpDlgProc,WalkTwoSetDlgProc)
1756#pragma alloc_text(UDIRS,add_udir,remove_udir,remove_ldir,load_udirs)
1757#pragma alloc_text(UDIRS,save_udirs,load_setups,save_setups,add_setups)
1758#pragma alloc_text(UDIRS,remove_setup)
Note: See TracBrowser for help on using the repository browser.