https://git.reactos.org/?p=reactos.git;a=commitdiff;h=aedba8441af6dbe3da9bee501ecd74dce851b5a1

commit aedba8441af6dbe3da9bee501ecd74dce851b5a1
Author:     Katayama Hirofumi MZ <[email protected]>
AuthorDate: Wed Nov 20 10:00:26 2019 +0900
Commit:     GitHub <[email protected]>
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__ */

Reply via email to