source: trunk/dll/extract.c@ 1300

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

Add the option of creating a subdirectory from the arcname for the extract path. (Ticket 22)

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