source: trunk/dll/chklist.c@ 1036

Last change on this file since 1036 was 907, checked in by Steven Levine, 18 years ago

Avoid out of memory traps in Compare Directories
Rework Compare Directories progress display for 2 second update rate
Start refactoring to reduce dependence on fm3dll.h
Add timer services (IsITimerExpired etc.)

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 14.7 KB
Line 
1
2/***********************************************************************
3
4 $Id: chklist.c 907 2008-01-06 07:26:17Z stevenhl $
5
6 Utility windows and mouse positioning
7
8 Copyright (c) 1993-98 M. Kimes
9 Copyright (c) 2005, 2008 Steven H.Levine
10
11 10 Jan 05 SHL Allow DND_TARGET to hold CCHMAXPATH
12 14 Jul 06 SHL Use Runtime_Error
13 22 Mar 07 GKY Use QWL_USER
14 20 Aug 07 GKY Move #pragma alloc_text to end for OpenWatcom compat
15
16***********************************************************************/
17
18#include <string.h>
19#include <ctype.h>
20
21#define INCL_DOS
22#define INCL_WIN
23#define INCL_GPI
24#define INCL_LONGLONG
25
26#include "fm3dlg.h"
27#include "fm3str.h"
28#include "makelist.h" // AddToList
29#include "errutil.h" // Dos_Error...
30#include "strutil.h" // GetPString
31#include "fm3dll.h"
32
33#pragma data_seg(DATA1)
34
35static PSZ pszSrcFile = __FILE__;
36
37VOID CenterOverWindow(HWND hwnd)
38{
39 SWP swp;
40 POINTL ptl;
41
42 if (!fDontMoveMouse) {
43 if (WinQueryWindowPos(hwnd, &swp)) {
44 ptl.x = swp.x + (swp.cx / 2);
45 ptl.y = swp.y + (swp.cy / 2);
46 WinMapWindowPoints(WinQueryWindow(hwnd, QW_PARENT), HWND_DESKTOP, &ptl,
47 1L);
48 WinSetPointerPos(HWND_DESKTOP, ptl.x, ptl.y);
49 }
50 }
51}
52
53BOOL PopupMenu(HWND hwndParent, HWND hwndOwner, HWND hwndMenu)
54{
55 POINTL ptl;
56 BOOL rc;
57
58 if (!WinQueryPointerPos(HWND_DESKTOP, &ptl))
59 ptl.x = ptl.y = 32;
60 WinMapWindowPoints(HWND_DESKTOP, hwndParent, &ptl, 1L);
61 rc = WinPopupMenu(hwndParent, hwndOwner, hwndMenu,
62 ptl.x, ptl.y, 0,
63 PU_HCONSTRAIN | PU_VCONSTRAIN |
64 PU_KEYBOARD | PU_MOUSEBUTTON1);
65 if (rc)
66 CenterOverWindow(hwndMenu);
67 return rc;
68}
69
70VOID PosOverOkay(HWND hwnd)
71{
72 SWP swp;
73 POINTL ptl;
74
75 if (!fDontMoveMouse) {
76 if (WinQueryWindowPos(WinWindowFromID(hwnd, DID_OK), &swp)) {
77 ptl.x = swp.x + (swp.cx / 2);
78 ptl.y = swp.y + (swp.cy / 2);
79 WinMapWindowPoints(hwnd, HWND_DESKTOP, &ptl, 1L);
80 WinSetPointerPos(HWND_DESKTOP, ptl.x, ptl.y);
81 }
82 }
83}
84
85MRESULT EXPENTRY CheckListProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
86{
87 CHECKLIST *cl;
88
89 switch (msg) {
90 case WM_INITDLG:
91 if (mp2) {
92
93 SHORT x;
94
95 WinSetWindowPtr(hwnd, QWL_USER, (PVOID) mp2);
96 cl = (CHECKLIST *) mp2;
97 if (!cl->list || !cl->list[0]) {
98 WinDismissDlg(hwnd, 0);
99 break;
100 }
101 WinSetDlgItemText(hwnd, CHECK_PROMPT, cl->prompt);
102 for (x = 0; cl->list[x]; x++) {
103 WinSendDlgItemMsg(hwnd, CHECK_LISTBOX, LM_INSERTITEM,
104 MPFROM2SHORT(LIT_END, 0), MPFROMP(cl->list[x]));
105 WinSendDlgItemMsg(hwnd, CHECK_LISTBOX, LM_SELECTITEM,
106 MPFROM2SHORT(x, 0), MPFROMSHORT(TRUE));
107 }
108 PosOverOkay(hwnd);
109 WinEnableWindow(WinWindowFromID(hwnd, CHECK_INFO),
110 ((cl->flags & CHECK_FILES) != 0));
111 WinShowWindow(WinWindowFromID(hwnd, CHECK_INFO),
112 ((cl->flags & CHECK_FILES) != 0));
113 {
114 HBITMAP hbm, hbmd, hbmdd;
115 HPS hps;
116
117 hps = WinGetPS(WinWindowFromID(hwnd, CHECK_BITMAP));
118 hbm = GpiLoadBitmap(hps, 0, cl->cmd, 28, 28);
119 if (hbm) {
120 hbmd =
121 (HBITMAP) WinSendDlgItemMsg(hwnd, CHECK_BITMAP, SM_QUERYHANDLE,
122 MPVOID, MPVOID);
123 hbmdd =
124 (HBITMAP) WinSendDlgItemMsg(hwnd, CHECK_BITMAP, SM_SETHANDLE,
125 MPFROMLONG(hbm), MPVOID);
126 if (hbmdd && hbmd && hbmd != hbmdd)
127 GpiDeleteBitmap(hbmd);
128 }
129 if (hps)
130 WinReleasePS(hps);
131 WinSetWindowPos(WinWindowFromID(hwnd, CHECK_BITMAP), HWND_TOP,
132 0, 0, 28, 28, SWP_SIZE);
133 }
134 }
135 else
136 WinDismissDlg(hwnd, 0);
137 break;
138
139 case WM_ADJUSTWINDOWPOS:
140 PostMsg(hwnd, UM_SETDIR, MPVOID, MPVOID);
141 break;
142
143 case UM_SETDIR:
144 PaintRecessedWindow(WinWindowFromID(hwnd, CHECK_HELP), (HPS) 0, FALSE,
145 TRUE);
146 return 0;
147
148 case WM_CONTROL:
149 switch (SHORT1FROMMP(mp1)) {
150 case CHECK_LISTBOX:
151 switch (SHORT2FROMMP(mp1)) {
152 case LN_ENTER:
153 {
154 SHORT x;
155 CHAR szBuffer[CCHMAXPATH];
156
157 x = (SHORT) WinSendDlgItemMsg(hwnd, CHECK_LISTBOX,
158 LM_QUERYSELECTION,
159 MPFROMSHORT(LIT_FIRST), MPVOID);
160 if (x >= 0) {
161 *szBuffer = 0;
162 WinSendDlgItemMsg(hwnd, CHECK_LISTBOX, LM_QUERYITEMTEXT,
163 MPFROM2SHORT(x, CCHMAXPATH), MPFROMP(szBuffer));
164 if (*szBuffer)
165 QuickView(hwnd, szBuffer);
166 }
167 }
168 break;
169 }
170 break;
171 }
172 return 0;
173
174 case WM_COMMAND:
175 switch (SHORT1FROMMP(mp1)) {
176 case CHECK_INFO:
177 cl = INSTDATA(hwnd);
178 if (cl)
179 WinDlgBox(HWND_DESKTOP, hwnd, FileInfoProc, FM3ModHandle,
180 FLE_FRAME, (PVOID) cl->list);
181 break;
182
183 case IDM_HELP:
184 if (hwndHelp)
185 WinSendMsg(hwndHelp, HM_DISPLAY_HELP,
186 MPFROM2SHORT(HELP_CHECKLIST, 0),
187 MPFROMSHORT(HM_RESOURCEID));
188 break;
189
190 case DID_OK:
191 cl = INSTDATA(hwnd);
192 if (cl) {
193
194 CHAR szBuffer[CCHMAXPATH + 1];
195 UINT numfiles = 0, numalloc = 0;
196 INT error;
197 SHORT x;
198
199 FreeList(cl->list);
200 cl->list = NULL;
201 x = (SHORT) WinSendDlgItemMsg(hwnd, CHECK_LISTBOX, LM_QUERYSELECTION,
202 MPFROMSHORT(LIT_FIRST), MPVOID);
203 if (x >= 0) {
204 do {
205 *szBuffer = 0;
206 WinSendDlgItemMsg(hwnd, CHECK_LISTBOX, LM_QUERYITEMTEXT,
207 MPFROM2SHORT(x, CCHMAXPATH), MPFROMP(szBuffer));
208 if (*szBuffer) {
209 error = AddToList(szBuffer, &cl->list, &numfiles, &numalloc);
210 if (error) {
211 Runtime_Error(pszSrcFile, __LINE__, "AddToList");
212 break;
213 }
214 }
215 x = (SHORT) WinSendDlgItemMsg(hwnd, CHECK_LISTBOX,
216 LM_QUERYSELECTION,
217 MPFROMSHORT(x), MPVOID);
218 } while (x >= 0);
219 }
220 WinDismissDlg(hwnd, 1);
221 }
222 else
223 WinDismissDlg(hwnd, 0);
224 break;
225
226 case DID_CANCEL:
227 WinDismissDlg(hwnd, 0);
228 break;
229 }
230 return 0;
231 }
232 return WinDefDlgProc(hwnd, msg, mp1, mp2);
233}
234
235MRESULT EXPENTRY DropListProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
236{
237 CHECKLIST *cl;
238 static BOOL Shadow = FALSE, Wild = FALSE;
239
240 switch (msg) {
241 case WM_INITDLG:
242 if (mp2) {
243
244 SHORT x;
245
246 WinSetWindowPtr(hwnd, QWL_USER, (PVOID) mp2);
247 cl = (CHECKLIST *) mp2;
248 if (!cl->list || !cl->list[0]) {
249 WinDismissDlg(hwnd, 0);
250 break;
251 }
252 if (IsRoot(cl->list[0])) {
253 WinDismissDlg(hwnd, DND_COMPARE);
254 break;
255 }
256 WinSendDlgItemMsg(hwnd, DND_LISTBOX, LM_DELETEALL, MPVOID, MPVOID);
257 for (x = 0; cl->list[x]; x++) {
258 WinSendDlgItemMsg(hwnd, DND_LISTBOX, LM_INSERTITEM,
259 MPFROM2SHORT(LIT_END, 0), MPFROMP(cl->list[x]));
260 WinSendDlgItemMsg(hwnd, DND_LISTBOX, LM_SELECTITEM,
261 MPFROM2SHORT(x, 0), MPFROMSHORT(TRUE));
262 }
263 WinSendDlgItemMsg(hwnd, DND_TARGET, EM_SETTEXTLIMIT,
264 (MPARAM) CCHMAXPATH, (MPARAM) 0);
265 PostMsg(hwnd, UM_UNDO, MPVOID, MPVOID);
266 }
267 else
268 WinDismissDlg(hwnd, 0);
269 break;
270
271 case UM_UNDO:
272 cl = INSTDATA(hwnd);
273 if (cl) {
274
275 CHAR *p;
276
277 WinSetDlgItemText(hwnd, DND_TARGET, cl->prompt);
278 WinEnableWindow(WinWindowFromID(hwnd, DND_LAUNCH),
279 (IsExecutable(cl->prompt)));
280 WinEnableWindow(WinWindowFromID(hwnd, DND_COPY), TRUE);
281 WinEnableWindow(WinWindowFromID(hwnd, DND_MOVE), TRUE);
282 WinEnableWindow(WinWindowFromID(hwnd, DND_RENAME), TRUE);
283 WinEnableWindow(WinWindowFromID(hwnd, DND_OBJECT), TRUE);
284 WinEnableWindow(WinWindowFromID(hwnd, DND_SHADOW), TRUE);
285 WinEnableWindow(WinWindowFromID(hwnd, DND_EXTRACT), TRUE);
286 WinEnableWindow(WinWindowFromID(hwnd, DND_SETICON), FALSE);
287 p = strrchr(cl->list[0], '.');
288 if (p) {
289 p++;
290 if (!stricmp(p, "ICO") || !stricmp(p, "PTR"))
291 WinEnableWindow(WinWindowFromID(hwnd, DND_SETICON), TRUE);
292 }
293 if (IsFile(cl->prompt)) {
294 WinEnableWindow(WinWindowFromID(hwnd, DND_OBJECT), FALSE);
295 WinEnableWindow(WinWindowFromID(hwnd, DND_SHADOW), FALSE);
296 WinEnableWindow(WinWindowFromID(hwnd, DND_EXTRACT), FALSE);
297 WinEnableWindow(WinWindowFromID(hwnd, DND_RENAME), FALSE);
298 }
299 else {
300
301 ARC_TYPE *info;
302
303 info = find_type(cl->list[0], NULL);
304 if (!info)
305 WinEnableWindow(WinWindowFromID(hwnd, DND_EXTRACT), FALSE);
306 }
307 if (Shadow)
308 WinCheckButton(hwnd, DND_SHADOW, TRUE);
309 if (Wild)
310 WinCheckButton(hwnd, DND_RENAME, TRUE);
311 PostMsg(hwnd, UM_SETUP, MPVOID, MPVOID);
312 if (cl->prompt && isalpha(*cl->prompt) &&
313 (driveflags[toupper(*cl->prompt) - 'A'] & DRIVE_NOTWRITEABLE)) {
314 WinEnableWindow(WinWindowFromID(hwnd, DND_COPY), FALSE);
315 WinEnableWindow(WinWindowFromID(hwnd, DND_MOVE), FALSE);
316 WinEnableWindow(WinWindowFromID(hwnd, DND_RENAME), FALSE);
317 WinEnableWindow(WinWindowFromID(hwnd, DND_OBJECT), FALSE);
318 WinEnableWindow(WinWindowFromID(hwnd, DND_SHADOW), FALSE);
319 WinEnableWindow(WinWindowFromID(hwnd, DND_EXTRACT), FALSE);
320 }
321 if (cl->prompt && IsFile(cl->prompt) == 1) {
322
323 ARC_TYPE *info;
324
325 info = find_type(cl->prompt, NULL);
326 if (!info) {
327 WinEnableWindow(WinWindowFromID(hwnd, DND_COPY), FALSE);
328 WinEnableWindow(WinWindowFromID(hwnd, DND_MOVE), FALSE);
329 WinEnableWindow(WinWindowFromID(hwnd, DND_RENAME), FALSE);
330 WinEnableWindow(WinWindowFromID(hwnd, DND_OBJECT), FALSE);
331 WinEnableWindow(WinWindowFromID(hwnd, DND_SHADOW), FALSE);
332 WinEnableWindow(WinWindowFromID(hwnd, DND_EXTRACT), FALSE);
333 }
334 }
335 }
336 break;
337
338 case UM_SETUP:
339 cl = WinQueryWindowPtr(hwnd, QWL_USER);
340 if (cl) {
341 if (cl->flags == DO_MOVE)
342 WinSetFocus(HWND_DESKTOP, WinWindowFromID(hwnd, DND_MOVE));
343 else if (cl->flags == DO_LINK)
344 WinSetFocus(HWND_DESKTOP, WinWindowFromID(hwnd, DND_COMPARE));
345 else
346 WinSetFocus(HWND_DESKTOP, WinWindowFromID(hwnd, DND_COPY));
347 }
348 return 0;
349
350 case WM_ADJUSTWINDOWPOS:
351 PostMsg(hwnd, UM_SETDIR, MPVOID, MPVOID);
352 break;
353
354 case UM_SETDIR:
355 PaintRecessedWindow(WinWindowFromID(hwnd, DND_HELP), (HPS) 0, FALSE,
356 TRUE);
357 return 0;
358
359 case WM_CONTROL:
360 switch (SHORT1FROMMP(mp1)) {
361 case DND_LISTBOX:
362 switch (SHORT2FROMMP(mp1)) {
363 case LN_SETFOCUS:
364 WinSetDlgItemText(hwnd, DND_HELP, GetPString(IDS_DNDLISTBOXHELPTEXT));
365 break;
366 case LN_KILLFOCUS:
367 WinSetDlgItemText(hwnd, DND_HELP, GetPString(IDS_DNDHELPTEXT));
368 break;
369 case LN_ENTER:
370 {
371 SHORT x;
372 CHAR szBuffer[CCHMAXPATH];
373
374 x = (SHORT) WinSendDlgItemMsg(hwnd, DND_LISTBOX, LM_QUERYSELECTION,
375 MPFROMSHORT(LIT_FIRST), MPVOID);
376 if (x >= 0) {
377 *szBuffer = 0;
378 WinSendDlgItemMsg(hwnd, DND_LISTBOX, LM_QUERYITEMTEXT,
379 MPFROM2SHORT(x, CCHMAXPATH), MPFROMP(szBuffer));
380 if (*szBuffer)
381 QuickView(hwnd, szBuffer);
382 }
383 }
384 break;
385 }
386 break;
387 case DND_TARGET:
388 switch (SHORT2FROMMP(mp1)) {
389 case EN_SETFOCUS:
390 WinSetDlgItemText(hwnd, DND_HELP, GetPString(IDS_DNDTARGETHELPTEXT));
391 break;
392 case EN_KILLFOCUS:
393 WinSetDlgItemText(hwnd, DND_HELP, GetPString(IDS_DNDHELPTEXT));
394 break;
395 }
396 break;
397 }
398 return 0;
399
400 case WM_COMMAND:
401 switch (SHORT1FROMMP(mp1)) {
402 case IDM_HELP:
403 if (hwndHelp)
404 WinSendMsg(hwndHelp, HM_DISPLAY_HELP,
405 MPFROM2SHORT(HELP_DNDDLG, 0), MPFROMSHORT(HM_RESOURCEID));
406 break;
407
408 case DND_INFO:
409 cl = INSTDATA(hwnd);
410 if (cl)
411 WinDlgBox(HWND_DESKTOP, hwnd, FileInfoProc, FM3ModHandle,
412 FLE_FRAME, (PVOID) cl->list);
413 break;
414
415 case DND_CHANGETARGET:
416 cl = INSTDATA(hwnd);
417 if (cl) {
418 if (cl->prompt && *cl->prompt) {
419 if (!IsFile(cl->prompt)) {
420
421 CHAR newpath[CCHMAXPATH];
422
423 strcpy(newpath, cl->prompt);
424 if (WinDlgBox(HWND_DESKTOP, hwnd, WalkAllDlgProc,
425 FM3ModHandle, WALK_FRAME,
426 MPFROMP(newpath)) && *newpath) {
427 strcpy(cl->prompt, newpath);
428 PostMsg(hwnd, UM_UNDO, MPVOID, MPVOID);
429 }
430 }
431 else {
432
433 FILEDLG fdlg;
434 FILESTATUS3 fs3;
435 CHAR drive[3], *pdrive = drive, filename[CCHMAXPATH], *p;
436
437 memset(&fdlg, 0, sizeof(FILEDLG));
438 fdlg.cbSize = (ULONG) sizeof(FILEDLG);
439 fdlg.fl = FDS_HELPBUTTON | FDS_CENTER |
440 FDS_OPEN_DIALOG | FDS_CUSTOM;
441 fdlg.pszTitle = GetPString(IDS_NEWTARGETTEXT);
442 fdlg.pszOKButton = GetPString(IDS_CHANGETEXT);
443 *drive = *cl->prompt;
444 drive[1] = ':';
445 drive[2] = 0;
446 fdlg.pszIDrive = pdrive;
447 strcpy(fdlg.szFullFile, cl->prompt);
448 p = strrchr(fdlg.szFullFile, '\\');
449 if (p)
450 *p = 0;
451 strcat(fdlg.szFullFile, "\\*");
452
453 fdlg.pfnDlgProc = (PFNWP) CustomFileDlg;
454 fdlg.hMod = FM3ModHandle;
455 fdlg.usDlgId = FDLG_FRAME;
456
457 if (WinFileDlg(HWND_DESKTOP, hwnd, &fdlg)) {
458 if (fdlg.lReturn != DID_CANCEL && !fdlg.lSRC) {
459 if (!DosQueryPathInfo(fdlg.szFullFile,
460 FIL_QUERYFULLNAME,
461 filename, sizeof(filename))) {
462 if (!DosQueryPathInfo(filename,
463 FIL_STANDARD, &fs3, sizeof(fs3))) {
464 p = filename;
465 while (*p) {
466 if (*p == '/')
467 *p = '\\';
468 p++;
469 }
470 strcpy(cl->prompt, filename);
471 PostMsg(hwnd, UM_UNDO, MPVOID, MPVOID);
472 }
473// else saymsg(MB_ENTER,hwnd,DEBUG_STRING,"DosQueryPathInfo FIL_STANDARDL failed");
474 }
475// else saymsg(MB_ENTER,hwnd,DEBUG_STRING,"DosQueryPathInfo FIL_QUERYFULLNAME failed");
476 }
477// else saymsg(MB_ENTER,hwnd,DEBUG_STRING,"lReturn = %lu lSRC = %lu",fdlg.lReturn,fdlg.lSRC);
478 }
479// else saymsg(MB_ENTER,hwnd,DEBUG_STRING,"WinFileDlg failed");
480 }
481 }
482 }
483 break;
484
485 case DND_TARGETINFO:
486 cl = INSTDATA(hwnd);
487 if (cl) {
488
489 CHAR *list[2];
490
491 list[0] = cl->prompt;
492 list[1] = NULL;
493 WinDlgBox(HWND_DESKTOP, hwnd, FileInfoProc, FM3ModHandle,
494 FLE_FRAME, (PVOID) & list);
495 }
496 break;
497
498 case DND_EXTRACT:
499 case DND_LAUNCH:
500 case DND_COPY:
501 case DND_MOVE:
502 case DND_OBJECT:
503 case DND_COMPARE:
504 case DND_SETICON:
505 case DND_APPEND:
506 cl = INSTDATA(hwnd);
507 if (cl) {
508
509 SHORT x;
510 CHAR szBuffer[CCHMAXPATH + 1];
511 UINT numfiles = 0, numalloc = 0;
512 INT error;
513 USHORT cmd;
514
515 FreeList(cl->list);
516 cl->list = NULL;
517 x = (SHORT) WinSendDlgItemMsg(hwnd, DND_LISTBOX, LM_QUERYSELECTION,
518 MPFROMSHORT(LIT_FIRST), MPVOID);
519 if (x >= 0) {
520 do {
521 *szBuffer = 0;
522 WinSendDlgItemMsg(hwnd, DND_LISTBOX, LM_QUERYITEMTEXT,
523 MPFROM2SHORT(x, CCHMAXPATH), MPFROMP(szBuffer));
524 if (*szBuffer) {
525 error = AddToList(szBuffer, &cl->list, &numfiles, &numalloc);
526 if (error) {
527 Runtime_Error(pszSrcFile, __LINE__, "AddToList");
528 break;
529 }
530 }
531 x = (SHORT) WinSendDlgItemMsg(hwnd, DND_LISTBOX,
532 LM_QUERYSELECTION,
533 MPFROMSHORT(x), MPVOID);
534 } while (x >= 0);
535 }
536 cmd = SHORT1FROMMP(mp1);
537 switch (cmd) {
538 case DND_COPY:
539 if (WinQueryButtonCheckstate(hwnd, DND_RENAME)) {
540 Wild = TRUE;
541 cmd = DND_WILDCOPY;
542 }
543 else
544 Wild = FALSE;
545 break;
546 case DND_MOVE:
547 if (WinQueryButtonCheckstate(hwnd, DND_RENAME)) {
548 Wild = TRUE;
549 cmd = DND_WILDMOVE;
550 }
551 else
552 Wild = FALSE;
553 break;
554 case DND_OBJECT:
555 if (WinQueryButtonCheckstate(hwnd, DND_SHADOW)) {
556 Shadow = TRUE;
557 cmd = DND_SHADOW;
558 }
559 else
560 Shadow = FALSE;
561 break;
562 }
563 WinDismissDlg(hwnd, cmd);
564 }
565 else
566 WinDismissDlg(hwnd, 0);
567 break;
568
569 case DID_CANCEL:
570 WinDismissDlg(hwnd, 0);
571 break;
572 }
573 return 0;
574 }
575 return WinDefDlgProc(hwnd, msg, mp1, mp2);
576}
577
578#pragma alloc_text(CHECKLIST,CheckListProc)
579#pragma alloc_text(DNDLIST,DropListProc)
580#pragma alloc_text(MISC7,PosOverOkay,CenterOverWindow,PopupMenu)
Note: See TracBrowser for help on using the repository browser.