Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Replace format floppy disk with standard format drive dialog #108

Closed
wants to merge 10 commits into from
4 changes: 2 additions & 2 deletions src/res.rc
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ BEGIN
MENUITEM "&Copy Disk...", IDM_DISKCOPY
MENUITEM "&Label Disk...", IDM_LABEL
MENUITEM SEPARATOR
MENUITEM "&Format Disk...", IDM_FORMAT
MENUITEM "&Format Drive...", IDM_FORMAT
MENUITEM SEPARATOR
MENUITEM "&Select Drive...", IDM_DRIVESMORE
END
Expand Down Expand Up @@ -613,7 +613,7 @@ BEGIN

MH_MYITEMS+IDM_DISKCOPY, "Copies the contents of a floppy disk"
MH_MYITEMS+IDM_LABEL, "Assigns or changes a disk's volume label"
MH_MYITEMS+IDM_FORMAT, "Formats a floppy disk"
MH_MYITEMS+IDM_FORMAT, "Formats a drive"
// MH_MYITEMS+IDM_SYSDISK, "Copies MS-DOS files to a floppy disk"
MH_MYITEMS+IDM_CONNECT, "Connects to a network drive"
MH_MYITEMS+IDM_DISCONNECT, "Disconnects from a network drive"
Expand Down
24 changes: 2 additions & 22 deletions src/wfcomman.c
Original file line number Diff line number Diff line change
Expand Up @@ -1632,28 +1632,8 @@ AppCommandProc(register DWORD id)

case IDM_FORMAT:

if (CancelInfo.hCancelDlg) {
SetFocus(CancelInfo.hCancelDlg);
break;
}

if (CancelInfo.hThread) {
//
// Don't create any new worker threads
// Just create old dialog
//

CreateDialog(hAppInstance, (LPTSTR) MAKEINTRESOURCE(CANCELDLG), hwndFrame, (DLGPROC) CancelDlgProc);

return TRUE;
}

if (!FmifsLoaded())
break;

// Don't use modal dialog box

FormatDiskette(hwndFrame,FALSE);
// Don't use modal dialog box, set hWndParent = NULL
DialogBox(hAppInstance, (LPTSTR)MAKEINTRESOURCE(FORMATSELECTDLG), NULL, (DLGPROC)FormatSelectDlgProc);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In order for the dialog to be positioned like the others, we need to pass hwndFrame as the third parameter to DialogBox.

Copy link
Contributor Author

@matthewjustice matthewjustice Apr 22, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@craigwi Good point, and I actually originally wrote the code that way. I later changed the parameter to NULL to avoid making this dialog modal. Really, I was more concerned about the dialog created by SHFormatDrive being modal, because formatting can be a long-running operation. SHFormatDrive requires a parent HWND (says MSDN), so I used the first dialog (the one you commented on) as its parent. Therefore, to prevent a situation where both dialogs were modal, I used NULL in the line you mentioned.

I see a few options:

  1. Just change the line you called out and make hWndParent=hwndFrame. That will solve the positioning issue, but will make the dialogs modal.
  2. Make your suggested change, and also change the call to SHFormatDrive so that it its parent HWND is NULL, to avoid the modal concern. This goes against MSDN's guidance, so I'm not sure what the side effects may be, although it seems to work.
  3. Make your suggested change, and also change the call to SHFormatDrive so that it its parent HWND is a hidden window. This avoids the modal problem while still complying with MSDN's recommendation. This is actually what explorer.exe seems to do, and it seems the proper thing to do, but I had avoided this approach before since involved extra window management.

What do you think?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suggest making the FORMATSELECTDLG modeless by calling CreateDialog instead of DialogBox. You can also save the hwnd returned to activate it so there is only one. I tried this out and the basic cases seem to work.

There are several other examples of modeless dialogs (e.g., CancelDlg) that you can use as a pattern.

I would like to see the FileCopy dialog becomes modelsss in this way. It has always annoyed me that it was modal.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good suggestion; thanks! I had forgotten about CreateDialog. It has been a while since I've written C/Win32 code! I'll look into making that change.

break;

case IDM_SHAREAS:
Expand Down
6 changes: 4 additions & 2 deletions src/wfdlgs.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,9 @@
#define UNCOMPRESSPROGDLG 58
#define COMPRESSERRDLG 59 // Compression Error Dialog

#define GOTODIRDLG 60
#define ABOUTDLG 61
#define GOTODIRDLG 60
#define ABOUTDLG 61
#define FORMATSELECTDLG 62

