[SHELL32] Improve UI of drive formatting (#2048)

- Add stub window (StubWindow32) to the drive formatting dialog to avoid locked.
- Separate the thread of drive formatting.
- Move CStubWindow32 codes.
CORE-12756
This commit is contained in:
Katayama Hirofumi MZ 2019-11-20 10:00:26 +09:00 committed by GitHub
parent 2a93f61fcb
commit aedba8441a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 127 additions and 20 deletions

View file

@ -67,17 +67,6 @@ LoadPropSheetHandlers(LPCWSTR pwszPath, PROPSHEETHEADERW *pHeader, UINT cMaxPage
return cPages;
}
// CStubWindow32 --- The owner window of file property sheets.
// This window hides taskbar button of property sheet.
class CStubWindow32 : public CWindowImpl<CStubWindow32>
{
public:
DECLARE_WND_CLASS_EX(_T("StubWindow32"), 0, COLOR_WINDOWTEXT)
BEGIN_MSG_MAP(CStubWindow32)
END_MSG_MAP()
};
/*************************************************************************
*
* SH_ShowPropertiesDialog

View file

@ -4,7 +4,7 @@
* Copyright 1997 Marcus Meissner
* Copyright 1998, 1999, 2002 Juergen Schmied
* Copyright 2009 Andrew Hill
* Copyright 2017-2018 Katayama Hirofumi MZ
* Copyright 2017-2019 Katayama Hirofumi MZ
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@ -22,6 +22,7 @@
*/
#include <precomp.h>
#include <process.h>
WINE_DEFAULT_DEBUG_CHANNEL (shell);
@ -141,6 +142,119 @@ static BOOL DoEjectDrive(const WCHAR *physical, UINT nDriveType, INT *pnStringID
return bResult;
}
// A callback function for finding the stub windows.
static BOOL CALLBACK
EnumStubProc(HWND hwnd, LPARAM lParam)
{
CSimpleArray<HWND> *pStubs = reinterpret_cast<CSimpleArray<HWND> *>(lParam);
WCHAR szClass[64];
GetClassNameW(hwnd, szClass, _countof(szClass));
if (lstrcmpiW(szClass, L"StubWindow32") == 0)
{
pStubs->Add(hwnd);
}
return TRUE;
}
// Another callback function to find the owned window of the stub window.
static BOOL CALLBACK
EnumStubProc2(HWND hwnd, LPARAM lParam)
{
HWND *phwnd = reinterpret_cast<HWND *>(lParam);
if (phwnd[0] == GetWindow(hwnd, GW_OWNER))
{
phwnd[1] = hwnd;
return FALSE;
}
return TRUE;
}
// Parameters for format_drive_thread function below.
struct THREAD_PARAMS
{
UINT nDriveNumber;
};
static unsigned __stdcall format_drive_thread(void *args)
{
THREAD_PARAMS *params = (THREAD_PARAMS *)args;
UINT nDriveNumber = params->nDriveNumber;
LONG_PTR nProp = nDriveNumber | 0x7F00;
// Search the stub windows that already exist.
CSimpleArray<HWND> old_stubs;
EnumWindows(EnumStubProc, (LPARAM)&old_stubs);
for (INT n = 0; n < old_stubs.GetSize(); ++n)
{
HWND hwndStub = old_stubs[n];
// The target stub window has the prop.
if (GetPropW(hwndStub, L"DriveNumber") == (HANDLE)nProp)
{
// Found.
HWND ahwnd[2];
ahwnd[0] = hwndStub;
ahwnd[1] = NULL;
EnumWindows(EnumStubProc2, (LPARAM)ahwnd);
// Activate.
BringWindowToTop(ahwnd[1]);
delete params;
return 0;
}
}
// Create a stub window.
DWORD style = WS_DISABLED | WS_CLIPSIBLINGS | WS_CAPTION;
DWORD exstyle = WS_EX_WINDOWEDGE | WS_EX_APPWINDOW;
CStubWindow32 stub;
if (!stub.Create(NULL, NULL, NULL, style, exstyle))
{
ERR("StubWindow32 creation failed\n");
delete params;
return 0;
}
// Add prop to the target stub window.
SetPropW(stub, L"DriveNumber", (HANDLE)nProp);
// Do format.
SHFormatDrive(stub, nDriveNumber, SHFMT_ID_DEFAULT, 0);
// Clean up.
RemovePropW(stub, L"DriveNumber");
stub.DestroyWindow();
delete params;
return 0;
}
static HRESULT DoFormatDrive(HWND hwnd, UINT nDriveNumber)
{
THREAD_PARAMS *params = new THREAD_PARAMS;
params->nDriveNumber = nDriveNumber;
// Create thread to avoid locked.
unsigned tid;
HANDLE hThread = (HANDLE)_beginthreadex(NULL, 0, format_drive_thread, params, 0, &tid);
if (hThread == NULL)
{
delete params;
return E_FAIL;
}
CloseHandle(hThread);
return S_OK;
}
HRESULT CALLBACK DrivesContextMenuCallback(IShellFolder *psf,
HWND hwnd,
IDataObject *pdtobj,
@ -226,14 +340,7 @@ HRESULT CALLBACK DrivesContextMenuCallback(IShellFolder *psf,
{
if (wParam == CMDID_FORMAT)
{
/* do format */
DWORD dwRet = SHFormatDrive(hwnd, szDrive[0] - 'A', SHFMT_ID_DEFAULT, 0);
switch (dwRet)
{
case SHFMT_ERROR: case SHFMT_CANCEL: case SHFMT_NOFORMAT:
hr = E_FAIL;
break;
}
hr = DoFormatDrive(hwnd, szDrive[0] - 'A');
}
else if (wParam == CMDID_EJECT)
{

View file

@ -126,4 +126,15 @@ AddPropSheetPageCallback(HPROPSHEETPAGE hPage, LPARAM lParam)
HRESULT WINAPI
Shell_DefaultContextMenuCallBack(IShellFolder *psf, IDataObject *pdtobj);
// CStubWindow32 --- The owner window of file property sheets.
// This window hides taskbar button of property sheet.
class CStubWindow32 : public CWindowImpl<CStubWindow32>
{
public:
DECLARE_WND_CLASS_EX(_T("StubWindow32"), 0, COLOR_WINDOWTEXT)
BEGIN_MSG_MAP(CStubWindow32)
END_MSG_MAP()
};
#endif /* _PRECOMP_H__ */