From c44a8a62663eec7bfb7a74995fa97d30f6939f11 Mon Sep 17 00:00:00 2001 From: Katayama Hirofumi MZ Date: Fri, 24 Nov 2017 20:26:33 +0900 Subject: [PATCH] make drive property sheet modeless --- dll/win32/shell32/dialogs/drive.cpp | 67 +++++++++++++++------- dll/win32/shell32/shelldesktop/CDesktopBrowser.cpp | 50 +++++++++++++--- 2 files changed, 87 insertions(+), 30 deletions(-) diff --git a/dll/win32/shell32/dialogs/drive.cpp b/dll/win32/shell32/dialogs/drive.cpp index a5919f027f..079f8f42af 100644 --- a/dll/win32/shell32/dialogs/drive.cpp +++ b/dll/win32/shell32/dialogs/drive.cpp @@ -2,6 +2,7 @@ * Shell Library Functions * * Copyright 2005 Johannes Anderwald + * Copyright 2017 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 @@ -19,6 +20,7 @@ */ #include "precomp.h" +#include #define MAX_PROPERTY_SHEET_PAGE 32 @@ -120,25 +122,50 @@ AddPropSheetPageCallback(HPROPSHEETPAGE hPage, LPARAM lParam) return FALSE; } -typedef struct _DRIVE_PROP_PAGE +struct DrivePropSheet { - LPCSTR resname; - DLGPROC dlgproc; - UINT DriveType; -} DRIVE_PROP_PAGE; + DrivePropSheet(); + virtual ~DrivePropSheet(); + + HWND hwnd; + HPSXA hpsx; + CComObject *pDrvDefExt; + WCHAR wszName[256]; + PROPSHEETHEADERW psh; + HPROPSHEETPAGE hpsp[MAX_PROPERTY_SHEET_PAGE]; + CComPtr pDataObj; +}; +CAtlList shell32_prop_sheet; + +DrivePropSheet::DrivePropSheet() : hwnd(NULL), hpsx(NULL), pDrvDefExt(NULL) +{ + wszName[0] = 0; + ZeroMemory(&psh, sizeof(psh)); + ZeroMemory(&hpsp, sizeof(hpsp)); +} + +DrivePropSheet::~DrivePropSheet() +{ + if (hpsx) + SHDestroyPropSheetExtArray(hpsx); + if (pDrvDefExt) + pDrvDefExt->Release(); +} BOOL SH_ShowDriveProperties(WCHAR *pwszDrive, LPCITEMIDLIST pidlFolder, PCUITEMID_CHILD_ARRAY apidl) { - HPSXA hpsx = NULL; - HPROPSHEETPAGE hpsp[MAX_PROPERTY_SHEET_PAGE]; - PROPSHEETHEADERW psh; - CComObject *pDrvDefExt = NULL; - WCHAR wszName[256]; + DrivePropSheet *pSheet = new DrivePropSheet(); + shell32_prop_sheet.AddTail(pSheet); + + HPSXA& hpsx = pSheet->hpsx; + WCHAR *wszName = pSheet->wszName; + PROPSHEETHEADERW& psh = pSheet->psh; + HPROPSHEETPAGE* hpsp = pSheet->hpsp; + CComObject*& pDrvDefExt = pSheet->pDrvDefExt; - ZeroMemory(&psh, sizeof(PROPSHEETHEADERW)); psh.dwSize = sizeof(PROPSHEETHEADERW); - psh.dwFlags = 0; // FIXME: make it modeless + psh.dwFlags = PSH_MODELESS; // modeless psh.hwndParent = NULL; psh.nStartPage = 0; psh.phpage = hpsp; @@ -152,10 +179,9 @@ SH_ShowDriveProperties(WCHAR *pwszDrive, LPCITEMIDLIST pidlFolder, PCUITEMID_CHI psh.pszCaption = wszName; psh.dwFlags |= PSH_PROPTITLE; } - ILFree(completePidl); - CComPtr pDataObj; + CComPtr& pDataObj = pSheet->pDataObj; HRESULT hr = SHCreateDataObject(pidlFolder, 1, apidl, NULL, IID_PPV_ARG(IDataObject, &pDataObj)); if (SUCCEEDED(hr)) @@ -179,15 +205,14 @@ SH_ShowDriveProperties(WCHAR *pwszDrive, LPCITEMIDLIST pidlFolder, PCUITEMID_CHI SHAddFromPropSheetExtArray(hpsx, (LPFNADDPROPSHEETPAGE)AddPropSheetPageCallback, (LPARAM)&psh); } - HWND hwnd = (HWND)PropertySheetW(&psh); + pSheet->hwnd = (HWND)PropertySheetW(&psh); - if (hpsx) - SHDestroyPropSheetExtArray(hpsx); - if (pDrvDefExt) - pDrvDefExt->Release(); - - if (!hwnd) + if (!pSheet->hwnd) + { + shell32_prop_sheet.RemoveTail(); + delete pSheet; return FALSE; + } return TRUE; } diff --git a/dll/win32/shell32/shelldesktop/CDesktopBrowser.cpp b/dll/win32/shell32/shelldesktop/CDesktopBrowser.cpp index e452039aa6..96397c2592 100644 --- a/dll/win32/shell32/shelldesktop/CDesktopBrowser.cpp +++ b/dll/win32/shell32/shelldesktop/CDesktopBrowser.cpp @@ -2,6 +2,7 @@ * Shell Desktop * * Copyright 2008 Thomas Bluemel + * Copyright 2017 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 @@ -20,18 +21,26 @@ #include "shelldesktop.h" -// Support for multiple monitors is disabled till LVM_SETWORKAREAS gets implemented -#ifdef MULTIMONITOR_SUPPORT -#include +#ifndef _ATL_NO_EXCEPTIONS + #define _ATL_NO_EXCEPTIONS #endif - - +#include WINE_DEFAULT_DEBUG_CHANNEL(desktop); static const WCHAR szProgmanClassName[] = L"Progman"; static const WCHAR szProgmanWindowName[] = L"Program Manager"; +struct DrivePropSheet +{ + DrivePropSheet(); + virtual ~DrivePropSheet(); + + HWND hwnd; + //...hidden members... +}; +extern CAtlList shell32_prop_sheet; + class CDesktopBrowser : public CWindowImpl, public CComObjectRootEx, @@ -472,14 +481,37 @@ BOOL WINAPI SHDesktopMessageLoop(HANDLE hDesktop) while ((bRet = GetMessageW(&Msg, NULL, 0, 0)) != 0) { - if (bRet != -1) + if (bRet == -1) + break; // fatal error, quit + + // do property sheets + BOOL bProcessed = FALSE; + for (POSITION pos = shell32_prop_sheet.GetHeadPosition(); pos != NULL;) { - if (shellView->TranslateAcceleratorW(&Msg) != S_OK) + DrivePropSheet*& pSheet = shell32_prop_sheet.GetNext(pos); + HWND& hwndSheet = pSheet->hwnd; + if (SendMessageW(hwndSheet, PSM_ISDIALOGMESSAGE, 0, (LPARAM)&Msg)) { - TranslateMessage(&Msg); - DispatchMessage(&Msg); + if (!SendMessageW(hwndSheet, PSM_GETCURRENTPAGEHWND, 0, 0)) + { + // to be destroyed + DestroyWindow(hwndSheet); + hwndSheet = NULL; + shell32_prop_sheet.RemoveAt(pos); + } + bProcessed = TRUE; + break; } } + + if (bProcessed) + continue; + + if (shellView->TranslateAcceleratorW(&Msg) == S_OK) + continue; + + TranslateMessage(&Msg); + DispatchMessage(&Msg); } return TRUE; -- 2.14.2