source: trunk/dll/dircnrs.c@ 1844

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

Serialize local hard drive scanning to reduce drive thrashing continue to scan all other drive types in separate threads. Ticket [561] Remove unneed SubbyScan code and improve suppression of blank lines and duplicate subdirectory name caused by running Stubby in worker threads.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 107.3 KB
Line 
1
2/***********************************************************************
3
4 $Id: dircnrs.c 1838 2015-08-02 22:14:21Z gyoung $
5
6 Directory containers
7
8 Copyright (c) 1993-98 M. Kimes
9 Copyright (c) 2001, 2010 Steven H. Levine
10
11 16 Oct 02 SHL Handle large partitions
12 01 Aug 04 SHL Rework lstrip/rstrip usage
13 23 May 05 SHL Use QWL_USER
14 24 May 05 SHL Rework Win_Error usage
15 25 May 05 SHL Use ULONGLONG and CommaFmtULL
16 26 May 05 SHL More large file formatting updates
17 05 Jun 05 SHL Use QWL_USER
18 10 Nov 05 SHL Comments
19 13 Jul 06 SHL Use Runtime_Error
20 26 Jul 06 SHL Use chop_at_crnl
21 15 Aug 06 SHL Rework warning message text
22 07 Jan 07 GKY Move error strings etc. to string file
23 30 Mar 07 GKY Remove GetPString for window class names
24 06 Apr 07 GKY Work around PM DragInfo and DrgFreeDISH limits
25 06 Apr 07 GKY Add some error checking in drag/drop
26 19 Apr 07 SHL Use FreeDragInfoData. Add more drag/drop error checking.
27 12 May 07 SHL Use dcd->ulItemsToUnHilite; sync with UnHilite arg mods
28 10 Jun 07 GKY Add CheckPmDrgLimit including IsFm2Window as part of work around PM drag limit
29 02 Aug 07 SHL Sync with CNRITEM mods
30 06 Aug 07 GKY Reduce DosSleep times (ticket 148)
31 20 Aug 07 GKY Move #pragma alloc_text to end for OpenWatcom compat
32 26 Aug 07 GKY DosSleep(1) in loops changed to (0)
33 22 Nov 07 GKY Use CopyPresParams to fix presparam inconsistencies in menus
34 10 Jan 08 SHL Sync with CfgDlgProc mods
35 19 Jan 08 JBS Ticket 150: fix/improve save and restore of dir cnr state at FM/2 close/reopen
36 15 Feb 08 SHL Sync with settings menu rework
37 22 Feb 08 JBS Ticket 230: Fix/improve various code related to state or presparam values in the INI file.
38 11 May 08 GKY Avoid using stale dcd after free
39 11 May 08 SHL Add stale dcd sanity checks
40 21 Jun 08 GKY Fix columns to honor preferences on new container open.
41 22 Jun 08 GKY Included free_... functions for fortify checking
42 06 Jul 08 GKY Update delete/undelete to include move to and open XWP trashcan
43 11 Jul 08 JBS Ticket 230: Simplified code and eliminated some local variables by incorporating
44 all the details view settings (both the global variables and those in the
45 DIRCNRDATA struct) into a new struct: DETAILS_SETTINGS.
46 20 Jul 08 GKY Add save/append filename to clipboard.
47 Change menu wording to make these easier to find
48 02 Aug 08 GKY Always pass temp variable point to treecnr UM_SHOWME to avoid
49 freeing dcd->directory early
50 25 Aug 08 GKY Check TMP directory space warn if lee than 5 MiB prevent archiver from opening if
51 less than 10 KiB (It hangs and can't be closed)
52 29 Nov 08 GKY Remove or replace with a mutex semaphore DosEnterCriSec where appropriate.
53 10 Dec 08 SHL Integrate exception handler support
54 26 Dec 08 GKY Fixed DROPHELP to check for copy as default is action is DO_DEFAULT
55 01 Jan 09 GKY Add Seek and Scan to drives & directory context menus pass drive/dir as search root
56 07 Feb 09 GKY Eliminate Win_Error2 by moving function names to PCSZs used in Win_Error
57 07 Feb 09 GKY Move repeated strings to PCSZs.
58 07 Feb 09 GKY Allow user to turn off alert and/or error beeps in settings notebook.
59 07 Feb 09 GKY Add *DateFormat functions to format dates based on locale
60 08 Mar 09 GKY Renamed commafmt.h i18nutil.h
61 08 Mar 09 GKY Additional strings move to PCSZs in init.c
62 12 Mar 09 SHL Use common SearchContainer
63 14 Mar 09 GKY Prevent execution of UM_SHOWME while drive scan is occuring
64 29 Mar 09 SHL Keep more keys away from PM if extended search in progress
65 29 Mar 09 SHL Increase extended search timeout to 3 seconds
66 28 Jun 09 GKY Added AddBackslashToPath() to remove repeatative code.
67 22 Jul 09 GKY Code changes to use semaphores to serialize drive scanning
68 22 Jul 09 SHL Cleanup of SETFOCUS code
69 14 Sep 09 SHL Drop experimental code
70 15 Sep 09 SHL Show rescan progress while filling container
71 13 Dec 09 GKY Fixed separate paramenters. Please note that appname should be used in
72 profile calls for user settings that work and are setable in more than one
73 miniapp; FM3Str should be used for setting only relavent to FM/2 or that
74 aren't user settable; realappname should be used for setting applicable to
75 one or more miniapp but not to FM/2
76 17 Jan 10 GKY Changes to get working with Watcom 1.9 Beta (1/16/10).
77 Mostly cast CHAR CONSTANT * as CHAR *.
78 28 May 10 GKY Yet another attempt to prevent duplicate directory names in the tree by
79 suppressing SHOW_ME during initial drive scan.
80 20 Nov 10 GKY Rework scanning code to remove redundant scans, prevent double directory
81 entries in the tree container, fix related semaphore performance using
82 combination of event and mutex semaphores
83 04 Aug 12 GKY Changes to use Unlock to unlock files if Unlock.exe is in path both from menu/toolbar and as part of
84 copy, move and delete operations
85 22 Feb 14 GKY Fix warn readonly yes don't ask to work when recursing directories.
86 02 Mar 14 GKY Speed up intial drive scans Ticket 528
87 26 Jun 14 SHL Rework DirObjWndProc UM_RESCAN to avoid hanging FM/2 Lite when tree hidden
88 30 Aug 14 GKY Add semaphore hmtxFiltering to prevent freeing dcd while filtering. Prevents
89 a trap when FM2 is shutdown while directory containers are still populating
90 02 May 15 GKY Changes to allow a JAVA executable object to be created using "Real object"
91 menu item on a jar file.
92 02 Aug 15 GKY Remove unneed SubbyScan code and improve suppression of blank lines and
93 duplicate subdirectory name caused by running Stubby in worker threads.
94
95***********************************************************************/
96
97#include <stdlib.h>
98#include <string.h>
99#include <ctype.h>
100#include <limits.h>
101//#include <malloc.h> // _msize _heapchk
102// #include <process.h> // _beginthread
103
104#define INCL_DOS
105#define INCL_WIN
106#define INCL_DOSERRORS
107#define INCL_LONGLONG
108#define INCL_WINWORKPLACE
109
110#include "fm3dll.h"
111#include "fm3dll2.h" // #define's for UM_*, control id's, etc.
112#include "mainwnd2.h" // Data declaration(s)
113#include "grep.h" // Data declaration(s)
114#include "info.h" // Data declaration(s)
115#include "treecnr.h" // Data declaration(s)
116#include "dircnrs.h" // Data declaration(s)
117#include "init.h" // Data declaration(s)
118#include "fm3dlg.h"
119#include "fm3str.h"
120#include "mle.h"
121#include "arccnrs.h" // StartArcCnr
122#include "comp.h" // COMPARE
123#include "filldir.h" // EmptyCnr...
124#include "errutil.h" // Dos_Error...
125#include "strutil.h" // GetPString
126#include "notebook.h" // CfgDlgProc
127#include "command.h" // RunCommand
128#include "worker.h" // Action, MassAction
129#include "misc.h" // GetTidForThread, AdjustCnrColsForFSType, AdjustCnrColsForPref
130 // AdjustDetailsSwitches, CnrDirectEdit, OpenEdit, QuickPopup
131 // SayFilter, SaySort, SayView, SetCnrCols, SetDetailsSwitches
132 // SetSortChecks, SetViewMenu, SwitchCommand, CheckMenu
133 // CurrentRecord, DrawTargetEmphasis, IsFm2Window
134#include "chklist.h" // CenterOverWindow, DropListProc
135#include "common.h" // CommonCnrProc, CommonCreateTextChildren, CommonFrameWndProc
136 // CommonTextPaint, CommonTextButton, CommonTextProc
137#include "mainwnd.h" // CountDirCnrs, GetNextWindowPos, MakeBubble, TopWindow
138#include "select.h" // DeselectAll, HideAll, InvertAll, SelectAll, SelectList
139 // SpecialSelect2
140#include "dirsize.h" // DirSizeProc
141#include "flesh.h" // Flesh, Stubby, UnFlesh
142#include "valid.h" // IsValidDir
143#include "objwin.h" // MakeObjWin
144#include "notify.h" // NotifyError
145#include "objcnr.h" // ObjCnrDlgProc
146#include "draglist.h" // DoFileDrag, FreeDragInfoData, PickUp
147#include "saveclip.h" // SaveListDlgProc
148#include "findrec.h" // ShowCnrRecord
149#include "sortcnr.h" // SortDirCnr
150#include "seeall.h" // StartSeeAll
151#include "update.h" // UpdateCnrList, UpdateCnrRecord
152#include "walkem.h" // add_udir
153#include "strips.h" // chop_at_crnl
154#include "droplist.h" // AcceptOneDrop, CheckPmDrgLimit, DropHelp, GetOneDrop
155#include "presparm.h" // CopyPresParams
156#include "defview.h" // DefaultViewKeys
157#include "systemf.h" // ExecOnList
158#include "filter.h" // Filter
159#include "findrec.h" // FindCnrRecord
160#include "input.h" // InputDlgProc
161#include "shadow.h" // OpenObject
162#include "mkdir.h" // PMMkDir
163#include "collect.h" // StartCollector
164#include "viewer.h" // StartMLEEditor
165#include "newview.h" // StartViewer
166#include "undel.h" // UndeleteDlgProc
167#include "i18nutil.h" // commafmt
168#include "getnames.h" // insert_filename
169#include "wrappers.h" // xfree
170#include "fortify.h"
171#include "excputil.h" // 06 May 08 SHL added
172#include "pathutil.h" // AddBackslashToPath
173#include "copyf.h" // ignorereadonly
174#if 0
175#define __PMPRINTF__
176#include "PMPRINTF.H"
177#endif
178
179// Data definitions
180#pragma data_seg(GLOBAL1)
181HWND DirCnrMenu;
182HWND hwndAttr;
183HWND hwndDate;
184
185#pragma data_seg(GLOBAL2)
186INT sortFlags;
187
188#pragma data_seg(DATA1)
189
190static PSZ pszSrcFile = __FILE__;
191
192MRESULT EXPENTRY DirFrameWndProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
193{
194 return CommonFrameWndProc(DIR_CNR, hwnd, msg, mp1, mp2);
195}
196
197MRESULT EXPENTRY DirTextProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
198{
199 static BOOL emphasized = FALSE;
200 static HWND hwndButtonPopup = (HWND) 0;
201 static USHORT lastid = 0;
202 static ULONG timestamp = ULONG_MAX;
203
204 switch (msg) {
205 case WM_CREATE:
206 return CommonTextProc(hwnd, msg, mp1, mp2);
207
208 case WM_COMMAND:
209 {
210 DIRCNRDATA *dcd;
211 MRESULT mr;
212
213 mr = WinSendMsg(WinWindowFromID(WinQueryWindow(hwnd,
214 QW_PARENT),
215 DIR_CNR), msg, mp1, mp2);
216 if (hwndButtonPopup &&
217 SHORT1FROMMP(mp1) > IDM_DETAILSTITLES &&
218 SHORT1FROMMP(mp1) < IDM_DETAILSSETUP) {
219 dcd = WinQueryWindowPtr(WinWindowFromID(WinQueryWindow(hwnd,
220 QW_PARENT),
221 DIR_CNR), QWL_USER);
222 if (dcd)
223 SetDetailsSwitches(hwndButtonPopup, &dcd->ds);
224 }
225 return mr;
226 }
227
228 case UM_CONTEXTMENU:
229 case WM_CONTEXTMENU:
230 {
231 USHORT id;
232
233 id = WinQueryWindowUShort(hwnd, QWS_ID);
234 switch (id) {
235 case DIR_FOLDERICON:
236 if (fNoFoldMenu) {
237 PostMsg(WinWindowFromID(WinQueryWindow(hwnd, QW_PARENT),
238 DIR_CNR),
239 WM_COMMAND, MPFROM2SHORT(IDM_PREVIOUS, 0), mp2);
240 break;
241 }
242 // else intentional fallthru
243 case DIR_SELECTED:
244 case DIR_VIEW:
245 case DIR_SORT:
246 {
247 POINTL ptl = { 0, 0 };
248 SWP swp;
249 DIRCNRDATA *dcd;
250
251 if (hwndButtonPopup)
252 WinDestroyWindow(hwndButtonPopup);
253 if (id == DIR_SELECTED && msg == WM_CONTEXTMENU)
254 id = DIR_MAX;
255 if (id == lastid) {
256
257 ULONG check;
258
259 DosQuerySysInfo(QSV_MS_COUNT,
260 QSV_MS_COUNT, &check, sizeof(check));
261 if (check < timestamp + 500) {
262 lastid = 0;
263 goto MenuAbort;
264 }
265 }
266 hwndButtonPopup = WinLoadMenu(HWND_DESKTOP, FM3ModHandle, id);
267 CopyPresParams(hwndButtonPopup, hwnd);
268 if (hwndButtonPopup) {
269 WinSetWindowUShort(hwndButtonPopup, QWS_ID, id);
270 dcd = WinQueryWindowPtr(WinWindowFromID(WinQueryWindow(hwnd,
271 QW_PARENT),
272 DIR_CNR), QWL_USER);
273 if (id == DIR_SORT) { // don't have sort pathname in dirs
274 WinSendMsg(hwndButtonPopup,
275 MM_DELETEITEM,
276 MPFROM2SHORT(IDM_SORTNAME, FALSE), MPVOID);
277 WinSendMsg(hwndButtonPopup,
278 MM_DELETEITEM,
279 MPFROM2SHORT(IDM_SORTNONE, FALSE), MPVOID);
280 if (dcd)
281 SetSortChecks(hwndButtonPopup, dcd->sortFlags);
282 }
283 else if (id == DIR_VIEW) {
284 if (dcd) {
285 SetViewMenu(hwndButtonPopup, dcd->flWindowAttr);
286 SetDetailsSwitches(hwndButtonPopup, &dcd->ds);
287 }
288 }
289 else if (id == DIR_MAX) {
290
291 int x;
292 BOOL enable;
293 USHORT ids[] = { IDM_SELECTBOTH,
294 IDM_SELECTMORE,
295 IDM_SELECTONE,
296 IDM_SELECTNEWER,
297 IDM_SELECTOLDER,
298 IDM_SELECTBIGGER,
299 IDM_SELECTSMALLER,
300 IDM_DESELECTBOTH,
301 IDM_DESELECTMORE,
302 IDM_DESELECTONE,
303 IDM_DESELECTNEWER,
304 IDM_DESELECTOLDER,
305 IDM_DESELECTBIGGER,
306 IDM_DESELECTSMALLER,
307 0
308 };
309
310 enable = (CountDirCnrs(dcd->hwndParent) > 1);
311 for (x = 0; ids[x]; x++)
312 WinEnableMenuItem(hwndButtonPopup, ids[x], enable);
313 }
314 else if (id == DIR_SELECTED) {
315 if (dcd)
316 WinEnableMenuItem(hwndButtonPopup,
317 IDM_RESELECT, (dcd->lastselection != NULL));
318 }
319 ptl.x = 0;
320 if (WinPopupMenu(HWND_OBJECT,
321 HWND_OBJECT,
322 hwndButtonPopup, -32767, -32767, 0, 0)) {
323 WinQueryWindowPos(hwndButtonPopup, &swp);
324 ptl.y = -(swp.cy + 2);
325 }
326 else {
327 WinQueryWindowPos(hwnd, &swp);
328 ptl.y = swp.cy + 2;
329 }
330 if (WinPopupMenu(hwnd,
331 hwnd,
332 hwndButtonPopup,
333 ptl.x,
334 ptl.y,
335 0,
336 PU_HCONSTRAIN | PU_VCONSTRAIN |
337 PU_KEYBOARD | PU_MOUSEBUTTON1)) {
338 CenterOverWindow(hwndButtonPopup);
339 PaintRecessedWindow(hwnd, (HPS) 0, FALSE, FALSE);
340 }
341 }
342 }
343 break;
344 default:
345 PostMsg(WinWindowFromID(WinQueryWindow(hwnd, QW_PARENT), DIR_CNR),
346 WM_CONTROL, MPFROM2SHORT(DIR_CNR, CN_CONTEXTMENU), MPVOID);
347 break;
348 }
349 } // case WM_CONTENT_MENU
350
351 MenuAbort:
352
353 if (msg == UM_CONTEXTMENU)
354 return 0;
355 break;
356
357 case WM_MENUEND:
358 if (hwndButtonPopup == (HWND) mp2) {
359 lastid = WinQueryWindowUShort((HWND) mp2, QWS_ID);
360 WinDestroyWindow(hwndButtonPopup);
361 hwndButtonPopup = (HWND) 0;
362 DosQuerySysInfo(QSV_MS_COUNT,
363 QSV_MS_COUNT, &timestamp, sizeof(timestamp));
364 switch (lastid) {
365 case DIR_VIEW:
366 case DIR_SORT:
367 case DIR_FOLDERICON:
368 case DIR_SELECTED:
369 case DIR_MAX:
370 PaintRecessedWindow(hwnd, (HPS) 0, TRUE, FALSE);
371 break;
372 }
373 }
374 break;
375
376 case WM_BUTTON3DOWN:
377 case WM_BUTTON1DOWN:
378 case WM_BUTTON3UP:
379 case WM_BUTTON1UP:
380 {
381 USHORT id;
382
383 id = WinQueryWindowUShort(hwnd, QWS_ID);
384 switch (id) {
385 case DIR_FILTER:
386 case DIR_VIEW:
387 case DIR_SORT:
388 case DIR_SELECTED:
389 case DIR_FOLDERICON:
390 case DIR_MAX:
391 return CommonTextButton(hwnd, msg, mp1, mp2);
392 }
393 }
394 break;
395
396 case WM_BUTTON1DBLCLK:
397 {
398 NOTIFYRECORDENTER nr;
399
400 if (WinQueryWindowUShort(hwnd, QWS_ID) != DIR_FOLDERICON) {
401 memset(&nr, 0, sizeof(NOTIFYRECORDENTER));
402 nr.hwndCnr = WinWindowFromID(WinQueryWindow(hwnd, QW_PARENT), DIR_CNR);
403 WinSendMsg(WinQueryWindow(hwnd, QW_PARENT),
404 WM_CONTROL, MPFROM2SHORT(DIR_CNR, CN_ENTER), MPFROMP(&nr));
405 }
406 }
407 break;
408
409 case WM_MOUSEMOVE:
410 {
411 USHORT id = WinQueryWindowUShort(hwnd, QWS_ID);
412 PCSZ s = NULL;
413
414 if (fOtherHelp) {
415 if ((!hwndBubble ||
416 WinQueryWindowULong(hwndBubble, QWL_USER) != hwnd) &&
417 !WinQueryCapture(HWND_DESKTOP)) {
418 switch (id) {
419 case DIR_TOTALS:
420 s = GetPString(IDS_DIRCNRTOTALHELP);
421 break;
422 case DIR_SELECTED:
423 s = GetPString(IDS_DIRCNRSELECTEDHELP);
424 break;
425 case DIR_VIEW:
426 s = GetPString(IDS_DIRCNRVIEWHELP);
427 break;
428 case DIR_SORT:
429 s = GetPString(IDS_DIRCNRSORTHELP);
430 break;
431 case DIR_FILTER:
432 s = GetPString(IDS_DIRCNRFILTERHELP);
433 break;
434 case DIR_MAX:
435 s = GetPString(IDS_DIRCNRMAXHELP);
436 break;
437 case DIR_FOLDERICON:
438 s = GetPString(IDS_DIRCNRFOLDERHELP);
439 break;
440 default:
441 break;
442 }
443 if (s)
444 MakeBubble(hwnd, TRUE, s);
445 else if (hwndBubble)
446 WinDestroyWindow(hwndBubble);
447 }
448 }
449 switch (id) {
450 case DIR_MAX:
451 case DIR_FOLDERICON:
452 case DIR_FILTER:
453 case DIR_SORT:
454 case DIR_VIEW:
455 case DIR_SELECTED:
456 return CommonTextButton(hwnd, msg, mp1, mp2);
457 }
458 }
459 break;
460
461 case WM_CHORD:
462 case WM_BUTTON3CLICK:
463 case WM_BUTTON1CLICK:
464 case UM_CLICKED:
465 case UM_CLICKED3:
466 {
467 USHORT id, cmd = 0;
468
469 id = WinQueryWindowUShort(hwnd, QWS_ID);
470 if (msg == UM_CLICKED || msg == UM_CLICKED3) {
471 switch (id) {
472 case DIR_MAX:
473 cmd = IDM_MAXIMIZE;
474 break;
475 case DIR_VIEW:
476 case DIR_SELECTED:
477 case DIR_SORT:
478 PostMsg(hwnd, UM_CONTEXTMENU, MPVOID, MPVOID);
479 break;
480 case DIR_FILTER:
481 cmd = IDM_FILTER;
482 break;
483 default:
484 break;
485 }
486 }
487 else if (id == DIR_FOLDERICON) {
488 if ((msg == WM_BUTTON1CLICK && (SHORT2FROMMP(mp2) & KC_CTRL)))
489 cmd = IDM_PREVIOUS;
490 else if (msg == WM_BUTTON3CLICK || msg == WM_CHORD)
491 cmd = IDM_RESCAN;
492 else if (msg == WM_BUTTON1CLICK && (SHORT2FROMMP(mp2) & KC_SHIFT))
493 cmd = IDM_WALKDIR;
494 else if (msg == WM_BUTTON1CLICK && (SHORT2FROMMP(mp2) & KC_ALT))
495 cmd = IDM_WINDOWDLG;
496 else
497 cmd = IDM_PARENT;
498 }
499 if (cmd)
500 PostMsg(WinWindowFromID(WinQueryWindow(hwnd, QW_PARENT),
501 DIR_CNR),
502 WM_COMMAND, MPFROM2SHORT(cmd, 0), MPVOID);
503 }
504 if (msg == UM_CLICKED || msg == UM_CLICKED3)
505 return 0;
506 break;
507
508 case DM_DROP:
509 case DM_DRAGOVER:
510 case DM_DRAGLEAVE:
511 case DM_DROPHELP:
512 case WM_BEGINDRAG:
513 if (msg == DM_DRAGOVER) {
514 if (!emphasized) {
515 emphasized = TRUE;
516 DrawTargetEmphasis(hwnd, emphasized);
517 }
518 }
519 else if (msg != WM_BEGINDRAG) {
520 if (emphasized) {
521 emphasized = FALSE;
522 DrawTargetEmphasis(hwnd, emphasized);
523 }
524 }
525 switch (WinQueryWindowUShort(hwnd, QWS_ID)) {
526 case DIR_FOLDERICON:
527 switch (msg) {
528 case DM_DRAGOVER:
529 if (AcceptOneDrop(hwnd, mp1, mp2))
530 return MRFROM2SHORT(DOR_DROP, DO_MOVE);
531 return (MRFROM2SHORT(DOR_NODROP, 0)); // Drop not valid
532 case DM_DROPHELP:
533 DropHelp(mp1, mp2, hwnd, GetPString(IDS_DIRCNRFOLDERDROPHELP));
534 return 0;
535 case DM_DROP:
536 {
537 char szFrom[CCHMAXPATH + 2];
538
539 if (emphasized) {
540 emphasized = FALSE;
541 DrawTargetEmphasis(hwnd, emphasized);
542 }
543 if (GetOneDrop(hwnd, mp1, mp2, szFrom, sizeof(szFrom)))
544 WinSendMsg(WinWindowFromID(WinQueryWindow(hwnd, QW_PARENT),
545 DIR_CNR),
546 WM_COMMAND, MPFROM2SHORT(IDM_SWITCH, 0),
547 MPFROMP(szFrom));
548 }
549 return 0;
550 default:
551 return PFNWPStatic(hwnd, msg, mp1, mp2);
552 }
553 case DIR_MAX:
554 if (msg == WM_BEGINDRAG)
555 return PFNWPStatic(hwnd, msg, mp1, mp2);
556 default:
557 {
558 CNRDRAGINFO cnd;
559 USHORT dcmd;
560
561 switch (msg) {
562 case DM_DROP:
563 dcmd = CN_DROP;
564 break;
565 case DM_DRAGOVER:
566 dcmd = CN_DRAGOVER;
567 break;
568 case DM_DRAGLEAVE:
569 dcmd = CN_DRAGLEAVE;
570 break;
571 case DM_DROPHELP:
572 dcmd = CN_DROPHELP;
573 break;
574 case WM_BEGINDRAG:
575 dcmd = CN_INITDRAG;
576 break;
577 }
578 memset(&cnd, 0, sizeof(cnd));
579 cnd.pDragInfo = (PDRAGINFO) mp1;
580 cnd.pRecord = NULL;
581 return WinSendMsg(WinQueryWindow(hwnd, QW_PARENT),
582 WM_CONTROL,
583 MPFROM2SHORT(DIR_CNR, dcmd), MPFROMP(&cnd));
584 }
585 }
586 }
587 return PFNWPStatic(hwnd, msg, mp1, mp2);
588}
589
590MRESULT EXPENTRY DirClientWndProc(HWND hwnd, ULONG msg, MPARAM mp1,
591 MPARAM mp2)
592{
593 switch (msg) {
594 case UM_CONTAINERDIR:
595 if (mp1) {
596
597 DIRCNRDATA *dcd;
598
599 *(CHAR *)mp1 = 0;
600 dcd = WinQueryWindowPtr(WinWindowFromID(hwnd, DIR_CNR), QWL_USER);
601 if (dcd)
602 strcpy((CHAR *)mp1, dcd->directory);
603 return MRFROMLONG(TRUE);
604 }
605 return 0;
606
607 case UM_CONTAINERHWND:
608 return MRFROMLONG(WinWindowFromID(hwnd, DIR_CNR));
609
610 case UM_VIEWSMENU:
611 return MRFROMLONG(CheckMenu(hwnd, &DirCnrMenu, DIRCNR_POPUP));
612
613 case UM_DRIVECMD:
614 case WM_INITMENU:
615 case UM_FILTER:
616 case UM_INITMENU:
617 case MM_PORTHOLEINIT:
618 case UM_COMMAND:
619 case UM_FILESMENU:
620 case UM_UPDATERECORD:
621 case UM_UPDATERECORDLIST:
622 return WinSendMsg(WinWindowFromID(hwnd, DIR_CNR), msg, mp1, mp2);
623
624 case WM_PSETFOCUS:
625 case WM_SETFOCUS:
626 if (mp2)
627 PostMsg(hwnd, UM_FOCUSME, MPVOID, MPVOID);
628 break;
629
630 case UM_FOCUSME:
631 WinSetFocus(HWND_DESKTOP, WinWindowFromID(hwnd, DIR_CNR));
632 break;
633
634 case WM_PAINT:
635 {
636 HPS hps;
637 RECTL rcl;
638
639 hps = WinBeginPaint(hwnd, (HPS) 0, NULL);
640 if (hps) {
641 WinQueryWindowRect(hwnd, &rcl);
642 WinFillRect(hps, &rcl, CLR_PALEGRAY);
643 CommonTextPaint(hwnd, hps);
644 WinEndPaint(hps);
645 }
646 }
647 break;
648
649 case UM_SIZE:
650 case WM_SIZE:
651 if (msg == UM_SIZE) {
652
653 SWP swp;
654
655 WinQueryWindowPos(hwnd, &swp);
656 mp1 = MPFROM2SHORT(swp.cx, swp.cy);
657 mp2 = MPFROM2SHORT(swp.cx, swp.cy);
658 }
659 {
660 USHORT cx, cy, bx;
661
662 cx = SHORT1FROMMP(mp2);
663 cy = SHORT2FROMMP(mp2);
664 WinSetWindowPos(WinWindowFromID(hwnd, DIR_CNR), HWND_TOP,
665 0, 0, cx, cy - 24, SWP_SHOW | SWP_MOVE | SWP_SIZE);
666 if (WinWindowFromID(hwnd, DIR_MAX) != (HWND) 0) {
667 WinSetWindowPos(WinWindowFromID(hwnd, DIR_MAX), HWND_TOP,
668 cx - 22,
669 cy - 22, 20, 20, SWP_SHOW | SWP_MOVE | SWP_SIZE);
670 cx -= 24;
671 }
672 WinSetWindowPos(WinWindowFromID(hwnd, DIR_FOLDERICON), HWND_TOP,
673 2, cy - 22, 24, 20, SWP_SHOW | SWP_MOVE | SWP_SIZE);
674 WinSetWindowPos(WinWindowFromID(hwnd, DIR_TOTALS), HWND_TOP,
675 29,
676 cy - 22,
677 (cx / 3) - 2, 20, SWP_SHOW | SWP_MOVE | SWP_SIZE);
678 WinSetWindowPos(WinWindowFromID(hwnd, DIR_SELECTED), HWND_TOP,
679 29 + (cx / 3) + 2,
680 cy - 22,
681 (cx / 3) - 2, 20, SWP_SHOW | SWP_MOVE | SWP_SIZE);
682 bx = (cx - (29 + (((cx / 3) + 2) * 2))) / 3;
683 WinSetWindowPos(WinWindowFromID(hwnd, DIR_VIEW), HWND_TOP,
684 29 + (((cx / 3) + 2) * 2),
685 cy - 22, bx - 4, 20, SWP_SHOW | SWP_MOVE | SWP_SIZE);
686 WinSetWindowPos(WinWindowFromID(hwnd, DIR_SORT), HWND_TOP,
687 29 + (((cx / 3) + 2) * 2) + bx,
688 cy - 22, bx - 4, 20, SWP_SHOW | SWP_MOVE | SWP_SIZE);
689 WinSetWindowPos(WinWindowFromID(hwnd, DIR_FILTER), HWND_TOP,
690 29 + (((cx / 3) + 2) * 2) + (bx * 2),
691 cy - 22, bx - 4, 20, SWP_SHOW | SWP_MOVE | SWP_SIZE);
692 }
693 CommonTextPaint(hwnd, (HPS) 0);
694 if (msg == UM_SIZE) {
695 WinSetWindowPos(WinQueryWindow(hwnd, QW_PARENT), HWND_TOP, 0, 0, 0, 0,
696 SWP_SHOW | SWP_ZORDER | SWP_ACTIVATE);
697 return 0;
698 }
699 break;
700
701 case WM_COMMAND:
702 case WM_CONTROL:
703 case WM_CLOSE:
704 return WinSendMsg(WinWindowFromID(hwnd, DIR_CNR), msg, mp1, mp2);
705 }
706 return WinDefWindowProc(hwnd, msg, mp1, mp2);
707}
708
709MRESULT EXPENTRY DirObjWndProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
710{
711 DIRCNRDATA *dcd;
712 CHAR tf[64];
713 CHAR tb[64];
714 CHAR s[CCHMAXPATH * 2];
715
716 switch (msg) {
717 case WM_CREATE:
718 DbgMsg(pszSrcFile, __LINE__, "WM_CREATE mp1 %p mp2 %p", mp1, mp2); // 18 Jul 08 SHL fixme
719 break;
720
721 case DM_PRINTOBJECT:
722 return MRFROMLONG(DRR_TARGET);
723
724 case DM_DISCARDOBJECT:
725 dcd = INSTDATA(hwnd);
726 if (fFM2Deletes && dcd) {
727 LISTINFO *li;
728 CNRDRAGINFO cni;
729 cni.pRecord = NULL;
730 cni.pDragInfo = (PDRAGINFO) mp1;
731 li =
732 DoFileDrop(dcd->hwndCnr, dcd->directory, FALSE, MPVOID,
733 MPFROMP(&cni));
734 CheckPmDrgLimit(cni.pDragInfo);
735 if (li) {
736 li->type = (fDefaultDeletePerm) ? IDM_PERMDELETE : IDM_DELETE;
737 if (!PostMsg(hwnd, UM_MASSACTION, MPFROMP(li), MPVOID))
738 FreeListInfo(li);
739 else
740 return MRFROMLONG(DRR_SOURCE);
741 }
742 }
743 return MRFROMLONG(DRR_TARGET);
744
745 case UM_UPDATERECORDLIST:
746 dcd = WinQueryWindowPtr(hwnd, QWL_USER);
747 if (dcd && mp1) {
748
749 INT numentries = 0;
750 CHAR **list = (CHAR **) mp1;
751
752 while (list[numentries])
753 numentries++;
754 if (numentries)
755 UpdateCnrList(dcd->hwndCnr, list, numentries, TRUE, dcd);
756 }
757 return 0;
758
759 case UM_SETUP:
760# ifdef FORTIFY
761 // DbgMsg(pszSrcFile, __LINE__, "UM_SETUP hwnd %p TID %u", hwnd, GetTidForThread()); // 18 Jul 08 SHL fixme
762 Fortify_EnterScope();
763# endif
764 dcd = WinQueryWindowPtr(hwnd, QWL_USER);
765 if (dcd) {
766# ifdef FORTIFY
767 Fortify_BecomeOwner(dcd); // We free dcd
768 if (GetTidForThread() != 1)
769 Fortify_ChangeScope(dcd, -1);
770# endif
771 // set unique id
772 WinSetWindowUShort(hwnd, QWS_ID, DIROBJ_FRAME + (DIR_FRAME - dcd->id));
773 dcd->hwndObject = hwnd;
774 if (ParentIsDesktop(hwnd, dcd->hwndParent))
775 DosSleep(100);
776 }
777 else
778 PostMsg(hwnd, WM_CLOSE, MPVOID, MPVOID);
779# ifdef FORTIFY
780 // TID 1 will free data
781 if (GetTidForThread() != 1)
782 Fortify_LeaveScope();
783# endif
784 return 0;
785
786 case UM_RESCAN2:
787 dcd = WinQueryWindowPtr(hwnd, QWL_USER);
788 if (dcd && dcd->hwndFrame == WinQueryActiveWindow(dcd->hwndParent)) {
789 FSALLOCATE fsa;
790 CHAR szFree[64];
791 DosError(FERR_DISABLEHARDERR);
792 if (!DosQueryFSInfo(toupper(*dcd->directory) - '@',
793 FSIL_ALLOC, &fsa, sizeof(FSALLOCATE))) {
794 CommaFmtULL(tb, sizeof(tb),
795 (ULONGLONG) fsa.cUnitAvail * (fsa.cSectorUnit *
796 fsa.cbSector), 'K');
797 sprintf(szFree, " {%s %s}", tb, GetPString(IDS_FREETEXT));
798 }
799 else
800 *szFree = 0;
801 DosRequestMutexSem(hmtxFiltering, SEM_INDEFINITE_WAIT);
802 commafmt(tf, sizeof(tf), dcd->totalfiles);
803 CommaFmtULL(tb, sizeof(tb), dcd->ullTotalBytes, ' ');
804 DosReleaseMutexSem(hmtxFiltering);
805 if (!fMoreButtons) {
806 sprintf(s, " [%s / %s]%s%s%s%s %s",
807 tf, tb, szFree,
808 (*dcd->mask.szMask || dcd->mask.antiattr ||
809 dcd->mask.attrFile != ALLATTRS) ? " (" : NullStr,
810 (*dcd->mask.szMask) ? dcd->mask.szMask :
811 (dcd->mask.antiattr ||
812 dcd->mask.attrFile != ALLATTRS) ?
813 GetPString(IDS_ALLTEXT) : NullStr,
814 (*dcd->mask.szMask || dcd->mask.antiattr ||
815 dcd->mask.attrFile != ALLATTRS) ? ")" : NullStr,
816 dcd->directory);
817 }
818 else {
819 sprintf(s, " [%s / %s]%s %s", tf, tb, szFree, dcd->directory);
820 }
821 if (dcd->hwndFrame == WinQueryActiveWindow(dcd->hwndParent))
822 WinSetWindowText(hwndStatus, s);
823 }
824 return 0;
825
826 case UM_FLESH:
827 dcd = WinQueryWindowPtr(hwnd, QWL_USER);
828 if (dcd) {
829
830 PCNRITEM pci, pciC;
831
832 pci = WinSendMsg(dcd->hwndCnr,
833 CM_QUERYRECORD,
834 MPVOID, MPFROM2SHORT(CMA_FIRST, CMA_ITEMORDER));
835 while (pci && (INT) pci != -1) {
836 if (!pci->pszFileName || !strcmp(pci->pszFileName, NullStr)) {
837 Runtime_Error(pszSrcFile, __LINE__, "pci->pszFileName NULL for %p", pci);
838 return 0;
839 }
840 if (pci->attrFile & FILE_DIRECTORY) {
841 pciC = WinSendMsg(dcd->hwndCnr,
842 CM_QUERYRECORD,
843 MPFROMP(pci),
844 MPFROM2SHORT(CMA_FIRSTCHILD, CMA_ITEMORDER));
845 if (!pciC) {
846 Stubby(dcd->hwndCnr, pci);
847 }
848 }
849 pci = WinSendMsg(dcd->hwndCnr,
850 CM_QUERYRECORD,
851 MPFROMP(pci), MPFROM2SHORT(CMA_NEXT, CMA_ITEMORDER));
852 }
853 dcd->firsttree = TRUE;
854 }
855 return 0;
856
857 case UM_RESCAN:
858 // populate container
859 dcd = WinQueryWindowPtr(hwnd, QWL_USER);
860 if (dcd) {
861 DosRequestMutexSem(hmtxFM2Globals, SEM_INDEFINITE_WAIT);
862 if (dcd->stopflag)
863 dcd->stopflag--;
864 if (dcd->stopflag) {
865 DosReleaseMutexSem(hmtxFM2Globals);
866 return 0;
867 }
868 DosReleaseMutexSem(hmtxFM2Globals);
869 if (mp1) {
870 strcpy(dcd->previous, dcd->directory);
871 strcpy(dcd->directory, (CHAR *)mp1);
872 }
873 MakeValidDir(dcd->directory);
874 {
875 sprintf(s,
876 "%s%s%s",
877 (ParentIsDesktop(dcd->hwndFrame, (HWND) 0)) ?
878 "VDir" :
879 NullStr,
880 (ParentIsDesktop(dcd->hwndFrame, (HWND) 0)) ?
881 (!dcd->dontclose) ?
882 " Master: " : ": " : NullStr, dcd->directory);
883 WinSetWindowText(dcd->hwndFrame, s);
884 WinSetWindowText(WinWindowFromID(dcd->hwndFrame, FID_TITLEBAR), s);
885 }
886 RemoveCnrItems(dcd->hwndCnr, NULL, 0, CMA_FREE | CMA_INVALIDATE | CMA_ERASE);
887 AdjustCnrColsForFSType(dcd->hwndCnr, dcd->directory, &dcd->ds, FALSE);
888 DosRequestMutexSem(hmtxFiltering, SEM_INDEFINITE_WAIT);
889 dcd->ullTotalBytes = dcd->totalfiles = dcd->selectedfiles = dcd->selectedbytes = 0;
890 DosReleaseMutexSem(hmtxFiltering);
891 WinSetDlgItemText(dcd->hwndClient, DIR_TOTALS, "0 / 0k");
892 WinSetDlgItemText(dcd->hwndClient, DIR_SELECTED, "0 / 0k");
893 if (hwndStatus &&
894 dcd->hwndFrame == WinQueryActiveWindow(dcd->hwndParent)) {
895 WinSetWindowText(hwndStatus, (CHAR *) GetPString(IDS_PLEASEWAITSCANNINGTEXT));
896 if (hwndMain)
897 WinSendMsg(hwndMain, UM_LOADFILE, MPVOID, MPVOID);
898 }
899 // 2014-06-26 SHL FM/2 Lite may not have drive tree yet
900 if (hwndTree) {
901 if (fSwitchTreeOnDirChg) {
902 // Keep drive tree in sync with directory container
903 PSZ pszTempDir;
904 while (fInitialDriveScan)
905 DosSleep(10); // Allow to complete
906 DosSleep(50);
907 pszTempDir = xstrdup(dcd->directory, pszSrcFile, __LINE__);
908 if (pszTempDir) {
909 if (hwndMain) {
910 if (TopWindow(hwndMain, (HWND) 0) == dcd->hwndFrame)
911 if (!PostMsg(hwndTree, UM_SHOWME, MPFROMP(pszTempDir), MPVOID))
912 free(pszTempDir);
913 }
914 else {
915 if (!PostMsg(hwndTree, UM_SHOWME, MPFROMP(pszTempDir), MPVOID))
916 free(pszTempDir);
917 }
918 }
919 } // fSwitchTreeOnDirChg
920 } // if hwndTree
921 dcd->firsttree = FALSE;
922 WinStartTimer(WinQueryAnchorBlock(hwnd), dcd->hwndCnr, ID_DIRCNR_TIMER, 500);
923 // fixme to check errors
924 FillDirCnr(dcd->hwndCnr, dcd->directory, dcd, &dcd->ullTotalBytes);
925 WinStopTimer(WinQueryAnchorBlock(hwnd), dcd->hwndCnr, ID_DIRCNR_TIMER);
926 PostMsg(dcd->hwndCnr, UM_RESCAN, MPVOID, MPVOID);
927 if (mp2 && !fLeaveTree && (dcd->flWindowAttr & CV_TREE)) {
928 ULONG flWindowAttr = dcd->flWindowAttr;
929 CNRINFO cnri;
930 flWindowAttr &= ~(CV_NAME | CV_TREE | CV_ICON | CV_DETAIL | CV_TEXT);
931 if (dcd->lastattr) {
932 if (dcd->lastattr & CV_TEXT)
933 flWindowAttr |= CV_TEXT;
934 else if (dcd->lastattr & CV_DETAIL)
935 flWindowAttr |= CV_DETAIL;
936 else if (dcd->lastattr & CV_ICON)
937 flWindowAttr |= CV_ICON;
938 else
939 flWindowAttr |= CV_NAME;
940 }
941 else
942 flWindowAttr |= CV_NAME;
943 flWindowAttr |= CV_FLOW;
944 memset(&cnri, 0, sizeof(CNRINFO));
945 cnri.cb = sizeof(CNRINFO);
946 if (WinSendMsg(dcd->hwndCnr, CM_QUERYCNRINFO, MPFROMP(&cnri),
947 MPFROMLONG(sizeof(CNRINFO)))) {
948 dcd->flWindowAttr = cnri.flWindowAttr = flWindowAttr;
949 WinSendMsg(dcd->hwndCnr, CM_SETCNRINFO,
950 MPFROMP(&cnri), MPFROMLONG(CMA_FLWINDOWATTR));
951 SayView(WinWindowFromID(dcd->hwndClient,
952 DIR_VIEW), dcd->flWindowAttr);
953 }
954 }
955 if (dcd->flWindowAttr & CV_TREE)
956 PostMsg(dcd->hwndObject, UM_FLESH, MPVOID, MPVOID);
957 if (*dcd->previous) {
958 if (strlen(dcd->previous) > strlen(dcd->directory) &&
959 !strnicmp(dcd->directory, dcd->previous,
960 strlen(dcd->directory)))
961 {
962 PCNRITEM pci = FindCnrRecord(dcd->hwndCnr,
963 dcd->previous,
964 NULL, TRUE, FALSE, TRUE);
965 if (pci && (INT) pci != -1) {
966 // make found item current (cursored) item
967 WinSendMsg(dcd->hwndCnr, CM_SETRECORDEMPHASIS, MPFROMP(pci),
968 MPFROM2SHORT(TRUE, CRA_CURSORED));
969 // make sure that record shows in viewport
970 ShowCnrRecord(dcd->hwndCnr, (PMINIRECORDCORE) pci);
971 }
972 }
973 }
974 }
975 return 0;
976
977 case UM_COMMAND:
978 if (mp1) {
979
980 LISTINFO *li = (LISTINFO *) mp1;
981
982 switch (li->type) {
983 case IDM_DOITYOURSELF:
984 case IDM_APPENDTOCLIP:
985 case IDM_APPENDTOCLIPFILENAME:
986 case IDM_SAVETOCLIP:
987 case IDM_SAVETOCLIPFILENAME:
988 case IDM_ARCHIVE:
989 case IDM_ARCHIVEM:
990 case IDM_VIEWTEXT:
991 case IDM_VIEWBINARY:
992 case IDM_VIEWARCHIVE:
993 case IDM_VIEW:
994 case IDM_EDITTEXT:
995 case IDM_EDITBINARY:
996 case IDM_EDIT:
997 case IDM_OBJECT:
998 case IDM_SHADOW:
999 case IDM_SHADOW2:
1000 case IDM_JAVAEXE:
1001 case IDM_PRINT:
1002 case IDM_ATTRS:
1003 case IDM_DELETE:
1004 case IDM_PERMDELETE:
1005 case IDM_MCIPLAY:
1006 case IDM_UPDATE:
1007 if (li->type == IDM_DELETE)
1008 ignorereadonly = FALSE;
1009 if (PostMsg(hwnd, UM_MASSACTION, mp1, mp2))
1010 return (MRESULT) TRUE;
1011 break;
1012 default:
1013 if (PostMsg(hwnd, UM_ACTION, mp1, mp2))
1014 return (MRESULT) TRUE;
1015 }
1016 }
1017 return 0;
1018
1019 case UM_SELECT:
1020 dcd = WinQueryWindowPtr(hwnd, QWL_USER);
1021 if (dcd) {
1022 switch (SHORT1FROMMP(mp1)) {
1023 case IDM_SELECTBOTH:
1024 case IDM_SELECTONE:
1025 case IDM_SELECTMORE:
1026 case IDM_SELECTNEWER:
1027 case IDM_SELECTOLDER:
1028 case IDM_SELECTBIGGER:
1029 case IDM_SELECTSMALLER:
1030 case IDM_DESELECTBOTH:
1031 case IDM_DESELECTONE:
1032 case IDM_DESELECTMORE:
1033 case IDM_DESELECTNEWER:
1034 case IDM_DESELECTOLDER:
1035 case IDM_DESELECTBIGGER:
1036 case IDM_DESELECTSMALLER:
1037 SpecialSelect2(dcd->hwndParent, SHORT1FROMMP(mp1));
1038 break;
1039 case IDM_SELECTLIST:
1040 {
1041 CHAR filename[CCHMAXPATH], *p, *pp;
1042 ULONG size;
1043
1044 strcpy(filename, PCSZ_STARDOTLST);
1045 size = CCHMAXPATH;
1046 PrfQueryProfileData(fmprof, appname, "SaveToListName",
1047 filename, &size);
1048 pp = strrchr(filename, '\\');
1049 if (!pp)
1050 pp = filename;
1051 p = strrchr(pp, '.');
1052 if (p && *(p + 1) && p > pp + 1) {
1053 if (pp > filename)
1054 pp++;
1055 *pp = '*';
1056 pp++;
1057 if (p > pp)
1058 memmove(pp, p, strlen(p) + 1);
1059 }
1060 if (insert_filename(hwnd, filename, FALSE, FALSE))
1061 SelectList(dcd->hwndCnr, TRUE, FALSE, FALSE, NULL, filename,
1062 NULL);
1063 }
1064 break;
1065 case IDM_SELECTALL:
1066 SelectAll(dcd->hwndCnr, TRUE, TRUE, NULL, NULL, FALSE);
1067 break;
1068 case IDM_DESELECTALL:
1069 DeselectAll(dcd->hwndCnr, TRUE, TRUE, NULL, NULL, FALSE);
1070 break;
1071 case IDM_SELECTALLFILES:
1072 SelectAll(dcd->hwndCnr, TRUE, FALSE, NULL, NULL, FALSE);
1073 break;
1074 case IDM_DESELECTALLFILES:
1075 DeselectAll(dcd->hwndCnr, TRUE, FALSE, NULL, NULL, FALSE);
1076 break;
1077 case IDM_SELECTALLDIRS:
1078 SelectAll(dcd->hwndCnr, FALSE, TRUE, NULL, NULL, FALSE);
1079 break;
1080 case IDM_DESELECTALLDIRS:
1081 DeselectAll(dcd->hwndCnr, FALSE, TRUE, NULL, NULL, FALSE);
1082 break;
1083 case IDM_DESELECTMASK:
1084 case IDM_SELECTMASK:
1085 {
1086 MASK mask;
1087 PCNRITEM pci = (PCNRITEM) mp2;
1088
1089 memset(&mask, 0, sizeof(MASK));
1090 mask.fNoAttribs = TRUE;
1091 mask.fNoDirs = TRUE;
1092 mask.fText = TRUE;
1093 strcpy(mask.prompt,
1094 GetPString((SHORT1FROMMP(mp1) == IDM_SELECTMASK) ?
1095 IDS_SELECTFILTERTEXT : IDS_DESELECTFILTERTEXT));
1096 if (pci && (INT) pci != -1)
1097 strcpy(mask.szMask, pci->pszFileName);
1098 if (WinDlgBox(HWND_DESKTOP,
1099 dcd->hwndCnr,
1100 PickMaskDlgProc,
1101 FM3ModHandle, MSK_FRAME, MPFROMP(&mask))) {
1102 if (SHORT1FROMMP(mp1) == IDM_SELECTMASK)
1103 SelectAll(dcd->hwndCnr,
1104 TRUE, TRUE, mask.szMask, mask.szText, FALSE);
1105 else
1106 DeselectAll(dcd->hwndCnr,
1107 TRUE, TRUE, mask.szMask, mask.szText, FALSE);
1108 }
1109 }
1110 break;
1111
1112 case IDM_DESELECTCLIP:
1113 case IDM_SELECTCLIP:
1114 {
1115 CHAR **list;
1116
1117 list = ListFromClipboard(hwnd);
1118 if (list) {
1119 SelectList(dcd->hwndCnr, TRUE, FALSE,
1120 (SHORT1FROMMP(mp1) == IDM_DESELECTCLIP),
1121 NULL, NULL, list);
1122 FreeList(list);
1123 }
1124 }
1125 break;
1126
1127 case IDM_INVERT:
1128 InvertAll(dcd->hwndCnr);
1129 break;
1130 }
1131 }
1132 return 0;
1133
1134 case UM_MASSACTION:
1135 if (mp1) {
1136 dcd = WinQueryWindowPtr(hwnd, QWL_USER);
1137 if (dcd) {
1138 WORKER *wk;
1139# ifdef FORTIFY
1140 Fortify_EnterScope();
1141# endif
1142 wk = xmallocz(sizeof(WORKER), pszSrcFile, __LINE__);
1143 if (!wk)
1144 FreeListInfo((LISTINFO *) mp1);
1145 else {
1146 wk->size = sizeof(WORKER);
1147 wk->hwndCnr = dcd->hwndCnr;
1148 wk->hwndParent = dcd->hwndParent;
1149 wk->hwndFrame = dcd->hwndFrame;
1150 wk->hwndClient = dcd->hwndClient;
1151 wk->li = (LISTINFO *) mp1;
1152 strcpy(wk->directory, dcd->directory);
1153 if (xbeginthread(MassAction,
1154 122880,
1155 wk,
1156 pszSrcFile,
1157 __LINE__) == -1)
1158 {
1159 free(wk);
1160 FreeListInfo((LISTINFO *)mp1);
1161 }
1162 }
1163# ifdef FORTIFY
1164 DosSleep(1); // Allow MassAction to take ownership
1165 Fortify_LeaveScope();
1166# endif
1167 }
1168 }
1169 return 0;
1170
1171 case UM_ACTION:
1172 if (mp1) {
1173
1174 dcd = WinQueryWindowPtr(hwnd, QWL_USER);
1175 if (dcd) {
1176
1177 WORKER *wk;
1178# ifdef FORTIFY
1179 Fortify_EnterScope();
1180# endif
1181 wk = xmallocz(sizeof(WORKER), pszSrcFile, __LINE__);
1182 if (!wk)
1183 FreeListInfo((LISTINFO *) mp1);
1184 else {
1185 wk->size = sizeof(WORKER);
1186 wk->hwndCnr = dcd->hwndCnr;
1187 wk->hwndParent = dcd->hwndParent;
1188 wk->hwndFrame = dcd->hwndFrame;
1189 wk->hwndClient = dcd->hwndClient;
1190 wk->li = (LISTINFO *) mp1;
1191 strcpy(wk->directory, dcd->directory);
1192
1193 if (xbeginthread(Action,
1194 122880,
1195 wk,
1196 pszSrcFile,
1197 __LINE__) == -1)
1198 {
1199 Runtime_Error(pszSrcFile, __LINE__,
1200 GetPString(IDS_COULDNTSTARTTHREADTEXT));
1201 free(wk);
1202 FreeListInfo((LISTINFO *) mp1);
1203 }
1204 }
1205# ifdef FORTIFY
1206 Fortify_LeaveScope();
1207# endif
1208 }
1209 }
1210 return 0;
1211
1212 case WM_CLOSE:
1213 WinDestroyWindow(hwnd);
1214 break;
1215
1216 case WM_DESTROY:
1217# ifdef FORTIFY
1218 DbgMsg(pszSrcFile, __LINE__, "WM_DESTROY hwnd %p TID %u", hwnd, GetTidForThread()); // 18 Jul 08 SHL fixme
1219# endif
1220 dcd = WinQueryWindowPtr(hwnd, QWL_USER);
1221 if (!dcd)
1222 Runtime_Error(pszSrcFile, __LINE__, NULL);
1223 else {
1224 if (dcd->hwndRestore)
1225 WinSetWindowPos(dcd->hwndRestore,
1226 HWND_TOP,
1227 0,
1228 0,
1229 0,
1230 0,
1231 SWP_RESTORE | SWP_SHOW | SWP_ACTIVATE | SWP_ZORDER);
1232 FreeList(dcd->lastselection);
1233 WinSetWindowPtr(dcd->hwndCnr, QWL_USER, NULL); // 13 Apr 10 SHL Set NULL before freeing dcd
1234 DosRequestMutexSem(hmtxFiltering, SEM_INDEFINITE_WAIT);
1235 xfree(dcd, pszSrcFile, __LINE__);
1236 dcd = NULL;
1237 DosReleaseMutexSem(hmtxFiltering);
1238 DosPostEventSem(CompactSem);
1239 }
1240# ifdef FORTIFY
1241 Fortify_LeaveScope();
1242# endif
1243 // 22 Jul 08 SHL fixme to understand
1244 if (!PostMsg((HWND) 0, WM_QUIT, MPVOID, MPVOID))
1245 WinSendMsg((HWND) 0, WM_QUIT, MPVOID, MPVOID);
1246 break;
1247 }
1248 return WinDefWindowProc(hwnd, msg, mp1, mp2);
1249}
1250
1251MRESULT EXPENTRY DirCnrWndProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
1252{
1253 DIRCNRDATA *dcd = INSTDATA(hwnd);
1254 CHAR tf[64];
1255 CHAR tb[64];
1256 CHAR s[CCHMAXPATH];
1257
1258 switch (msg) {
1259 case WM_CREATE:
1260# ifdef FORTIFY
1261 Fortify_EnterScope();
1262# endif
1263 break;
1264
1265 case DM_PRINTOBJECT:
1266 return MRFROMLONG(DRR_TARGET);
1267
1268 case DM_DISCARDOBJECT:
1269 if (dcd)
1270 return WinSendMsg(dcd->hwndObject, msg, mp1, mp2);
1271 else
1272 return MRFROMLONG(DRR_TARGET);
1273
1274 case WM_CHAR:
1275 shiftstate = (SHORT1FROMMP(mp1) & (KC_SHIFT | KC_ALT | KC_CTRL));
1276 if (SHORT1FROMMP(mp1) & KC_KEYUP)
1277 return (MRESULT) TRUE;
1278 if (SHORT1FROMMP(mp1) & KC_VIRTUALKEY) {
1279 switch (SHORT2FROMMP(mp2)) {
1280 case VK_INSERT:
1281 if ((shiftstate & KC_CTRL) == KC_CTRL)
1282 PostMsg(hwnd, WM_COMMAND, MPFROM2SHORT(IDM_MKDIR, 0), MPVOID);
1283 // Alt-Insert - create file
1284 else if ((shiftstate & KC_ALT) == KC_ALT)
1285 PostMsg(hwnd, WM_COMMAND, MPFROM2SHORT(IDM_CREATE, 0), MPVOID);
1286 break;
1287 case VK_PAGEUP:
1288 if ((shiftstate & KC_CTRL) == KC_CTRL)
1289 PostMsg(hwnd, WM_COMMAND, MPFROM2SHORT(IDM_PARENT, 0), MPVOID);
1290 break;
1291 case VK_PAGEDOWN:
1292 if ((shiftstate & KC_CTRL) == KC_CTRL)
1293 PostMsg(hwnd, WM_COMMAND, MPFROM2SHORT(IDM_PREVIOUS, 0), MPVOID);
1294 break;
1295 case VK_HOME:
1296 if ((shiftstate & KC_CTRL) == KC_CTRL && dcd) {
1297 PSZ p;
1298 strcpy(s, dcd->directory);
1299 p = strchr(s, '\\');
1300 if (p) {
1301 p++;
1302 *p = 0;
1303 WinSendMsg(hwnd, UM_SETDIR, MPFROMP(s), MPVOID);
1304 }
1305 }
1306 break;
1307 case VK_DELETE:
1308 if ((shiftstate & KC_CTRL) == KC_CTRL)
1309 PostMsg(hwnd, WM_COMMAND, MPFROM2SHORT(IDM_PERMDELETE, 0), MPVOID);
1310 else if ((shiftstate & KC_SHIFT) == KC_SHIFT)
1311 PostMsg(hwnd, WM_COMMAND, MPFROM2SHORT(IDM_SAVETOCLIP, 0), MPVOID);
1312 else
1313 PostMsg(hwnd, WM_COMMAND, MPFROM2SHORT(IDM_DELETE, 0), MPVOID);
1314 break;
1315 } // switch
1316 }
1317
1318 if (SearchContainer(hwnd, msg, mp1, mp2))
1319 return (MRESULT)TRUE; // Avoid default handler
1320 break; // Let default handler see key too
1321
1322 case WM_MOUSEMOVE:
1323 case WM_BUTTON1UP:
1324 case WM_BUTTON2UP:
1325 case WM_BUTTON3UP:
1326 case WM_CHORD:
1327 shiftstate = (SHORT2FROMMP(mp2) & (KC_ALT | KC_SHIFT | KC_CTRL));
1328 break;
1329
1330 case WM_BUTTON1MOTIONEND:
1331 {
1332 CNRINFO cnri;
1333
1334 memset(&cnri, 0, sizeof(CNRINFO));
1335 cnri.cb = sizeof(CNRINFO);
1336 if (WinSendMsg(hwnd, CM_QUERYCNRINFO, MPFROMP(&cnri),
1337 MPFROMLONG(sizeof(CNRINFO)))) {
1338 if (cnri.flWindowAttr & CV_DETAIL)
1339 PrfWriteProfileData(fmprof, appname, "CnrSplitBar",
1340 (PVOID) & cnri.xVertSplitbar, sizeof(LONG));
1341 }
1342 }
1343 break;
1344
1345 case UM_COMPARE:
1346 if (dcd && mp1 && mp2) {
1347
1348 COMPARE *cmp;
1349 CHAR *leftdir = (CHAR *)mp1, *rightdir = (CHAR *)mp2;
1350
1351 if (!IsFile(leftdir) && !IsFile(rightdir)) {
1352# ifdef FORTIFY
1353 Fortify_EnterScope();
1354# endif
1355 cmp = xmallocz(sizeof(COMPARE), pszSrcFile, __LINE__);
1356 if (cmp) {
1357 cmp->size = sizeof(COMPARE);
1358 strcpy(cmp->leftdir, leftdir);
1359 strcpy(cmp->rightdir, rightdir);
1360 cmp->hwndParent = dcd->hwndParent;
1361 cmp->dcd.hwndParent = dcd->hwndParent;
1362 WinDlgBox(HWND_DESKTOP,
1363 HWND_DESKTOP,
1364 CompareDlgProc, FM3ModHandle, COMP_FRAME, MPFROMP(cmp));
1365 }
1366# ifdef FORTIFY
1367 Fortify_LeaveScope();
1368# endif
1369 }
1370 }
1371 return 0;
1372
1373 case WM_PRESPARAMCHANGED:
1374 PresParamChanged(hwnd, PCSZ_DIRCNR, mp1, mp2);
1375 break;
1376
1377 case UM_UPDATERECORDLIST:
1378 if (dcd && mp1)
1379 WinSendMsg(dcd->hwndObject, msg, mp1, mp2);
1380 return 0;
1381
1382 case UM_UPDATERECORD:
1383 if (dcd && mp1) {
1384
1385 CHAR *filename;
1386
1387 filename = mp1;
1388 if (filename)
1389 UpdateCnrRecord(hwnd, filename, TRUE, dcd);
1390 }
1391 return 0;
1392
1393 case WM_SETFOCUS:
1394 // put name of our window (directory name) on status line
1395 if (mp2) {
1396 // Getting focus
1397 if (dcd && hwndStatus) {
1398 // put name of our window (directory name) on status line
1399 PCNRITEM pci = NULL;
1400 if (fAutoView && hwndMain) {
1401 pci = WinSendMsg(hwnd, CM_QUERYRECORDEMPHASIS, MPFROMLONG(CMA_FIRST),
1402 MPFROMSHORT(CRA_CURSORED));
1403 if (pci && (INT) pci != -1 &&
1404 (!(driveflags[toupper(*pci->pszFileName) - 'A'] & DRIVE_SLOW)))
1405 WinSendMsg(hwndMain, UM_LOADFILE, MPFROMP(pci->pszFileName), MPVOID);
1406 else
1407 WinSendMsg(hwndMain, UM_LOADFILE, MPVOID, MPVOID);
1408 }
1409 if (*dcd->directory) {
1410 if (hwndMain)
1411 WinSendMsg(hwndMain,
1412 UM_SETUSERLISTNAME, MPFROMP(dcd->directory), MPVOID);
1413 else
1414 add_udir(FALSE, dcd->directory);
1415 }
1416
1417 if (hwndMain)
1418 PostMsg(hwndMain, UM_ADVISEFOCUS, MPFROMLONG(dcd->hwndFrame), MPVOID);
1419 }
1420
1421 LastDir = hwnd;
1422 PostMsg(hwnd, UM_RESCAN, MPVOID, MPVOID);
1423 if (fSwitchTreeOnFocus && hwndTree && dcd && *dcd->directory) {
1424 PSZ pszTempDir = xstrdup(dcd->directory, pszSrcFile, __LINE__);
1425 if (pszTempDir) {
1426 if (!PostMsg(hwndTree, UM_SHOWME, MPFROMP(pszTempDir), MPVOID))
1427 free(pszTempDir); // Failed
1428 }
1429 }
1430 }
1431 break;
1432
1433 case UM_SETDIR:
1434 if (dcd && mp1) {
1435
1436 CHAR fullname[CCHMAXPATH];
1437
1438 DosError(FERR_DISABLEHARDERR);
1439 if (!DosQueryPathInfo((CHAR *)mp1,
1440 FIL_QUERYFULLNAME, fullname, sizeof(fullname))) {
1441 if (stricmp(dcd->directory, fullname)) {
1442 strcpy(dcd->previous, dcd->directory);
1443 strcpy(dcd->directory, fullname);
1444 // DosEnterCritSec(); // GKY 11-27-08
1445 dcd->stopflag++;
1446 // DosExitCritSec();
1447 // DbgMsg(pszSrcFile, __LINE__, "WM_RESCAN");
1448 if (!PostMsg(dcd->hwndObject, UM_RESCAN, MPVOID, MPFROMLONG(1L))) {
1449 strcpy(dcd->directory, dcd->previous);
1450 // DosEnterCritSec(); // GKY 11-27-08
1451 dcd->stopflag--;
1452 // DosExitCritSec();
1453 }
1454 else if (*dcd->directory) {
1455 if (hwndMain)
1456 WinSendMsg(hwndMain,
1457 UM_SETUSERLISTNAME, MPFROMP(dcd->directory), MPVOID);
1458 else
1459 add_udir(FALSE, dcd->directory);
1460 }
1461 }
1462 }
1463 }
1464 break;
1465
1466 case WM_TIMER:
1467 // Started/stopped by DirObjWndPro
1468 // dcd = WinQueryWindowPtr(hwnd, QWL_USER);
1469 if (dcd) {
1470 commafmt(tb, sizeof(tb), dcd->totalfiles);
1471 CommaFmtULL(tf, sizeof(tf), dcd->ullTotalBytes, 'K');
1472 sprintf(s, "%s / %s", tb, tf);
1473 // DbgMsg(pszSrcFile, __LINE__, "WM_TIMER %s", s); // 15 Sep 09 SHL fixme debug
1474 WinSetDlgItemText(dcd->hwndClient, DIR_TOTALS, s);
1475 }
1476 break; // WM_TIMER
1477
1478 case UM_RESCAN:
1479 if (dcd) {
1480
1481 CNRINFO cnri;
1482 CHAR szDate[DATE_BUF_BYTES];
1483 PCNRITEM pci;
1484
1485 memset(&cnri, 0, sizeof(CNRINFO));
1486 cnri.cb = sizeof(CNRINFO);
1487 WinSendMsg(hwnd,
1488 CM_QUERYCNRINFO,
1489 MPFROMP(&cnri), MPFROMLONG(sizeof(CNRINFO)));
1490 cnri.pszCnrTitle = dcd->directory;
1491 WinSendMsg(hwnd,
1492 CM_SETCNRINFO, MPFROMP(&cnri), MPFROMLONG(CMA_CNRTITLE));
1493 DosRequestMutexSem(hmtxFiltering, SEM_INDEFINITE_WAIT);
1494 dcd->totalfiles = cnri.cRecords;
1495 commafmt(tb, sizeof(tb), dcd->totalfiles);
1496 CommaFmtULL(tf, sizeof(tf), dcd->ullTotalBytes, 'K');
1497 DosReleaseMutexSem(hmtxFiltering);
1498 sprintf(s, "%s / %s", tb, tf);
1499 WinSetDlgItemText(dcd->hwndClient, DIR_TOTALS, s);
1500 commafmt(tb, sizeof(tb), dcd->selectedfiles);
1501 CommaFmtULL(tf, sizeof(tf), dcd->selectedbytes, 'K');
1502 sprintf(s, "%s / %s", tb, tf);
1503 WinSetDlgItemText(dcd->hwndClient, DIR_SELECTED, s);
1504 if (hwndStatus &&
1505 dcd->hwndFrame == WinQueryActiveWindow(dcd->hwndParent)) {
1506 PostMsg(dcd->hwndObject, UM_RESCAN2, MPVOID, MPVOID);
1507 if ((fSplitStatus && hwndStatus2) || fMoreButtons) {
1508 pci = WinSendMsg(hwnd,
1509 CM_QUERYRECORDEMPHASIS,
1510 MPFROMLONG(CMA_FIRST), MPFROMSHORT(CRA_CURSORED));
1511 if (pci && (INT) pci != -1) {
1512 if (fSplitStatus && hwndStatus2) {
1513 CommaFmtULL(tb, sizeof(tb), pci->cbFile + pci->easize, ' ');
1514 if (!fMoreButtons) {
1515 DateFormat(szDate, pci->date);
1516 sprintf(s, " %s %s %02u%s%02u%s%02u [%s] %s",
1517 tb,
1518 szDate,
1519 pci->time.hours,
1520 TimeSeparator,
1521 pci->time.minutes,
1522 TimeSeparator,
1523 pci->time.seconds,
1524 pci->pszDispAttr, pci->pszFileName);
1525 }
1526 else {
1527 *tf = 0;
1528 if (pci->cbFile + pci->easize > 1024) {
1529 CommaFmtULL(tf, sizeof(tf), pci->cbFile + pci->easize, 'K');
1530 }
1531 sprintf(s,
1532 GetPString(IDS_STATUSSIZETEXT),
1533 tb, *tf ? " (" : NullStr, tf, *tf ? ")" : NullStr);
1534 }
1535 WinSetWindowText(hwndStatus2, s);
1536 }
1537 else
1538 WinSetWindowText(hwndStatus2, NullStr);
1539 if (fMoreButtons) {
1540 WinSetWindowText(hwndName, pci->pszFileName);
1541 DateFormat(szDate, pci->date);
1542 sprintf(s, "%s %02u%s%02u%s%02u",
1543 szDate,
1544 pci->time.hours, TimeSeparator,
1545 pci->time.minutes, TimeSeparator,
1546 pci->time.seconds);
1547 WinSetWindowText(hwndDate, s);
1548 WinSetWindowText(hwndAttr, pci->pszDispAttr);
1549 }
1550 }
1551 else {
1552 WinSetWindowText(hwndStatus2, NullStr);
1553 WinSetWindowText(hwndName, NullStr);
1554 WinSetWindowText(hwndDate, NullStr);
1555 WinSetWindowText(hwndAttr, NullStr);
1556 }
1557 }
1558 }
1559 }
1560 return 0;
1561
1562 case UM_SORTRECORD:
1563 if (dcd) {
1564
1565 CNRINFO cnri;
1566
1567 memset(&cnri, 0, sizeof(CNRINFO));
1568 cnri.cb = sizeof(CNRINFO);
1569 WinSendMsg(hwnd,
1570 CM_QUERYCNRINFO,
1571 MPFROMP(&cnri), MPFROMLONG(sizeof(CNRINFO)));
1572 cnri.pSortRecord = (PVOID) SortDirCnr;
1573 WinSendMsg(hwnd,
1574 CM_SETCNRINFO, MPFROMP(&cnri), MPFROMLONG(CMA_PSORTRECORD));
1575 WinSendMsg(hwnd,
1576 CM_SORTRECORD,
1577 MPFROMP(SortDirCnr), MPFROMLONG(dcd->sortFlags));
1578 }
1579 return 0;
1580
1581 case UM_SETUP:
1582 if (dcd) {
1583 if (!dcd->hwndObject) {
1584 // first time through -- set things up
1585
1586 CNRINFO cnri;
1587
1588 memset(&cnri, 0, sizeof(CNRINFO));
1589 cnri.cb = sizeof(CNRINFO);
1590 WinSendMsg(hwnd,
1591 CM_QUERYCNRINFO,
1592 MPFROMP(&cnri), MPFROMLONG(sizeof(CNRINFO)));
1593 cnri.cyLineSpacing = 0;
1594 cnri.cxTreeIndent = 12L;
1595
1596 cnri.flWindowAttr &= (~(CV_TREE | CV_ICON | CV_DETAIL | CV_TEXT));
1597 cnri.flWindowAttr |= (CV_NAME | CA_DETAILSVIEWTITLES | CV_MINI |
1598 CV_FLOW);
1599 cnri.pSortRecord = (PVOID) SortDirCnr;
1600
1601 {
1602 ULONG size = sizeof(ULONG);
1603
1604 PrfQueryProfileData(fmprof, appname, "DirflWindowAttr",
1605 (PVOID) & cnri.flWindowAttr, &size);
1606 size = sizeof(MASK);
1607 if (!*dcd->mask.szMask &&
1608 !dcd->mask.attrFile && !dcd->mask.antiattr) {
1609 if (PrfQueryProfileSize(fmprof, appname, "DirFilter", &size) && size) {
1610 PrfQueryProfileData(fmprof, appname, "DirFilter", &dcd->mask, &size);
1611 SetMask(dcd->mask.szMask, &dcd->mask);
1612 }
1613 else
1614 dcd->mask.attrFile = (FILE_READONLY | FILE_NORMAL |
1615 FILE_ARCHIVED | FILE_DIRECTORY |
1616 FILE_HIDDEN | FILE_SYSTEM);
1617 }
1618 *(dcd->mask.prompt) = 0;
1619 }
1620 if (dcd->flWindowAttr)
1621 cnri.flWindowAttr = dcd->flWindowAttr;
1622 else
1623 dcd->flWindowAttr = cnri.flWindowAttr;
1624 cnri.flWindowAttr &= (~(CA_MIXEDTARGETEMPH | CA_ORDEREDTARGETEMPH |
1625 CA_TITLEREADONLY | CA_TITLESEPARATOR));
1626 cnri.flWindowAttr |= CV_FLOW;
1627 dcd->flWindowAttr |= CV_FLOW;
1628 if (WinWindowFromID(dcd->hwndFrame, FID_TITLEBAR))
1629 cnri.flWindowAttr &= (~CA_CONTAINERTITLE);
1630 else
1631 cnri.flWindowAttr |= CA_CONTAINERTITLE;
1632 if (!dcd->sortFlags)
1633 dcd->sortFlags = sortFlags;
1634 WinSendMsg(hwnd,
1635 CM_SETCNRINFO,
1636 MPFROMP(&cnri),
1637 MPFROMLONG(CMA_FLWINDOWATTR | CMA_LINESPACING |
1638 CMA_CXTREEINDENT | CMA_PSORTRECORD));
1639 SetCnrCols(hwnd, FALSE);
1640 if (xbeginthread(MakeObjWin,
1641 245760,
1642 dcd,
1643 pszSrcFile,
1644 __LINE__) == -1)
1645 {
1646 Runtime_Error(pszSrcFile, __LINE__,
1647 GetPString(IDS_COULDNTSTARTTHREADTEXT));
1648 PostMsg(hwnd, WM_CLOSE, MPVOID, MPVOID);
1649 return 0;
1650 }
1651 else
1652 DosSleep(32); // 05 Aug 07 GKY 64
1653 WinEnableMenuItem(DirCnrMenu, IDM_FINDINTREE, (hwndTree != (HWND) 0));
1654 }
1655 // 2014-06-11 SHL fm/2 lite can get here before drive scan completes
1656 //if (!fInitialDriveScan) // 2014-08-30 GKY This doesn't seem to be needed
1657 PostMsg(hwnd, UM_SETUP2, MPVOID, MPVOID);
1658 }
1659 else {
1660 PostMsg(hwnd, WM_CLOSE, MPVOID, MPVOID);
1661 return 0;
1662 }
1663 return 0;
1664
1665 case UM_SETUP2:
1666 if (dcd) {
1667 // DbgMsg(pszSrcFile, __LINE__, "DirCnrWndProc UM_SETUP2 %x", hwnd);
1668 AdjustCnrColsForPref(hwnd, NULL, &dcd->ds, FALSE);
1669 SayFilter(WinWindowFromID(WinQueryWindow(hwnd, QW_PARENT),
1670 DIR_FILTER), &dcd->mask, FALSE);
1671 SaySort(WinWindowFromID(WinQueryWindow(hwnd, QW_PARENT),
1672 DIR_SORT), dcd->sortFlags, FALSE);
1673 SayView(WinWindowFromID(WinQueryWindow(hwnd, QW_PARENT),
1674 DIR_VIEW), dcd->flWindowAttr);
1675 } else
1676 PostMsg(hwnd, WM_CLOSE, MPVOID, MPVOID);
1677 return 0;
1678
1679 case WM_MENUEND:
1680 if (dcd) {
1681
1682 HWND hwndMenu = (HWND) mp2;
1683
1684 if (hwndMenu == DirCnrMenu ||
1685 hwndMenu == FileMenu ||
1686 hwndMenu == DirMenu) {
1687 MarkAll(hwnd, TRUE, FALSE, TRUE);
1688 if (dcd->cnremphasized) {
1689 WinSendMsg(hwnd, CM_SETRECORDEMPHASIS, MPVOID,
1690 MPFROM2SHORT(FALSE, CRA_SOURCE));
1691 dcd->cnremphasized = FALSE;
1692 }
1693 }
1694 }
1695 break;
1696
1697 case UM_OPENWINDOWFORME:
1698 if (dcd) {
1699 if (mp1 && !IsFile((CHAR *)mp1)) {
1700 OpenDirCnr(hwnd, dcd->hwndParent, dcd->hwndFrame, FALSE, (char *)mp1);
1701 }
1702 else if (mp1 && IsFile(mp1) == 1 &&
1703 CheckDriveSpaceAvail(ArcTempRoot, ullDATFileSpaceNeeded, ullTmpSpaceNeeded) != 2) {
1704 StartArcCnr(HWND_DESKTOP,
1705 dcd->hwndFrame, (CHAR *)mp1, 4, (ARC_TYPE *) mp2);
1706 }
1707 }
1708 return 0;
1709
1710 case MM_PORTHOLEINIT:
1711 if (dcd) {
1712 switch (SHORT1FROMMP(mp1)) {
1713 case 0:
1714 case 1:
1715 {
1716 ULONG wmsg;
1717
1718 wmsg = (SHORT1FROMMP(mp1) == 0) ? UM_FILESMENU : UM_VIEWSMENU;
1719 PortholeInit((HWND) WinSendMsg(dcd->hwndClient,
1720 wmsg, MPVOID, MPVOID), mp1, mp2);
1721 }
1722 break;
1723 }
1724 }
1725 break;
1726
1727 case UM_INITMENU:
1728 case WM_INITMENU:
1729 if (dcd) {
1730 switch (SHORT1FROMMP(mp1)) {
1731 case IDM_FILESMENU:
1732 CopyPresParams((HWND) mp2, hwndMainMenu);
1733 if (isalpha(*dcd->directory)) {
1734 if (driveflags[toupper(*dcd->directory) - 'A'] & DRIVE_NOTWRITEABLE) {
1735 WinEnableMenuItem((HWND) mp2, IDM_MOVEMENU, FALSE);
1736 WinEnableMenuItem((HWND) mp2, IDM_RENAME, FALSE);
1737 WinEnableMenuItem((HWND) mp2, IDM_MKDIR, FALSE);
1738 WinEnableMenuItem((HWND) mp2, IDM_UNDELETE, FALSE);
1739 WinEnableMenuItem((HWND) mp2, IDM_DELETESUBMENU, FALSE);
1740 WinEnableMenuItem((HWND) mp2, IDM_DELETE, FALSE);
1741 WinEnableMenuItem((HWND) mp2, IDM_EDIT, FALSE);
1742 WinEnableMenuItem((HWND) mp2, IDM_EDITTEXT, FALSE);
1743 WinEnableMenuItem((HWND) mp2, IDM_EDITBINARY, FALSE);
1744 WinEnableMenuItem((HWND) mp2, IDM_ATTRS, FALSE);
1745 }
1746 else {
1747 WinEnableMenuItem((HWND) mp2, IDM_MOVEMENU, TRUE);
1748 WinEnableMenuItem((HWND) mp2, IDM_RENAME, TRUE);
1749 WinEnableMenuItem((HWND) mp2, IDM_MKDIR, TRUE);
1750 WinEnableMenuItem((HWND) mp2, IDM_UNDELETE, TRUE);
1751 WinEnableMenuItem((HWND) mp2, IDM_DELETESUBMENU, TRUE);
1752 WinEnableMenuItem((HWND) mp2, IDM_DELETE, TRUE);
1753 WinEnableMenuItem((HWND) mp2, IDM_EDIT, TRUE);
1754 WinEnableMenuItem((HWND) mp2, IDM_EDITTEXT, TRUE);
1755 WinEnableMenuItem((HWND) mp2, IDM_EDITBINARY, TRUE);
1756 WinEnableMenuItem((HWND) mp2, IDM_ATTRS, TRUE);
1757 }
1758 WinEnableMenuItem((HWND) mp2, IDM_UNLOCKFILE, fUnlock);
1759 }
1760 break;
1761
1762 case IDM_VIEWSMENU:
1763 SetViewMenu((HWND) mp2, dcd->flWindowAttr);
1764 CopyPresParams((HWND) mp2, hwndMainMenu);
1765 WinEnableMenuItem((HWND) mp2, IDM_RESELECT,
1766 (dcd->lastselection != NULL));
1767 if (isalpha(*dcd->directory)) {
1768 if (driveflags[toupper(*dcd->directory) - 'A'] & DRIVE_NOTWRITEABLE)
1769 WinEnableMenuItem((HWND) mp2, IDM_MKDIR, FALSE);
1770 else
1771 WinEnableMenuItem((HWND) mp2, IDM_MKDIR, TRUE);
1772 }
1773 WinEnableMenuItem((HWND) mp2,
1774 IDM_SELECTCOMPAREMENU,
1775 (CountDirCnrs(dcd->hwndParent) > 1));
1776 break;
1777
1778 case IDM_DETAILSSETUP:
1779 SetDetailsSwitches((HWND) mp2, &dcd->ds);
1780 break;
1781
1782 case IDM_COMMANDSMENU:
1783 SetupCommandMenu((HWND) mp2, hwnd);
1784 break;
1785
1786 case IDM_SORTSUBMENU:
1787 SetSortChecks((HWND) mp2, dcd->sortFlags);
1788 break;
1789
1790 case IDM_WINDOWSMENU:
1791 SetupWinList((HWND) mp2,
1792 (hwndMain) ? hwndMain : (HWND) 0, dcd->hwndFrame);
1793 break;
1794 }
1795 dcd->hwndLastMenu = (HWND) mp2;
1796 }
1797 if (msg == WM_INITMENU)
1798 break;
1799 return 0;
1800
1801 case UM_FILTER:
1802 if (dcd) {
1803
1804 PCNRITEM pci;
1805
1806 if (mp1)
1807 SetMask((CHAR *)mp1, &dcd->mask);
1808
1809 dcd->suspendview = 1;
1810 WinSendMsg(hwnd, CM_FILTER, MPFROMP(Filter), MPFROMP(&dcd->mask));
1811 dcd->suspendview = 0;
1812 if (fAutoView && hwndMain) {
1813 pci = WinSendMsg(hwnd, CM_QUERYRECORDEMPHASIS,
1814 MPFROMLONG(CMA_FIRST), MPFROMSHORT(CRA_CURSORED));
1815 if (pci && (INT) pci != -1 &&
1816 (!(driveflags[toupper(*pci->pszFileName) - 'A'] & DRIVE_SLOW)))
1817 WinSendMsg(hwndMain, UM_LOADFILE, MPFROMP(pci->pszFileName), MPVOID);
1818 else
1819 WinSendMsg(hwndMain, UM_LOADFILE, MPVOID, MPVOID);
1820 }
1821 PostMsg(hwnd, UM_RESCAN, MPVOID, MPVOID);
1822 }
1823 return 0;
1824
1825 case UM_COMMAND:
1826 if (mp1) {
1827 if (dcd) {
1828 if (!PostMsg(dcd->hwndObject, UM_COMMAND, mp1, mp2)) {
1829 Runtime_Error(pszSrcFile, __LINE__, PCSZ_POSTMSG);
1830 FreeListInfo((LISTINFO *) mp1);
1831 }
1832 else
1833 return (MRESULT) TRUE;
1834 }
1835 else
1836 FreeListInfo((LISTINFO *) mp1);
1837 }
1838 return 0;
1839
1840 case UM_NOTIFY:
1841 if (mp2)
1842 Notify((CHAR *)mp2);
1843 return 0;
1844
1845 case UM_DRIVECMD:
1846 if (mp1)
1847 WinSendMsg(hwnd, WM_COMMAND, MPFROM2SHORT(IDM_SWITCH, 0), mp1);
1848 return 0;
1849
1850 case WM_COMMAND:
1851 DosError(FERR_DISABLEHARDERR);
1852 if (dcd) {
1853 switch (SHORT1FROMMP(mp1)) {
1854 case IDM_SETTARGET:
1855 SetTargetDir(hwnd, FALSE, NULL);
1856 break;
1857
1858 case IDM_CREATE:
1859 {
1860 STRINGINPARMS sip;
1861 CHAR filename[CCHMAXPATHCOMP];
1862
1863 memset(&sip, 0, sizeof(sip));
1864 sip.help = GetPString(IDS_CREATETEXT);
1865 sip.prompt = GetPString(IDS_CREATEPROMPTTEXT);
1866 sip.inputlen = CCHMAXPATHCOMP - (strlen(dcd->directory) - 1);
1867 strcpy(filename, "NEWFILE.TXT");
1868 sip.ret = filename;
1869 sip.title = GetPString(IDS_CREATETITLETEXT);
1870 if (WinDlgBox(HWND_DESKTOP, hwnd, InputDlgProc, FM3ModHandle,
1871 STR_FRAME, &sip)) {
1872 bstrip(sip.ret);
1873 if (*sip.ret) {
1874 CHAR newfile[CCHMAXPATH];
1875 FILE *fp;
1876 INT test;
1877 PCNRITEM pci;
1878
1879 strcpy(newfile, dcd->directory);
1880 AddBackslashToPath(newfile);
1881# if 0
1882 if (newfile[strlen(newfile) - 1] != '\\')
1883 strcat(newfile, "\\");
1884# endif
1885 strcat(newfile, sip.ret);
1886 test = IsFile(newfile);
1887 if (test != 1) {
1888 CHAR *modew = "w";
1889
1890 fp = xfopen(newfile, modew, pszSrcFile, __LINE__, TRUE);
1891 }
1892 if (test != 1 && !fp) {
1893 saymsg(MB_ENTER,
1894 hwnd,
1895 GetPString(IDS_ERRORTEXT),
1896 GetPString(IDS_CREATEERRORTEXT), newfile);
1897 }
1898 else {
1899 if (fp) {
1900 WinSendMsg(hwnd, UM_UPDATERECORD, MPFROMP(newfile), MPVOID);
1901 fclose(fp);
1902 }
1903 if (*editor) {
1904
1905 CHAR *dummy[2];
1906
1907 dummy[0] = newfile;
1908 dummy[1] = NULL;
1909 ExecOnList(hwnd,
1910 editor, WINDOWED | SEPARATE, NULL, NULL,
1911 dummy, NULL, pszSrcFile, __LINE__);
1912 }
1913 else
1914 StartMLEEditor(dcd->hwndParent, 4, newfile, dcd->hwndFrame);
1915 pci = FindCnrRecord(hwnd, newfile, NULL, TRUE, FALSE, TRUE);
1916 if (pci && (INT) pci != -1)
1917 // make sure that record shows in viewport
1918 ShowCnrRecord(hwnd, (PMINIRECORDCORE) pci);
1919 }
1920 }
1921 }
1922 }
1923 break;
1924
1925 case IDM_CONTEXTMENU:
1926 {
1927 PCNRITEM pci;
1928
1929 pci = (PCNRITEM) CurrentRecord(hwnd);
1930 PostMsg(hwnd, WM_CONTROL, MPFROM2SHORT(DIR_CNR, CN_CONTEXTMENU),
1931 MPFROMP(pci));
1932 }
1933 break;
1934
1935 case IDM_MAXIMIZE:
1936 PostMsg(hwndMain, UM_MAXIMIZE, MPFROMLONG(dcd->hwndFrame), MPVOID);
1937 break;
1938
1939 case IDM_SHOWALLFILESCNR:
1940 StartSeeAll(HWND_DESKTOP, FALSE, dcd->directory);
1941 break;
1942
1943 case IDM_SHOWALLFILES:
1944 {
1945 PCNRITEM pci;
1946
1947 pci = WinSendMsg(hwnd, CM_QUERYRECORDEMPHASIS,
1948 MPFROMLONG(CMA_FIRST), MPFROMSHORT(CRA_CURSORED));
1949 if (pci && (INT) pci != -1) {
1950
1951 static CHAR dirname[CCHMAXPATH];
1952
1953 strcpy(dirname, pci->pszFileName);
1954 MakeValidDir(dirname);
1955 StartSeeAll(HWND_DESKTOP, FALSE, dirname);
1956 }
1957 }
1958 break;
1959
1960 case IDM_FINDINTREE:
1961 if (hwndTree) {
1962 PSZ pszTempDir = xstrdup(dcd->directory, pszSrcFile, __LINE__);
1963
1964 if (pszTempDir) {
1965 if (!PostMsg(hwndTree, UM_SHOWME, MPFROMP(pszTempDir),
1966 MPFROMLONG(1L)))
1967 free(pszTempDir);
1968 }
1969 }
1970 break;
1971
1972 case IDM_BEGINEDIT:
1973 OpenEdit(hwnd);
1974 break;
1975
1976 case IDM_ENDEDIT:
1977 WinSendMsg(hwnd, CM_CLOSEEDIT, MPVOID, MPVOID);
1978 break;
1979
1980 case IDM_SHOWSELECT:
1981 QuickPopup(hwnd,
1982 dcd,
1983 CheckMenu(hwnd, &DirCnrMenu, DIRCNR_POPUP), IDM_SELECTSUBMENU);
1984 break;
1985
1986 case IDM_SHOWSORT:
1987 QuickPopup(hwnd, dcd, CheckMenu(hwnd, &DirCnrMenu, DIRCNR_POPUP),
1988 IDM_SORTSUBMENU);
1989 break;
1990
1991 case IDM_VIEWORARC:
1992 {
1993 SWP swp;
1994 PCNRITEM pci;
1995
1996 pci = (PCNRITEM) WinSendMsg(hwnd, CM_QUERYRECORDEMPHASIS,
1997 MPFROMLONG(CMA_FIRST),
1998 MPFROMSHORT(CRA_CURSORED));
1999 if (pci && (INT) pci != -1) {
2000 WinQueryWindowPos(dcd->hwndFrame, &swp);
2001 DefaultViewKeys(hwnd,
2002 dcd->hwndFrame,
2003 dcd->hwndParent, &swp, pci->pszFileName);
2004 }
2005 }
2006 break;
2007
2008 case IDM_DIRCNRSETTINGS:
2009 if (!ParentIsDesktop(dcd->hwndParent, dcd->hwndParent))
2010 PostMsg(dcd->hwndParent, msg, MPFROMLONG(IDM_DIRCNRSETTINGS), mp2);
2011 else {
2012 WinDlgBox(HWND_DESKTOP,
2013 hwnd,
2014 CfgDlgProc,
2015 FM3ModHandle,
2016 CFG_FRAME,
2017 MPFROMLONG(IDM_DIRCNRSETTINGS));
2018 }
2019 break;
2020
2021 case IDM_QTREE:
2022 case IDM_TREE:
2023 {
2024 CHAR newpath[CCHMAXPATH];
2025 APIRET rc;
2026 PCNRITEM pci;
2027
2028 if (SHORT1FROMMP(mp1) == IDM_TREE) {
2029 pci = (PCNRITEM) CurrentRecord(hwnd);
2030 if (pci && (INT) pci != -1)
2031 strcpy(newpath, pci->pszFileName);
2032 else
2033 strcpy(newpath, dcd->directory);
2034 }
2035 else
2036 strcpy(newpath, dcd->directory);
2037 MakeValidDir(newpath);
2038 rc = WinDlgBox(HWND_DESKTOP, dcd->hwndClient, ObjCnrDlgProc,
2039 FM3ModHandle, QTREE_FRAME, MPFROMP(newpath));
2040 if (rc)
2041 WinSendMsg(hwnd, UM_SETDIR, MPFROMP(newpath), MPVOID);
2042 }
2043 break;
2044
2045 case IDM_RESELECT:
2046 SelectList(hwnd, TRUE, FALSE, FALSE, NULL, NULL, dcd->lastselection);
2047 break;
2048
2049 case IDM_HELP:
2050 if (hwndHelp) {
2051 if (!ParentIsDesktop(dcd->hwndFrame, dcd->hwndParent))
2052 PostMsg(dcd->hwndParent, UM_COMMAND, mp1, mp2);
2053 else
2054 WinSendMsg(hwndHelp, HM_HELP_CONTENTS, MPVOID, MPVOID);
2055 }
2056 break;
2057
2058 case IDM_WINDOWDLG:
2059 if (!ParentIsDesktop(dcd->hwndFrame, dcd->hwndParent))
2060 PostMsg(dcd->hwndParent, UM_COMMAND,
2061 MPFROM2SHORT(IDM_WINDOWDLG, 0), MPVOID);
2062 break;
2063
2064 case IDM_SORTSMARTNAME:
2065 case IDM_SORTNAME:
2066 case IDM_SORTFILENAME:
2067 case IDM_SORTSIZE:
2068 case IDM_SORTEASIZE:
2069 case IDM_SORTFIRST:
2070 case IDM_SORTLAST:
2071 case IDM_SORTLWDATE:
2072 case IDM_SORTLADATE:
2073 case IDM_SORTCRDATE:
2074 case IDM_SORTSUBJECT:
2075 dcd->sortFlags &= (SORT_REVERSE | SORT_DIRSFIRST | SORT_DIRSLAST);
2076 case IDM_SORTDIRSFIRST:
2077 case IDM_SORTDIRSLAST:
2078 case IDM_SORTREVERSE:
2079 switch (SHORT1FROMMP(mp1)) {
2080 case IDM_SORTSUBJECT:
2081 dcd->sortFlags |= SORT_SUBJECT;
2082 break;
2083 case IDM_SORTSMARTNAME:
2084 case IDM_SORTFILENAME:
2085 dcd->sortFlags |= SORT_FILENAME;
2086 break;
2087 case IDM_SORTSIZE:
2088 dcd->sortFlags |= SORT_SIZE;
2089 break;
2090 case IDM_SORTEASIZE:
2091 dcd->sortFlags |= SORT_EASIZE;
2092 break;
2093 case IDM_SORTFIRST:
2094 dcd->sortFlags |= SORT_FIRSTEXTENSION;
2095 break;
2096 case IDM_SORTLAST:
2097 dcd->sortFlags |= SORT_LASTEXTENSION;
2098 break;
2099 case IDM_SORTLWDATE:
2100 dcd->sortFlags |= SORT_LWDATE;
2101 break;
2102 case IDM_SORTLADATE:
2103 dcd->sortFlags |= SORT_LADATE;
2104 break;
2105 case IDM_SORTCRDATE:
2106 dcd->sortFlags |= SORT_CRDATE;
2107 break;
2108 case IDM_SORTDIRSFIRST:
2109 if (dcd->sortFlags & SORT_DIRSFIRST)
2110 dcd->sortFlags &= (~SORT_DIRSFIRST);
2111 else {
2112 dcd->sortFlags |= SORT_DIRSFIRST;
2113 dcd->sortFlags &= (~SORT_DIRSLAST);
2114 }
2115 break;
2116 case IDM_SORTDIRSLAST:
2117 if (dcd->sortFlags & SORT_DIRSLAST)
2118 dcd->sortFlags &= (~SORT_DIRSLAST);
2119 else {
2120 dcd->sortFlags |= SORT_DIRSLAST;
2121 dcd->sortFlags &= (~SORT_DIRSFIRST);
2122 }
2123 break;
2124 case IDM_SORTREVERSE:
2125 if (dcd->sortFlags & SORT_REVERSE)
2126 dcd->sortFlags &= (~SORT_REVERSE);
2127 else
2128 dcd->sortFlags |= SORT_REVERSE;
2129 break;
2130 }
2131 WinSendMsg(hwnd, CM_SORTRECORD, MPFROMP(SortDirCnr),
2132 MPFROMLONG(dcd->sortFlags));
2133 SaySort(WinWindowFromID(WinQueryWindow(hwnd, QW_PARENT),
2134 DIR_SORT), dcd->sortFlags, FALSE);
2135 break;
2136
2137 case IDM_COLLECT:
2138 case IDM_GREP:
2139 if (!Collector) {
2140
2141 HWND hwndC;
2142 SWP swp;
2143
2144 if (!ParentIsDesktop(hwnd, dcd->hwndParent) && !fAutoTile &&
2145 (!fExternalCollector && !strcmp(realappname, FM3Str)))
2146 GetNextWindowPos(dcd->hwndParent, &swp, NULL, NULL);
2147 hwndC = StartCollector((fExternalCollector ||
2148 strcmp(realappname, FM3Str)) ?
2149 HWND_DESKTOP : dcd->hwndParent, 4);
2150 if (hwndC) {
2151 if (!ParentIsDesktop(hwnd, dcd->hwndParent) && !fAutoTile &&
2152 (!fExternalCollector && !strcmp(realappname, FM3Str)))
2153 WinSetWindowPos(hwndC, HWND_TOP, swp.x, swp.y,
2154 swp.cx, swp.cy, SWP_MOVE | SWP_SIZE |
2155 SWP_SHOW | SWP_ZORDER);
2156 else if (!ParentIsDesktop(hwnd, dcd->hwndParent) && fAutoTile &&
2157 !strcmp(realappname, FM3Str))
2158 TileChildren(dcd->hwndParent, TRUE);
2159 WinSetWindowPos(hwndC, HWND_TOP, 0, 0, 0, 0, SWP_ACTIVATE);
2160 DosSleep(100); // 05 Aug 07 GKY 250
2161 }
2162 }
2163 else
2164 StartCollector(dcd->hwndParent, 4);
2165 if (SHORT1FROMMP(mp1) == IDM_GREP) {
2166 PCNRITEM pci = NULL;
2167
2168 pci = WinSendMsg(hwnd,
2169 CM_QUERYRECORDEMPHASIS,
2170 MPFROMLONG(CMA_FIRST), MPFROMSHORT(CRA_CURSORED));
2171 if (pci && (INT) pci != -1)
2172 PostMsg(Collector, WM_COMMAND,
2173 MPFROM2SHORT(IDM_GREP, 0), MPFROMP(pci->pszFileName));
2174 else
2175 PostMsg(Collector, WM_COMMAND,
2176 MPFROM2SHORT(IDM_GREP, 0), MPVOID);
2177 }
2178 else
2179 PostMsg(hwnd, WM_COMMAND, MPFROM2SHORT(IDM_COLLECTOR, 0), MPVOID);
2180 break;
2181
2182 case IDM_COLLECTOR:
2183 DosSleep(32); // 05 Aug 07 GKY 64
2184 {
2185 CHAR **list;
2186
2187 list = BuildList(hwnd);
2188 if (list) {
2189 if (Collector) {
2190 if (!PostMsg(Collector,
2191 WM_COMMAND,
2192 MPFROM2SHORT(IDM_COLLECTOR, 0), MPFROMP(list)))
2193 FreeList(list);
2194 else if (fUnHilite)
2195 UnHilite(hwnd, TRUE, &dcd->lastselection, 0);
2196 }
2197 else
2198 FreeList(list);
2199 }
2200 }
2201 break;
2202
2203 case IDM_UNDELETE:
2204 {
2205 PCNRITEM pci;
2206 CHAR path[CCHMAXPATH];
2207 HOBJECT hObject;
2208 HWND hwndDesktop;
2209
2210 hObject = WinQueryObject("<XWP_TRASHCAN>");
2211 if (hObject != NULLHANDLE && fTrashCan) {
2212 hwndDesktop = WinQueryDesktopWindow((HAB) 0, NULLHANDLE);
2213 WinSetFocus(HWND_DESKTOP, hwndDesktop);
2214 WinOpenObject(hObject, 0, TRUE);
2215 }
2216 else {
2217 pci = (PCNRITEM) CurrentRecord(hwnd);
2218 if (pci && (INT) pci != -1) {
2219 strcpy(path, pci->pszFileName);
2220 MakeValidDir(path);
2221 WinDlgBox(HWND_DESKTOP, hwnd, UndeleteDlgProc, FM3ModHandle,
2222 UNDEL_FRAME, MPFROMP(path));
2223 }
2224 }
2225 }
2226 break;
2227
2228 case IDM_UNDELETESPEC:
2229 {
2230 HOBJECT hObject;
2231 HWND hwndDesktop;
2232
2233 hObject = WinQueryObject("<XWP_TRASHCAN>");
2234 if (hObject != NULLHANDLE && fTrashCan) {
2235 hwndDesktop = WinQueryDesktopWindow((HAB) 0, NULLHANDLE);
2236 WinSetFocus(HWND_DESKTOP, hwndDesktop);
2237 WinOpenObject(hObject, 0, TRUE);
2238 }
2239 else
2240 WinDlgBox(HWND_DESKTOP,
2241 hwnd,
2242 UndeleteDlgProc,
2243 FM3ModHandle, UNDEL_FRAME, MPFROMP(dcd->directory));
2244 }
2245 break;
2246
2247 case IDM_RESORT:
2248# if 0
2249 WinSendMsg(hwnd,
2250 CM_SORTRECORD,
2251 MPFROMP(SortDirCnr),
2252 MPFROMLONG((fSyncUpdates) ? sortFlags : dcd->sortFlags));
2253#endif
2254 WinSendMsg(hwnd,
2255 CM_SORTRECORD,
2256 MPFROMP(SortDirCnr), MPFROMLONG(dcd->sortFlags));
2257 break;
2258
2259 case IDM_FILTER:
2260 {
2261 BOOL empty = FALSE;
2262 PCNRITEM pci;
2263 CHAR *p;
2264
2265 if (!*dcd->mask.szMask) {
2266 empty = TRUE;
2267 pci = (PCNRITEM) CurrentRecord(hwnd);
2268 if (pci && !(pci->attrFile & FILE_DIRECTORY)) {
2269 p = strrchr(pci->pszFileName, '\\');
2270 if (p) {
2271 p++;
2272 strcpy(dcd->mask.szMask, p);
2273 }
2274 }
2275 }
2276 *(dcd->mask.prompt) = 0;
2277
2278 if (WinDlgBox(HWND_DESKTOP, hwnd, PickMaskDlgProc,
2279 FM3ModHandle, MSK_FRAME, MPFROMP(&dcd->mask)))
2280 WinSendMsg(hwnd, UM_FILTER, MPVOID, MPVOID);
2281 else if (empty)
2282 *dcd->mask.szMask = 0;
2283 SayFilter(WinWindowFromID(WinQueryWindow(hwnd, QW_PARENT),
2284 DIR_FILTER), &dcd->mask, FALSE);
2285 }
2286 break;
2287
2288 case IDM_UNHIDEALL:
2289 WinSendMsg(hwnd, CM_FILTER, MPFROMP(Filter), MPFROMP(&dcd->mask));
2290 break;
2291
2292 case IDM_HIDEALL:
2293 if (fAutoView && hwndMain)
2294 PostMsg(hwndMain, UM_LOADFILE, MPVOID, MPVOID);
2295 dcd->suspendview = 1;
2296 HideAll(hwnd);
2297 dcd->suspendview = 0;
2298 PostMsg(hwnd, UM_RESCAN, MPVOID, MPVOID);
2299 break;
2300
2301 case IDM_SELECTBOTH:
2302 case IDM_SELECTONE:
2303 case IDM_SELECTMORE:
2304 case IDM_SELECTNEWER:
2305 case IDM_SELECTOLDER:
2306 case IDM_SELECTBIGGER:
2307 case IDM_SELECTSMALLER:
2308 case IDM_DESELECTBOTH:
2309 case IDM_DESELECTONE:
2310 case IDM_DESELECTMORE:
2311 case IDM_DESELECTNEWER:
2312 case IDM_DESELECTOLDER:
2313 case IDM_DESELECTBIGGER:
2314 case IDM_DESELECTSMALLER:
2315 if (ParentIsDesktop(hwnd, dcd->hwndParent)) {
2316 Runtime_Error(pszSrcFile, __LINE__, "ParentIsDesktop unexpected");
2317 break;
2318 }
2319 case IDM_SELECTLIST:
2320 case IDM_SELECTALL:
2321 case IDM_DESELECTALL:
2322 case IDM_SELECTALLFILES:
2323 case IDM_DESELECTALLFILES:
2324 case IDM_SELECTALLDIRS:
2325 case IDM_DESELECTALLDIRS:
2326 case IDM_SELECTMASK:
2327 case IDM_DESELECTMASK:
2328 case IDM_INVERT:
2329 case IDM_SELECTCLIP:
2330 case IDM_DESELECTCLIP:
2331 {
2332 PCNRITEM pci;
2333
2334 pci = (PCNRITEM) CurrentRecord(hwnd);
2335 if ((INT) pci == -1)
2336 pci = NULL;
2337 if (SHORT1FROMMP(mp1) == IDM_HIDEALL) {
2338 if (pci) {
2339 if (!(pci->rc.flRecordAttr & CRA_SELECTED))
2340 pci->rc.flRecordAttr |= CRA_FILTERED;
2341 WinSendMsg(hwnd, CM_INVALIDATERECORD, MPFROMP(&pci),
2342 MPFROM2SHORT(1, CMA_ERASE | CMA_REPOSITION));
2343 break;
2344 }
2345 }
2346 PostMsg(dcd->hwndObject, UM_SELECT, mp1, MPFROMP(pci));
2347 }
2348 break;
2349
2350 case IDM_RESCAN:
2351 //DosEnterCritSec(); //GKY 11-27-08
2352 dcd->stopflag++;
2353 // DosExitCritSec();
2354 // DbgMsg(pszSrcFile, __LINE__, "WM_RESCAN");
2355 if (!PostMsg(dcd->hwndObject, UM_RESCAN, MPVOID, MPVOID)) {
2356 //DosEnterCritSec(); //GKY 11-27-08
2357 dcd->stopflag--;
2358 //DosExitCritSec();
2359 }
2360 break;
2361
2362 case IDM_SHOWLNAMES:
2363 case IDM_SHOWSUBJECT:
2364 case IDM_SHOWEAS:
2365 case IDM_SHOWSIZE:
2366 case IDM_SHOWICON:
2367 case IDM_SHOWLWDATE:
2368 case IDM_SHOWLWTIME:
2369 case IDM_SHOWLADATE:
2370 case IDM_SHOWLATIME:
2371 case IDM_SHOWCRDATE:
2372 case IDM_SHOWCRTIME:
2373 case IDM_SHOWATTR:
2374 AdjustDetailsSwitches(hwnd,
2375 dcd->hwndLastMenu,
2376 SHORT1FROMMP(mp1),
2377 dcd->directory, NULL, &dcd->ds, FALSE);
2378 break;
2379
2380 case IDM_TREEVIEW:
2381 case IDM_ICON:
2382 case IDM_TEXT:
2383 case IDM_DETAILS:
2384 case IDM_NAME:
2385 case IDM_MINIICONS:
2386 case IDM_DETAILSTITLES:
2387 {
2388 CNRINFO cnri;
2389
2390 memset(&cnri, 0, sizeof(CNRINFO));
2391 cnri.cb = sizeof(CNRINFO);
2392 WinSendMsg(hwnd, CM_QUERYCNRINFO, MPFROMP(&cnri),
2393 MPFROMLONG(sizeof(CNRINFO)));
2394 switch (SHORT1FROMMP(mp1)) {
2395 case IDM_TREEVIEW:
2396 if (!(cnri.flWindowAttr & CV_TREE))
2397 dcd->lastattr = cnri.flWindowAttr;
2398 cnri.flWindowAttr &= (~(CV_ICON | CV_TREE | CV_TEXT |
2399 CV_DETAIL | CV_NAME | CA_TREELINE));
2400 cnri.flWindowAttr |= CA_TREELINE | CV_TREE | CV_ICON;
2401 if (!dcd->firsttree)
2402 PostMsg(dcd->hwndObject, UM_FLESH, MPVOID, MPVOID);
2403 break;
2404 case IDM_ICON:
2405 cnri.flWindowAttr &= (~(CV_ICON | CV_TREE | CV_TEXT |
2406 CV_DETAIL | CV_NAME | CA_TREELINE));
2407 cnri.flWindowAttr |= CV_ICON;
2408 break;
2409 case IDM_NAME:
2410 cnri.flWindowAttr &= (~(CV_ICON | CV_TREE | CV_TEXT |
2411 CV_DETAIL | CV_NAME | CA_TREELINE));
2412 cnri.flWindowAttr |= CV_NAME;
2413 break;
2414 case IDM_TEXT:
2415 cnri.flWindowAttr &= (~(CV_ICON | CV_TREE | CV_TEXT |
2416 CV_DETAIL | CV_NAME | CA_TREELINE));
2417 cnri.flWindowAttr |= CV_TEXT;
2418 break;
2419 case IDM_DETAILS:
2420 cnri.flWindowAttr &= (~(CV_ICON | CV_TREE | CV_TEXT |
2421 CV_DETAIL | CV_NAME | CA_TREELINE));
2422 cnri.flWindowAttr |= CV_DETAIL;
2423 break;
2424 case IDM_MINIICONS:
2425 if (cnri.flWindowAttr & CV_MINI)
2426 cnri.flWindowAttr &= (~CV_MINI);
2427 else
2428 cnri.flWindowAttr |= CV_MINI;
2429 break;
2430 case IDM_DETAILSTITLES:
2431 if (cnri.flWindowAttr & CA_DETAILSVIEWTITLES)
2432 cnri.flWindowAttr &= (~CA_DETAILSVIEWTITLES);
2433 else
2434 cnri.flWindowAttr |= CA_DETAILSVIEWTITLES;
2435 break;
2436 }
2437 cnri.flWindowAttr &= (~(CA_ORDEREDTARGETEMPH | CA_MIXEDTARGETEMPH));
2438 cnri.flWindowAttr |= CV_FLOW;
2439 dcd->flWindowAttr = cnri.flWindowAttr;
2440 WinSendMsg(hwnd, CM_SETCNRINFO, MPFROMP(&cnri),
2441 MPFROMLONG(CMA_FLWINDOWATTR));
2442 WinSendMsg(hwnd, CM_INVALIDATERECORD, MPVOID,
2443 MPFROM2SHORT(0, CMA_ERASE | CMA_REPOSITION));
2444 SayView(WinWindowFromID(WinQueryWindow(hwnd, QW_PARENT),
2445 DIR_VIEW), dcd->flWindowAttr);
2446 }
2447 break;
2448
2449 case IDM_SAVETOLIST:
2450 WinDlgBox(HWND_DESKTOP, hwnd, SaveListDlgProc, FM3ModHandle,
2451 SAV_FRAME, MPFROMP(&hwnd));
2452 break;
2453
2454 case IDM_SIZES:
2455 {
2456 PCNRITEM pci;
2457 CHAR path[CCHMAXPATH];
2458
2459 pci = (PCNRITEM) CurrentRecord(hwnd);
2460 if (pci && (INT) pci != -1)
2461 strcpy(path, pci->pszFileName);
2462 else
2463 strcpy(path, dcd->directory);
2464 MakeValidDir(path);
2465 WinDlgBox(HWND_DESKTOP,
2466 HWND_DESKTOP, DirSizeProc, FM3ModHandle, DSZ_FRAME, path);
2467 }
2468 break;
2469
2470 case IDM_MKDIR:
2471 {
2472 PCNRITEM pci;
2473 BOOL saved;
2474
2475 saved = fSelectedAlways;
2476 fSelectedAlways = FALSE;
2477 pci = (PCNRITEM)CurrentRecord(hwnd);
2478 // 01 Oct 07 SHL Make below selected directory or in current directory
2479 PMMkDir(dcd->hwndParent,
2480 pci && (INT)pci != -1 ? pci->pszFileName : dcd->directory,
2481 FALSE);
2482 fSelectedAlways = saved;
2483 }
2484 break;
2485
2486 case IDM_SWITCH:
2487 if (mp2) {
2488 strcpy(dcd->previous, dcd->directory);
2489 strcpy(dcd->directory, (CHAR *)mp2);
2490 //DosEnterCritSec(); // GKY 11-27-08
2491 dcd->stopflag++;
2492 //DosExitCritSec();
2493 //DbgMsg(pszSrcFile, __LINE__, "WM_RESCAN");
2494 if (!PostMsg(dcd->hwndObject, UM_RESCAN, MPVOID, MPFROMLONG(1L))) {
2495 strcpy(dcd->directory, dcd->previous);
2496 //DosEnterCritSec(); // GKY 11-27-08
2497 dcd->stopflag--;
2498 //DosExitCritSec();
2499 }
2500 else if (*dcd->directory) {
2501 if (hwndMain)
2502 WinSendMsg(hwndMain,
2503 UM_SETUSERLISTNAME, MPFROMP(dcd->directory), MPVOID);
2504 else
2505 add_udir(FALSE, dcd->directory);
2506 }
2507 }
2508 break;
2509
2510 case IDM_PARENT:
2511 {
2512 CHAR tempname1[CCHMAXPATH], tempname2[CCHMAXPATH];
2513
2514 strcpy(tempname1, dcd->directory);
2515 AddBackslashToPath(tempname1);
2516 strcat(tempname1, "..");
2517 DosError(FERR_DISABLEHARDERR);
2518 if (!DosQueryPathInfo(tempname1,
2519 FIL_QUERYFULLNAME,
2520 tempname2, sizeof(tempname2))) {
2521 if (stricmp(dcd->directory, tempname2)) {
2522 strcpy(dcd->previous, dcd->directory);
2523 strcpy(dcd->directory, tempname2);
2524 dcd->stopflag++;
2525 //DbgMsg(pszSrcFile, __LINE__, "WM_RESCAN");
2526 if (!PostMsg(dcd->hwndObject,
2527 UM_RESCAN, MPVOID, MPFROMLONG(1L))) {
2528 strcpy(dcd->directory, dcd->previous);
2529 dcd->stopflag--;
2530 }
2531 else if (*dcd->directory) {
2532 if (hwndMain)
2533 WinSendMsg(hwndMain,
2534 UM_SETUSERLISTNAME,
2535 MPFROMP(dcd->directory), MPVOID);
2536 else
2537 add_udir(FALSE, dcd->directory);
2538 }
2539 }
2540 }
2541 }
2542 break;
2543
2544 case IDM_PREVIOUS:
2545 if (*dcd->previous && stricmp(dcd->directory, dcd->previous)) {
2546
2547 CHAR tempname[CCHMAXPATH];
2548
2549 if (IsValidDir(dcd->previous)) {
2550 strcpy(tempname, dcd->directory);
2551 strcpy(dcd->directory, dcd->previous);
2552 strcpy(dcd->previous, tempname);
2553 dcd->stopflag++; ;
2554 //DbgMsg(pszSrcFile, __LINE__, "WM_RESCAN");
2555 if (!PostMsg(dcd->hwndObject, UM_RESCAN, MPVOID, MPFROMLONG(1L))) {
2556 strcpy(dcd->directory, dcd->previous);
2557 dcd->stopflag--;
2558 }
2559 else if (*dcd->directory) {
2560 if (hwndMain)
2561 WinSendMsg(hwndMain,
2562 UM_SETUSERLISTNAME,
2563 MPFROMP(dcd->directory), MPVOID);
2564 else
2565 add_udir(FALSE, dcd->directory);
2566 }
2567 }
2568 else
2569 *dcd->previous = 0;
2570 }
2571 break;
2572
2573 case IDM_WALKDIR:
2574 {
2575 CHAR newdir[CCHMAXPATH];
2576
2577 strcpy(newdir, dcd->directory);
2578 if (!WinDlgBox(HWND_DESKTOP,
2579 dcd->hwndParent,
2580 WalkAllDlgProc,
2581 FM3ModHandle,
2582 WALK_FRAME, MPFROMP(newdir)) || !*newdir)
2583 break;
2584 if (stricmp(newdir, dcd->directory)) {
2585 strcpy(dcd->previous, dcd->directory);
2586 strcpy(dcd->directory, newdir);
2587 dcd->stopflag++;
2588 //DbgMsg(pszSrcFile, __LINE__, "WM_RESCAN");
2589 if (!PostMsg(dcd->hwndObject, UM_RESCAN, MPVOID, MPFROMLONG(1L))) {
2590 strcpy(dcd->directory, dcd->previous);
2591 dcd->stopflag--;
2592 }
2593 else if (*dcd->directory) {
2594 if (hwndMain)
2595 WinSendMsg(hwndMain,
2596 UM_SETUSERLISTNAME,
2597 MPFROMP(dcd->directory), MPVOID);
2598 else
2599 add_udir(FALSE, dcd->directory);
2600 }
2601 }
2602 }
2603 break;
2604
2605 case IDM_OPENICONME:
2606 OpenObject(dcd->directory, PCSZ_ICON, dcd->hwndFrame);
2607 break;
2608 case IDM_OPENDETAILSME:
2609 OpenObject(dcd->directory, Details, dcd->hwndFrame);
2610 break;
2611 case IDM_OPENTREEME:
2612 OpenObject(dcd->directory, PCSZ_TREE, dcd->hwndFrame);
2613 break;
2614 case IDM_OPENSETTINGSME:
2615 OpenObject(dcd->directory, Settings, dcd->hwndFrame);
2616 break;
2617
2618 case IDM_DOITYOURSELF:
2619 case IDM_UPDATE:
2620 case IDM_OPENWINDOW:
2621 case IDM_OPENSETTINGS:
2622 case IDM_OPENDEFAULT:
2623 case IDM_OPENICON:
2624 case IDM_OPENDETAILS:
2625 case IDM_OPENTREE:
2626 case IDM_OBJECT:
2627 case IDM_SHADOW:
2628 case IDM_SHADOW2:
2629 case IDM_JAVAEXE:
2630 case IDM_DELETE:
2631 case IDM_PERMDELETE:
2632 case IDM_PRINT:
2633 case IDM_ATTRS:
2634 case IDM_INFO:
2635 case IDM_COPY:
2636 case IDM_MOVE:
2637 case IDM_WPSMOVE:
2638 case IDM_WPSCOPY:
2639 case IDM_WILDCOPY:
2640 case IDM_WILDMOVE:
2641 case IDM_RENAME:
2642 case IDM_COMPARE:
2643 case IDM_EAS:
2644 case IDM_SUBJECT:
2645 case IDM_VIEW:
2646 case IDM_VIEWTEXT:
2647 case IDM_VIEWBINARY:
2648 case IDM_VIEWARCHIVE:
2649 case IDM_EDIT:
2650 case IDM_EDITTEXT:
2651 case IDM_EDITBINARY:
2652 case IDM_SAVETOCLIP:
2653 case IDM_SAVETOCLIPFILENAME:
2654 case IDM_APPENDTOCLIP:
2655 case IDM_APPENDTOCLIPFILENAME:
2656 case IDM_ARCHIVE:
2657 case IDM_ARCHIVEM:
2658 case IDM_EXTRACT:
2659 case IDM_MCIPLAY:
2660 case IDM_COLLECTFROMFILE:
2661 case IDM_UUDECODE:
2662 case IDM_UNLOCKFILE:
2663 case IDM_MERGE:
2664 {
2665 LISTINFO *li;
2666 ULONG action = UM_ACTION;
2667 li = xmallocz(sizeof(LISTINFO), pszSrcFile, __LINE__);
2668 if (li) {
2669 li->type = SHORT1FROMMP(mp1);
2670 li->hwnd = hwnd;
2671 li->list = BuildList(hwnd);
2672 if (li->type == IDM_DELETE)
2673 ignorereadonly = FALSE;
2674 switch (SHORT1FROMMP(mp1)) {
2675 case IDM_WILDMOVE:
2676 case IDM_WILDCOPY:
2677 case IDM_MOVE:
2678 case IDM_COPY:
2679 case IDM_WPSMOVE:
2680 case IDM_WPSCOPY:
2681 break;
2682 default:
2683 strcpy(li->targetpath, dcd->directory);
2684 break;
2685 }
2686 if (li->list) {
2687 if (SHORT1FROMMP(mp1) == IDM_COLLECTFROMFILE) {
2688 if (!Collector) {
2689
2690 HWND hwndC;
2691 SWP swp;
2692
2693 if (!ParentIsDesktop(hwnd, dcd->hwndParent) &&
2694 !fAutoTile &&
2695 (!fExternalCollector && !strcmp(realappname, FM3Str)))
2696 GetNextWindowPos(dcd->hwndParent, &swp, NULL, NULL);
2697 hwndC = StartCollector((fExternalCollector ||
2698 strcmp(realappname, FM3Str)) ?
2699 HWND_DESKTOP : dcd->hwndParent, 4);
2700 if (hwndC) {
2701 if (!ParentIsDesktop(hwnd, dcd->hwndParent) &&
2702 !fAutoTile && (!fExternalCollector &&
2703 !strcmp(realappname, FM3Str)))
2704 WinSetWindowPos(hwndC, HWND_TOP, swp.x, swp.y,
2705 swp.cx, swp.cy, SWP_MOVE | SWP_SIZE |
2706 SWP_SHOW | SWP_ZORDER);
2707 else if (!ParentIsDesktop(hwnd, dcd->hwndParent) &&
2708 fAutoTile && !strcmp(realappname, FM3Str))
2709 TileChildren(dcd->hwndParent, TRUE);
2710 WinSetWindowPos(hwndC, HWND_TOP, 0, 0, 0, 0,
2711 SWP_ACTIVATE);
2712 DosSleep(100); //05 Aug 07 GKY 250
2713 }
2714 }
2715 else
2716 StartCollector(dcd->hwndParent, 4);
2717 }
2718 switch (SHORT1FROMMP(mp1)) {
2719 case IDM_APPENDTOCLIP:
2720 case IDM_APPENDTOCLIPFILENAME:
2721 case IDM_SAVETOCLIP:
2722 case IDM_SAVETOCLIPFILENAME:
2723 case IDM_ARCHIVE:
2724 case IDM_ARCHIVEM:
2725 case IDM_DELETE:
2726 case IDM_PERMDELETE:
2727 case IDM_ATTRS:
2728 case IDM_PRINT:
2729 case IDM_SHADOW:
2730 case IDM_SHADOW2:
2731 case IDM_JAVAEXE:
2732 case IDM_OBJECT:
2733 case IDM_VIEW:
2734 case IDM_VIEWTEXT:
2735 case IDM_VIEWBINARY:
2736 case IDM_EDIT:
2737 case IDM_EDITTEXT:
2738 case IDM_EDITBINARY:
2739 case IDM_MCIPLAY:
2740 case IDM_UPDATE:
2741 case IDM_DOITYOURSELF:
2742 case IDM_INFO:
2743 case IDM_EAS:
2744 action = UM_MASSACTION;
2745 break;
2746 }
2747 if (li->type == IDM_DELETE)
2748 ignorereadonly = FALSE;
2749 if (SHORT1FROMMP(mp1) == IDM_OBJECT ||
2750 SHORT1FROMMP(mp1) == IDM_SHADOW ||
2751 SHORT1FROMMP(mp1) == IDM_SHADOW2)
2752 *li->targetpath = 0;
2753 if (!PostMsg(dcd->hwndObject, action, MPFROMP(li), MPVOID)) {
2754 Runtime_Error(pszSrcFile, __LINE__, PCSZ_POSTMSG);
2755 FreeListInfo(li);
2756 }
2757 else if (fUnHilite)
2758 UnHilite(hwnd, TRUE, &dcd->lastselection, 0);
2759 }
2760 else
2761 free(li);
2762 }
2763 }
2764 break;
2765
2766 case IDM_DRIVESMENU:
2767 if (!hwndMain)
2768 PostMsg(hwnd, WM_COMMAND, MPFROM2SHORT(IDM_WALKDIR, 0), MPVOID);
2769 break;
2770
2771 default:
2772 if (SwitchCommand(dcd->hwndLastMenu, SHORT1FROMMP(mp1)))
2773 return 0;
2774 else {
2775 if (SHORT1FROMMP(mp1) >= IDM_COMMANDSTART &&
2776 SHORT1FROMMP(mp1) < IDM_QUICKTOOLSTART) {
2777
2778 register INT x;
2779
2780 if (!cmdloaded)
2781 load_commands();
2782 x = SHORT1FROMMP(mp1);// - IDM_COMMANDSTART;
2783 if (x >= 0) {
2784 //x++;
2785 RunCommand(hwnd, x);
2786 if (fUnHilite)
2787 UnHilite(hwnd, TRUE, &dcd->lastselection, 0);
2788 }
2789 }
2790 }
2791 break;
2792 }
2793 }
2794 return 0;
2795
2796 case UM_FIXCNRMLE:
2797 case UM_FIXEDITNAME:
2798 return CommonCnrProc(hwnd, msg, mp1, mp2);
2799
2800 case UM_FILESMENU:
2801 {
2802 PCNRITEM pci;
2803 HWND menuHwnd = (HWND) 0;
2804
2805 pci = (PCNRITEM) CurrentRecord(hwnd);
2806 if (pci && (INT) pci != -1) {
2807 if (pci->attrFile & FILE_DIRECTORY) {
2808 menuHwnd = CheckMenu(hwndMainMenu, &DirMenu, DIR_POPUP);
2809 // WinEnableMenuItem(DirMenu,IDM_TREE,TRUE);
2810 }
2811 else
2812 menuHwnd = CheckMenu(hwndMainMenu, &FileMenu, FILE_POPUP);
2813 }
2814 return MRFROMLONG(menuHwnd);
2815 }
2816
2817 case WM_CONTROL:
2818 DosError(FERR_DISABLEHARDERR);
2819 if (dcd) {
2820 switch (SHORT2FROMMP(mp1)) {
2821 case CN_COLLAPSETREE:
2822 case CN_EXPANDTREE:
2823 {
2824 PCNRITEM pci = (PCNRITEM) mp2;
2825
2826 if (pci && (INT) pci != -1 && !(pci->flags & RECFLAGS_ENV)) {
2827 if (driveflags[toupper(*pci->pszFileName) - 'A'] & DRIVE_REMOVABLE) {
2828 struct
2829 {
2830 ULONG serial;
2831 CHAR volumelength;
2832 CHAR volumelabel[CCHMAXPATH];
2833 }
2834 volser;
2835 APIRET rc;
2836
2837 memset(&volser, 0, sizeof(volser));
2838 DosError(FERR_DISABLEHARDERR);
2839 // fixme?
2840 rc = DosQueryFSInfo(toupper(*pci->pszFileName) - '@',
2841 FSIL_VOLSER, &volser, sizeof(volser));
2842 if (rc) {
2843 Dos_Error(MB_ENTER, rc, HWND_DESKTOP, pszSrcFile, __LINE__,
2844 GetPString(IDS_CANTFINDDIRTEXT),
2845 pci->pszFileName);
2846 if (!fErrorBeepOff)
2847 DosBeep(250,100);
2848 driveserial[toupper(*pci->pszFileName) - 'A'] = -1;
2849 UnFlesh(hwnd, pci);
2850 PostMsg(hwnd, UM_RESCAN, MPVOID, MPVOID);
2851 }
2852 else {
2853 if (SHORT2FROMMP(mp1) == CN_COLLAPSETREE &&
2854 !volser.serial ||
2855 driveserial[toupper(*pci->pszFileName) - 'A'] !=
2856 volser.serial)
2857 UnFlesh(hwnd, pci);
2858 if (SHORT2FROMMP(mp1) != CN_COLLAPSETREE ||
2859 (!volser.serial ||
2860 driveserial[toupper(*pci->pszFileName) - 'A'] !=
2861 volser.serial)) {
2862 if (SHORT2FROMMP(mp1) == CN_EXPANDTREE && Flesh(hwnd, pci) &&
2863 !dcd->suspendview && fTopDir ) {
2864 PostMsg(hwnd, UM_TOPDIR, MPFROMP(pci), MPVOID);
2865 //DbgMsg(pszSrcFile, __LINE__, "UM_TOPDIR %p pci %p", hwnd, pci);
2866 }
2867 }
2868 driveserial[toupper(*pci->pszFileName) - 'A'] = volser.serial;
2869 }
2870 }
2871 else if (SHORT2FROMMP(mp1) == CN_EXPANDTREE) {
2872 if (Flesh(hwnd, pci) && !dcd->suspendview && fTopDir) {
2873 PostMsg(hwnd, UM_TOPDIR, MPFROMP(pci), MPVOID);
2874 //DbgMsg(pszSrcFile, __LINE__, "UM_TOPDIR %p pci %p", hwnd, pci);
2875 }
2876 }
2877 if (SHORT2FROMMP(mp1) == CN_EXPANDTREE && !dcd->suspendview)
2878 WinSendMsg(hwnd, UM_FILTER, MPVOID, MPVOID);
2879
2880 }
2881 }
2882 break;
2883
2884 case CN_CONTEXTMENU:
2885 {
2886 PCNRITEM pci = (PCNRITEM) mp2;
2887
2888 if (pci) {
2889 WinSendMsg(hwnd,
2890 CM_SETRECORDEMPHASIS,
2891 MPFROMP(pci), MPFROM2SHORT(TRUE, CRA_CURSORED));
2892 MarkAll(hwnd, FALSE, FALSE, TRUE);
2893 if (pci->attrFile & FILE_DIRECTORY)
2894 dcd->hwndLastMenu = CheckMenu(hwndMainMenu, &DirMenu, DIR_POPUP);
2895 else
2896 dcd->hwndLastMenu = CheckMenu(hwndMainMenu, &FileMenu, FILE_POPUP);
2897 }
2898 else {
2899 dcd->hwndLastMenu = CheckMenu(hwnd, &DirCnrMenu, DIRCNR_POPUP);
2900 if (dcd->hwndLastMenu && !dcd->cnremphasized) {
2901 WinSendMsg(hwnd,
2902 CM_SETRECORDEMPHASIS,
2903 MPVOID, MPFROM2SHORT(TRUE, CRA_SOURCE));
2904 dcd->cnremphasized = TRUE;
2905 }
2906 }
2907 if (dcd->hwndLastMenu) {
2908 if (dcd->hwndLastMenu == DirCnrMenu) {
2909 if (dcd->flWindowAttr & CV_MINI)
2910 WinCheckMenuItem(dcd->hwndLastMenu, IDM_MINIICONS, TRUE);
2911 }
2912 if (dcd->hwndLastMenu == DirMenu)
2913 WinEnableMenuItem(DirMenu, IDM_TREE, TRUE);
2914 if (!PopupMenu(hwnd, hwnd, dcd->hwndLastMenu)) {
2915 if (dcd->cnremphasized) {
2916 WinSendMsg(hwnd,
2917 CM_SETRECORDEMPHASIS,
2918 MPVOID, MPFROM2SHORT(FALSE, CRA_SOURCE));
2919 dcd->cnremphasized = TRUE;
2920 }
2921 MarkAll(hwnd, TRUE, FALSE, TRUE);
2922 }
2923 }
2924 }
2925 break;
2926
2927 case CN_DROPHELP:
2928 if (mp2) {
2929
2930 PDRAGINFO pDInfo;
2931 PCNRITEM pci;
2932 ULONG numitems;
2933 USHORT usOperation;
2934
2935 pci = (PCNRITEM) ((PCNRDRAGINFO) mp2)->pRecord;
2936 pDInfo = (PDRAGINFO) ((PCNRDRAGINFO) mp2)->pDragInfo;
2937 if (!DrgAccessDraginfo(pDInfo)) {
2938 Win_Error(hwnd, hwnd, pszSrcFile, __LINE__,
2939 GetPString(IDS_DROPERRORTEXT));
2940 }
2941 else {
2942 numitems = DrgQueryDragitemCount(pDInfo);
2943 usOperation = pDInfo->usOperation;
2944 if (usOperation == DO_DEFAULT)
2945 usOperation = fCopyDefault ? DO_COPY : DO_MOVE;
2946 FreeDragInfoData(hwnd, pDInfo);
2947 saymsg(MB_ENTER | MB_ICONASTERISK,
2948 hwnd,
2949 GetPString(IDS_DROPHELPHDRTEXT),
2950 GetPString(IDS_DROPHELPTEXT),
2951 numitems,
2952 &"s"[numitems == 1L],
2953 pci ? NullStr : GetPString(IDS_NOTEXT),
2954 pci ? NullStr : " ",
2955 pci ? pci->pszFileName : NullStr,
2956 pci ? " " : NullStr,
2957 GetPString((usOperation == DO_MOVE) ?
2958 IDS_MOVETEXT :
2959 (usOperation == DO_LINK) ?
2960 IDS_LINKTEXT : IDS_COPYTEXT));
2961 }
2962 }
2963 return 0;
2964
2965 case CN_DRAGLEAVE:
2966 return 0;
2967
2968 case CN_DRAGAFTER:
2969 case CN_DRAGOVER:
2970 if (mp2) {
2971
2972 PDRAGITEM pDItem; // Pointer to DRAGITEM
2973 PDRAGINFO pDInfo; // Pointer to DRAGINFO
2974 PCNRITEM pci;
2975 USHORT uso;
2976
2977 pci = (PCNRITEM) ((PCNRDRAGINFO) mp2)->pRecord;
2978 pDInfo = ((PCNRDRAGINFO) mp2)->pDragInfo;
2979 if (!DrgAccessDraginfo(pDInfo)) {
2980 Win_Error(HWND_DESKTOP, HWND_DESKTOP, pszSrcFile, __LINE__,
2981 PCSZ_DRGACCESSDRAGINFO);
2982 return (MRFROM2SHORT(DOR_NEVERDROP, 0));
2983 }
2984 if (*dcd->directory &&
2985 (driveflags[toupper(*dcd->directory) - 'A'] &
2986 DRIVE_NOTWRITEABLE)) {
2987 DrgFreeDraginfo(pDInfo);
2988 return MRFROM2SHORT(DOR_DROP, // Return okay to link
2989 DO_LINK); // (compare) only
2990 }
2991 if (pci) {
2992 if (pci->rc.flRecordAttr & CRA_SOURCE) {
2993 DrgFreeDraginfo(pDInfo);
2994 return (MRFROM2SHORT(DOR_NODROP, 0));
2995 }
2996 uso = pDInfo->usOperation;
2997 if (uso == DO_DEFAULT)
2998 uso = fCopyDefault ? DO_COPY : DO_MOVE;
2999 if (!(pci->attrFile & FILE_DIRECTORY)) {
3000 if (uso != DO_LINK && uso != DO_COPY && uso != DO_MOVE) {
3001 DrgFreeDraginfo(pDInfo);
3002 return MRFROM2SHORT(DOR_NODROP, 0);
3003 }
3004 if (uso != DO_LINK &&
3005 !(driveflags[toupper(*pci->pszFileName) - 'A'] &
3006 DRIVE_NOTWRITEABLE)) {
3007
3008 ARC_TYPE *info = NULL;
3009
3010 if (!fQuickArcFind &&
3011 !(driveflags[toupper(*pci->pszFileName) - 'A'] &
3012 DRIVE_SLOW))
3013 info = find_type(pci->pszFileName, NULL);
3014 else
3015 info = quick_find_type(pci->pszFileName, NULL);
3016 if (!info || ((uso == DO_MOVE && !info->move) ||
3017 (uso == DO_COPY && !info->create))) {
3018 DrgFreeDraginfo(pDInfo);
3019 return MRFROM2SHORT(DOR_NODROP, 0);
3020 }
3021 }
3022 }
3023 }
3024
3025 /**
3026 * Access DRAGITEM index to DRAGITEM
3027 * Check valid rendering mechanisms and data
3028 */
3029 pDItem = DrgQueryDragitemPtr(pDInfo, 0);
3030 if (DrgVerifyRMF(pDItem, (CHAR *) DRM_OS2FILE, NULL) ||
3031 ((!pci || (pci->attrFile & FILE_DIRECTORY)) &&
3032 DrgVerifyRMF(pDItem, (CHAR *) DRM_FM2ARCMEMBER, (CHAR *) DRF_FM2ARCHIVE))) {
3033 DrgFreeDraginfo(pDInfo);
3034 if (driveflags[toupper(*dcd->directory) - 'A'] &
3035 DRIVE_NOTWRITEABLE)
3036 return MRFROM2SHORT(DOR_DROP, DO_LINK);
3037 if (toupper(*dcd->directory) < 'C')
3038 return MRFROM2SHORT(DOR_DROP, DO_COPY);
3039 return MRFROM2SHORT(DOR_DROP, // Return okay to drop
3040 ((fCopyDefault) ? DO_COPY : DO_MOVE));
3041 }
3042 DrgFreeDraginfo(pDInfo); // Free DRAGINFO
3043 }
3044 return MRFROM2SHORT(DOR_NODROP, 0); // Drop not valid
3045
3046 case CN_INITDRAG:
3047 {
3048 BOOL wasemphasized = FALSE;
3049 PCNRDRAGINIT pcd = (PCNRDRAGINIT) mp2;
3050 PCNRITEM pci;
3051
3052 if (pcd) {
3053 pci = (PCNRITEM) pcd->pRecord;
3054 if (pci) {
3055 if ((INT) pci == -1)
3056 pci = NULL;
3057 else if (pci->rc.flRecordAttr & CRA_SELECTED)
3058 wasemphasized = TRUE;
3059 }
3060 else if (!*dcd->directory) {
3061 Runtime_Error(pszSrcFile, __LINE__, NULL);
3062 break;
3063 }
3064 else if (IsRoot(dcd->directory)) {
3065 saymsg(MB_ENTER, hwnd, GetPString(IDS_ERRORTEXT),
3066 GetPString(IDS_CANTDRAGROOTDIR));
3067 break;
3068 }
3069 if (hwndStatus2) {
3070 if (pci)
3071 WinSetWindowText(hwndStatus2, (CHAR *) GetPString(IDS_DRAGFILEOBJTEXT));
3072 else
3073 WinSetWindowText(hwndStatus2, (CHAR *) GetPString(IDS_DRAGDIRTEXT));
3074 }
3075 if (DoFileDrag(hwnd,
3076 dcd->hwndObject,
3077 mp2,
3078 NULL,
3079 pci ? NULL : dcd->directory,
3080 pci ? TRUE : FALSE)) {
3081 if ((pci && fUnHilite && wasemphasized) || dcd->ulItemsToUnHilite) {
3082 UnHilite(hwnd, TRUE, &dcd->lastselection, dcd->ulItemsToUnHilite);
3083 }
3084 }
3085 if (hwndStatus2) {
3086 WinSetFocus(HWND_DESKTOP, hwnd);
3087 PostMsg(hwnd, UM_RESCAN, MPVOID, MPVOID);
3088 }
3089 }
3090 }
3091 return 0;
3092
3093 case CN_DROP:
3094 if (mp2) {
3095
3096 LISTINFO *li;
3097 ULONG action = UM_ACTION;
3098
3099 li = DoFileDrop(hwnd, dcd->directory, TRUE, mp1, mp2);
3100 CheckPmDrgLimit(((PCNRDRAGINFO)mp2)->pDragInfo);
3101 if (li) {
3102 if (li->list && li->list[0] && IsRoot(li->list[0]))
3103 li->type = DO_LINK;
3104 else if (fDragndropDlg && (!*li->arcname || !li->info)) {
3105
3106 CHECKLIST cl;
3107
3108 memset(&cl, 0, sizeof(cl));
3109 cl.size = sizeof(cl);
3110 cl.flags = li->type;
3111 cl.list = li->list;
3112 cl.cmd = li->type;
3113 cl.prompt = li->targetpath;
3114 li->type = WinDlgBox(HWND_DESKTOP, dcd->hwndParent,
3115 DropListProc, FM3ModHandle,
3116 DND_FRAME, MPFROMP(&cl));
3117 if (li->type == DID_ERROR)
3118 Win_Error(DND_FRAME, HWND_DESKTOP, pszSrcFile, __LINE__,
3119 GetPString(IDS_DRAGDROPDIALOGTEXT));
3120 if (!li->type) {
3121 FreeListInfo(li);
3122 return 0;
3123 }
3124 li->list = cl.list;
3125 if (!li->list || !li->list[0]) {
3126 FreeListInfo(li);
3127 return 0;
3128 }
3129 }
3130 switch (li->type) {
3131 case DND_LAUNCH:
3132 strcat(li->targetpath, " %a");
3133 ExecOnList(dcd->hwndParent, li->targetpath,
3134 PROMPT | WINDOWED, NULL, NULL, li->list, NULL,
3135 pszSrcFile, __LINE__);
3136 FreeList(li->list);
3137 li->list = NULL;
3138 break;
3139 case DO_LINK:
3140 if (fLinkSetsIcon) {
3141 li->type = IDM_SETICON;
3142 action = UM_MASSACTION;
3143 }
3144 else
3145 li->type = IDM_COMPARE;
3146 break;
3147 case DND_EXTRACT:
3148 if (*li->targetpath && !IsFile(li->targetpath))
3149 li->type = IDM_EXTRACT;
3150 break;
3151 case DND_MOVE:
3152 li->type = IDM_MOVE;
3153 if (*li->targetpath && IsFile(li->targetpath) == 1) {
3154 action = UM_MASSACTION;
3155 li->type = IDM_ARCHIVEM;
3156 }
3157 break;
3158 case DND_WILDMOVE:
3159 li->type = IDM_WILDMOVE;
3160 if (*li->targetpath && IsFile(li->targetpath) == 1) {
3161 action = UM_MASSACTION;
3162 li->type = IDM_ARCHIVEM;
3163 }
3164 break;
3165 case DND_OBJECT:
3166 li->type = IDM_OBJECT;
3167 action = UM_MASSACTION;
3168 break;
3169 case DND_SHADOW:
3170 li->type = IDM_SHADOW;
3171 action = UM_MASSACTION;
3172 break;
3173 case DND_COMPARE:
3174 li->type = IDM_COMPARE;
3175 break;
3176 case DND_SETICON:
3177 action = UM_MASSACTION;
3178 li->type = IDM_SETICON;
3179 break;
3180 case DND_COPY:
3181 li->type = IDM_COPY;
3182 if (*li->targetpath && IsFile(li->targetpath) == 1) {
3183 action = UM_MASSACTION;
3184 li->type = IDM_ARCHIVE;
3185 }
3186 break;
3187 case DND_WILDCOPY:
3188 li->type = IDM_WILDCOPY;
3189 if (*li->targetpath && IsFile(li->targetpath) == 1) {
3190 action = UM_MASSACTION;
3191 li->type = IDM_ARCHIVE;
3192 }
3193 break;
3194 default:
3195 if (*li->arcname && li->info) {
3196 action = UM_MASSACTION;
3197 li->type =
3198 (li->type == DO_MOVE) ? IDM_FAKEEXTRACTM : IDM_FAKEEXTRACT;
3199 }
3200 else if (*li->targetpath && IsFile(li->targetpath) == 1) {
3201 action = UM_MASSACTION;
3202 li->type = (li->type == DO_MOVE) ? IDM_ARCHIVEM : IDM_ARCHIVE;
3203 }
3204 else
3205 li->type = (li->type == DO_MOVE) ? IDM_MOVE : IDM_COPY;
3206 break;
3207 }
3208 if (!li->list || !li->list[0])
3209 FreeListInfo(li);
3210 else if (!PostMsg(dcd->hwndObject, action, MPFROMP(li), MPVOID))
3211 FreeListInfo(li);
3212 else {
3213
3214 USHORT usop = 0;
3215
3216 switch (li->type) {
3217 case IDM_COPY:
3218 case IDM_WILDCOPY:
3219 usop = DO_COPY;
3220 break;
3221 case IDM_MOVE:
3222 case IDM_WILDMOVE:
3223 case IDM_ARCHIVEM:
3224 usop = DO_MOVE;
3225 break;
3226 }
3227 if (usop)
3228 return MRFROM2SHORT(DOR_DROP, usop);
3229 }
3230 }
3231 }
3232 return 0;
3233
3234 case CN_ENDEDIT:
3235 case CN_BEGINEDIT:
3236 {
3237 PFIELDINFO pfi = ((PCNREDITDATA) mp2)->pFieldInfo;
3238 PCNRITEM pci = (PCNRITEM) ((PCNREDITDATA) mp2)->pRecord;
3239
3240 if (pfi || pci) {
3241
3242 MRESULT mre;
3243
3244 mre = CnrDirectEdit(hwnd, msg, mp1, mp2);
3245 if (mre != (MRESULT) - 1)
3246 return mre;
3247 }
3248 else if (!pfi && !pci)
3249 PostMsg(hwnd, UM_FIXCNRMLE, MPFROMLONG(CCHMAXPATH), MPVOID);
3250 }
3251 return 0;
3252
3253 case CN_REALLOCPSZ:
3254 {
3255 PFIELDINFO pfi = ((PCNREDITDATA) mp2)->pFieldInfo;
3256 PCNRITEM pci = (PCNRITEM) ((PCNREDITDATA) mp2)->pRecord;
3257 HWND hwndMLE;
3258 CHAR testname[CCHMAXPATH];
3259
3260 if (!pci && !pfi) {
3261 hwndMLE = WinWindowFromID(hwnd, CID_MLE);
3262 WinQueryWindowText(hwndMLE, sizeof(s), s);
3263 chop_at_crnl(s);
3264 bstrip(s);
3265 if (*s) {
3266 if (!DosQueryPathInfo(s,
3267 FIL_QUERYFULLNAME,
3268 testname, sizeof(testname))) {
3269 if (!SetDir(dcd->hwndParent, hwnd, testname, 1)) {
3270 PostMsg(hwnd, UM_SETDIR, MPFROMP(testname), MPVOID);
3271 }
3272 }
3273 }
3274 }
3275 else {
3276
3277 MRESULT mre;
3278
3279 mre = CnrDirectEdit(hwnd, msg, mp1, mp2);
3280 if (mre != (MRESULT) - 1)
3281 return mre;
3282 }
3283 }
3284 return 0;
3285
3286 case CN_EMPHASIS:
3287 if (!mp2)
3288 Runtime_Error(pszSrcFile, __LINE__, "mp2 NULL");
3289 else {
3290 PNOTIFYRECORDEMPHASIS pre = mp2;
3291 PCNRITEM pci;
3292 CHAR s[CCHMAXPATHCOMP + 91];
3293
3294 pci = (PCNRITEM) (pre ? pre->pRecord : NULL);
3295 if (!pci) {
3296 if (hwndStatus2)
3297 WinSetWindowText(hwndStatus2, NullStr);
3298 if (fMoreButtons) {
3299 WinSetWindowText(hwndName, NullStr);
3300 WinSetWindowText(hwndDate, NullStr);
3301 WinSetWindowText(hwndAttr, NullStr);
3302 }
3303 if (hwndMain)
3304 WinSendMsg(hwndMain, UM_LOADFILE, MPVOID, MPVOID);
3305 break;
3306 }
3307 if (pre->fEmphasisMask & CRA_SELECTED) {
3308 if (pci->rc.flRecordAttr & CRA_SELECTED) {
3309 dcd->selectedbytes += (pci->cbFile + pci->easize);
3310 dcd->selectedfiles++;
3311 }
3312 else if (dcd->selectedfiles) {
3313 dcd->selectedbytes -= (pci->cbFile + pci->easize);
3314 dcd->selectedfiles--;
3315 }
3316 if (!dcd->suspendview) {
3317 commafmt(tf, sizeof(tf), dcd->selectedfiles);
3318 CommaFmtULL(tb, sizeof(tb), dcd->selectedbytes, 'K');
3319 sprintf(s, "%s / %s", tf, tb);
3320 WinSetDlgItemText(dcd->hwndClient, DIR_SELECTED, s);
3321 }
3322 }
3323 if (!dcd->suspendview && hwndMain && pci->pszFileName != NullStr &&
3324 (pre->fEmphasisMask & CRA_CURSORED) &&
3325 (pci->rc.flRecordAttr & CRA_CURSORED) &&
3326 WinQueryActiveWindow(dcd->hwndParent) == dcd->hwndFrame) {
3327 if (driveflags[toupper(*pci->pszFileName) - 'A'] & DRIVE_SLOW)
3328 WinSendMsg(hwndMain, UM_LOADFILE, MPVOID, MPVOID);
3329 else
3330 WinSendMsg(hwndMain,
3331 UM_LOADFILE, MPFROMP(pci->pszFileName), MPVOID);
3332 }
3333 if (!dcd->suspendview &&
3334 WinQueryActiveWindow(dcd->hwndParent) == dcd->hwndFrame) {
3335 if (pre->fEmphasisMask & CRA_CURSORED) {
3336 if (pci->rc.flRecordAttr & CRA_CURSORED) {
3337 if (fSplitStatus && hwndStatus2) {
3338 CommaFmtULL(tb, sizeof(tb), pci->cbFile + pci->easize, ' ');
3339 if (!fMoreButtons) {
3340 CHAR date[11];
3341
3342 DateFormat(date, pci->date);
3343 sprintf(s, " %s %s %02u%s%02u%s%02u [%s] %s",
3344 tb, date, pci->time.hours, TimeSeparator,
3345 pci->time.minutes, TimeSeparator, pci->time.seconds,
3346 pci->pszDispAttr, pci->pszFileName);
3347 }
3348 else {
3349 *tf = 0;
3350 if (pci->cbFile + pci->easize > 1024) {
3351 CommaFmtULL(tf, sizeof(tf),
3352 pci->cbFile + pci->easize, 'K');
3353 }
3354 sprintf(s, GetPString(IDS_STATUSSIZETEXT),
3355 tb,
3356 *tf ? " (" : NullStr, tf, *tf ? ")" : NullStr);
3357 }
3358 WinSetWindowText(hwndStatus2, s);
3359 }
3360 if (fMoreButtons) {
3361 CHAR szDate[DATE_BUF_BYTES];
3362
3363 WinSetWindowText(hwndName, pci->pszFileName);
3364 DateFormat(szDate, pci->date);
3365 sprintf(s, "%s %02u%s%02u%s%02u",
3366 szDate, pci->time.hours, TimeSeparator, pci->time.minutes,
3367 TimeSeparator, pci->time.seconds);
3368 WinSetWindowText(hwndDate, s);
3369 WinSetWindowText(hwndAttr, pci->pszDispAttr);
3370 }
3371 }
3372 }
3373 }
3374 }
3375 break;
3376
3377 case CN_ENTER:
3378 if (mp2) {
3379
3380 PCNRITEM pci = (PCNRITEM) ((PNOTIFYRECORDENTER) mp2)->pRecord;
3381 FILEFINDBUF3 ffb;
3382 HDIR hDir = HDIR_CREATE;
3383 ULONG nm = 1;
3384 APIRET status = 0;
3385
3386 SetShiftState();
3387 if (pci) {
3388 if (pci->rc.flRecordAttr & CRA_INUSE)
3389 break;
3390 DosError(FERR_DISABLEHARDERR);
3391 status = DosFindFirst(pci->pszFileName,
3392 &hDir,
3393 FILE_NORMAL | FILE_DIRECTORY |
3394 FILE_ARCHIVED | FILE_READONLY |
3395 FILE_HIDDEN | FILE_SYSTEM,
3396 &ffb, sizeof(ffb), &nm, FIL_STANDARD);
3397 priority_bumped();
3398 if (!status) {
3399 DosFindClose(hDir);
3400 if (ffb.attrFile & FILE_DIRECTORY) {
3401 if ((shiftstate & (KC_CTRL | KC_ALT)) == (KC_CTRL | KC_ALT))
3402 PostMsg(hwnd,
3403 WM_COMMAND,
3404 MPFROM2SHORT(IDM_SHOWALLFILES, 0), MPVOID);
3405 else if ((shiftstate & (KC_CTRL | KC_SHIFT)) ==
3406 (KC_CTRL | KC_SHIFT))
3407 OpenObject(pci->pszFileName, Settings, dcd->hwndFrame);
3408 else if (shiftstate & KC_CTRL)
3409 OpenObject(pci->pszFileName, Default, dcd->hwndFrame);
3410 else if (shiftstate & KC_SHIFT) {
3411
3412 HWND hwndDir;
3413
3414 hwndDir = OpenDirCnr((HWND) 0,
3415 dcd->hwndParent,
3416 dcd->hwndFrame,
3417 FALSE, pci->pszFileName);
3418 if (hwndDir) {
3419 if (fMinOnOpen)
3420 WinSetWindowPos(dcd->hwndFrame,
3421 HWND_BOTTOM,
3422 0, 0, 0, 0, SWP_MINIMIZE | SWP_ZORDER);
3423 if (fAutoTile)
3424 TileChildren(dcd->hwndParent, TRUE);
3425 WinSetWindowPos(hwndDir,
3426 HWND_TOP, 0, 0, 0, 0, SWP_ACTIVATE);
3427 }
3428 }
3429 else {
3430 strcpy(dcd->previous, dcd->directory);
3431 strcpy(dcd->directory, pci->pszFileName);
3432 dcd->stopflag++;
3433 //DbgMsg(pszSrcFile, __LINE__, "WM_RESCAN");
3434 if (!PostMsg(dcd->hwndObject,
3435 UM_RESCAN, MPVOID, MPFROMLONG(1))) {
3436 dcd->stopflag--;
3437 }
3438 else if (*dcd->directory) {
3439 if (hwndMain)
3440 WinSendMsg(hwndMain,
3441 UM_SETUSERLISTNAME,
3442 MPFROMP(dcd->directory), MPVOID);
3443 else
3444 add_udir(FALSE, dcd->directory);
3445 }
3446 }
3447 }
3448 else {
3449
3450 SWP swp;
3451
3452 WinQueryWindowPos(dcd->hwndFrame, &swp);
3453 WinSendMsg(hwnd,
3454 CM_SETRECORDEMPHASIS,
3455 MPFROMP(pci), MPFROM2SHORT(TRUE, CRA_INUSE));
3456 DefaultViewKeys(hwnd,
3457 dcd->hwndFrame,
3458 dcd->hwndParent, &swp, pci->pszFileName);
3459 WinSendMsg(hwnd,
3460 CM_SETRECORDEMPHASIS,
3461 MPFROMP(pci),
3462 MPFROM2SHORT(FALSE,
3463 CRA_INUSE |
3464 ((fUnHilite) ? CRA_SELECTED : 0)));
3465 }
3466 }
3467 else {
3468 if (!*dcd->directory || IsValidDir(dcd->directory)) {
3469 NotifyError(pci->pszFileName, status);
3470 RemoveCnrItems(hwnd, pci, 1, CMA_FREE | CMA_INVALIDATE | CMA_ERASE);
3471 if (hwndStatus)
3472 WinSetWindowText(hwndStatus,
3473 (CHAR *) GetPString(IDS_RESCANSUGGESTEDTEXT));
3474 }
3475 else {
3476 dcd->stopflag++;
3477 //DbgMsg(pszSrcFile, __LINE__, "WM_RESCAN");
3478 if (!PostMsg(dcd->hwndObject,
3479 UM_RESCAN, MPVOID, MPFROMLONG(1L))) {
3480 dcd->stopflag--;
3481 }
3482 else if (*dcd->directory) {
3483 if (hwndMain)
3484 WinSendMsg(hwndMain,
3485 UM_SETUSERLISTNAME,
3486 MPFROMP(dcd->directory), MPVOID);
3487 else
3488 add_udir(FALSE, dcd->directory);
3489 }
3490 }
3491 }
3492 }
3493 else if (*dcd->directory)
3494 OpenObject(dcd->directory, Default, hwnd);
3495 } // CN_ENTER
3496 break;
3497 } // switch mp1
3498 break;
3499 } // if dcd
3500 return 0;
3501
3502 case UM_LOADFILE:
3503 if (dcd && mp2) {
3504
3505 HWND hwnd;
3506
3507 if ((INT)mp1 == 5 || (INT)mp1 == 13 || (INT)mp1 == 21)
3508 hwnd = StartViewer(HWND_DESKTOP, (INT)mp1,
3509 (CHAR *)mp2, dcd->hwndFrame);
3510 else
3511 hwnd = StartMLEEditor(dcd->hwndParent,
3512 (INT)mp1, (CHAR *)mp2, dcd->hwndFrame);
3513 xfree((CHAR *)mp2, pszSrcFile, __LINE__);
3514 return MRFROMLONG(hwnd);
3515 }
3516 return 0;
3517
3518 case WM_SAVEAPPLICATION:
3519 if (dcd && ParentIsDesktop(hwnd, dcd->hwndParent)) {
3520
3521 SWP swp;
3522
3523 WinQueryWindowPos(dcd->hwndFrame, &swp);
3524 if (!(swp.fl & (SWP_HIDE | SWP_MINIMIZE | SWP_MAXIMIZE)))
3525 PrfWriteProfileData(fmprof, appname, "VDirSizePos", &swp, sizeof(swp));
3526 }
3527 break;
3528
3529 case WM_CLOSE:
3530 WinSendMsg(hwnd, WM_SAVEAPPLICATION, MPVOID, MPVOID);
3531 if (LastDir == hwnd)
3532 LastDir = (HWND) 0;
3533 DosRequestMutexSem(hmtxFiltering, SEM_INDEFINITE_WAIT);
3534 if (dcd) {
3535 dcd->stopflag++;
3536 if (!dcd->dontclose && ParentIsDesktop(dcd->hwndFrame, (HWND) 0))
3537 PostMsg((HWND) 0, WM_QUIT, MPVOID, MPVOID);
3538 if (dcd->hwndObject) {
3539 // Ensure object window destroy does not attempt duplicate clean up
3540 WinSetWindowPtr(dcd->hwndObject, QWL_USER, NULL);
3541 if (!PostMsg(dcd->hwndObject, WM_CLOSE, MPVOID, MPVOID))
3542 Win_Error(dcd->hwndObject, hwnd, pszSrcFile, __LINE__, "hwndObject WinPostMsg failed");
3543 }
3544 if (dcd->hwndRestore)
3545 WinSetWindowPos(dcd->hwndRestore,
3546 HWND_TOP,
3547 0,
3548 0,
3549 0,
3550 0,
3551 SWP_RESTORE | SWP_SHOW | SWP_ACTIVATE | SWP_ZORDER);
3552 FreeList(dcd->lastselection);
3553 WinSetWindowPtr(hwnd, QWL_USER, NULL);
3554 DosPostEventSem(CompactSem);
3555 }
3556 DosReleaseMutexSem(hmtxFiltering);
3557 WinDestroyWindow(WinQueryWindow(WinQueryWindow(hwnd, QW_PARENT),
3558 QW_PARENT));
3559 return 0;
3560
3561 case WM_DESTROY:
3562# ifdef FORTIFY
3563 DbgMsg(pszSrcFile, __LINE__, "WM_DESTROY hwnd %p TID %u", hwnd, GetTidForThread()); // 18 Jul 08 SHL fixme
3564# endif
3565 if (DirMenu)
3566 WinDestroyWindow(DirMenu);
3567 if (DirCnrMenu)
3568 WinDestroyWindow(DirCnrMenu);
3569 if (FileMenu)
3570 WinDestroyWindow(FileMenu);
3571 DirMenu = DirCnrMenu = FileMenu = (HWND) 0;
3572 EmptyCnr(hwnd);
3573 DosRequestMutexSem(hmtxFiltering, SEM_INDEFINITE_WAIT);
3574 xfree(dcd, pszSrcFile, __LINE__);
3575 dcd = NULL;
3576 DosReleaseMutexSem(hmtxFiltering);
3577# ifdef FORTIFY
3578 Fortify_LeaveScope();
3579# endif
3580 break;
3581 } // switch
3582
3583 if (dcd && dcd->oldproc) {
3584# ifdef FORTIFY // 11 May 08 SHL fixme debug fortify
3585 if ((ULONG)dcd->oldproc == 0xa9a9a9a9)
3586 DbgMsg(pszSrcFile, __LINE__, "calling oldproc after dcd free msg %x mp1 %x mp2 %x",
3587 msg, mp1, mp2);
3588# endif
3589 return dcd->oldproc(hwnd, msg, mp1, mp2);
3590 }
3591 else
3592 return PFNWPCnr(hwnd, msg, mp1, mp2);
3593}
3594
3595/**
3596 * Search container for matching text
3597 * @return TRUE if key completely handled here
3598 */
3599
3600MRESULT EXPENTRY SearchContainer(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
3601{
3602 DIRCNRDATA *dcd = INSTDATA(hwnd);
3603 ULONG thistime;
3604 UINT len;
3605 SEARCHSTRING srch;
3606 PCNRITEM pci;
3607 USHORT key;
3608
3609 if (!dcd)
3610 return FALSE;
3611
3612 // Just to be safe, caller has probably already checked
3613 if (SHORT1FROMMP(mp1) & KC_KEYUP)
3614 return FALSE; // Let PM process key
3615
3616 // Just to be safe, caller has probably already cached
3617 shiftstate = (SHORT1FROMMP(mp1) & (KC_SHIFT | KC_ALT | KC_CTRL));
3618
3619 // If not plain character or suppressed
3620 // Shift toggles configured setting
3621 if (shiftstate & (KC_ALT | KC_CTRL) || (shiftstate & KC_SHIFT ? !fNoSearch : fNoSearch))
3622 return FALSE; // Let PM process key
3623
3624 if (SHORT1FROMMP(mp1) & KC_VIRTUALKEY) {
3625 key = SHORT2FROMMP(mp2);
3626 if (key == VK_BACKSPACE)
3627 key = '\x8';
3628 else if (key == VK_ESC)
3629 key = '\x1b';
3630 else
3631 return FALSE; // Let PM process key
3632 }
3633 else if (SHORT1FROMMP(mp1) & KC_CHAR)
3634 key = SHORT1FROMMP(mp2);
3635 else
3636 return FALSE;
3637
3638 thistime = WinQueryMsgTime(WinQueryAnchorBlock(hwnd));
3639 if (thistime > dcd->lasttime + 3000)
3640 *dcd->szCommonName = 0; // 3 seconds since last character
3641 dcd->lasttime = thistime;
3642
3643 switch (key) {
3644 case '\x1b': // Esc
3645 *dcd->szCommonName = 0;
3646 break;
3647 default:
3648 if (key == ' ' && !*dcd->szCommonName)
3649 break; // Let PM process space to allow select toggle
3650 len = strlen(dcd->szCommonName);
3651 if (key == '\x8') {
3652 // Backspace
3653 if (len) {
3654 len--;
3655 dcd->szCommonName[len] = 0; // Chop
3656 }
3657 }
3658 else {
3659 if (len >= CCHMAXPATH - 1) {
3660 if (!fErrorBeepOff)
3661 DosBeep(250,100);
3662 // WinAlarm(hwnd,WA_WARNING);
3663 }
3664 else {
3665 dcd->szCommonName[len] = toupper(key);
3666 dcd->szCommonName[len + 1] = 0;
3667 }
3668 }
3669 // Case insensitive search
3670 memset(&srch, 0, sizeof(SEARCHSTRING));
3671 srch.cb = (ULONG) sizeof(SEARCHSTRING);
3672 srch.pszSearch = (PSZ) dcd->szCommonName;
3673 srch.fsPrefix = TRUE;
3674 srch.fsCaseSensitive = FALSE;
3675 srch.usView = CV_ICON;
3676 pci = WinSendMsg(hwnd, CM_SEARCHSTRING, MPFROMP(&srch),
3677 MPFROMLONG(CMA_FIRST));
3678 if (pci && (INT) pci != -1) {
3679 // Got match make found item current item
3680 USHORT attrib = CRA_CURSORED;
3681 // 29 Mar 09 SHL fixme to clear other object select if not extended select
3682 if (!stricmp(pci->pszDisplayName, dcd->szCommonName))
3683 attrib |= CRA_SELECTED;
3684 WinSendMsg(hwnd, CM_SETRECORDEMPHASIS, MPFROMP(pci),
3685 MPFROM2SHORT(TRUE, attrib));
3686 // make sure that record shows in viewport
3687 ShowCnrRecord(hwnd, (PMINIRECORDCORE) pci);
3688 return (MRESULT)TRUE;
3689 }
3690 else {
3691 if (key == ' ')
3692 return FALSE; // Let PM process space to toggle select
3693 // No match
3694 // Erase non-matching last character, len is not yet incremented
3695 dcd->szCommonName[len] = 0;
3696 if (len == 0 && key != '\\') {
3697 // Let's see if user forgot leading backslash
3698 // key = SHORT1FROMMP(mp2);
3699 if (SearchContainer(hwnd, msg, mp1, MPFROM2SHORT('\\', 0))) {
3700 if (SearchContainer(hwnd, msg, mp1, mp2))
3701 return (MRESULT)TRUE; // Grab key from PM
3702 }
3703 }
3704 if (*dcd->szCommonName)
3705 return (MRESULT)TRUE; // Have partial match, grab key from PM
3706#if 0 // 15 Mar 09 SHL fixme to not hang
3707 if (!fErrorBeepOff)
3708 DosBeep(250,100);
3709 // WinAlarm(hwnd,WA_WARNING);
3710#endif
3711 }
3712 } // switch
3713
3714 return FALSE; // Let PM process key
3715}
3716
3717HWND StartDirCnr(HWND hwndParent, CHAR * directory, HWND hwndRestore,
3718 ULONG flags)
3719{
3720 /**
3721 * bitmapped flags:
3722 * 0x00000001 = don't close app when window closes
3723 * 0x00000002 = no frame controls
3724 */
3725
3726 HWND hwndFrame = (HWND) 0, hwndClient;
3727 ULONG FrameFlags = FCF_TITLEBAR | FCF_SYSMENU |
3728 FCF_SIZEBORDER | FCF_MINMAX | FCF_ICON | FCF_NOBYTEALIGN | FCF_ACCELTABLE;
3729 USHORT id;
3730 static USHORT idinc = 0;
3731 DIRCNRDATA *dcd;
3732 static BOOL first = FALSE;
3733
3734 if (flags & 2)
3735 FrameFlags &= (~(FCF_TITLEBAR | FCF_SYSMENU | FCF_SIZEBORDER |
3736 FCF_MINMAX | FCF_ICON));
3737 if (!idinc)
3738 idinc = (rand() % 100);
3739 if (!hwndParent)
3740 hwndParent = HWND_DESKTOP;
3741 if (ParentIsDesktop(hwndParent, hwndParent))
3742 FrameFlags |= (FCF_TASKLIST | FCF_MENU);
3743 if (!hwndMain && !first) {
3744 if (DirCnrMenu) {
3745 MENUITEM mi;
3746 memset(&mi, 0, sizeof(mi));
3747 WinSendMsg(DirCnrMenu,
3748 MM_DELETEITEM, MPFROM2SHORT(IDM_DRIVESMENU, FALSE), MPVOID);
3749 mi.iPosition = MIT_END;
3750 mi.afStyle = MIS_TEXT;
3751 mi.id = IDM_DRIVESMENU;
3752 WinSendMsg(DirCnrMenu,
3753 MM_INSERTITEM,
3754 MPFROMP(&mi), MPFROMP(GetPString(IDS_DRIVESMENUTEXT)));
3755 }
3756 first = TRUE;
3757 }
3758 if (directory) {
3759 hwndFrame = WinCreateStdWindow(hwndParent,
3760 WS_VISIBLE,
3761 &FrameFlags,
3762 (CHAR *) WC_DIRCONTAINER,
3763 NULL,
3764 WS_VISIBLE | fwsAnimate,
3765 FM3ModHandle, DIR_FRAME, &hwndClient);
3766 if (hwndFrame && hwndClient) {
3767 id = DIR_FRAME + idinc++;
3768 if (idinc > 99)
3769 idinc = 0;
3770 WinSetWindowUShort(hwndFrame, QWS_ID, id);
3771# ifdef FORTIFY
3772 Fortify_EnterScope();
3773# endif
3774 dcd = xmallocz(sizeof(DIRCNRDATA), pszSrcFile, __LINE__);
3775 if (!dcd) {
3776 PostMsg(hwndClient, WM_CLOSE, MPVOID, MPVOID);
3777 hwndFrame = (HWND) 0;
3778 }
3779 else {
3780 dcd->size = sizeof(DIRCNRDATA);
3781 dcd->id = id;
3782 dcd->type = DIR_FRAME;
3783 dcd->hwndParent = (hwndParent) ? hwndParent : HWND_DESKTOP;
3784 dcd->hwndFrame = hwndFrame;
3785 dcd->hwndClient = hwndClient;
3786 dcd->hwndRestore = hwndRestore;
3787 dcd->dontclose = ((flags & 1) != 0);
3788 dcd->ds.detailslongname = dsDirCnrDefault.detailslongname;
3789 dcd->ds.detailssubject = dsDirCnrDefault.detailssubject;
3790 dcd->ds.detailsea = dsDirCnrDefault.detailsea;
3791 dcd->ds.detailssize = dsDirCnrDefault.detailssize;
3792 dcd->ds.detailsicon = dsDirCnrDefault.detailsicon;
3793 dcd->ds.detailsattr = dsDirCnrDefault.detailsattr;
3794 dcd->ds.detailscrdate = dsDirCnrDefault.detailscrdate;
3795 dcd->ds.detailscrtime = dsDirCnrDefault.detailscrtime;
3796 dcd->ds.detailslwdate = dsDirCnrDefault.detailslwdate;
3797 dcd->ds.detailslwtime = dsDirCnrDefault.detailslwtime;
3798 dcd->ds.detailsladate = dsDirCnrDefault.detailsladate;
3799 dcd->ds.detailslatime = dsDirCnrDefault.detailslatime;
3800 strcpy(dcd->directory, directory);
3801 add_udir(FALSE, directory);
3802 {
3803 PFNWP oldproc;
3804
3805 oldproc = WinSubclassWindow(hwndFrame, (PFNWP) DirFrameWndProc);
3806 WinSetWindowPtr(hwndFrame, QWL_USER, (PVOID) oldproc);
3807 }
3808 dcd->hwndCnr = WinCreateWindow(hwndClient,
3809 WC_CONTAINER,
3810 NULL,
3811 CCS_AUTOPOSITION | CCS_MINIICONS |
3812 CCS_MINIRECORDCORE | ulCnrType, // |
3813 //WS_VISIBLE,
3814 0,
3815 0,
3816 0,
3817 0,
3818 hwndClient,
3819 HWND_TOP, (ULONG) DIR_CNR, NULL, NULL);
3820 if (!dcd->hwndCnr) {
3821 Win_Error(hwndClient, hwndClient, pszSrcFile, __LINE__,
3822 PCSZ_WINCREATEWINDOW);
3823 PostMsg(hwndClient, WM_CLOSE, MPVOID, MPVOID);
3824 DosRequestMutexSem(hmtxFiltering, SEM_INDEFINITE_WAIT);
3825 free(dcd);
3826 DosReleaseMutexSem(hmtxFiltering);
3827 hwndFrame = (HWND) 0;
3828 }
3829 else {
3830# ifdef FORTIFY
3831 Fortify_ChangeScope(dcd, -1);
3832# endif
3833 RestorePresParams(dcd->hwndCnr, PCSZ_DIRCNR);
3834 WinSetWindowPtr(dcd->hwndCnr, QWL_USER, (PVOID) dcd);
3835 dcd->oldproc = WinSubclassWindow(dcd->hwndCnr,
3836 (PFNWP) DirCnrWndProc);
3837 {
3838 USHORT ids[] = { DIR_TOTALS, DIR_SELECTED, DIR_VIEW, DIR_SORT,
3839 DIR_FILTER, DIR_FOLDERICON, DIR_MAX, 0
3840 };
3841
3842 if (!(flags & 2))
3843 ids[6] = 0;
3844 CommonCreateTextChildren(dcd->hwndClient,
3845 WC_DIRSTATUS, ids);
3846 }
3847 if (!PostMsg(dcd->hwndCnr, UM_SETUP, MPVOID, MPVOID))
3848 WinSendMsg(dcd->hwndCnr, UM_SETUP, MPVOID, MPVOID);
3849 if (FrameFlags & FCF_TASKLIST) {
3850
3851 SWP swp, swpD;
3852 ULONG size = sizeof(swp);
3853 LONG cxScreen, cyScreen;
3854
3855 WinQueryTaskSizePos(WinQueryAnchorBlock(hwndFrame), 0, &swp);
3856 if (PrfQueryProfileData(fmprof, appname, "VDirSizePos", &swpD, &size)) {
3857 cxScreen = WinQuerySysValue(HWND_DESKTOP, SV_CXSCREEN);
3858 cyScreen = WinQuerySysValue(HWND_DESKTOP, SV_CYSCREEN);
3859 if (swp.x + swpD.cx > cxScreen)
3860 swp.x = cxScreen - swpD.cx;
3861 if (swp.y + swpD.cy > cyScreen)
3862 swp.y = cyScreen - swpD.cy;
3863 swp.cx = swpD.cx;
3864 swp.cy = swpD.cy;
3865 }
3866 WinSetWindowPos(hwndFrame,
3867 HWND_TOP,
3868 swp.x,
3869 swp.y,
3870 swp.cx,
3871 swp.cy,
3872 SWP_SIZE | SWP_MOVE | SWP_SHOW | SWP_ZORDER |
3873 SWP_ACTIVATE);
3874 }
3875 WinShowWindow(dcd->hwndCnr, TRUE);
3876 }
3877 }
3878# ifdef FORTIFY
3879 Fortify_LeaveScope();
3880# endif
3881 }
3882 }
3883 return hwndFrame;
3884}
3885
3886#pragma alloc_text(DIRCNRS,DirCnrWndProc,DirObjWndProc,DirClientWndProc)
3887#pragma alloc_text(DIRCNRS,DirTextProc,DirFrameWndProc)
3888#pragma alloc_text(STARTUP,StartDirCnr)
Note: See TracBrowser for help on using the repository browser.