source: trunk/dll/walkem.c@ 1471

Last change on this file since 1471 was 1471, checked in by Steven Levine, 16 years ago

Remember last filter mask selection
Use Ctrl-click to select state or commonly used directory quicklist entry without activating.
Use Ctrl-click to select walk dialog user list entry without activating.
Avoid drivebar MB2 exception
Remember last seek and scan mask selection across runs
Avoid traps when changing tree container display style
Restore missing drives to drive list dropdown
Minor documentation updates

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