
Overview
This class basically brings up the Windows Disk-Format dialog box. You'd have
thought it would have become part of the common dialogs by now. What's worse is
that some of the information in KB article Q173688 is now incorrect as far as
Windows XP and Windows 2000 are concerned. I presume that the KB article was
written during the 9x days and they forgot to remove or update it later. What
confused me was that the KB article states that the information in it
applies to XP and 2K. The first shock for me was to discover that the
Quick-Format option behaved exactly opposite to how it was described in the KB
article. In addition the Make-system-disk option was not even working properly.
Anyway I've written a class - CFormatDriveDialog that basically wraps the stuff
for you. I have stuck to the MS recommended constant definitions where they
work, but in other cases I've either discarded them or added my own.
Strong warning
The information in KB article Q173688 is partially incorrect. Do not follow
it blindly if you intend to build on this class. Also note that this class
should only be used on Win2K/XP systems. The KB article is to be followed for
older OS versions like 9x and ME.
Class Reference
There's just one public method here (of course, in addition to the
parameter-less constructor).
DoModal
int CFormatDriveDialog::DoModal(HWND hWnd, UINT Drive, bool
bQuickFormat, LPCTSTR vol_label);
hWnd - The window handle of the dialog's parent. This cannot be
NULL.
Drive - The drive code (0 for A, 1 for B, 2 for C etc.) I've
defined constants like DRIVEA, DRIVEB, DRIVEC
etc. which you may use instead of raw numbers. They are defined in the header
file.
bQuickFormat - If true then the Quick-Format check box is ticked by
default.
vol_label - The default value for the volume label to be
used.
Return Value
IDOK if a successful format was completed and IDCANCEL
if the format operation was cancelled or if some error occurred.
Sample Usage
void Cnish_testDlg::OnBnClickedButton1()
{
UpdateData(true);
CFormatDriveDialog dlg;
int d=dlg.DoModal(AfxGetMainWnd()->m_hWnd,DRIVEA,
bQuickFormat,m_vollab);
if(d==IDOK)
MessageBox("yeah");
}
Tech Details
We call the SHFormatDrive function from shell32.dll. I use
LoadLibrary and
load shell32.dll and then call GetProcAddress to get SHFormatDrive's address. I
also use SetWindowsHookEx to set a CBT hook because we need to set the volume
label. The hook proc calls EnumChildWindows and when we encounter a child window
with "Edit" class, we know this is the volume label edit box, because that's the
only edit box in the dialog. Refer the source code for full details. A snipped
partial listing is given below with comments not found in the actual source
code.
int CFormatDriveDialog::DoModal(...)
{
FMTDRIVEFUNC* pshfd;
HMODULE hMod = LoadLibrary("shell32.dll");
if(hMod)
{
pshfd = reinterpret_cast<FMTDRIVEFUNC*>
(GetProcAddress(hMod,"SHFormatDrive"));
m_hHook = SetWindowsHookEx(WH_CBT,CBTProc,
AfxGetApp()->m_hInstance,AfxGetApp()->m_nThreadID);
rv = ((*pshfd)(hWnd,Drive,SHFMT_ID_DEFAULT,Options)==
SHFMT_FMTSUCCESS) ? IDOK : IDCANCEL;
FreeLibrary(hMod);
}
}
LRESULT CALLBACK CFormatDriveDialog::CBTProc(...)
{
if (nCode == HCBT_ACTIVATE )
{
HWND hWnd = reinterpret_cast<HWND>(wParam);
EnumChildWindows(hWnd,EnumChildProc,NULL);
UnhookWindowsHookEx(m_hHook);
CFormatDriveDialog::m_hHook = NULL;
}
return FALSE;
}
BOOL CALLBACK CFormatDriveDialog::EnumChildProc(...)
{
char buff[256];
GetClassName(hwnd,buff,255);
if(strcmp(buff,"Edit")==0)
{
SetWindowText(hwnd,m_vol_label);
return FALSE;
}
return TRUE;
}
Conclusion
There are several return codes and option codes mentioned in the above
mentioned KB article. But none of them work as expected, and some of them don't
work at all. In addition the code constant given for Quick-Format works in the
exact opposite manner. Of course I base my results from trying out the code on
my own machine which is an XP professional box. I also got James T Johnson to
test it partially on his XP professional box and Smitha(Tweety) to test it on
her Windows 2000 professional box. But I have no idea how this class will work
on untested OS versions with or without service packs.
Nish is a real nice guy who has been writing code since 1990 when he first got his hands on an 8088 with 640 KB RAM. Originally from sunny Trivandrum in India, he has been living in various places over the past few years and often thinks it’s time he settled down somewhere.
Nish has been a Microsoft Visual C++ MVP since October, 2002 - awfully nice of Microsoft, he thinks. He maintains an MVP tips and tricks web site -
www.voidnish.com where you can find a consolidated list of his articles, writings and ideas on VC++, MFC, .NET and C++/CLI. Oh, and you might want to check out his blog on C++/CLI, MFC, .NET and a lot of other stuff -
blog.voidnish.com.
Nish loves reading Science Fiction, P G Wodehouse and Agatha Christie, and also fancies himself to be a decent writer of sorts. He has authored a romantic comedy
Summer Love and Some more Cricket as well as a programming book –
Extending MFC applications with the .NET Framework.
Nish's latest book
C++/CLI in Action published by Manning Publications is now available for purchase. You can read more about the book on his blog.
Despite his wife's attempts to get him into cooking, his best effort so far has been a badly done omelette. Some day, he hopes to be a good cook, and to cook a tasty dinner for his wife.