Show progress dialog during startup (#9255)

* Show progress dialog during startup for selection enumeration that can take a long time.

* Updated with better code organization and a timer to ensure the progress dialog does not appear in most cases.

* Update based on PR feedback

* Change progress dialog delay from 1500ms to 2500ms

* Move progress dialog invocation off the main UI thread

Co-authored-by: Chris Davis (EDGE) <chrdavis@microsoft.com>
This commit is contained in:
Chris Davis
2021-04-02 03:07:12 -07:00
committed by GitHub
parent 6613522e53
commit d128939227
12 changed files with 463 additions and 106 deletions

View File

@@ -275,7 +275,7 @@ HRESULT GetDatedFileName(_Out_ PWSTR result, UINT cchMax, _In_ PCWSTR source, SY
return hr;
}
HRESULT _GetShellItemArrayFromDataOject(_In_ IUnknown* dataSource, _COM_Outptr_ IShellItemArray** items)
HRESULT GetShellItemArrayFromDataObject(_In_ IUnknown* dataSource, _COM_Outptr_ IShellItemArray** items)
{
*items = nullptr;
CComPtr<IDataObject> dataObj;
@@ -292,73 +292,6 @@ HRESULT _GetShellItemArrayFromDataOject(_In_ IUnknown* dataSource, _COM_Outptr_
return hr;
}
HRESULT _ParseEnumItems(_In_ IEnumShellItems* pesi, _In_ IPowerRenameManager* psrm, _In_ int depth = 0)
{
HRESULT hr = E_INVALIDARG;
// We shouldn't get this deep since we only enum the contents of
// regular folders but adding just in case
if ((pesi) && (depth < (MAX_PATH / 2)))
{
hr = S_OK;
ULONG celtFetched;
CComPtr<IShellItem> spsi;
while ((S_OK == pesi->Next(1, &spsi, &celtFetched)) && (SUCCEEDED(hr)))
{
CComPtr<IPowerRenameItemFactory> spsrif;
hr = psrm->GetRenameItemFactory(&spsrif);
if (SUCCEEDED(hr))
{
CComPtr<IPowerRenameItem> spNewItem;
hr = spsrif->Create(spsi, &spNewItem);
if (SUCCEEDED(hr))
{
spNewItem->PutDepth(depth);
hr = psrm->AddItem(spNewItem);
}
if (SUCCEEDED(hr))
{
bool isFolder = false;
if (SUCCEEDED(spNewItem->GetIsFolder(&isFolder)) && isFolder)
{
// Bind to the IShellItem for the IEnumShellItems interface
CComPtr<IEnumShellItems> spesiNext;
hr = spsi->BindToHandler(nullptr, BHID_EnumItems, IID_PPV_ARGS(&spesiNext));
if (SUCCEEDED(hr))
{
// Parse the folder contents recursively
hr = _ParseEnumItems(spesiNext, psrm, depth + 1);
}
}
}
}
spsi = nullptr;
}
}
return hr;
}
// Iterate through the data source and add paths to the rotation manager
HRESULT EnumerateDataObject(_In_ IUnknown* dataSource, _In_ IPowerRenameManager* psrm)
{
CComPtr<IShellItemArray> spsia;
HRESULT hr = E_FAIL;
if (SUCCEEDED(_GetShellItemArrayFromDataOject(dataSource, &spsia)))
{
CComPtr<IEnumShellItems> spesi;
if (SUCCEEDED(spsia->EnumItems(&spesi)))
{
hr = _ParseEnumItems(spesi, psrm);
}
}
return hr;
}
BOOL GetEnumeratedFileName(__out_ecount(cchMax) PWSTR pszUniqueName, UINT cchMax, __in PCWSTR pszTemplate, __in_opt PCWSTR pszDir, unsigned long ulMinLong, __inout unsigned long* pulNumUsed)
{
PWSTR pszName = nullptr;
@@ -528,7 +461,7 @@ bool DataObjectContainsRenamableItem(_In_ IUnknown* dataSource)
{
bool hasRenamable = false;
CComPtr<IShellItemArray> spsia;
if (SUCCEEDED(_GetShellItemArrayFromDataOject(dataSource, &spsia)))
if (SUCCEEDED(GetShellItemArrayFromDataObject(dataSource, &spsia)))
{
CComPtr<IEnumShellItems> spesi;
if (SUCCEEDED(spsia->EnumItems(&spesi)))
@@ -549,3 +482,30 @@ bool DataObjectContainsRenamableItem(_In_ IUnknown* dataSource)
}
return hasRenamable;
}
HWND CreateMsgWindow(_In_ HINSTANCE hInst, _In_ WNDPROC pfnWndProc, _In_ void* p)
{
WNDCLASS wc = { 0 };
PCWSTR wndClassName = L"MsgWindow";
wc.lpfnWndProc = DefWindowProc;
wc.cbWndExtra = sizeof(void*);
wc.hInstance = hInst;
wc.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1);
wc.lpszClassName = wndClassName;
RegisterClass(&wc);
HWND hwnd = CreateWindowEx(
0, wndClassName, nullptr, 0, 0, 0, 0, 0, HWND_MESSAGE, 0, hInst, nullptr);
if (hwnd)
{
SetWindowLongPtr(hwnd, 0, (LONG_PTR)p);
if (pfnWndProc)
{
SetWindowLongPtr(hwnd, GWLP_WNDPROC, (LONG_PTR)pfnWndProc);
}
}
return hwnd;
}