source: trunk/dll/dircnrs.c@ 1787

Last change on this file since 1787 was 1786, checked in by Gregg Young, 11 years ago

Add semaphore hmtxFiltering to prevent freeing dcd while filtering. Prevents a trap when FM2 is shutdown while directory containers are still populating (Ticket 535)

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