source: trunk/dll/extract.c@ 1344

Last change on this file since 1344 was 1344, checked in by Gregg Young, 17 years ago

Update extract to filename based subdirectory; Remember now remembers the previous directory and ignores filename as extract path which is identical to its previous behavior. (Ticket 22)

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 14.8 KB
Line 
1
2/***********************************************************************
3
4 $Id: extract.c 1344 2008-12-19 13:40:20Z gyoung $
5
6 Copyright (c) 1993-98 M. Kimes
7 Copyright (c) 2004, 2007 Steven H. Levine
8
9 01 Aug 04 SHL Rework lstrip/rstrip usage
10 05 Jun 05 SHL Use QWL_USER
11 17 Jul 06 SHL Use Runtime_Error
12 20 Dec 06 GKY Added checkbox to make default extract with directories
13 22 Mar 07 GKY Use QWL_USER
14 19 Apr 07 SHL Sync with AcceptOneDrop GetOneDrop mods
15 20 Aug 07 GKY Move #pragma alloc_text to end for OpenWatcom compat
16 19 Jul 08 GKY Replace save_dir2(dir) with pFM2SaveDirectory
17 29 Nov 08 GKY Add the option of creating a subdirectory from the arcname
18 for the extract path.
19
20***********************************************************************/
21
22#include <string.h>
23#include <ctype.h>
24
25#define INCL_WIN
26#define INCL_DOS
27#define INCL_LONGLONG // dircnrs.h
28
29#include "fm3dll.h"
30#include "fm3dll2.h" // #define's for UM_*, control id's, etc.
31#include "init.h" // Data declaration(s)
32#include "arccnrs.h" // Data declaration(s)
33#include "notebook.h" // Data declaration(s)
34#include "mainwnd.h" // Data declaration(s)
35#include "fm3dlg.h"
36#include "fm3str.h"
37#include "errutil.h" // Dos_Error...
38#include "strutil.h" // GetPString
39#include "cmdline.h" // CmdLineDlgProc
40#include "extract.h"
41#include "walkem.h" // WalkExtractDlgProc
42#include "droplist.h" // AcceptOneDrop, DropHelp, GetOneDrop
43#include "misc.h" // DrawTargetEmphasis
44#include "chklist.h" // PosOverOkay
45#include "mkdir.h" // SetDir
46#include "valid.h" // MakeValidDir
47#include "systemf.h" // runemf2
48#include "dirs.h" // save_dir2
49#include "strips.h" // bstrip
50
51#pragma data_seg(DATA1)
52
53static PSZ pszSrcFile = __FILE__;
54
55MRESULT EXPENTRY ExtractTextProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
56{
57 PFNWP oldproc = (PFNWP) WinQueryWindowPtr(hwnd, QWL_USER);
58 static BOOL emphasized = FALSE;
59
60 switch (msg) {
61 case DM_DRAGOVER:
62 if (!emphasized) {
63 emphasized = TRUE;
64 DrawTargetEmphasis(hwnd, emphasized);
65 }
66 if (AcceptOneDrop(hwnd, mp1, mp2))
67 return MRFROM2SHORT(DOR_DROP, DO_MOVE);
68 return MRFROM2SHORT(DOR_NEVERDROP, 0);
69
70 case DM_DRAGLEAVE:
71 if (emphasized) {
72 emphasized = FALSE;
73 DrawTargetEmphasis(hwnd, emphasized);
74 }
75 break;
76
77 case DM_DROPHELP:
78 DropHelp(mp1, mp2, hwnd, GetPString(IDS_EXTDROPHELPTEXT));
79 return 0;
80
81 case DM_DROP:
82 {
83 char szFrom[CCHMAXPATH + 2];
84
85 if (emphasized) {
86 emphasized = FALSE;
87 DrawTargetEmphasis(hwnd, emphasized);
88 }
89 if (GetOneDrop(hwnd, mp1, mp2, szFrom, sizeof(szFrom)))
90 WinSendMsg(WinQueryWindow(hwnd, QW_PARENT), WM_COMMAND,
91 MPFROM2SHORT(IDM_SWITCH, 0), MPFROMP(szFrom));
92 }
93 return 0;
94 }
95 return (oldproc) ? oldproc(hwnd, msg, mp1, mp2) :
96 WinDefWindowProc(hwnd, msg, mp1, mp2);
97}
98
99MRESULT EXPENTRY ExtractDlgProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
100{
101 EXTRDATA *arcdata = NULL;
102 ULONG size;
103 BOOL fFileNameExtPath;
104
105 switch (msg) {
106 case WM_INITDLG:
107 WinSetWindowPtr(hwnd, QWL_USER, mp2);
108 arcdata = (EXTRDATA *) mp2;
109 {
110 BOOL fDirectory = FALSE;
111 BOOL fRemember = FALSE;
112 PFNWP oldproc;
113
114 fFileNameExtPath = FALSE;
115 oldproc = WinSubclassWindow(WinWindowFromID(hwnd, EXT_DIRECTORY),
116 (PFNWP) ExtractTextProc);
117 if (oldproc)
118 WinSetWindowPtr(WinWindowFromID(hwnd, EXT_DIRECTORY),
119 QWL_USER, (PVOID) oldproc);
120 size = sizeof(BOOL);
121 PrfQueryProfileData(fmprof, FM3Str, "RememberExt",
122 (PVOID) & fRemember, &size);
123 size = sizeof(BOOL);
124 PrfQueryProfileData(fmprof, FM3Str, "DirectoryExt",
125 (PVOID) & fDirectory, &size);
126 size = sizeof(BOOL);
127 PrfQueryProfileData(fmprof, FM3Str, "FileNamePathExt",
128 (PVOID) & fFileNameExtPath, &size);
129 WinCheckButton(hwnd, EXT_REMEMBER, fRemember);
130 WinCheckButton(hwnd, EXT_AWDIRS, fDirectory);
131 WinCheckButton(hwnd, EXT_FILENAMEEXT, fFileNameExtPath);
132 WinSendDlgItemMsg(hwnd, EXT_DIRECTORY, EM_SETTEXTLIMIT,
133 MPFROM2SHORT(CCHMAXPATH, 0), MPVOID);
134 WinSendDlgItemMsg(hwnd, EXT_COMMAND, EM_SETTEXTLIMIT,
135 MPFROM2SHORT(256, 0), MPVOID);
136 WinSendDlgItemMsg(hwnd, EXT_MASK, EM_SETTEXTLIMIT,
137 MPFROM2SHORT(256, 0), MPVOID);
138 WinSendDlgItemMsg(hwnd, EXT_FILENAME, EM_SETTEXTLIMIT,
139 MPFROM2SHORT(CCHMAXPATH, 0), MPVOID);
140 if (arcdata->arcname && *arcdata->arcname)
141 WinSetDlgItemText(hwnd, EXT_FILENAME, arcdata->arcname);
142 else
143 WinSetDlgItemText(hwnd, EXT_FILENAME, GetPString(IDS_EXTVARIOUSTEXT));
144
145 if (fFileNameExtPath && arcdata->arcname) {
146
147 CHAR FileName[CCHMAXPATH];
148 PSZ p;
149
150 strcpy(FileName, arcdata->arcname);
151 p = strrchr(FileName, '.');
152 if (p)
153 *p = 0;
154 else {
155 p = FileName + strlen(arcdata->arcname);
156 p--;
157 *p = 0;
158 }
159 strcpy(arcdata->extractdir, FileName);
160 WinSetDlgItemText(hwnd, EXT_DIRECTORY, arcdata->extractdir);
161 }
162 if (fDirectory) {
163 WinSendDlgItemMsg(hwnd, EXT_WDIRS, BM_SETCHECK,
164 MPFROM2SHORT(TRUE, 0), MPVOID);
165 WinSetDlgItemText(hwnd, EXT_COMMAND, arcdata->info->exwdirs);
166 }
167 else {
168 WinSendDlgItemMsg(hwnd, EXT_NORMAL, BM_SETCHECK,
169 MPFROM2SHORT(TRUE, 0), MPVOID);
170 WinSetDlgItemText(hwnd, EXT_COMMAND, arcdata->info->extract);
171
172 }
173 if (fRemember) {
174
175 CHAR textdir[CCHMAXPATH];
176
177 PrfQueryProfileString(fmprof, FM3Str, "Ext_ExtractDir", NULL, textdir, sizeof(textdir));
178 if (*textdir && !IsFile(textdir))
179 strcpy(arcdata->extractdir, textdir);
180 PrfQueryProfileString(fmprof, FM3Str, "Ext_Mask", NULL, textdir, sizeof(textdir));
181 WinSetDlgItemText(hwnd, EXT_MASK, textdir);
182 }
183 if (*extractpath && (!fRemember || !*arcdata->extractdir)) {
184 if (arcdata->arcname && *arcdata->arcname &&
185 !strcmp(extractpath, "*")) {
186
187 CHAR *p;
188
189 strcpy(arcdata->extractdir, arcdata->arcname);
190 p = strrchr(arcdata->extractdir, '\\');
191 if (p) {
192 if (p < arcdata->extractdir + 3)
193 p++;
194 *p = 0;
195 }
196 }
197 else
198 strcpy(arcdata->extractdir, extractpath);
199 }
200 if (!*arcdata->extractdir) {
201 if (*lastextractpath)
202 strcpy(arcdata->extractdir, lastextractpath);
203 else if (arcdata->arcname && *arcdata->arcname) {
204
205 CHAR *p;
206
207 strcpy(arcdata->extractdir, arcdata->arcname);
208 p = strrchr(arcdata->extractdir, '\\');
209 if (p) {
210 if (p < arcdata->extractdir + 3)
211 p++;
212 *p = 0;
213 }
214 }
215 if (!*arcdata->extractdir)
216 strcpy(arcdata->extractdir, pFM2SaveDirectory);
217 }
218 WinSetDlgItemText(hwnd, EXT_DIRECTORY, arcdata->extractdir);
219 if (!arcdata->info->exwdirs)
220 WinEnableWindow(WinWindowFromID(hwnd, EXT_WDIRS), FALSE);
221 else if (fRemember) {
222 fRemember = FALSE;
223 size = sizeof(BOOL);
224 PrfQueryProfileData(fmprof, FM3Str, "Ext_WDirs",
225 (PVOID) &fRemember, &size);
226 if (fRemember)
227 PostMsg(WinWindowFromID(hwnd, EXT_WDIRS), BM_CLICK, MPVOID, MPVOID);
228 }
229 }
230 *arcdata->command = 0;
231 PosOverOkay(hwnd);
232 break;
233
234 case WM_ADJUSTWINDOWPOS:
235 PostMsg(hwnd, UM_SETDIR, MPVOID, MPVOID);
236 break;
237
238 case UM_SETDIR:
239 PaintRecessedWindow(WinWindowFromID(hwnd, EXT_HELP), (HPS) 0, FALSE,
240 TRUE);
241 return 0;
242
243 case WM_CONTROL:
244 arcdata = (EXTRDATA *) WinQueryWindowPtr(hwnd, QWL_USER);
245 switch (SHORT1FROMMP(mp1)) {
246 case EXT_REMEMBER:
247 {
248 BOOL fRemember = WinQueryButtonCheckstate(hwnd, EXT_REMEMBER);
249 size = sizeof(BOOL);
250 PrfWriteProfileData(fmprof, FM3Str, "RememberExt",
251 (PVOID) &fRemember, size);
252 WinSendDlgItemMsg(hwnd, EXT_FILENAMEEXT, BM_SETCHECK,
253 MPFROM2SHORT(FALSE, 0), MPVOID);
254 }
255 break;
256
257 case EXT_AWDIRS:
258 {
259 BOOL fDirectory = WinQueryButtonCheckstate(hwnd, EXT_AWDIRS);
260 size = sizeof(BOOL);
261 PrfWriteProfileData(fmprof, FM3Str, "DirectoryExt",
262 (PVOID) &fDirectory, size);
263
264 if (fDirectory) {
265 WinSendDlgItemMsg(hwnd, EXT_WDIRS, BM_SETCHECK,
266 MPFROM2SHORT(TRUE, 0), MPVOID);
267 WinSetDlgItemText(hwnd, EXT_COMMAND, arcdata->info->exwdirs);
268 }
269 else {
270 WinSendDlgItemMsg(hwnd, EXT_NORMAL, BM_SETCHECK,
271 MPFROM2SHORT(TRUE, 0), MPVOID);
272 WinSetDlgItemText(hwnd, EXT_COMMAND, arcdata->info->extract);
273 }
274 }
275 break;
276
277 case EXT_FILENAMEEXT:
278 {
279 BOOL fFileNameExtPath = WinQueryButtonCheckstate(hwnd, EXT_FILENAMEEXT);
280 BOOL fRemember = WinQueryButtonCheckstate(hwnd, EXT_REMEMBER);
281 size = sizeof(BOOL);
282 PrfWriteProfileData(fmprof, FM3Str, "FileNamePathExt",
283 fRemember ? FALSE : (PVOID) &fFileNameExtPath, size);
284 if (fRemember)
285 break;
286 if (fFileNameExtPath && arcdata->arcname) {
287 CHAR FileName[CCHMAXPATH];
288 PSZ p;
289
290 strcpy(FileName, arcdata->arcname);
291 p = strrchr(FileName, '.');
292 if (p)
293 *p = 0;
294 else {
295 p = FileName + strlen(arcdata->arcname);
296 p--;
297 *p = 0;
298 }
299 strcpy(arcdata->extractdir, FileName);
300 WinSetDlgItemText(hwnd, EXT_DIRECTORY, arcdata->extractdir);
301 }
302 else {
303 *arcdata->extractdir = 0;
304 if (*extractpath) {
305 if (arcdata->arcname && *arcdata->arcname &&
306 !strcmp(extractpath, "*")) {
307
308 CHAR *p;
309
310 strcpy(arcdata->extractdir, arcdata->arcname);
311 p = strrchr(arcdata->extractdir, '\\');
312 if (p) {
313 if (p < arcdata->extractdir + 3)
314 p++;
315 *p = 0;
316 }
317 }
318 else
319 strcpy(arcdata->extractdir, extractpath);
320 }
321 if (!*arcdata->extractdir) {
322 if (arcdata->arcname && *arcdata->arcname) {
323
324 CHAR *p;
325
326 strcpy(arcdata->extractdir, arcdata->arcname);
327 p = strrchr(arcdata->extractdir, '\\');
328 if (p) {
329 if (p < arcdata->extractdir + 3)
330 p++;
331 *p = 0;
332 }
333 }
334 if (!*arcdata->extractdir)
335 strcpy(arcdata->extractdir, pFM2SaveDirectory);
336 }
337 WinSetDlgItemText(hwnd, EXT_DIRECTORY, arcdata->extractdir);
338 }
339 }
340 break;
341
342 case EXT_FILENAME:
343 if (SHORT2FROMMP(mp1) == EN_KILLFOCUS)
344 WinSetDlgItemText(hwnd, EXT_HELP, GetPString(IDS_ARCDEFAULTHELPTEXT));
345 if (SHORT2FROMMP(mp1) == EN_SETFOCUS)
346 WinSetDlgItemText(hwnd, EXT_HELP, GetPString(IDS_ARCARCNAMEHELPTEXT));
347 break;
348
349 case EXT_DIRECTORY:
350 if (SHORT2FROMMP(mp1) == EN_KILLFOCUS)
351 WinSetDlgItemText(hwnd, EXT_HELP, GetPString(IDS_ARCDEFAULTHELPTEXT));
352 if (SHORT2FROMMP(mp1) == EN_SETFOCUS)
353 WinSetDlgItemText(hwnd, EXT_HELP,
354 GetPString(IDS_EXTEXTRACTDIRHELPTEXT));
355 break;
356
357 case EXT_COMMAND:
358 if (SHORT2FROMMP(mp1) == EN_KILLFOCUS)
359 WinSetDlgItemText(hwnd, EXT_HELP, GetPString(IDS_ARCDEFAULTHELPTEXT));
360 if (SHORT2FROMMP(mp1) == EN_SETFOCUS)
361 WinSetDlgItemText(hwnd, EXT_HELP, GetPString(IDS_ARCCMDHELPTEXT));
362 break;
363
364 case EXT_MASK:
365 if (SHORT2FROMMP(mp1) == EN_KILLFOCUS)
366 WinSetDlgItemText(hwnd, EXT_HELP, GetPString(IDS_ARCDEFAULTHELPTEXT));
367 if (SHORT2FROMMP(mp1) == EN_SETFOCUS)
368 WinSetDlgItemText(hwnd, EXT_HELP, GetPString(IDS_ARCMASKHELPTEXT));
369 break;
370
371 case EXT_NORMAL:
372 if ((BOOL) WinSendDlgItemMsg(hwnd, EXT_NORMAL, BM_QUERYCHECK,
373 MPVOID, MPVOID))
374 WinSetDlgItemText(hwnd, EXT_COMMAND, arcdata->info->extract);
375 break;
376
377 case EXT_WDIRS:
378 if (arcdata->info->exwdirs) {
379 if ((BOOL) WinSendDlgItemMsg(hwnd, EXT_WDIRS, BM_QUERYCHECK,
380 MPVOID, MPVOID))
381 WinSetDlgItemText(hwnd, EXT_COMMAND, arcdata->info->exwdirs);
382 }
383 break;
384 }
385 return 0;
386
387 case WM_COMMAND:
388 arcdata = (EXTRDATA *) WinQueryWindowPtr(hwnd, QWL_USER);
389 switch (SHORT1FROMMP(mp1)) {
390 case IDM_SWITCH:
391 if (mp2) {
392
393 CHAR tdir[CCHMAXPATH];
394
395 strcpy(tdir, (CHAR *) mp2);
396 MakeValidDir(tdir);
397 WinSetDlgItemText(hwnd, EXT_DIRECTORY, tdir);
398 }
399 break;
400
401 case DID_CANCEL:
402 arcdata->ret = 0;
403 WinDismissDlg(hwnd, 0);
404 break;
405 case DID_OK:
406 {
407 CHAR s[CCHMAXPATH + 1];
408 BOOL fRemember;
409
410 fRemember = WinQueryButtonCheckstate(hwnd, EXT_REMEMBER);
411 *s = 0;
412 WinQueryDlgItemText(hwnd, EXT_DIRECTORY, CCHMAXPATH, s);
413 bstrip(s);
414 if (*s) {
415 if (!SetDir(WinQueryWindow(WinQueryWindow(hwnd, QW_PARENT),
416 QW_OWNER), hwnd, s, fFileNameExtPath ? 1:0)) {
417 strcpy(arcdata->extractdir, s);
418 WinSetDlgItemText(hwnd, EXT_DIRECTORY, s);
419 if ((!isalpha(*s) || s[1] != ':') && *s != '.')
420 saymsg(MB_ENTER, hwnd,
421 GetPString(IDS_WARNINGTEXT),
422 GetPString(IDS_SPECIFYDRIVETEXT));
423 }
424 else
425 break;
426 strcpy(lastextractpath, s);
427 if (fRemember) {
428 PrfWriteProfileString(fmprof, FM3Str, "Ext_ExtractDir", s);
429 fRemember = WinQueryButtonCheckstate(hwnd, EXT_WDIRS);
430 size = sizeof(BOOL);
431 PrfWriteProfileData(fmprof, FM3Str, "Ext_WDirs",
432 (PVOID) &fRemember, size);
433 fRemember = TRUE;
434 }
435 *s = 0;
436 WinQueryDlgItemText(hwnd, EXT_COMMAND, 256, s);
437 if (*s) {
438 strcpy(arcdata->command, s);
439 *s = 0;
440 WinQueryDlgItemText(hwnd, EXT_MASK, 256, s);
441 *arcdata->masks = 0;
442 strcpy(arcdata->masks, s);
443 if (fRemember)
444 PrfWriteProfileString(fmprof, FM3Str, "Ext_Mask", s);
445 arcdata->ret = 1;
446 WinDismissDlg(hwnd, 1);
447 break;
448 }
449 }
450 }
451 DosBeep(50, 100); // Complain a refuse to quit
452 break;
453
454 case IDM_HELP:
455 if (hwndHelp)
456 WinSendMsg(hwndHelp, HM_DISPLAY_HELP,
457 MPFROM2SHORT(HELP_EXTRACT, 0), MPFROMSHORT(HM_RESOURCEID));
458 break;
459
460 case EXT_WALK:
461 {
462 CHAR temp[CCHMAXPATH + 1];
463
464 strcpy(temp, arcdata->extractdir);
465 if (WinDlgBox(HWND_DESKTOP, WinQueryWindow(WinQueryWindow(hwnd,
466 QW_PARENT),
467 QW_OWNER),
468 WalkExtractDlgProc, FM3ModHandle, WALK_FRAME,
469 (PVOID) temp)) {
470 if (*temp && stricmp(temp, arcdata->extractdir)) {
471 strcpy(arcdata->extractdir, temp);
472 }
473 }
474 WinSetDlgItemText(hwnd, EXT_DIRECTORY, arcdata->extractdir);
475 }
476 break;
477
478 case EXT_SEE:
479 {
480 CHAR s[1001], *p;
481 EXECARGS ex;
482
483 WinQueryDlgItemText(hwnd, EXT_COMMAND, 256, s);
484 lstrip(s);
485 if (!*s)
486 Runtime_Error(pszSrcFile, __LINE__, "no command");
487 else {
488 p = strchr(s, ' ');
489 if (p)
490 *p = 0; // Drop options
491 memset(&ex, 0, sizeof(EXECARGS));
492 ex.commandline = s;
493 ex.flags = WINDOWED | SEPARATEKEEP | MAXIMIZED;
494 *ex.path = 0;
495 *ex.environment = 0;
496 if (WinDlgBox(HWND_DESKTOP,
497 hwnd,
498 CmdLineDlgProc,
499 FM3ModHandle, EXEC_FRAME, MPFROMP(&ex)) && *s) {
500 runemf2(ex.flags,
501 hwnd, pszSrcFile, __LINE__,
502 NULL, (*ex.environment) ? ex.environment : NULL, "%s", s);
503 }
504 }
505 }
506 break;
507 }
508 return 0;
509
510 case WM_CLOSE:
511 break;
512 }
513 return WinDefDlgProc(hwnd, msg, mp1, mp2);
514}
515
516#pragma alloc_text(FMEXTRACT,ExtractTextProc,ExtractDlgProc)
Note: See TracBrowser for help on using the repository browser.