https://git.reactos.org/?p=reactos.git;a=commitdiff;h=aedba8441af6dbe3da9be…
commit aedba8441af6dbe3da9bee501ecd74dce851b5a1
Author: Katayama Hirofumi MZ <katayama.hirofumi.mz(a)gmail.com>
AuthorDate: Wed Nov 20 10:00:26 2019 +0900
Commit: GitHub <noreply(a)github.com>
CommitDate: Wed Nov 20 10:00:26 2019 +0900
[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
---
dll/win32/shell32/dialogs/fprop.cpp | 11 ---
dll/win32/shell32/folders/CDrivesFolder.cpp | 125 ++++++++++++++++++++++++++--
dll/win32/shell32/precomp.h | 11 +++
3 files changed, 127 insertions(+), 20 deletions(-)
diff --git a/dll/win32/shell32/dialogs/fprop.cpp b/dll/win32/shell32/dialogs/fprop.cpp
index 108f7e03aff..3cab59b1f3b 100644
--- a/dll/win32/shell32/dialogs/fprop.cpp
+++ b/dll/win32/shell32/dialogs/fprop.cpp
@@ -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
diff --git a/dll/win32/shell32/folders/CDrivesFolder.cpp
b/dll/win32/shell32/folders/CDrivesFolder.cpp
index 35f6a7d735a..53c1b94dbaa 100644
--- a/dll/win32/shell32/folders/CDrivesFolder.cpp
+++ b/dll/win32/shell32/folders/CDrivesFolder.cpp
@@ -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)
{
diff --git a/dll/win32/shell32/precomp.h b/dll/win32/shell32/precomp.h
index c58886e49ef..071a5c7b160 100644
--- a/dll/win32/shell32/precomp.h
+++ b/dll/win32/shell32/precomp.h
@@ -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__ */