#define IDD_TEXT -1
#define IDD_TEXT1 100
Expand Down Expand Up @@ -200,6 +201,7 @@

#define IDD_GOTODIR 355
#define IDD_GOTOLIST 356
#define IDD_SELECTDRIVE 357

#define IDD_ASSOCFIRST 100
#define IDD_ASSOCLAST 109
Expand Down
109 changes: 96 additions & 13 deletions src/wfdlgs3.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,12 @@
#include "winfile.h"
#include "lfn.h"
#include "wfcopy.h"
#include <shlobj.h>

#define LABEL_NTFS_MAX 32
#define LABEL_FAT_MAX 11
#define CCH_VERSION 40
#define CCH_DRIVE 3

VOID FormatDrive( IN PVOID ThreadParameter );
VOID CopyDiskette( IN PVOID ThreadParameter );
Expand Down Expand Up @@ -727,6 +729,90 @@ FormatDlgProc(register HWND hDlg, UINT wMsg, WPARAM wParam, LPARAM lParam)
return TRUE;
}

/*----------------------------------------------------------------------------*/
/* */
/* FormatSelectDlgProc() - DialogProc callback function for FORMATSELECTDLG */
/* */
/*----------------------------------------------------------------------------*/

INT_PTR
FormatSelectDlgProc(register HWND hDlg, UINT wMsg, WPARAM wParam, LPARAM lParam)
{
HWND hwndSelectDrive;
INT driveIndex;
INT comboxIndex;
DRIVE drive;
DWORD dwFormatResult;
TCHAR szDrive[CCH_DRIVE] = { 0 };

switch (wMsg)
{
case WM_INITDIALOG:
{
// Build the list of drives that can be selected for formatting.
// Do not include remote drives or CD/DVD drives.
szDrive[1] = ':';
hwndSelectDrive = GetDlgItem(hDlg, IDD_SELECTDRIVE);
if (hwndSelectDrive)
{
for (driveIndex = 0; driveIndex < cDrives; driveIndex++)
{
drive = rgiDrive[driveIndex];
if (!IsRemoteDrive(drive) && !IsCDRomDrive(drive))
{
// Set the drive letter as the string and the drive index as the data.
DRIVESET(szDrive, drive);
comboxIndex = SendMessage(hwndSelectDrive, CB_ADDSTRING, 0, (LPARAM)szDrive);
SendMessage(hwndSelectDrive, CB_SETITEMDATA, comboxIndex, (LPARAM)drive);
}
}

SendMessage(hwndSelectDrive, CB_SETCURSEL, 0, 0);
}

return TRUE;
}
case WM_COMMAND:
switch (GET_WM_COMMAND_ID(wParam, lParam))
{
case IDOK:
{
// Hide this dialog window while the SHFormatDrive dialog is displayed.
// SHFormatDrive needs a parent window, and this dialog will serve as
// that parent, even if it is hidden.
ShowWindow(hDlg, SW_HIDE);

// Retrieve the selected drive index and call SHFormatDrive with it.
comboxIndex = (INT)SendDlgItemMessage(hDlg, IDD_SELECTDRIVE, CB_GETCURSEL, 0, 0);
drive = (DRIVE)SendDlgItemMessage(hDlg, IDD_SELECTDRIVE, CB_GETITEMDATA, comboxIndex, 0);
dwFormatResult = SHFormatDrive(hDlg, drive, SHFMT_ID_DEFAULT, 0);

// If the format results in an error, show FORMATSELECTDLG again so
// the user can select a different drive if needed, or cancel.
// Otherwise, if the format was successful, just close FORMATSELECTDLG.
if (dwFormatResult == SHFMT_ERROR || dwFormatResult == SHFMT_CANCEL || dwFormatResult == SHFMT_NOFORMAT)
{
// SHFormatDrive sometimes sets the parent window title when it encounters an error.
// We don't want this; set the title back before we show the dialog.
// Future improvement: title text and initial title should load from the same resource string.
SetWindowText(hDlg, TEXT("Format Drive"));
ShowWindow(hDlg, SW_SHOW);
}
else
{
EndDialog(hDlg, IDOK);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

According to the documentation (referenced at https://stackoverflow.com/questions/13788680/enddialog-vs-destroywindow), this needs to be DestroyWindow(). Also see the function DestroyCancelWindow() in wfdlgs3.c.

}

return TRUE;
}
case IDCANCEL:
EndDialog(hDlg, IDCANCEL);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ditto.

return TRUE;
}
}
return FALSE;
}

/*--------------------------------------------------------------------------*/
/* */
/* AboutDlgProc() - DialogProc callback function for ABOUTDLG */
Expand Down Expand Up @@ -1674,22 +1760,19 @@ LockFormatDisk(DRIVE drive1, DRIVE drive2,
DWORD dwMessage, DWORD dwCommand, BOOL bLock)
{
HMENU hMenu;
static DWORD adwCommands[] = {
IDM_DISKCOPY,
IDM_FORMAT,
0
};

INT i=0;

// Gray out disk:{format,copy}
// Gray out menu item dwCommand
hMenu = GetMenu(hwndFrame);

while (adwCommands[i]) {
if (dwCommand != adwCommands[i])
EnableMenuItem( hMenu, dwCommand ,
bLock ? MF_BYCOMMAND | MF_GRAYED : MF_BYCOMMAND | MF_ENABLED );
i++;
// Special case for IDM_FORMAT, as it no longer invokes FormatDiskette,
// it can be safely left enabled even when copying diskettes.
// This change is made here rather than removing the calls to
// LockFormatDisk with IDM_FORMAT since LockFormatDisk also
// changes the state of aDriveInfo.
if (dwCommand != IDM_FORMAT)
{
EnableMenuItem(hMenu, dwCommand,
bLock ? MF_BYCOMMAND | MF_GRAYED : MF_BYCOMMAND | MF_ENABLED);
}

//
Expand Down
1 change: 0 additions & 1 deletion src/wfinit.c
Original file line number Diff line number Diff line change
Expand Up @@ -409,7 +409,6 @@ InitMenus()

if (nFloppies == 0) {
EnableMenuItem(hMenu, IDM_DISKCOPY, MF_BYCOMMAND | MF_GRAYED);
EnableMenuItem(hMenu, IDM_FORMAT, MF_BYCOMMAND | MF_GRAYED);
}


Expand Down
10 changes: 10 additions & 0 deletions src/winfile.dlg
Original file line number Diff line number Diff line change
Expand Up @@ -528,6 +528,16 @@ BEGIN
CONTROL "&Quick Format", IDD_VERIFY, "button", BS_CHECKBOX | BS_AUTOCHECKBOX | WS_TABSTOP | WS_CHILD, 11, 62, 90, 12
END

FORMATSELECTDLG DIALOG LOADONCALL MOVEABLE DISCARDABLE 11, 28, 183, 44
CAPTION "Format Drive"
FONT 8, "MS Shell Dlg"
STYLE WS_BORDER | WS_CAPTION | WS_DLGFRAME | WS_SYSMENU | WS_VISIBLE | DS_MODALFRAME | WS_POPUP
BEGIN
CONTROL "OK", 1, "button", BS_DEFPUSHBUTTON | WS_TABSTOP | WS_CHILD, 140, 6, 40, 14
CONTROL "Cancel", 2, "button", BS_PUSHBUTTON | WS_TABSTOP | WS_CHILD, 140, 23, 40, 14
CONTROL "&Drive to format:", -1, "static", SS_LEFTNOWORDWRAP | WS_CHILD, 5, 7, 49, 10
CONTROL "", IDD_SELECTDRIVE, "combobox", CBS_DROPDOWNLIST | WS_TABSTOP | WS_VSCROLL | WS_CHILD, 55, 4, 65, 40
END

FORMATPROGRESSDLG DIALOG LOADONCALL MOVEABLE DISCARDABLE 30, 30, 150, 50
CAPTION "Formatting Disk"
Expand Down
1 change: 1 addition & 0 deletions src/winfile.h
Original file line number Diff line number Diff line change
Expand Up @@ -614,6 +614,7 @@ INT_PTR ExitDlgProc(HWND hDlg, UINT wMsg, WPARAM wParam, LPARAM lParam);
INT_PTR DiskLabelDlgProc(HWND hDlg, UINT wMsg, WPARAM wParam, LPARAM lParam);
INT_PTR ChooseDriveDlgProc(HWND hDlg, UINT wMsg, WPARAM wParam, LPARAM lParam);
INT_PTR FormatDlgProc(HWND hDlg, UINT wMsg, WPARAM wParam, LPARAM lParam);
INT_PTR FormatSelectDlgProc(HWND hDlg, UINT wMsg, WPARAM wParam, LPARAM lParam);
INT_PTR OtherDlgProc(register HWND hDlg, UINT wMsg, WPARAM wParam, LPARAM lParam);

INT_PTR ProgressDlgProc(HWND hDlg, UINT wMsg, WPARAM wParam, LPARAM lParam);
Expand Down