3030// added drop handler for copy/move items to target folder
3131// Version 1.8.1 (c) 2023 thomas694
3232// fixed deleting empty subfolders
33- // Version 1.8.2 (c) 2024 thomas694
33+ // Version 1.8.2 (c) Feb 2024 thomas694
3434// fixed copy/move files progress dialog
35- // Version 1.8.3 (c) 2024 thomas694
35+ // Version 1.8.3 (c) Mar 2024 thomas694
3636// fixed problem moving items across volumes
37+ // Version 1.8.4 (c) Nov 2024 thomas694
38+ // fixed copy/move files progress dialog, smoother progress bar
3739//
3840// DFTContextMenuHandler is free software: you can redistribute it and/or modify
3941// it under the terms of the GNU General Public License as published by
@@ -1708,20 +1710,45 @@ int CCmdLineContextMenu::StartMoveFilesHere()
17081710 return 1 ;
17091711}
17101712
1711- void DoWork ()
1713+ void CCmdLineContextMenu::DoEvents ()
17121714{
1715+ if (m_lastExec == -1 ) {
1716+ time (&m_lastExec);
1717+ return ;
1718+ }
1719+ time_t now;
1720+ time (&now);
1721+ double diff = difftime (now, m_lastExec);
1722+ if (diff < 10 ) return ;
1723+ m_lastExec = now;
1724+
17131725 MSG msg;
1714- if (PeekMessage (&msg, NULL , 0 , 0 , 1 )) {
1715- TranslateMessage (&msg);
1716- DispatchMessageW (&msg);
1726+ BOOL result;
1727+
1728+ while (PeekMessage (&msg, NULL , 0 , 0 , PM_NOREMOVE))
1729+ {
1730+ result = GetMessage (&msg, NULL , 0 , 0 );
1731+ if (result == 0 )
1732+ {
1733+ PostQuitMessage (msg.wParam );
1734+ break ;
1735+ }
1736+ else if (result == -1 )
1737+ {
1738+ }
1739+ else
1740+ {
1741+ TranslateMessage (&msg);
1742+ DispatchMessage (&msg);
1743+ }
17171744 }
17181745}
17191746
17201747int CCmdLineContextMenu::CopyFilesHere (StringArray strFilenames, string szFolderDroppedIn)
17211748{
1722- size_t lTotalItems, lFiles;
1723- lTotalItems = lFiles = strFilenames.size ();
1724- size_t lDoneItems = 0 ;
1749+ size_t lDoneItems, lTotalItems, lFiles;
1750+ lFiles = strFilenames.size ();
1751+ lDoneItems = lTotalItems = 0 ;
17251752
17261753 IProgressDialog* pProgressDlg;
17271754 HRESULT hr = CoCreateInstance (CLSID_ProgressDialog, NULL , CLSCTX_INPROC_SERVER, IID_PPV_ARGS (&pProgressDlg));
@@ -1730,7 +1757,14 @@ int CCmdLineContextMenu::CopyFilesHere(StringArray strFilenames, string szFolder
17301757 pProgressDlg->SetTitle (_T (" Copying items..." ));
17311758 pProgressDlg->StartProgressDialog (NULL , NULL , PROGDLG_AUTOTIME, NULL );
17321759 pProgressDlg->SetProgress (lDoneItems, lTotalItems);
1733- DoWork ();
1760+ DoEvents ();
1761+
1762+ pProgressDlg->SetLine (2 , _T (" Preparing to copy..." ), true , NULL );
1763+ for (int i = 0 ; i < lFiles; i++) {
1764+ lTotalItems += CountFilesInSubfolders (strFilenames[i].data ());
1765+ if (pProgressDlg->HasUserCancelled ())
1766+ lFiles = 0 ;
1767+ }
17341768 }
17351769
17361770 int i;
@@ -1747,7 +1781,7 @@ int CCmdLineContextMenu::CopyFilesHere(StringArray strFilenames, string szFolder
17471781 break ;
17481782 lDoneItems++;
17491783 pProgressDlg->SetProgress (lDoneItems, lTotalItems);
1750- DoWork ();
1784+ DoEvents ();
17511785 string sItem = _T (" " );
17521786 sItem .append (sName ).append (sExt );
17531787 pProgressDlg->SetLine (2 , sItem .data (), true , NULL );
@@ -1759,7 +1793,7 @@ int CCmdLineContextMenu::CopyFilesHere(StringArray strFilenames, string szFolder
17591793 sNewFilename = _T (" \\\\ ?\\ " ) + sNewFilename ;
17601794
17611795 if (PathIsDirectory (strFilenames[i].data ())) {
1762- CopyDirectory (strFilenames[i].data (), sNewFilename , pProgressDlg, &lDoneItems, & lTotalItems);
1796+ CopyDirectory (strFilenames[i].data (), sNewFilename , pProgressDlg, &lDoneItems, lTotalItems);
17631797
17641798 } else {
17651799 bool ret = CopyFile (strFilenames[i].data (), sNewFilename .c_str (), true );
@@ -1774,7 +1808,33 @@ int CCmdLineContextMenu::CopyFilesHere(StringArray strFilenames, string szFolder
17741808 return 1 ;
17751809}
17761810
1777- int CCmdLineContextMenu::CopyDirectory (string sourceDir, string destDir, IProgressDialog* pProgressDlg, size_t * currentItems, size_t * totalItems)
1811+ size_t CCmdLineContextMenu::CountFilesInSubfolders (string sourceDir)
1812+ {
1813+ size_t itemsCnt = 0 ;
1814+ HANDLE hFind;
1815+ WIN32_FIND_DATA fd;
1816+ string searchFolder = sourceDir + _T (" \\ *" );
1817+
1818+ hFind = ::FindFirstFile (searchFolder.c_str (), &fd);
1819+ if (hFind != INVALID_HANDLE_VALUE)
1820+ {
1821+ do
1822+ {
1823+ if (_tcscmp (fd.cFileName , _T (" ." )) == 0 || _tcscmp (fd.cFileName , _T (" .." )) == 0 ) { continue ; }
1824+ if (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
1825+ itemsCnt += CountFilesInSubfolders (sourceDir + _T (" \\ " ) + fd.cFileName );
1826+ }
1827+ else {
1828+ itemsCnt++;
1829+ }
1830+ } while (::FindNextFile (hFind, &fd) == TRUE );
1831+ ::FindClose (hFind);
1832+ hFind = NULL ;
1833+ }
1834+ return itemsCnt;
1835+ }
1836+
1837+ int CCmdLineContextMenu::CopyDirectory (string sourceDir, string destDir, IProgressDialog* pProgressDlg, size_t * currentItems, size_t totalItems)
17781838{
17791839 string strSource;
17801840 string strDest;
@@ -1786,23 +1846,6 @@ int CCmdLineContextMenu::CopyDirectory(string sourceDir, string destDir, IProgre
17861846 return ::GetLastError ();
17871847
17881848 string searchFolder = sourceDir + _T (" \\ *" );
1789-
1790- if (pProgressDlg != NULL ) {
1791- hFind = ::FindFirstFile (searchFolder.c_str (), &fd);
1792- if (hFind != INVALID_HANDLE_VALUE)
1793- {
1794- do
1795- {
1796- if (_tcscmp (fd.cFileName , _T (" ." )) == 0 || _tcscmp (fd.cFileName , _T (" .." )) == 0 ) { continue ; }
1797- (*totalItems)++;
1798- } while (!pProgressDlg->HasUserCancelled () && ::FindNextFile (hFind, &fd) == TRUE );
1799- ::FindClose (hFind);
1800- hFind = NULL ;
1801- }
1802- if (pProgressDlg->HasUserCancelled ())
1803- return -1 ;
1804- }
1805-
18061849 hFind = ::FindFirstFile (searchFolder.c_str (), &fd);
18071850 if (hFind != INVALID_HANDLE_VALUE)
18081851 {
@@ -1823,8 +1866,8 @@ int CCmdLineContextMenu::CopyDirectory(string sourceDir, string destDir, IProgre
18231866 if (pProgressDlg != NULL ) {
18241867 if (pProgressDlg->HasUserCancelled ())
18251868 break ;
1826- pProgressDlg->SetProgress (*currentItems, * totalItems);
1827- DoWork ();
1869+ pProgressDlg->SetProgress (*currentItems, totalItems);
1870+ DoEvents ();
18281871 }
18291872
18301873 if (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
@@ -1886,17 +1929,25 @@ BOOL CCmdLineContextMenu::RemoveDirectory(string strDirectory)
18861929
18871930int CCmdLineContextMenu::MoveFilesHere (StringArray strFilenames, string szFolderDroppedIn)
18881931{
1889- size_t lFiles;
1932+ size_t lDoneItems, lTotalItems, lFiles;
18901933 lFiles = strFilenames.size ();
1934+ lDoneItems = lTotalItems = 0 ;
18911935
18921936 IProgressDialog* pProgressDlg;
18931937 HRESULT hr = CoCreateInstance (CLSID_ProgressDialog, NULL , CLSCTX_INPROC_SERVER, IID_PPV_ARGS (&pProgressDlg));
18941938 if (FAILED (hr)) pProgressDlg = NULL ;
18951939 if (pProgressDlg != NULL ) {
18961940 pProgressDlg->SetTitle (_T (" Moving items..." ));
18971941 pProgressDlg->StartProgressDialog (NULL , NULL , PROGDLG_AUTOTIME, NULL );
1898- pProgressDlg->SetProgress (0 , lFiles);
1899- DoWork ();
1942+ pProgressDlg->SetProgress (lDoneItems, lTotalItems);
1943+ DoEvents ();
1944+
1945+ pProgressDlg->SetLine (2 , _T (" Preparing to move..." ), true , NULL );
1946+ for (int i = 0 ; i < lFiles; i++) {
1947+ lTotalItems += CountFilesInSubfolders (strFilenames[i].data ());
1948+ if (pProgressDlg->HasUserCancelled ())
1949+ lFiles = 0 ;
1950+ }
19001951 }
19011952
19021953 bool isSameVolume = true ;
@@ -1924,8 +1975,9 @@ int CCmdLineContextMenu::MoveFilesHere(StringArray strFilenames, string szFolder
19241975 if (pProgressDlg != NULL ) {
19251976 if (pProgressDlg->HasUserCancelled ())
19261977 break ;
1927- pProgressDlg->SetProgress (i + 1 , lFiles);
1928- DoWork ();
1978+ lDoneItems++;
1979+ pProgressDlg->SetProgress (lDoneItems, lTotalItems);
1980+ DoEvents ();
19291981 string sItem = _T (" " );
19301982 sItem .append (sName ).append (sExt );
19311983 pProgressDlg->SetLine (2 , sItem .data (), true , NULL );
@@ -1944,18 +1996,9 @@ int CCmdLineContextMenu::MoveFilesHere(StringArray strFilenames, string szFolder
19441996 ret = MoveFile (sOldFilename .c_str (), sNewFilename .c_str ());
19451997 if (!ret)
19461998 break ;
1947- /*
1948- if (ret == false) {
1949- DWORD error = ::GetLastError();
1950- std::string sMessage = std::system_category().message(error);
1951- string message = string(sMessage.begin(), sMessage.end());
1952- MessageBox(NULL, message.c_str(), _T("Error"), 0);
1953- }
1954- */
19551999 }
19562000 else {
1957- size_t dummy;
1958- int result = CopyDirectory (sOldFilename , sNewFilename , NULL , &dummy, &dummy);
2001+ int result = CopyDirectory (sOldFilename , sNewFilename , pProgressDlg, &lDoneItems, lTotalItems);
19592002 if (result == 0 )
19602003 CCmdLineContextMenu::RemoveDirectory (sOldFilename .c_str ());
19612004 else
0 commit comments