source: trunk/dll/dircnrs.c@ 1877

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

Remove debug code

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