mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 10:04:49 +00:00
[SHELL32] Update the status bar asynchronously (#5420)
- Selecting all in system32 was too slow. - Make CDefView::UpdateStatusbar function asynchronized by using a thread. - It makes selecting all very quick. - Add m_hUpdateStatusbarThread to asynchronize. CORE-18663
This commit is contained in:
parent
8d821292de
commit
9a1487f3a8
1 changed files with 57 additions and 14 deletions
|
@ -36,6 +36,7 @@ TODO:
|
||||||
|
|
||||||
#include "precomp.h"
|
#include "precomp.h"
|
||||||
|
|
||||||
|
#include <process.h>
|
||||||
#include <atlwin.h>
|
#include <atlwin.h>
|
||||||
#include <ui/rosctrls.h>
|
#include <ui/rosctrls.h>
|
||||||
|
|
||||||
|
@ -153,6 +154,7 @@ class CDefView :
|
||||||
SFVM_CUSTOMVIEWINFO_DATA m_viewinfo_data;
|
SFVM_CUSTOMVIEWINFO_DATA m_viewinfo_data;
|
||||||
|
|
||||||
HICON m_hMyComputerIcon;
|
HICON m_hMyComputerIcon;
|
||||||
|
HANDLE m_hUpdateStatusbarThread;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
HRESULT _MergeToolbar();
|
HRESULT _MergeToolbar();
|
||||||
|
@ -171,6 +173,8 @@ class CDefView :
|
||||||
HRESULT IncludeObject(PCUITEMID_CHILD pidl);
|
HRESULT IncludeObject(PCUITEMID_CHILD pidl);
|
||||||
HRESULT OnDefaultCommand();
|
HRESULT OnDefaultCommand();
|
||||||
HRESULT OnStateChange(UINT uFlags);
|
HRESULT OnStateChange(UINT uFlags);
|
||||||
|
static unsigned __stdcall _UpdateStatusbarProc(void *args);
|
||||||
|
void UpdateStatusbarWorker(HANDLE hThread);
|
||||||
void UpdateStatusbar();
|
void UpdateStatusbar();
|
||||||
void CheckToolbar();
|
void CheckToolbar();
|
||||||
BOOL CreateList();
|
BOOL CreateList();
|
||||||
|
@ -428,7 +432,9 @@ CDefView::CDefView() :
|
||||||
m_cScrollDelay(0),
|
m_cScrollDelay(0),
|
||||||
m_isEditing(FALSE),
|
m_isEditing(FALSE),
|
||||||
m_isParentFolderSpecial(FALSE),
|
m_isParentFolderSpecial(FALSE),
|
||||||
m_Destroyed(FALSE)
|
m_Destroyed(FALSE),
|
||||||
|
m_hMyComputerIcon(::LoadIconW(shell32_hInstance, MAKEINTRESOURCEW(IDI_SHELL_COMPUTER_DESKTOP))),
|
||||||
|
m_hUpdateStatusbarThread(NULL)
|
||||||
{
|
{
|
||||||
ZeroMemory(&m_FolderSettings, sizeof(m_FolderSettings));
|
ZeroMemory(&m_FolderSettings, sizeof(m_FolderSettings));
|
||||||
ZeroMemory(&m_sortInfo, sizeof(m_sortInfo));
|
ZeroMemory(&m_sortInfo, sizeof(m_sortInfo));
|
||||||
|
@ -437,8 +443,6 @@ CDefView::CDefView() :
|
||||||
m_viewinfo_data.clrText = GetSysColor(COLOR_WINDOWTEXT);
|
m_viewinfo_data.clrText = GetSysColor(COLOR_WINDOWTEXT);
|
||||||
m_viewinfo_data.clrTextBack = GetSysColor(COLOR_WINDOW);
|
m_viewinfo_data.clrTextBack = GetSysColor(COLOR_WINDOW);
|
||||||
m_viewinfo_data.hbmBack = NULL;
|
m_viewinfo_data.hbmBack = NULL;
|
||||||
|
|
||||||
m_hMyComputerIcon = LoadIconW(shell32_hInstance, MAKEINTRESOURCEW(IDI_SHELL_COMPUTER_DESKTOP));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CDefView::~CDefView()
|
CDefView::~CDefView()
|
||||||
|
@ -539,10 +543,9 @@ void CDefView::CheckToolbar()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CDefView::UpdateStatusbar()
|
void CDefView::UpdateStatusbarWorker(HANDLE hThread)
|
||||||
{
|
{
|
||||||
WCHAR szFormat[MAX_PATH] = {0};
|
WCHAR szFormat[MAX_PATH], szPartText[MAX_PATH];
|
||||||
WCHAR szPartText[MAX_PATH] = {0};
|
|
||||||
UINT cSelectedItems;
|
UINT cSelectedItems;
|
||||||
|
|
||||||
cSelectedItems = m_ListView.GetSelectedCount();
|
cSelectedItems = m_ListView.GetSelectedCount();
|
||||||
|
@ -571,12 +574,13 @@ void CDefView::UpdateStatusbar()
|
||||||
|
|
||||||
/* If we have something selected then only count selected file sizes. */
|
/* If we have something selected then only count selected file sizes. */
|
||||||
if (cSelectedItems)
|
if (cSelectedItems)
|
||||||
{
|
|
||||||
uFileFlags = LVNI_SELECTED;
|
uFileFlags = LVNI_SELECTED;
|
||||||
}
|
|
||||||
|
|
||||||
while ((nItem = m_ListView.GetNextItem(nItem, uFileFlags)) >= 0)
|
while ((nItem = m_ListView.GetNextItem(nItem, uFileFlags)) >= 0)
|
||||||
{
|
{
|
||||||
|
if (hThread != m_hUpdateStatusbarThread)
|
||||||
|
return;
|
||||||
|
|
||||||
PCUITEMID_CHILD pidl = _PidlByItem(nItem);
|
PCUITEMID_CHILD pidl = _PidlByItem(nItem);
|
||||||
|
|
||||||
uTotalFileSize += _ILGetFileSize(pidl, NULL, 0);
|
uTotalFileSize += _ILGetFileSize(pidl, NULL, 0);
|
||||||
|
@ -589,18 +593,14 @@ void CDefView::UpdateStatusbar()
|
||||||
|
|
||||||
/* Don't show the file size text if there is 0 bytes in the folder
|
/* Don't show the file size text if there is 0 bytes in the folder
|
||||||
* OR we only have folders selected. */
|
* OR we only have folders selected. */
|
||||||
|
szPartText[0] = UNICODE_NULL;
|
||||||
if ((cSelectedItems && !bIsOnlyFoldersSelected) || uTotalFileSize)
|
if ((cSelectedItems && !bIsOnlyFoldersSelected) || uTotalFileSize)
|
||||||
{
|
|
||||||
StrFormatByteSizeW(uTotalFileSize, szPartText, _countof(szPartText));
|
StrFormatByteSizeW(uTotalFileSize, szPartText, _countof(szPartText));
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
*szPartText = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_pShellBrowser->SendControlMsg(FCW_STATUS, SB_SETTEXT, 1, (LPARAM)szPartText, &lResult);
|
m_pShellBrowser->SendControlMsg(FCW_STATUS, SB_SETTEXT, 1, (LPARAM)szPartText, &lResult);
|
||||||
|
|
||||||
/* If we are in a Recycle Bin folder then show no text for the location part. */
|
/* If we are in a Recycle Bin folder then show no text for the location part. */
|
||||||
|
szPartText[0] = UNICODE_NULL;
|
||||||
if (!_ILIsBitBucket(m_pidlParent))
|
if (!_ILIsBitBucket(m_pidlParent))
|
||||||
{
|
{
|
||||||
LoadStringW(shell32_hInstance, IDS_MYCOMPUTER, szPartText, _countof(szPartText));
|
LoadStringW(shell32_hInstance, IDS_MYCOMPUTER, szPartText, _countof(szPartText));
|
||||||
|
@ -612,6 +612,38 @@ void CDefView::UpdateStatusbar()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned __stdcall CDefView::_UpdateStatusbarProc(void *args)
|
||||||
|
{
|
||||||
|
CDefView* pView = static_cast<CDefView*>(args);
|
||||||
|
pView->UpdateStatusbarWorker(pView->m_hUpdateStatusbarThread);
|
||||||
|
pView->Release();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CDefView::UpdateStatusbar()
|
||||||
|
{
|
||||||
|
HANDLE hOldThread = m_hUpdateStatusbarThread;
|
||||||
|
|
||||||
|
AddRef();
|
||||||
|
|
||||||
|
// We have to initialize m_hUpdateStatusbarThread before the target thread begins.
|
||||||
|
// So, we use CREATE_SUSPENDED.
|
||||||
|
HANDLE hNewThread = reinterpret_cast<HANDLE>(_beginthreadex(NULL, 0, _UpdateStatusbarProc,
|
||||||
|
this, CREATE_SUSPENDED, NULL));
|
||||||
|
if (hNewThread)
|
||||||
|
{
|
||||||
|
m_hUpdateStatusbarThread = hNewThread;
|
||||||
|
::ResumeThread(hNewThread);
|
||||||
|
|
||||||
|
if (hOldThread)
|
||||||
|
::CloseHandle(hOldThread);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Release();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**********************************************************
|
/**********************************************************
|
||||||
*
|
*
|
||||||
* ##### helperfunctions for initializing the view #####
|
* ##### helperfunctions for initializing the view #####
|
||||||
|
@ -2582,6 +2614,17 @@ HRESULT WINAPI CDefView::DestroyViewWindow()
|
||||||
{
|
{
|
||||||
TRACE("(%p)\n", this);
|
TRACE("(%p)\n", this);
|
||||||
|
|
||||||
|
if (m_hUpdateStatusbarThread)
|
||||||
|
{
|
||||||
|
HANDLE hOldThread = m_hUpdateStatusbarThread;
|
||||||
|
|
||||||
|
// Assigning NULL to m_hUpdateStatusbarThread will terminate the target thread immediately
|
||||||
|
m_hUpdateStatusbarThread = NULL;
|
||||||
|
::WaitForSingleObject(hOldThread, INFINITE);
|
||||||
|
|
||||||
|
::CloseHandle(hOldThread);
|
||||||
|
}
|
||||||
|
|
||||||
/* Make absolutely sure all our UI is cleaned up */
|
/* Make absolutely sure all our UI is cleaned up */
|
||||||
UIActivate(SVUIA_DEACTIVATE);
|
UIActivate(SVUIA_DEACTIVATE);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue