4 Virtual Floppy Drive for Windows
6 Save image GUI utility function
8 Copyright (c) 2003-2005 Ken Kato
12 #pragma message(__FILE__": Compiled as C++ for testing purpose.")
15 #define WIN32_LEAN_AND_MEAN
18 #pragma warning(push,3)
31 #include "vfdmsg_lib.h"
38 static INT CALLBACK
SaveDialogProc(
44 static void OnInit(HWND hDlg
, PCSAVE_PARAM pParam
);
45 static void OnTarget(HWND hDlg
, HWND hEdit
);
46 static void OnBrowse(HWND hDlg
);
47 static void OnOverwrite(HWND hDlg
, HWND hCheck
);
48 static void OnTruncate(HWND hDlg
, HWND hCheck
);
49 static DWORD
OnOK(HWND hDlg
);
52 // Show Save Image dialog box
54 DWORD WINAPI
VfdGuiSave(
62 // open the source device
64 param
.hDevice
= VfdOpenDevice(nDevice
);
66 if (param
.hDevice
== INVALID_HANDLE_VALUE
) {
67 return GetLastError();
70 // get current image information
72 param
.ImageName
= path
;
74 ret
= VfdGetImageInfo(
83 if (ret
== ERROR_SUCCESS
) {
87 ret
= GuiSaveParam(hParent
, ¶m
);
90 // close the source device
92 CloseHandle(param
.hDevice
);
101 switch (DialogBoxParam(
103 MAKEINTRESOURCE(IDD_SAVEDIALOG
),
109 return ERROR_SUCCESS
;
112 return ERROR_CANCELLED
;
115 return GetLastError();
120 // The dialog procedure
122 INT CALLBACK
SaveDialogProc(
130 OnInit(hDlg
, (PCSAVE_PARAM
)lParam
);
135 case MAKELONG(IDC_TARGETFILE
, EN_CHANGE
):
136 OnTarget(hDlg
, (HWND
)lParam
);
144 OnOverwrite(hDlg
, (HWND
)lParam
);
148 OnTruncate(hDlg
, (HWND
)lParam
);
152 if (OnOK(hDlg
) == ERROR_SUCCESS
) {
153 EndDialog(hDlg
, IDOK
);
158 EndDialog(hDlg
, IDCANCEL
);
164 ShowContextMenu(hDlg
, (HWND
)wParam
, lParam
);
169 LPHELPINFO info
= (LPHELPINFO
)lParam
;
171 if (info
->iContextType
== HELPINFO_WINDOW
) {
172 ShowHelpWindow(hDlg
, info
->iCtrlId
);
182 // Initialize the dialog
190 SetWindowLongPtr(hDlg
, GWLP_USERDATA
, (ULONG_PTR
)pParam
);
192 // clear the target existence flag
194 SetWindowLong(hDlg
, DWL_USER
, 0);
196 // Set dialog window title
198 SetControlText(hDlg
, 0, MSG_SAVE_TITLE
);
200 // Set control captions
202 SetControlText(hDlg
, IDC_IMAGEFILE_LABEL
, MSG_IMAGEFILE_LABEL
);
203 SetControlText(hDlg
, IDC_DISKTYPE_LABEL
, MSG_DISKTYPE_LABEL
);
204 SetControlText(hDlg
, IDC_MEDIATYPE_LABEL
, MSG_MEDIATYPE_LABEL
);
205 SetControlText(hDlg
, IDC_TARGETFILE_LABEL
, MSG_TARGETFILE_LABEL
);
206 SetControlText(hDlg
, IDC_IMAGEDESC_LABEL
, MSG_DESCRIPTION_LABEL
);
207 SetControlText(hDlg
, IDC_BROWSE
, MSG_BROWSE_BUTTON
);
208 SetControlText(hDlg
, IDC_OVERWRITE
, MSG_OVERWRITE_CHECK
);
209 SetControlText(hDlg
, IDC_TRUNCATE
, MSG_TRUNCATE_CHECK
);
210 SetControlText(hDlg
, IDOK
, MSG_SAVE_BUTTON
);
211 SetControlText(hDlg
, IDCANCEL
, MSG_CANCEL_BUTTON
);
215 if (pParam
->DiskType
== VFD_DISKTYPE_FILE
) {
216 SetDlgItemText(hDlg
, IDC_DISKTYPE
, "FILE");
219 SetDlgItemText(hDlg
, IDC_DISKTYPE
, "RAM");
222 // display media type
224 SetDlgItemText(hDlg
, IDC_MEDIATYPE
,
225 VfdMediaTypeName(pParam
->MediaType
));
227 // set current image and initial target
229 if (pParam
->ImageName
[0]) {
230 SetDlgItemText(hDlg
, IDC_IMAGEFILE
, pParam
->ImageName
);
231 SetDlgItemText(hDlg
, IDC_TARGETFILE
, pParam
->ImageName
);
233 else if (pParam
->DiskType
!= VFD_DISKTYPE_FILE
) {
234 SetDlgItemText(hDlg
, IDC_IMAGEFILE
, "<RAM>");
235 OnTarget(hDlg
, GetDlgItem(hDlg
, IDC_TARGETFILE
));
240 // Path is changed -- check specified target file
249 VFD_FILETYPE file_type
;
253 // clear the target existence flag
255 SetWindowLong(hDlg
, DWL_USER
, 0);
257 // clear the description and hint text
259 SetDlgItemText(hDlg
, IDC_IMAGEFILE_DESC
, NULL
);
260 SetDlgItemText(hDlg
, IDC_IMAGEFILE_HINT
, NULL
);
262 // get the target file name
264 if (GetWindowText(hEdit
, buf
, sizeof(buf
)) == 0) {
266 // target file is blank
268 EnableWindow(GetDlgItem(hDlg
, IDC_OVERWRITE
), FALSE
);
269 EnableWindow(GetDlgItem(hDlg
, IDC_TRUNCATE
), FALSE
);
270 EnableWindow(GetDlgItem(hDlg
, IDOK
), FALSE
);
278 // convert into a full path
280 if (GetFullPathName(buf
, sizeof(full
), full
, &file
)) {
286 // get the current image info
288 param
= (PCSAVE_PARAM
)GetWindowLongPtr(hDlg
, GWLP_USERDATA
);
290 if (_stricmp(param
->ImageName
, buf
) == 0) {
292 // target is the current file
296 VfdMakeFileDesc(desc
, sizeof(desc
),
297 param
->FileType
, param
->ImageSize
,
298 GetFileAttributes(param
->ImageName
));
300 SetDlgItemText(hDlg
, IDC_IMAGEFILE_DESC
, desc
);
301 SetControlText(hDlg
, IDC_IMAGEFILE_HINT
, MSG_CURRENT_FILE
);
303 if (param
->DiskType
== VFD_DISKTYPE_FILE
) {
305 // cannot overwrite the current FILE disk image
307 EnableWindow(GetDlgItem(hDlg
, IDC_OVERWRITE
), FALSE
);
308 EnableWindow(GetDlgItem(hDlg
, IDC_TRUNCATE
), FALSE
);
309 EnableWindow(GetDlgItem(hDlg
, IDOK
), FALSE
);
315 // check target image file
317 ret
= VfdCheckImageFile(
318 buf
, &file_attr
, &file_type
, &file_size
);
320 if (ret
== ERROR_FILE_NOT_FOUND
) {
321 // file does not exist
322 SetControlText(hDlg
, IDC_IMAGEFILE_DESC
, MSG_DESC_NEW_FILE
);
323 EnableWindow(GetDlgItem(hDlg
, IDC_OVERWRITE
), FALSE
);
324 EnableWindow(GetDlgItem(hDlg
, IDC_TRUNCATE
), FALSE
);
325 EnableWindow(GetDlgItem(hDlg
, IDOK
), TRUE
);
328 else if (ret
!= ERROR_SUCCESS
) {
329 SetDlgItemText(hDlg
, IDC_IMAGEFILE_DESC
, SystemMessage(ret
));
330 EnableWindow(GetDlgItem(hDlg
, IDC_OVERWRITE
), FALSE
);
331 EnableWindow(GetDlgItem(hDlg
, IDC_TRUNCATE
), FALSE
);
332 EnableWindow(GetDlgItem(hDlg
, IDOK
), FALSE
);
336 // set target file description
338 VfdMakeFileDesc(buf
, sizeof(buf
),
339 file_type
, file_size
, file_attr
);
341 SetDlgItemText(hDlg
, IDC_IMAGEFILE_DESC
, buf
);
343 // check target file type
345 if (file_type
== VFD_FILETYPE_ZIP
) {
346 SetControlText(hDlg
, IDC_IMAGEFILE_HINT
, MSG_TARGET_IS_ZIP
);
347 EnableWindow(GetDlgItem(hDlg
, IDC_OVERWRITE
), FALSE
);
348 EnableWindow(GetDlgItem(hDlg
, IDC_TRUNCATE
), FALSE
);
349 EnableWindow(GetDlgItem(hDlg
, IDOK
), FALSE
);
353 // the target is an existing raw file
355 EnableWindow(GetDlgItem(hDlg
, IDC_OVERWRITE
), TRUE
);
359 if (file_size
> VfdGetMediaSize(param
->MediaType
)) {
360 EnableWindow(GetDlgItem(hDlg
, IDC_TRUNCATE
), TRUE
);
361 SetControlText(hDlg
, IDC_IMAGEFILE_HINT
, MSG_SIZE_MISMATCH
);
364 EnableWindow(GetDlgItem(hDlg
, IDC_TRUNCATE
), FALSE
);
367 // check overwrite setting
369 if (IsDlgButtonChecked(hDlg
, IDC_OVERWRITE
) != BST_CHECKED
) {
370 EnableWindow(GetDlgItem(hDlg
, IDOK
), FALSE
);
373 EnableWindow(GetDlgItem(hDlg
, IDOK
), TRUE
);
376 // target file exists and overwritable
378 SetWindowLong(hDlg
, DWL_USER
, 1);
383 // Show save file dialog box
394 title
= ModuleMessage(MSG_SAVE_TITLE
);
396 ZeroMemory(&ofn
, sizeof(ofn
));
397 ZeroMemory(file
, sizeof(file
));
398 ZeroMemory(dir
, sizeof(dir
));
400 len
= GetDlgItemText(hDlg
, IDC_TARGETFILE
, file
, sizeof(file
));
402 if (len
&& file
[len
- 1] == '\\') {
404 ZeroMemory(file
, sizeof(file
));
407 // Different structure sizes must be used for NT and 2K/XP
408 ofn
.lStructSize
= IS_WINDOWS_NT() ?
409 OPENFILENAME_SIZE_VERSION_400
: sizeof(ofn
);
411 ofn
.hwndOwner
= hDlg
;
412 ofn
.lpstrFile
= file
;
413 ofn
.nMaxFile
= sizeof(file
);
414 ofn
.lpstrInitialDir
= dir
;
415 ofn
.lpstrTitle
= title
? title
: "Save Image";
416 ofn
.lpstrFilter
= "*.*\0*.*\0";
417 ofn
.Flags
= OFN_ENABLESIZING
| OFN_HIDEREADONLY
| OFN_PATHMUSTEXIST
;
419 if (GetSaveFileName(&ofn
)) {
420 SetDlgItemText(hDlg
, IDC_TARGETFILE
, file
);
421 SetFocus(GetDlgItem(hDlg
, IDC_TARGETFILE
));
433 if (GetWindowLong(hDlg
, DWL_USER
)) {
434 // the target file exists and overwritable
435 if (SendMessage(hCheck
, BM_GETCHECK
, 0, 0) != BST_CHECKED
) {
436 EnableWindow(GetDlgItem(hDlg
, IDOK
), FALSE
);
439 EnableWindow(GetDlgItem(hDlg
, IDOK
), TRUE
);
448 UNREFERENCED_PARAMETER(hDlg
);
449 UNREFERENCED_PARAMETER(hCheck
);
464 param
= (PCSAVE_PARAM
)GetWindowLongPtr(hDlg
, GWLP_USERDATA
);
467 return ERROR_INVALID_FUNCTION
;
470 // get the target image name
472 if (GetDlgItemText(hDlg
, IDC_TARGETFILE
, path
, sizeof(path
)) == 0) {
473 return ERROR_INVALID_FUNCTION
;
476 if (GetWindowLong(hDlg
, DWL_USER
)) {
477 // the target file exists and overwritable
478 overwrite
= (IsDlgButtonChecked(hDlg
, IDC_OVERWRITE
) == BST_CHECKED
);
479 truncate
= (IsDlgButtonChecked(hDlg
, IDC_TRUNCATE
) == BST_CHECKED
);
487 ret
= VfdDismountVolume(param
->hDevice
, FALSE
);
489 if (ret
== ERROR_ACCESS_DENIED
) {
490 PSTR msg
= ModuleMessage(MSG_UNMOUNT_CONFIRM
);
492 int reply
= MessageBox(
493 hDlg
, msg
? msg
: "retry", VFD_MSGBOX_TITLE
,
494 MB_ICONEXCLAMATION
| MB_CANCELTRYCONTINUE
);
500 if (reply
== IDRETRY
) {
503 else if (reply
== IDCANCEL
) {
504 return ERROR_CANCELLED
;
507 VfdDismountVolume(param
->hDevice
, TRUE
);
510 else if (ret
!= ERROR_SUCCESS
) {
512 MessageBox(hDlg
, SystemMessage(ret
),
513 VFD_MSGBOX_TITLE
, MB_ICONSTOP
);
518 ret
= VfdSaveImage(param
->hDevice
, path
, overwrite
, truncate
);
520 if (ret
!= ERROR_SUCCESS
) {
522 // show error message
524 MessageBox(hDlg
, SystemMessage(ret
),
525 VFD_MSGBOX_TITLE
, MB_ICONSTOP
);