From 8448c3ee1a72f2bea7324696b5ad4479f5938ca4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sergio=20At=C3=A1n?= <175652103+3V0S8N@users.noreply.github.com> Date: Fri, 15 May 2026 12:17:31 +0200 Subject: [PATCH 1/4] added easy7zip features Port abandoned Easy 7-Zip features (e7z.org, LGPL) UI features: free-space labels, "Open" button + path-history sharing in Extract/Copy dialogs, post-extract checkboxes (Open / Delete source / Close 7-Zip), tray background mode with animated icon, resizable progress + dialogs, percent label, context menu icons default on. Generic vanilla extensions used by these features: - CDialog: OnGetMinMaxInfo virtual + _minTrackSize + helper - NDir::DeleteFileIfArchive - BrowseDialog: FreeSpace_ConvertSizeToString + FormatPathFreeSpace - ViewSettings: SaveBoolVal / ReadBoolVal --- CPP/7zip/UI/Common/ZipRegistry.cpp | 62 +++-- CPP/7zip/UI/FileManager/App.cpp | 64 +++++- CPP/7zip/UI/FileManager/BrowseDialog.cpp | 73 ++++++ CPP/7zip/UI/FileManager/CopyDialog.cpp | 216 +++++++++++++++++- CPP/7zip/UI/FileManager/CopyDialog.h | 17 ++ CPP/7zip/UI/FileManager/CopyDialog.rc | 50 +++- CPP/7zip/UI/FileManager/CopyDialogRes.h | 8 + CPP/7zip/UI/FileManager/ListViewDialog.cpp | 12 +- CPP/7zip/UI/FileManager/MessagesDialog.cpp | 10 +- CPP/7zip/UI/FileManager/MessagesDialog.h | 2 +- CPP/7zip/UI/FileManager/Panel.h | 1 + CPP/7zip/UI/FileManager/PanelSplitFile.cpp | 23 +- CPP/7zip/UI/FileManager/ProgressDialog2.cpp | 185 ++++++++++++++- CPP/7zip/UI/FileManager/ProgressDialog2.h | 11 + CPP/7zip/UI/FileManager/ProgressDialog2.rc | 3 + .../UI/FileManager/ProgressDialog2Icon.rc | 19 ++ .../UI/FileManager/ProgressDialog2IconRes.h | 17 ++ CPP/7zip/UI/FileManager/ProgressDialog2Res.h | 2 + CPP/7zip/UI/FileManager/ProgressDialog2a.rc | 4 +- CPP/7zip/UI/FileManager/ViewSettings.cpp | 44 ++++ CPP/7zip/UI/FileManager/ViewSettings.h | 6 + CPP/7zip/UI/FileManager/trayico/tray00.ico | Bin 0 -> 318 bytes CPP/7zip/UI/FileManager/trayico/tray01.ico | Bin 0 -> 318 bytes CPP/7zip/UI/FileManager/trayico/tray02.ico | Bin 0 -> 318 bytes CPP/7zip/UI/FileManager/trayico/tray03.ico | Bin 0 -> 318 bytes CPP/7zip/UI/FileManager/trayico/tray04.ico | Bin 0 -> 318 bytes CPP/7zip/UI/FileManager/trayico/tray05.ico | Bin 0 -> 318 bytes CPP/7zip/UI/FileManager/trayico/tray06.ico | Bin 0 -> 318 bytes CPP/7zip/UI/FileManager/trayico/tray07.ico | Bin 0 -> 318 bytes CPP/7zip/UI/FileManager/trayico/tray08.ico | Bin 0 -> 318 bytes CPP/7zip/UI/FileManager/trayico/tray09.ico | Bin 0 -> 318 bytes CPP/7zip/UI/FileManager/trayico/tray10.ico | Bin 0 -> 318 bytes CPP/7zip/UI/FileManager/trayico/tray11.ico | Bin 0 -> 318 bytes CPP/7zip/UI/FileManager/trayico/tray12.ico | Bin 0 -> 318 bytes CPP/7zip/UI/FileManager/trayico/tray13.ico | Bin 0 -> 318 bytes CPP/7zip/UI/FileManager/trayico/tray14.ico | Bin 0 -> 318 bytes CPP/7zip/UI/GUI/ExtractDialog.cpp | 96 ++++++++ CPP/7zip/UI/GUI/ExtractDialog.h | 18 +- CPP/7zip/UI/GUI/ExtractDialog.rc | 48 ++-- CPP/7zip/UI/GUI/ExtractDialogRes.h | 5 + CPP/7zip/UI/GUI/ExtractGUI.cpp | 16 +- CPP/Windows/Control/Dialog.cpp | 9 + CPP/Windows/Control/Dialog.h | 12 +- CPP/Windows/FileDir.cpp | 15 ++ CPP/Windows/FileDir.h | 1 + 45 files changed, 965 insertions(+), 84 deletions(-) create mode 100644 CPP/7zip/UI/FileManager/ProgressDialog2Icon.rc create mode 100644 CPP/7zip/UI/FileManager/ProgressDialog2IconRes.h create mode 100644 CPP/7zip/UI/FileManager/trayico/tray00.ico create mode 100644 CPP/7zip/UI/FileManager/trayico/tray01.ico create mode 100644 CPP/7zip/UI/FileManager/trayico/tray02.ico create mode 100644 CPP/7zip/UI/FileManager/trayico/tray03.ico create mode 100644 CPP/7zip/UI/FileManager/trayico/tray04.ico create mode 100644 CPP/7zip/UI/FileManager/trayico/tray05.ico create mode 100644 CPP/7zip/UI/FileManager/trayico/tray06.ico create mode 100644 CPP/7zip/UI/FileManager/trayico/tray07.ico create mode 100644 CPP/7zip/UI/FileManager/trayico/tray08.ico create mode 100644 CPP/7zip/UI/FileManager/trayico/tray09.ico create mode 100644 CPP/7zip/UI/FileManager/trayico/tray10.ico create mode 100644 CPP/7zip/UI/FileManager/trayico/tray11.ico create mode 100644 CPP/7zip/UI/FileManager/trayico/tray12.ico create mode 100644 CPP/7zip/UI/FileManager/trayico/tray13.ico create mode 100644 CPP/7zip/UI/FileManager/trayico/tray14.ico diff --git a/CPP/7zip/UI/Common/ZipRegistry.cpp b/CPP/7zip/UI/Common/ZipRegistry.cpp index ca22a43dd..0d2cbed43 100644 --- a/CPP/7zip/UI/Common/ZipRegistry.cpp +++ b/CPP/7zip/UI/Common/ZipRegistry.cpp @@ -103,6 +103,8 @@ static LPCTSTR const kElimDup = TEXT("ElimDup"); static LPCTSTR const kNtSecur = TEXT("Security"); static LPCTSTR const kMemLimit = TEXT("MemLimit"); +static LPCTSTR const kFMCopyHistoryValueName = TEXT("CopyHistory"); + void CInfo::Save() const { CS_LOCK @@ -122,11 +124,13 @@ void CInfo::Save() const Key_Set_BoolPair(key, kShowPassword, ShowPassword); Key_Set_BoolPair(key, kOpnTrgFold, OpnTrgFold); - key.RecurseDeleteKey(kPathHistory); - if (WantPathHistory()) - key.SetValue_Strings(kPathHistory, Paths); - else - key.SetValue_Strings(kPathHistory, Empty); + // Store path history in shared FM key (cross-dialog: Extract GUI + FM context menu) + key.Close(); + if (key.Create(HKEY_CURRENT_USER, GetKeyPath(TEXT("FM"))) == ERROR_SUCCESS) + { + key.SetValue_Strings(kFMCopyHistoryValueName, Paths); + key.Close(); + } } void Save_ShowPassword(bool showPassword) @@ -158,29 +162,37 @@ void CInfo::Load() CS_LOCK CKey key; - if (OpenMainKey(key, kKeyName) != ERROR_SUCCESS) - return; - - key.GetValue_Strings(kPathHistory, Paths); - UInt32 v; - if (key.GetValue_UInt32_IfOk(kExtractMode, v) == ERROR_SUCCESS && v <= NPathMode::kAbsPaths) + + // Resilient against missing Extraction key; load paths from shared FM key + if (OpenMainKey(key, kKeyName) == ERROR_SUCCESS) { - PathMode = (NPathMode::EEnum)v; - PathMode_Force = true; + UInt32 v; + if (key.GetValue_UInt32_IfOk(kExtractMode, v) == ERROR_SUCCESS && v <= NPathMode::kAbsPaths) + { + PathMode = (NPathMode::EEnum)v; + PathMode_Force = true; + } + if (key.GetValue_UInt32_IfOk(kOverwriteMode, v) == ERROR_SUCCESS && v <= NOverwriteMode::kRenameExisting) + { + OverwriteMode = (NOverwriteMode::EEnum)v; + OverwriteMode_Force = true; + } + + Key_Get_BoolPair_true(key, kSplitDest, SplitDest); + + Key_Get_BoolPair(key, kElimDup, ElimDup); + // Key_Get_BoolPair(key, kAltStreams, AltStreams); + Key_Get_BoolPair(key, kNtSecur, NtSecurity); + Key_Get_BoolPair(key, kShowPassword, ShowPassword); + Key_Get_BoolPair(key, kOpnTrgFold, OpnTrgFold); + key.Close(); } - if (key.GetValue_UInt32_IfOk(kOverwriteMode, v) == ERROR_SUCCESS && v <= NOverwriteMode::kRenameExisting) + + if (key.Open(HKEY_CURRENT_USER, GetKeyPath(TEXT("FM")), KEY_READ) == ERROR_SUCCESS) { - OverwriteMode = (NOverwriteMode::EEnum)v; - OverwriteMode_Force = true; + key.GetValue_Strings(kFMCopyHistoryValueName, Paths); + key.Close(); } - - Key_Get_BoolPair_true(key, kSplitDest, SplitDest); - - Key_Get_BoolPair(key, kElimDup, ElimDup); - // Key_Get_BoolPair(key, kAltStreams, AltStreams); - Key_Get_BoolPair(key, kNtSecur, NtSecurity); - Key_Get_BoolPair(key, kShowPassword, ShowPassword); - Key_Get_BoolPair(key, kOpnTrgFold, OpnTrgFold); } bool Read_ShowPassword() @@ -607,7 +619,7 @@ void CContextMenuInfo::Load() Cascaded.Val = true; Cascaded.Def = false; - MenuIcons.Val = false; + MenuIcons.Val = true; MenuIcons.Def = false; ElimDup.Val = true; diff --git a/CPP/7zip/UI/FileManager/App.cpp b/CPP/7zip/UI/FileManager/App.cpp index d93b94cb8..ffff69c39 100644 --- a/CPP/7zip/UI/FileManager/App.cpp +++ b/CPP/7zip/UI/FileManager/App.cpp @@ -41,6 +41,8 @@ using namespace NName; extern HINSTANCE g_hInstance; +extern bool g_bProcessError; + #define kTempDirPrefix FTEXT("7zE") void CPanelCallbackImp::OnTab() @@ -591,7 +593,7 @@ UString CPanel::GetItemsInfoString(const CRecordVector &indices) info.Add_LF(); info += _currentFolderPrefix; - + for (i = 0; i < indices.Size() && (int)i < (int)kCopyDialog_NumInfoLines - 6; i++) { info.Add_LF(); @@ -612,7 +614,6 @@ UString CPanel::GetItemsInfoString(const CRecordVector &indices) bool IsCorrectFsName(const UString &name); - /* Returns true, if path is path that can be used as path for File System functions */ @@ -647,6 +648,9 @@ void CApp::OnCopy(bool move, bool copyToSame, unsigned srcPanelIndex) CRecordVector indices; UString destPath; + bool openOutputFolder = false; + bool deleteSourceFile = false; + bool close7Zip = false; bool useDestPanel = false; { @@ -685,10 +689,15 @@ void CApp::OnCopy(bool move, bool copyToSame, unsigned srcPanelIndex) LangString(move ? IDS_MOVE : IDS_COPY, copyDialog.Title); LangString(move ? IDS_MOVE_TO : IDS_COPY_TO, copyDialog.Static); copyDialog.Info = srcPanel.GetItemsInfoString(indices); + copyDialog.CurrentFolderPrefix = srcPanel._currentFolderPrefix; if (copyDialog.Create(srcPanel.GetParent()) != IDOK) return; + openOutputFolder = copyDialog.OpenOutputFolder; + deleteSourceFile = copyDialog.DeleteSourceFile; + close7Zip = copyDialog.Close7Zip; + destPath = copyDialog.Value; } @@ -820,6 +829,8 @@ void CApp::OnCopy(bool move, bool copyToSame, unsigned srcPanelIndex) SaveCopyHistory(copyFolders); } + g_bProcessError = false; + bool useSrcPanel = !useDestPanel || !srcPanel.Is_IO_FS_Folder(); bool useTemp = useSrcPanel && useDestPanel; @@ -916,6 +927,55 @@ void CApp::OnCopy(bool move, bool copyToSame, unsigned srcPanelIndex) disableNotify1.Restore(); disableNotify2.Restore(); srcPanel.SetFocusToList(); + + if (!g_bProcessError && result == S_OK) + { + if (openOutputFolder && NFind::DoesDirExist_FollowLink(us2fs(destPath))) + { + StartApplicationDontWait(destPath, destPath, _window); + } + if (deleteSourceFile) + { + UString srcFilePath(srcPanel._currentFolderPrefix); + srcPanel.OpenParentFolder(); + + while (!srcFilePath.IsEmpty()) + { + if (srcFilePath.Back() == '\\') + { + srcFilePath.DeleteBack(); + } + DWORD dwAttr = GetFileAttributesW(srcFilePath); + + if (dwAttr == INVALID_FILE_ATTRIBUTES) + { + int n = srcFilePath.ReverseFind(L'\\'); + if (n != -1) + { + srcPanel.OpenParentFolder(); + srcFilePath.ReleaseBuf_SetEnd(n); + } + else + { + break; + } + } + else if (dwAttr & FILE_ATTRIBUTE_ARCHIVE) + { + NDir::DeleteFileIfArchive(us2fs(srcFilePath)); + break; + } + else // directory or other non-archive + { + break; + } + } + } + if (close7Zip) + { + PostMessage(_window, WM_CLOSE, 0, 0); + } + } } void CApp::OnSetSameFolder(unsigned srcPanelIndex) diff --git a/CPP/7zip/UI/FileManager/BrowseDialog.cpp b/CPP/7zip/UI/FileManager/BrowseDialog.cpp index b12d8e814..f1dd8a305 100644 --- a/CPP/7zip/UI/FileManager/BrowseDialog.cpp +++ b/CPP/7zip/UI/FileManager/BrowseDialog.cpp @@ -566,6 +566,79 @@ wchar_t *Browse_ConvertSizeToString(UInt64 v, wchar_t *s) return s; } + +// ". B" with 2 decimals, or " B". +void FreeSpace_ConvertSizeToString(UInt64 v, wchar_t *s); +void FreeSpace_ConvertSizeToString(UInt64 v, wchar_t *s) +{ + unsigned shift = 0; + wchar_t unit = 0; + if (v >= ((UInt64)1 << 50)) { shift = 50; unit = 'P'; } + else if (v >= ((UInt64)1 << 40)) { shift = 40; unit = 'T'; } + else if (v >= ((UInt64)1 << 30)) { shift = 30; unit = 'G'; } + else if (v >= ((UInt64)1 << 20)) { shift = 20; unit = 'M'; } + else if (v >= ((UInt64)1 << 10)) { shift = 10; unit = 'K'; } + + if (unit == 0) + { + s = ConvertUInt64ToString(v, s); + *s++ = ' '; + *s++ = 'B'; + *s = 0; + return; + } + + const UInt64 whole = v >> shift; + UInt64 frac = ((v & (((UInt64)1 << shift) - 1)) * 100 + + ((UInt64)1 << (shift - 1))) >> shift; + if (frac >= 100) + frac = 99; + + s = ConvertUInt64ToString(whole, s); + *s++ = '.'; + *s++ = (wchar_t)('0' + (unsigned)(frac / 10)); + *s++ = (wchar_t)('0' + (unsigned)(frac % 10)); + *s++ = ' '; + *s++ = unit; + *s++ = 'B'; + *s = 0; +} + + +// Trims path, then formats free/total. +void FormatPathFreeSpace(UString &strPath, UString &strText); +void FormatPathFreeSpace(UString &strPath, UString &strText) +{ + strText.Empty(); + strPath.Trim(); + for (;;) + { + const DWORD attr = GetFileAttributesW(strPath); + if (attr != INVALID_FILE_ATTRIBUTES && (attr & FILE_ATTRIBUTE_DIRECTORY)) + break; + const int n = strPath.ReverseFind(L'\\'); + if (n == -1) + return; + strPath.ReleaseBuf_SetEnd(n); + } + + ULARGE_INTEGER freeBytes; + ULARGE_INTEGER totalBytes; + ULARGE_INTEGER totalFree; + if (!GetDiskFreeSpaceExW(strPath, &freeBytes, &totalBytes, &totalFree)) + return; + + wchar_t szFree[40]; + wchar_t szTotal[40]; + FreeSpace_ConvertSizeToString(totalFree.QuadPart, szFree); + FreeSpace_ConvertSizeToString(totalBytes.QuadPart, szTotal); + strText = szFree; + strText += L" Free (Total: "; + strText += szTotal; + strText += L")"; +} + + // Reload changes DirPrefix. Don't send DirPrefix in pathPrefix parameter HRESULT CBrowseDialog::Reload(const UString &pathPrefix, const UString &selectedName) diff --git a/CPP/7zip/UI/FileManager/CopyDialog.cpp b/CPP/7zip/UI/FileManager/CopyDialog.cpp index 9bc01d064..6e6d0e9a8 100644 --- a/CPP/7zip/UI/FileManager/CopyDialog.cpp +++ b/CPP/7zip/UI/FileManager/CopyDialog.cpp @@ -2,16 +2,34 @@ #include "StdAfx.h" +#include "../../../Common/StringConvert.h" + +#include "../../../Windows/FileFind.h" #include "../../../Windows/FileName.h" #include "../../../Windows/Control/Static.h" #include "BrowseDialog.h" #include "CopyDialog.h" +#include "FormatUtils.h" + +#include "Panel.h" +#include "ViewSettings.h" + #include "LangUtils.h" +extern void FormatPathFreeSpace(UString &strPath, UString &strText); + using namespace NWindows; +static bool IsFileExistentAndNotDir(const wchar_t * lpszFile) +{ + DWORD dwAttr = GetFileAttributesW(lpszFile); + return (dwAttr != INVALID_FILE_ATTRIBUTES) + && ((dwAttr & FILE_ATTRIBUTE_ARCHIVE) != 0) + && ((dwAttr & FILE_ATTRIBUTE_DIRECTORY) == 0); +} + bool CCopyDialog::OnInit() { #ifdef Z7_LANG @@ -20,6 +38,9 @@ bool CCopyDialog::OnInit() _path.Attach(GetItem(IDC_COPY)); SetText(Title); + _freeSpace.Attach(GetItem(IDC_FREE_SPACE)); + _freeSpace.SetText(L""); + NControl::CStatic staticContol; staticContol.Attach(GetItem(IDT_COPY)); staticContol.SetText(Static); @@ -30,8 +51,67 @@ bool CCopyDialog::OnInit() FOR_VECTOR (i, Strings) _path.AddString(Strings[i]); _path.SetText(Value); + ShowPathFreeSpace(Value); + + OpenOutputFolder = Read_OpenOutputFolder(); + Close7Zip = Read_Close7Zip(); + + CheckButton(IDC_CHECK_OPEN_OUTPUT_FOLDER, OpenOutputFolder); + CheckButton(IDC_CHECK_CLOSE_7ZIP, Close7Zip); + SetItemText(IDT_COPY_INFO, Info); NormalizeSize(true); + + Set_MinTrackSize_FromCurrent(4, 5, 4, 5); + + ///////////////////////////////////////////////////////// + + RealFileName.Empty(); + if (NFile::NFind::DoesDirExist_FollowLink(us2fs(CurrentFolderPrefix))) + { + EnableItem(IDC_COPY_ADD_FILE_NAME, false); + EnableItem(IDC_CHECK_DELETE_SOURCE_FILE, false); + } + else + { + while (!CurrentFolderPrefix.IsEmpty()) + { + if (CurrentFolderPrefix.Back() == '\\') + { + CurrentFolderPrefix.DeleteBack(); + } + + if (IsFileExistentAndNotDir(CurrentFolderPrefix)) + { + int n = CurrentFolderPrefix.ReverseFind(L'\\'); + int m = CurrentFolderPrefix.ReverseFind(L'.'); + if (n != -1) + { + n++; + } + else + { + n = 0; + } + if (m == -1 || m <= n) m = CurrentFolderPrefix.Len(); + RealFileName = CurrentFolderPrefix.Mid(n, m - n); + break; + } + else + { + int n = CurrentFolderPrefix.ReverseFind(L'\\'); + if (n != -1) + { + CurrentFolderPrefix.ReleaseBuf_SetEnd(n); + } + else + { + break; + } + } + } + } + return CModalDialog::OnInit(); } @@ -45,28 +125,41 @@ bool CCopyDialog::OnSize(WPARAM /* wParam */, int xSize, int ySize) const int y = ySize - my - by; const int x = xSize - mx - bx1; - InvalidateRect(NULL); - { RECT r; + + GetClientRectOfItem(IDC_COPY_ADD_FILE_NAME, r); + int bxAddFileName = r.right - r.left; + int byAddFileName = r.bottom - r.top; + MoveItem(IDC_COPY_ADD_FILE_NAME, xSize - mx - bxAddFileName, r.top, bxAddFileName, byAddFileName, false); + + GetClientRectOfItem(IDC_COPY_OPEN_PATH, r); + int bxOpen = r.right - r.left; + int byOpen = r.bottom - r.top; + MoveItem(IDC_COPY_OPEN_PATH, xSize - mx - bxOpen - mx/2 - bxAddFileName, r.top, bxOpen, byOpen, false); + GetClientRectOfItem(IDB_COPY_SET_PATH, r); - const int bx = RECT_SIZE_X(r); - MoveItem(IDB_COPY_SET_PATH, xSize - mx - bx, r.top, bx, RECT_SIZE_Y(r)); - ChangeSubWindowSizeX(_path, xSize - mx - mx - bx - mx); + int bxSet = RECT_SIZE_X(r); + int bySet = RECT_SIZE_Y(r); + MoveItem(IDB_COPY_SET_PATH, xSize - mx - bxSet - bxOpen - mx - bxAddFileName, r.top, bxSet, bySet, false); + ChangeSubWindowSizeX(_path, xSize - mx - mx - bxSet - bxOpen - mx - mx/2 - bxAddFileName); } { RECT r; GetClientRectOfItem(IDT_COPY_INFO, r); - NControl::CStatic staticContol; - staticContol.Attach(GetItem(IDT_COPY_INFO)); const int yPos = r.top; - staticContol.Move(mx, yPos, xSize - mx * 2, y - 2 - yPos); + const int xc = xSize - mx * 2; + MoveItem(IDT_COPY_INFO, mx, yPos, xc, y - 2 - yPos, false); + + GetClientRectOfItem(IDC_AFTER_EXTRACT, r); + MoveItem(IDC_AFTER_EXTRACT, mx, r.top, xc, r.bottom - r.top, false); } - MoveItem(IDCANCEL, x, y, bx1, by); - MoveItem(IDOK, x - mx - bx2, y, bx2, by); + MoveItem(IDCANCEL, x, y, bx1, by, false); + MoveItem(IDOK, x - mx - bx2, y, bx2, by, false); + InvalidateRect(NULL); return false; } @@ -77,6 +170,21 @@ bool CCopyDialog::OnButtonClicked(unsigned buttonID, HWND buttonHWND) case IDB_COPY_SET_PATH: OnButtonSetPath(); return true; + case IDC_COPY_OPEN_PATH: + OnButtonOpenPath(); + return true; + case IDC_COPY_ADD_FILE_NAME: + OnButtonAddFileName(); + return true; + case IDC_CHECK_OPEN_OUTPUT_FOLDER: + OpenOutputFolder = IsButtonCheckedBool(IDC_CHECK_OPEN_OUTPUT_FOLDER); + return true; + case IDC_CHECK_DELETE_SOURCE_FILE: + DeleteSourceFile = IsButtonCheckedBool(IDC_CHECK_DELETE_SOURCE_FILE); + return true; + case IDC_CHECK_CLOSE_7ZIP: + Close7Zip = IsButtonCheckedBool(IDC_CHECK_CLOSE_7ZIP); + return true; } return CModalDialog::OnButtonClicked(buttonID, buttonHWND); } @@ -94,10 +202,98 @@ void CCopyDialog::OnButtonSetPath() NFile::NName::NormalizeDirPathPrefix(resultPath); _path.SetCurSel(-1); _path.SetText(resultPath); + ShowPathFreeSpace(resultPath); } void CCopyDialog::OnOK() { + Save_OpenOutputFolder(OpenOutputFolder); + Save_Close7Zip(Close7Zip); + _path.GetText(Value); CModalDialog::OnOK(); } + +void CCopyDialog::OnButtonOpenPath() +{ + UString currentPath; + _path.GetText(currentPath); + + if (NFile::NFind::DoesDirExist_FollowLink(us2fs(currentPath))) + { + StartApplicationDontWait(currentPath, currentPath, *this); + } + else + { + const UString msg = MyFormatNew( + L"Folder \"{0}\" is not available yet.\n\n" + L"Note: the program will create the folder automatically when extracting.", + currentPath); + MessageBoxW(*this, msg, L"7-Zip", MB_ICONEXCLAMATION); + } +} + +void CCopyDialog::OnButtonAddFileName() +{ + UString currentPath; + _path.GetText(currentPath); + + currentPath.Trim(); + if (currentPath.Back() == '\\') + { + currentPath.DeleteBack(); + } + + UString strLastDir; + int n = currentPath.ReverseFind(L'\\'); + if (n != -1) + { + strLastDir = currentPath.Ptr(n+1); + } + else + { + strLastDir = currentPath; + } + if (strLastDir != RealFileName) + { + currentPath += L'\\'; + currentPath += RealFileName; + + _path.SetText(currentPath); + } + _path.SetFocus(); +} + +void CCopyDialog::ShowPathFreeSpace(UString & strPath) +{ + UString strText; + FormatPathFreeSpace(strPath, strText); + _freeSpace.SetText(strText); +} + +bool CCopyDialog::OnCommand(unsigned code, unsigned itemID, LPARAM lParam) +{ + if (itemID == IDC_COPY) + { + if (code == CBN_EDITCHANGE) + { + UString strPath; + _path.GetText(strPath); + + ShowPathFreeSpace(strPath); + return true; + } + else if (code == CBN_SELCHANGE) + { + int nSel = _path.GetCurSel(); + if (nSel != CB_ERR) + { + UString strPath; + _path.GetLBText(nSel, strPath); + ShowPathFreeSpace(strPath); + } + return true; + } + } + return CModalDialog::OnCommand(code, itemID, lParam); +} diff --git a/CPP/7zip/UI/FileManager/CopyDialog.h b/CPP/7zip/UI/FileManager/CopyDialog.h index 378242085..4d0d5bdd9 100644 --- a/CPP/7zip/UI/FileManager/CopyDialog.h +++ b/CPP/7zip/UI/FileManager/CopyDialog.h @@ -5,6 +5,7 @@ #include "../../../Windows/Control/ComboBox.h" #include "../../../Windows/Control/Dialog.h" +#include "../../../Windows/Control/Static.h" #include "CopyDialogRes.h" @@ -13,18 +14,34 @@ const int kCopyDialog_NumInfoLines = 11; class CCopyDialog: public NWindows::NControl::CModalDialog { NWindows::NControl::CComboBox _path; + NWindows::NControl::CStatic _freeSpace; virtual void OnOK() Z7_override; virtual bool OnInit() Z7_override; virtual bool OnSize(WPARAM wParam, int xSize, int ySize) Z7_override; virtual bool OnButtonClicked(unsigned buttonID, HWND buttonHWND) Z7_override; void OnButtonSetPath(); + void OnButtonOpenPath(); + void OnButtonAddFileName(); + bool OnCommand(unsigned code, unsigned itemID, LPARAM lParam) Z7_override; + + void ShowPathFreeSpace(UString & strPath); + public: + CCopyDialog(): OpenOutputFolder(false), DeleteSourceFile(false), Close7Zip(false) {} + UString Title; UString Static; UString Value; UString Info; UStringVector Strings; + bool OpenOutputFolder; + bool DeleteSourceFile; + bool Close7Zip; + + UString CurrentFolderPrefix; + UString RealFileName; + INT_PTR Create(HWND parentWindow = NULL) { return CModalDialog::Create(IDD_COPY, parentWindow); } }; diff --git a/CPP/7zip/UI/FileManager/CopyDialog.rc b/CPP/7zip/UI/FileManager/CopyDialog.rc index 73d3ea80d..f0026085b 100644 --- a/CPP/7zip/UI/FileManager/CopyDialog.rc +++ b/CPP/7zip/UI/FileManager/CopyDialog.rc @@ -1,18 +1,54 @@ #include "CopyDialogRes.h" #include "../../GuiCommon.rc" -#define xc 320 -#define yc 144 +#define xc 340 +#define yc 190 -#define y 40 +#define y 78 + +#define OPEN_XS 28 +#define FILENAME_XS 40 +#define SPACE_XS 4 + +#define FILENAME_X (xs - m - FILENAME_XS) +#define OPEN_X (FILENAME_X - OPEN_XS - SPACE_XS) +#define DOTS_X (OPEN_X - bxsDots - SPACE_XS) +#define PATH_Y (m + 12) +#define PATH_XS (DOTS_X - m - SPACE_XS) + +#define FREE_SPACE_Y (PATH_Y + 15) + +#define AFTER_EXTRACTION_Y (FREE_SPACE_Y + 12) + +#define OPTION_SPACE 10 + +#define OPEN_OUTPUT_FOLDER_X (m + 6) +#define OPEN_OUTPUT_FOLDER_XS 80 +#define OPEN_OUTPUT_FOLDER_Y (AFTER_EXTRACTION_Y + 12) + +#define DELETE_SOURCE_X (OPEN_OUTPUT_FOLDER_X + OPEN_OUTPUT_FOLDER_XS + OPTION_SPACE) +#define DELETE_SOURCE_XS 88 + +#define CLOSE_7ZIP_X (DELETE_SOURCE_X + DELETE_SOURCE_XS + OPTION_SPACE) +#define CLOSE_7ZIP_XS 54 + +#define INFO_Y (AFTER_EXTRACTION_Y + 27 + 4) +#define INFO_YS (by - m - 12 - 15 - 12 - 27 - 4 - 1) IDD_COPY DIALOG 0, 0, xs, ys MY_MODAL_RESIZE_DIALOG_STYLE MY_FONT CAPTION "Copy" { - LTEXT "", IDT_COPY, m, m, xc, 8 - COMBOBOX IDC_COPY, m, 20, xc - bxsDots - m, 65, MY_COMBO_WITH_EDIT - PUSHBUTTON "...", IDB_COPY_SET_PATH, xs - m - bxsDots, 18, bxsDots, bys, WS_GROUP - LTEXT "", IDT_COPY_INFO, m, y, xc, by - y - 1, SS_NOPREFIX | SS_LEFTNOWORDWRAP + LTEXT "", IDT_COPY, m, m, xc, 9 + COMBOBOX IDC_COPY, m, PATH_Y, PATH_XS, 160, MY_COMBO_WITH_EDIT + PUSHBUTTON "...", IDB_COPY_SET_PATH, DOTS_X, PATH_Y - 1, bxsDots, bys - 1, WS_GROUP + PUSHBUTTON "&Open", IDC_COPY_OPEN_PATH, OPEN_X, PATH_Y - 1, OPEN_XS, bys - 1, WS_GROUP + PUSHBUTTON "&Filename", IDC_COPY_ADD_FILE_NAME, FILENAME_X, PATH_Y - 1, FILENAME_XS, bys - 1, WS_GROUP + LTEXT "", IDC_FREE_SPACE, m, FREE_SPACE_Y, xc, 9 + GROUPBOX "After extraction completes successfully", IDC_AFTER_EXTRACT, m, AFTER_EXTRACTION_Y, xc, 27 + CONTROL "O&pen output folder", IDC_CHECK_OPEN_OUTPUT_FOLDER, MY_CHECKBOX, OPEN_OUTPUT_FOLDER_X, OPEN_OUTPUT_FOLDER_Y, OPEN_OUTPUT_FOLDER_XS, 10 + CONTROL "&Delete source archive", IDC_CHECK_DELETE_SOURCE_FILE, MY_CHECKBOX, DELETE_SOURCE_X, OPEN_OUTPUT_FOLDER_Y, DELETE_SOURCE_XS, 10 + CONTROL "&Close 7-Zip", IDC_CHECK_CLOSE_7ZIP, MY_CHECKBOX, CLOSE_7ZIP_X, OPEN_OUTPUT_FOLDER_Y, CLOSE_7ZIP_XS, 10 + LTEXT "", IDT_COPY_INFO, m, INFO_Y, xc, INFO_YS, SS_NOPREFIX | SS_LEFTNOWORDWRAP OK_CANCEL } diff --git a/CPP/7zip/UI/FileManager/CopyDialogRes.h b/CPP/7zip/UI/FileManager/CopyDialogRes.h index 85f5a39a4..7c47283c3 100644 --- a/CPP/7zip/UI/FileManager/CopyDialogRes.h +++ b/CPP/7zip/UI/FileManager/CopyDialogRes.h @@ -5,4 +5,12 @@ #define IDB_COPY_SET_PATH 102 #define IDT_COPY_INFO 103 +#define IDC_CHECK_OPEN_OUTPUT_FOLDER 104 +#define IDC_COPY_OPEN_PATH 105 +#define IDC_FREE_SPACE 106 +#define IDC_COPY_ADD_FILE_NAME 107 +#define IDC_CHECK_DELETE_SOURCE_FILE 108 +#define IDC_CHECK_CLOSE_7ZIP 109 +#define IDC_AFTER_EXTRACT 110 + #define IDS_SET_FOLDER 6007 diff --git a/CPP/7zip/UI/FileManager/ListViewDialog.cpp b/CPP/7zip/UI/FileManager/ListViewDialog.cpp index 6767e4c0c..748e4d45a 100644 --- a/CPP/7zip/UI/FileManager/ListViewDialog.cpp +++ b/CPP/7zip/UI/FileManager/ListViewDialog.cpp @@ -126,6 +126,8 @@ bool CListViewDialog::OnInit() _listView.SetColumnWidthAuto(1); StringsWereChanged = false; + Set_MinTrackSize_FromCurrent(3, 4, 3, 4); + NormalizeSize(); return CModalDialog::OnInit(); } @@ -146,15 +148,14 @@ bool CListViewDialog::OnSize(WPARAM /* wParam */, int xSize, int ySize) rect.top = y - my; InvalidateRect(&rect); */ - InvalidateRect(NULL); - - MoveItem(IDCANCEL, x, y, bx1, by); - MoveItem(IDOK, x - mx - bx2, y, bx2, by); + MoveItem(IDCANCEL, x, y, bx1, by, false); + MoveItem(IDOK, x - mx - bx2, y, bx2, by, false); /* if (wParam == SIZE_MAXSHOW || wParam == SIZE_MAXIMIZED || wParam == SIZE_MAXHIDE) mx = 0; */ - _listView.Move(mx, my, xSize - mx * 2, y - my * 2); + _listView.Move(mx, my, xSize - mx * 2, y - my * 2, false); + InvalidateRect(NULL); return false; } @@ -319,3 +320,4 @@ void CListViewDialog::OnOK() FocusedItemIndex = _listView.GetFocusedItem(); CModalDialog::OnOK(); } + diff --git a/CPP/7zip/UI/FileManager/MessagesDialog.cpp b/CPP/7zip/UI/FileManager/MessagesDialog.cpp index 57e56bcf7..06a01f707 100644 --- a/CPP/7zip/UI/FileManager/MessagesDialog.cpp +++ b/CPP/7zip/UI/FileManager/MessagesDialog.cpp @@ -55,6 +55,9 @@ bool CMessagesDialog::OnInit() _messageList.SetColumnWidthAuto(0); _messageList.SetColumnWidthAuto(1); + + Set_MinTrackSize_FromCurrent(3, 4, 3, 4); + NormalizeSize(); return CModalDialog::OnInit(); } @@ -68,9 +71,10 @@ bool CMessagesDialog::OnSize(WPARAM /* wParam */, int xSize, int ySize) int y = ySize - my - by; int x = xSize - mx - bx; - InvalidateRect(NULL); - MoveItem(IDOK, x, y, bx, by); - _messageList.Move(mx, my, xSize - mx * 2, y - my * 2); + MoveItem(IDOK, x, y, bx, by, false); + _messageList.Move(mx, my, xSize - mx * 2, y - my * 2, false); + InvalidateRect(NULL); return false; } + diff --git a/CPP/7zip/UI/FileManager/MessagesDialog.h b/CPP/7zip/UI/FileManager/MessagesDialog.h index 40b0379bf..62297a369 100644 --- a/CPP/7zip/UI/FileManager/MessagesDialog.h +++ b/CPP/7zip/UI/FileManager/MessagesDialog.h @@ -18,7 +18,7 @@ class CMessagesDialog: public NWindows::NControl::CModalDialog virtual bool OnSize(WPARAM wParam, int xSize, int ySize) Z7_override; public: const UStringVector *Messages; - + INT_PTR Create(HWND parent = NULL) { return CModalDialog::Create(IDD_MESSAGES, parent); } }; diff --git a/CPP/7zip/UI/FileManager/Panel.h b/CPP/7zip/UI/FileManager/Panel.h index b2432597f..43dbfd0ac 100644 --- a/CPP/7zip/UI/FileManager/Panel.h +++ b/CPP/7zip/UI/FileManager/Panel.h @@ -210,6 +210,7 @@ enum MyMessages }; UString GetFolderPath(IFolderFolder *folder); +void StartApplicationDontWait(const UString &dir, const UString &path, HWND window); class CPanel; diff --git a/CPP/7zip/UI/FileManager/PanelSplitFile.cpp b/CPP/7zip/UI/FileManager/PanelSplitFile.cpp index c452d41c1..3fa9aa8f0 100644 --- a/CPP/7zip/UI/FileManager/PanelSplitFile.cpp +++ b/CPP/7zip/UI/FileManager/PanelSplitFile.cpp @@ -493,7 +493,10 @@ void CApp::Combine() AddInfoFileName(info, L"..."); AddInfoFileName(info, fs2us(combiner.Names.Back())); } - + + bool openOutputFolder = false; + bool deleteSourceFile = false; + bool close7Zip = false; { CCopyDialog copyDialog; copyDialog.Value = path; @@ -502,9 +505,13 @@ void CApp::Combine() copyDialog.Title += srcPanel.GetItemRelPath(index); LangString(IDS_COMBINE_TO, copyDialog.Static); copyDialog.Info = info; + copyDialog.CurrentFolderPrefix = srcPanel.GetItemFullPath(index); if (copyDialog.Create(srcPanel.GetParent()) != IDOK) return; path = copyDialog.Value; + openOutputFolder = copyDialog.OpenOutputFolder; + deleteSourceFile = copyDialog.DeleteSourceFile; + close7Zip = copyDialog.Close7Zip; } NName::NormalizeDirPathPrefix(path); @@ -552,6 +559,20 @@ void CApp::Combine() if (combiner.Create(title, _window) != 0) return; + + if (openOutputFolder && NFind::DoesDirExist_FollowLink(us2fs(path))) + { + StartApplicationDontWait(path, path, _window); + } + if (deleteSourceFile) + { + for (i = 0; i < combiner.Names.Size(); i++) + NDir::DeleteFileIfArchive(us2fs(srcPath) + combiner.Names[i]); + } + if (close7Zip) + { + PostMessage(_window, WM_CLOSE, 0, 0); + } } RefreshTitleAlways(); diff --git a/CPP/7zip/UI/FileManager/ProgressDialog2.cpp b/CPP/7zip/UI/FileManager/ProgressDialog2.cpp index a070a0a37..7296105cb 100644 --- a/CPP/7zip/UI/FileManager/ProgressDialog2.cpp +++ b/CPP/7zip/UI/FileManager/ProgressDialog2.cpp @@ -13,17 +13,50 @@ #include "../../../Windows/ErrorMsg.h" #include "../GUI/ExtractRes.h" +#include "resourceGui.h" #include "LangUtils.h" #include "DialogSize.h" #include "ProgressDialog2.h" #include "ProgressDialog2Res.h" +#include "ProgressDialog2IconRes.h" using namespace NWindows; extern HINSTANCE g_hInstance; extern bool g_DisableUserQuestions; +// Set true by CProgressDialog when error messages occur. +bool g_bProcessError = false; + +#define WM_TRAY_ICON_NOTIFY (WM_APP + 10) +#define ID_SYSTRAY_ICON 100 + +static BOOL SetSysTray(HWND dlg, + DWORD message, + UINT id, + UINT flags, + UINT callbackMessage, + HICON icon, + const wchar_t *tip) +{ + NOTIFYICONDATAW data; + ZeroMemory(&data, sizeof(NOTIFYICONDATAW)); + + data.cbSize = sizeof(NOTIFYICONDATAW); + data.hWnd = dlg; + data.uID = id; + data.uFlags = flags; + data.uCallbackMessage = callbackMessage; + data.hIcon = icon; + + if (tip != NULL && *tip != 0) + { + ::lstrcpynW(data.szTip, tip, sizeof(data.szTip) / sizeof(WCHAR)); + } + + return Shell_NotifyIconW(message, &data); +} static const UINT_PTR kTimerID = 3; @@ -270,6 +303,10 @@ CProgressDialog::CProgressDialog(): IconID(-1), MainWindow(NULL) { + for (int i = 0; i < kNumTrayIcons; i++) + _iconSysTrayArray[i] = NULL; + _sysTrayIconArrayId = -1; + _sysTrayMenu = NULL; if (_dialogCreatedEvent.Create() != S_OK) throw 1334987; @@ -389,6 +426,7 @@ bool CProgressDialog::OnInit() LangString(IDS_PROGRESS_FOREGROUND, _foreground_String); LangString(IDS_CONTINUE, _continue_String); LangString(IDS_PROGRESS_PAUSED, _paused_String); + LangString(IDS_CANCEL, cancelString); SetText(_title); SetPauseText(); @@ -428,6 +466,8 @@ bool CProgressDialog::OnInit() SetTaskbarProgressState(); + Set_MinTrackSize_FromCurrent(2, 3, 3, 4); + return CModalDialog::OnInit(); } @@ -476,7 +516,13 @@ bool CProgressDialog::OnSize(WPARAM /* wParam */, int xSize, int ySize) int yPos = ySize - my - _buttonSizeY; ChangeSubWindowSizeX(GetItem(IDT_PROGRESS_STATUS), xSize - mx * 2); - ChangeSubWindowSizeX(GetItem(IDT_PROGRESS_FILE_NAME), xSize - mx * 2); + { + RECT rect; + GetClientRectOfItem(IDC_PROGRESS_PERCENT, rect); + int percent_width = rect.right - rect.left; + MoveItem(IDC_PROGRESS_PERCENT, xSize - mx - percent_width, rect.top, percent_width, rect.bottom - rect.top); + ChangeSubWindowSizeX(GetItem(IDT_PROGRESS_FILE_NAME), xSize - (mx * 2) - percent_width); + } ChangeSubWindowSizeX(GetItem(IDC_PROGRESS1), xSize - mx * 2); int bSizeX = _buttonSizeX; @@ -841,9 +887,18 @@ void CProgressDialog::UpdateStatInfo(bool showAll) { _prevPercentValue = percent; needSetTitle = true; + + wchar_t szPercent[32]; + wchar_t *p = ConvertUInt64ToString(percent, szPercent); + *p++ = L'%'; + *p = 0; + SetItemText(IDC_PROGRESS_PERCENT, szPercent); + + if (_background && _iconSysTrayArray[0] != NULL) + UpdateSysTrayIcon(false, true); } } - + { wchar_t s[64]; @@ -1051,6 +1106,9 @@ bool CProgressDialog::OnMessage(UINT message, WPARAM wParam, LPARAM lParam) { switch (message) { + case WM_TRAY_ICON_NOTIFY: + return OnTrayNotification(lParam); + case kCloseMessage: { if (_timer) @@ -1067,6 +1125,25 @@ bool CProgressDialog::OnMessage(UINT message, WPARAM wParam, LPARAM lParam) _externalCloseMessageWasReceived = true; break; } + if (_background) + { + SetSysTray(_window, NIM_DELETE, ID_SYSTRAY_ICON, 0, 0, NULL, NULL); + if (MainWindow != 0) + ShowWindow(MainWindow, SW_SHOW); + } + if (_iconSysTrayArray[0] != NULL) + { + for (int i = 0; i < kNumTrayIcons; i++) + { + DestroyIcon(_iconSysTrayArray[i]); + _iconSysTrayArray[i] = NULL; + } + } + if (_sysTrayMenu != NULL) + { + ::DestroyMenu(_sysTrayMenu); + _sysTrayMenu = NULL; + } return OnExternalCloseMessage(); } /* @@ -1123,8 +1200,12 @@ void CProgressDialog::SetTitleText() void CProgressDialog::SetPauseText() { - SetItemText(IDB_PAUSE, Sync.Get_Paused() ? _continue_String : _pause_String); + LPCWSTR pszText = Sync.Get_Paused() ? _continue_String : _pause_String; + SetItemText(IDB_PAUSE, pszText); SetTitleText(); + + if (_sysTrayMenu != NULL) + ModifyMenuW(_sysTrayMenu, IDB_PAUSE, MF_BYCOMMAND, IDB_PAUSE, pszText); } void CProgressDialog::OnPauseButton() @@ -1152,6 +1233,26 @@ void CProgressDialog::OnPriorityButton() _background = !_background; #ifndef UNDER_CE SetPriorityClass(GetCurrentProcess(), _background ? IDLE_PRIORITY_CLASS : NORMAL_PRIORITY_CLASS); + if (!_background) // foreground + { + if (_iconSysTrayArray[0] != NULL) + { + if (MainWindow != 0) + ShowWindow(MainWindow, SW_SHOW); + Show(SW_SHOW); + SetSysTray(_window, NIM_DELETE, ID_SYSTRAY_ICON, 0, 0, NULL, NULL); + } + } + else + { + if (LoadSysTrayIcons()) + { + if (MainWindow != 0) + ShowWindow(MainWindow, SW_HIDE); + Show(SW_HIDE); + UpdateSysTrayIcon(true, true); + } + } #endif SetPriorityText(); } @@ -1215,6 +1316,8 @@ void CProgressDialog::UpdateMessagesDialog() } if (!messages.IsEmpty()) { + g_bProcessError = true; + FOR_VECTOR (i, messages) AddMessage(messages[i]); // SetColumnWidthAuto() can be slow for big number of files. @@ -1396,6 +1499,82 @@ void CProgressDialog::CopyToClipboard() } +bool CProgressDialog::LoadSysTrayIcons() +{ + if (_iconSysTrayArray[0] != NULL) return true; + + int id = IDI_SYSTRAY_0; + for (int n = 0; n < kNumTrayIcons; n++, id++) + { + _iconSysTrayArray[n] = (HICON)LoadImage(g_hInstance, MAKEINTRESOURCE(id), IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR); + } + + return _iconSysTrayArray[0] != NULL; +} + +void CProgressDialog::UpdateSysTrayIcon(bool addIcon, bool updateTip) +{ + int newIconId = (_prevPercentValue / kTrayPercentPerIcon) % kNumTrayIcons; + bool updateIcon = newIconId > _sysTrayIconArrayId; + + if (updateIcon || updateTip || addIcon) + { + wchar_t tip[64]; + wchar_t *p = ConvertUInt64ToString(_prevPercentValue, tip); + *p++ = L'%'; + *p = 0; + + UINT flags = NIF_TIP; + if (updateIcon) + flags |= NIF_ICON; + + if (!SetSysTray(_window, NIM_MODIFY, ID_SYSTRAY_ICON, flags, 0, _iconSysTrayArray[newIconId], tip)) + { + SetSysTray(_window, NIM_DELETE, ID_SYSTRAY_ICON, 0, 0, NULL, NULL); + SetSysTray(_window, NIM_ADD, ID_SYSTRAY_ICON, NIF_ICON | NIF_MESSAGE | NIF_TIP, WM_TRAY_ICON_NOTIFY, + _iconSysTrayArray[newIconId], tip); + } + + _sysTrayIconArrayId = newIconId; + } +} + +bool CProgressDialog::CreateSysTrayMenu() +{ + if (_sysTrayMenu != NULL) return true; + + _sysTrayMenu = CreatePopupMenu(); + AppendMenuW(_sysTrayMenu, MF_STRING, IDB_PROGRESS_BACKGROUND, _foreground_String); + AppendMenuW(_sysTrayMenu, MF_STRING, IDB_PAUSE, Sync.Get_Paused() ? _continue_String : _pause_String); + AppendMenuW(_sysTrayMenu, MF_STRING, IDCANCEL, cancelString); + return _sysTrayMenu != NULL; +} + +bool CProgressDialog::OnTrayNotification(LPARAM lParam) +{ + switch (lParam) + { + case WM_RBUTTONUP: + if (CreateSysTrayMenu()) + { + POINT point; + ::GetCursorPos(&point); + ::TrackPopupMenu(_sysTrayMenu, TPM_LEFTALIGN | TPM_LEFTBUTTON | TPM_RIGHTBUTTON, point.x, point.y, 0, _window, NULL); + // BUGFIX: see "PRB: Menus for Notification Icons Don't Work Correctly" + ::PostMessage(_window, WM_NULL, 0, 0); + } + break; + + case WM_LBUTTONUP: + OnPriorityButton(); + break; + + default: + break; + } + return false; +} + static THREAD_FUNC_DECL MyThreadFunction(void *param) { CProgressThreadVirt *p = (CProgressThreadVirt *)param; diff --git a/CPP/7zip/UI/FileManager/ProgressDialog2.h b/CPP/7zip/UI/FileManager/ProgressDialog2.h index 60a5ca62a..481c50ca7 100644 --- a/CPP/7zip/UI/FileManager/ProgressDialog2.h +++ b/CPP/7zip/UI/FileManager/ProgressDialog2.h @@ -135,6 +135,7 @@ class CProgressDialog: public NWindows::NControl::CModalDialog UString _pause_String; UString _continue_String; UString _paused_String; + UString cancelString; int _buttonSizeX; int _buttonSizeY; @@ -143,6 +144,12 @@ class CProgressDialog: public NWindows::NControl::CModalDialog UString _title; + static const int kNumTrayIcons = 15; + static const int kTrayPercentPerIcon = 7; + HICON _iconSysTrayArray[kNumTrayIcons]; + int _sysTrayIconArrayId; + HMENU _sysTrayMenu; + class CU64ToI32Converter { unsigned _numShiftBits; @@ -230,6 +237,7 @@ class CProgressDialog: public NWindows::NControl::CModalDialog void OnPriorityButton(); bool OnButtonClicked(unsigned buttonID, HWND buttonHWND) Z7_override; bool OnMessage(UINT message, WPARAM wParam, LPARAM lParam) Z7_override; + bool OnTrayNotification(LPARAM lParam); void SetTitleText(); void ShowSize(unsigned id, UInt64 val, UInt64 &prev); @@ -265,6 +273,9 @@ class CProgressDialog: public NWindows::NControl::CModalDialog INT_PTR Create(const UString &title, NWindows::CThread &thread, HWND wndParent = NULL); + bool CreateSysTrayMenu(); + bool LoadSysTrayIcons(); + void UpdateSysTrayIcon(bool addIcon, bool updateTip); /* how it works: 1) the working thread calls ProcessWasFinished() diff --git a/CPP/7zip/UI/FileManager/ProgressDialog2.rc b/CPP/7zip/UI/FileManager/ProgressDialog2.rc index 4d0e0c7bf..f17a5dd73 100644 --- a/CPP/7zip/UI/FileManager/ProgressDialog2.rc +++ b/CPP/7zip/UI/FileManager/ProgressDialog2.rc @@ -1,6 +1,8 @@ #include "ProgressDialog2Res.h" #include "../../GuiCommon.rc" +#include "ProgressDialog2Icon.rc" + #undef DIALOG_ID #define DIALOG_ID IDD_PROGRESS #define xc 360 @@ -37,4 +39,5 @@ STRINGTABLE DISCARDABLE IDS_CONTINUE "&Continue" IDS_PROGRESS_ASK_CANCEL "Are you sure you want to cancel?" IDS_CLOSE "&Close" + IDS_CANCEL "&Cancel" } diff --git a/CPP/7zip/UI/FileManager/ProgressDialog2Icon.rc b/CPP/7zip/UI/FileManager/ProgressDialog2Icon.rc new file mode 100644 index 000000000..257220b1e --- /dev/null +++ b/CPP/7zip/UI/FileManager/ProgressDialog2Icon.rc @@ -0,0 +1,19 @@ +#include "ProgressDialog2IconRes.h" + +IDI_SYSTRAY_0 ICON "../../UI/FileManager/trayico/tray00.ico" +IDI_SYSTRAY_1 ICON "../../UI/FileManager/trayico/tray01.ico" +IDI_SYSTRAY_2 ICON "../../UI/FileManager/trayico/tray02.ico" +IDI_SYSTRAY_3 ICON "../../UI/FileManager/trayico/tray03.ico" +IDI_SYSTRAY_4 ICON "../../UI/FileManager/trayico/tray04.ico" +IDI_SYSTRAY_5 ICON "../../UI/FileManager/trayico/tray05.ico" +IDI_SYSTRAY_6 ICON "../../UI/FileManager/trayico/tray06.ico" +IDI_SYSTRAY_7 ICON "../../UI/FileManager/trayico/tray07.ico" +IDI_SYSTRAY_8 ICON "../../UI/FileManager/trayico/tray08.ico" +IDI_SYSTRAY_9 ICON "../../UI/FileManager/trayico/tray09.ico" +IDI_SYSTRAY_10 ICON "../../UI/FileManager/trayico/tray10.ico" +IDI_SYSTRAY_11 ICON "../../UI/FileManager/trayico/tray11.ico" +IDI_SYSTRAY_12 ICON "../../UI/FileManager/trayico/tray12.ico" +IDI_SYSTRAY_13 ICON "../../UI/FileManager/trayico/tray13.ico" +IDI_SYSTRAY_14 ICON "../../UI/FileManager/trayico/tray14.ico" +//IDI_SYSTRAY_15 ICON "../../UI/FileManager/trayico/tray15.ico" +//IDI_SYSTRAY_16 ICON "../../UI/FileManager/trayico/tray16.ico" diff --git a/CPP/7zip/UI/FileManager/ProgressDialog2IconRes.h b/CPP/7zip/UI/FileManager/ProgressDialog2IconRes.h new file mode 100644 index 000000000..80cd282be --- /dev/null +++ b/CPP/7zip/UI/FileManager/ProgressDialog2IconRes.h @@ -0,0 +1,17 @@ +#define IDI_SYSTRAY_0 310 +#define IDI_SYSTRAY_1 311 +#define IDI_SYSTRAY_2 312 +#define IDI_SYSTRAY_3 313 +#define IDI_SYSTRAY_4 314 +#define IDI_SYSTRAY_5 315 +#define IDI_SYSTRAY_6 316 +#define IDI_SYSTRAY_7 317 +#define IDI_SYSTRAY_8 318 +#define IDI_SYSTRAY_9 319 +#define IDI_SYSTRAY_10 320 +#define IDI_SYSTRAY_11 321 +#define IDI_SYSTRAY_12 322 +#define IDI_SYSTRAY_13 323 +#define IDI_SYSTRAY_14 324 +//#define IDI_SYSTRAY_15 325 +//#define IDI_SYSTRAY_16 326 diff --git a/CPP/7zip/UI/FileManager/ProgressDialog2Res.h b/CPP/7zip/UI/FileManager/ProgressDialog2Res.h index 736c7179a..fe5e23f13 100644 --- a/CPP/7zip/UI/FileManager/ProgressDialog2Res.h +++ b/CPP/7zip/UI/FileManager/ProgressDialog2Res.h @@ -3,6 +3,7 @@ #define IDS_CLOSE 408 #define IDS_CONTINUE 411 +#define IDS_CANCEL 415 #define IDB_PROGRESS_BACKGROUND 444 #define IDS_PROGRESS_FOREGROUND 445 @@ -25,6 +26,7 @@ #define IDL_PROGRESS_MESSAGES 101 #define IDT_PROGRESS_FILE_NAME 102 #define IDT_PROGRESS_STATUS 103 +#define IDC_PROGRESS_PERCENT 104 #define IDT_PROGRESS_PACKED_VAL 110 #define IDT_PROGRESS_FILES_VAL 111 diff --git a/CPP/7zip/UI/FileManager/ProgressDialog2a.rc b/CPP/7zip/UI/FileManager/ProgressDialog2a.rc index dc7d797ff..b3605c75b 100644 --- a/CPP/7zip/UI/FileManager/ProgressDialog2a.rc +++ b/CPP/7zip/UI/FileManager/ProgressDialog2a.rc @@ -39,6 +39,7 @@ #define yc (z0 + z0s + bys) +#define percent_width 23 DIALOG_ID DIALOG 0, 0, xs, ys MY_MODAL_RESIZE_DIALOG_STYLE MY_FONT CAPTION "Progress" @@ -75,7 +76,8 @@ CAPTION "Progress" RTEXT "", IDT_PROGRESS_RATIO_VAL, x3, y4, x3s, MY_TEXT_NOPREFIX LTEXT "", IDT_PROGRESS_STATUS, m, z3, xc, MY_TEXT_NOPREFIX - CONTROL "", IDT_PROGRESS_FILE_NAME, "Static", SS_NOPREFIX | SS_LEFTNOWORDWRAP, m, z2, xc, z2s + CONTROL "", IDT_PROGRESS_FILE_NAME, "Static", SS_NOPREFIX | SS_LEFTNOWORDWRAP, m, z2, xc - percent_width, z2s + RTEXT "", IDC_PROGRESS_PERCENT, m + xc - percent_width, z2, percent_width, z2s, SS_NOPREFIX | SS_CENTERIMAGE CONTROL "Progress1", IDC_PROGRESS1, "msctls_progress32", PBS_SMOOTH | WS_BORDER, m, z1, xc, z1s diff --git a/CPP/7zip/UI/FileManager/ViewSettings.cpp b/CPP/7zip/UI/FileManager/ViewSettings.cpp index bab209a02..5ca6f49d0 100644 --- a/CPP/7zip/UI/FileManager/ViewSettings.cpp +++ b/CPP/7zip/UI/FileManager/ViewSettings.cpp @@ -32,6 +32,9 @@ static LPCTSTR const kFolderHistoryValueName = TEXT("FolderHistory"); static LPCTSTR const kFastFoldersValueName = TEXT("FolderShortcuts"); static LPCTSTR const kCopyHistoryValueName = TEXT("CopyHistory"); +static LPCTSTR const kOpenOutputFolderValueName = TEXT("OpenOutputFolder"); +static LPCTSTR const kClose7ZipValueName = TEXT("Close7Zip"); + static NSynchronization::CCriticalSection g_CS; #define Set32(p, v) SetUi32(((Byte *)p), v) @@ -211,6 +214,21 @@ static bool ReadUi32Val(const TCHAR *name, UInt32 &value) return key.GetValue_UInt32_IfOk(name, value) == ERROR_SUCCESS; } +static void SaveBoolVal(const TCHAR *name, bool value) +{ + CKey key; + key.Create(HKEY_CURRENT_USER, kCUBasePath); + key.SetValue(name, value); +} + +static bool ReadBoolVal(const TCHAR *name, bool &value) +{ + CKey key; + if (key.Open(HKEY_CURRENT_USER, kCUBasePath, KEY_READ) != ERROR_SUCCESS) + return false; + return key.GetValue_bool_IfOk(name, value) == ERROR_SUCCESS; +} + void SaveToolbarsMask(UInt32 toolbarMask) { SaveUi32Val(kToolbars, toolbarMask); @@ -330,3 +348,29 @@ void AddUniqueStringToHeadOfList(UStringVector &list, const UString &s) i++; list.Insert(0, s); } + +void Save_OpenOutputFolder(bool open) +{ + SaveBoolVal(kOpenOutputFolderValueName, open); +} + +bool Read_OpenOutputFolder() +{ + bool b; + if (!ReadBoolVal(kOpenOutputFolderValueName, b)) + return false; + return b; +} + +void Save_Close7Zip(bool close7Zip) +{ + SaveBoolVal(kClose7ZipValueName, close7Zip); +} + +bool Read_Close7Zip() +{ + bool b; + if (!ReadBoolVal(kClose7ZipValueName, b)) + return false; + return b; +} diff --git a/CPP/7zip/UI/FileManager/ViewSettings.h b/CPP/7zip/UI/FileManager/ViewSettings.h index 02af0a155..b6c5dc87d 100644 --- a/CPP/7zip/UI/FileManager/ViewSettings.h +++ b/CPP/7zip/UI/FileManager/ViewSettings.h @@ -112,4 +112,10 @@ void ReadCopyHistory(UStringVector &folders); void AddUniqueStringToHeadOfList(UStringVector &list, const UString &s); +void Save_OpenOutputFolder(bool open); +bool Read_OpenOutputFolder(); + +void Save_Close7Zip(bool close7Zip); +bool Read_Close7Zip(); + #endif diff --git a/CPP/7zip/UI/FileManager/trayico/tray00.ico b/CPP/7zip/UI/FileManager/trayico/tray00.ico new file mode 100644 index 0000000000000000000000000000000000000000..8899fae6a031e40aa81a2be27a565bc1bd369584 GIT binary patch literal 318 zcmbu2F%E?=3`1S%@9o6=M~>N}^+>%zcuqk=Fp|`<<3y=c$kv*qpY|ecs2$k(gM#nq zSy%DQSkc$8_uO$sYK#FR6!{ck1xQ;iXH*(uKKV7rsM4(50E=h6F*-a~7ep2QEFl_4`X*TzPcY#B?1Y^_Q9=ql2Qx_~ENP?$S< z)>Z5oEBZ2f&mC8!#uzX{kxvm;fb_^^$3a8Pe}4SB{mKB$$_=o1)*nWPeMRo^k>_5? J`_6OsE#H``Pt5=T literal 0 HcmV?d00001 diff --git a/CPP/7zip/UI/FileManager/trayico/tray02.ico b/CPP/7zip/UI/FileManager/trayico/tray02.ico new file mode 100644 index 0000000000000000000000000000000000000000..0eb0d027edad036b7e6dd36ab3d42db95ad925ba GIT binary patch literal 318 zcmbu1u@%HH2t(z(>*FeQN_V%SNApPDfcwHpinIq75(py|veqi;qgJE?)qp1_D9jx_ z>niq)6@8h#=Z-5 LEBU%}-~E?=?fgw$ literal 0 HcmV?d00001 diff --git a/CPP/7zip/UI/FileManager/trayico/tray03.ico b/CPP/7zip/UI/FileManager/trayico/tray03.ico new file mode 100644 index 0000000000000000000000000000000000000000..7c6d19ff457e56fafcd8ff212ed9bab509463be2 GIT binary patch literal 318 zcmbu1u@QwZ3`3QF^rZSVN5z;KEhA+E^W*>pEp}wdmSd@qwN^=sjw1b02k>MAg}I|; zoyDFpqfN85+;K&!_YNZz`4nLVNRM2u`0aEN$yI=VP(^E}0 literal 0 HcmV?d00001 diff --git a/CPP/7zip/UI/FileManager/trayico/tray04.ico b/CPP/7zip/UI/FileManager/trayico/tray04.ico new file mode 100644 index 0000000000000000000000000000000000000000..42953770fd041c2aa9037d433370f3de28572735 GIT binary patch literal 318 zcmbu1u@!_c3_}$jJ*lX9ROxQTjFyquzXKd0Sa?R z&pL}eV@985@44fO)EEOsDDo-73XmSTJh7Y~+PHrC^*6it8v_6b>>j?zFQdc0BKP>n NbFbv*&U^P?z5y#FO2z;H literal 0 HcmV?d00001 diff --git a/CPP/7zip/UI/FileManager/trayico/tray05.ico b/CPP/7zip/UI/FileManager/trayico/tray05.ico new file mode 100644 index 0000000000000000000000000000000000000000..e0419234fd1b73bc851f34a44f27c0683178c637 GIT binary patch literal 318 zcmbu1F&2O@2t!k!yPceUP9C#I>yf+x{!n#r6&ex_5? K_nqhNU%mhkqDr3t literal 0 HcmV?d00001 diff --git a/CPP/7zip/UI/FileManager/trayico/tray06.ico b/CPP/7zip/UI/FileManager/trayico/tray06.ico new file mode 100644 index 0000000000000000000000000000000000000000..ab2035591252f6e5e1c254b53ee9633a0301e3e2 GIT binary patch literal 318 zcmbu1u@!_c3_}&(^`xS{mx_)RGg?Ms1M}qo#kFTgmTWne3R!EF^wD0V4YdPLzMwF7 z^sKYkGiLN@_MSVgNR2UIgd(3JtN`he%NpEp}wdmSd@qwN^<#?M2#9JMiQW3Uf!# zI*UDHMxSQyx#Nn|7z0Kq@+ra!kRG{Qv9#9ck2l}`ifMmk0N{Y#!w2~=I_xWQkB>a} LO1|#gcfaxpP8-s;AJh))d_lo? z^sK9RW~}II*n94{A~nW<5sG|@umYqlmn&YawIgEw@;%>JCgz3#;DFu3lYAH*o-1;X Ok39EEzV6(2|K$^{8%3A^ literal 0 HcmV?d00001 diff --git a/CPP/7zip/UI/FileManager/trayico/tray09.ico b/CPP/7zip/UI/FileManager/trayico/tray09.ico new file mode 100644 index 0000000000000000000000000000000000000000..5f9a865f7fb6bb0fdfc625ab73ec93eaa2805c15 GIT binary patch literal 318 zcmbu1I}(I23`3P2dQxr8P;ty0El0`?%##BYw8)Vqe`2W+wN^=sjw1bW2XtqHg}%`; z&*Ygo(dMwV+;PUL_l{x|`4nLX3Adas{B{sA-g?hhmcdwQKr~R-=pY`&hv$mi<0H?t LQm;Gr-LHBAlIKNn literal 0 HcmV?d00001 diff --git a/CPP/7zip/UI/FileManager/trayico/tray10.ico b/CPP/7zip/UI/FileManager/trayico/tray10.ico new file mode 100644 index 0000000000000000000000000000000000000000..8542a9b0a822564ca88351a8693f0a51a932598a GIT binary patch literal 318 zcmbu1I}(I23_}%Wds0y|ThVdF94$x64a}1R6x*&GS@I{A3Q=p7^wCkI4R=6yc39{e zE%QvCnGBjN}XN+Hc<}1r!tTZ4RsB3f(uj0dVMegyD N=US=vo#*bqdI9nILjeE) literal 0 HcmV?d00001 diff --git a/CPP/7zip/UI/FileManager/trayico/tray11.ico b/CPP/7zip/UI/FileManager/trayico/tray11.ico new file mode 100644 index 0000000000000000000000000000000000000000..c34cae78f87d5248d0748880a95c3dbdb6922a84 GIT binary patch literal 318 zcmbu1I}(I23`3P2dQxr8P;ty0El0`?%##BYw8)Vqe`2W+wN^=sjw1bW2XtqHg}%`; z&*Ygo(dMwV+;PUL_l{x|`4nLX3Adas{B|S8TkrYGG8iijhz9B!9mJ#f@LZ95eB`-S K>UHP7`&CcZ>_XZA literal 0 HcmV?d00001 diff --git a/CPP/7zip/UI/FileManager/trayico/tray12.ico b/CPP/7zip/UI/FileManager/trayico/tray12.ico new file mode 100644 index 0000000000000000000000000000000000000000..4105ed1f101a8200af3fd3785459ac48d32c89ee GIT binary patch literal 318 zcmbu1I}(I23_}%Wds0y|ThVdF94$x64a}1R6x*&GS@I{A3Q=p7^wCkI4R=6yc39{e zE%QvCnGBjOk&he|yd}SGol?Frub&U?pfpt24kfG(Li0JgLo7lo-1;Xk382( Kz3$w1zv>Aemq0@R literal 0 HcmV?d00001 diff --git a/CPP/7zip/UI/FileManager/trayico/tray14.ico b/CPP/7zip/UI/FileManager/trayico/tray14.ico new file mode 100644 index 0000000000000000000000000000000000000000..4788031d0a3edd6ba7827e20a6c2a664cf45de1f GIT binary patch literal 318 zcmbu1yAgme3_}%;o>bHv6=P+kyhLR-PvHFZ?w!K zd1el@F>Eb&oU!V?qZma#Mc6^YEvFmPp4h(n%omoyxzK=UpsvxAcoiR>D{_yIJl9IS J?>u+^>IH*|J<|XH literal 0 HcmV?d00001 diff --git a/CPP/7zip/UI/GUI/ExtractDialog.cpp b/CPP/7zip/UI/GUI/ExtractDialog.cpp index 5ccac5aa3..80beec020 100644 --- a/CPP/7zip/UI/GUI/ExtractDialog.cpp +++ b/CPP/7zip/UI/GUI/ExtractDialog.cpp @@ -5,6 +5,7 @@ #include "../../../Common/StringConvert.h" #include "../../../Common/Wildcard.h" +#include "../../../Windows/FileFind.h" #include "../../../Windows/FileName.h" #include "../../../Windows/FileDir.h" #include "../../../Windows/ResourceString.h" @@ -15,13 +16,18 @@ #include "../FileManager/BrowseDialog.h" +#include "../FileManager/FormatUtils.h" #include "../FileManager/LangUtils.h" #include "../FileManager/resourceGui.h" +#include "../FileManager/ViewSettings.h" + #include "ExtractDialog.h" #include "ExtractDialogRes.h" #include "ExtractRes.h" +extern void FormatPathFreeSpace(UString &strPath, UString &strText); + using namespace NWindows; using namespace NFile; using namespace NName; @@ -135,6 +141,21 @@ void CExtractDialog::GetButton_Bools(UINT id, CBoolPair &b1, CBoolPair &b2) #endif +static void StartApplication(const UString &dir, const UString &path) +{ + SHELLEXECUTEINFOW execInfo; + ZeroMemory(&execInfo, sizeof(execInfo)); + execInfo.cbSize = sizeof(execInfo); + execInfo.fMask = SEE_MASK_FLAG_DDEWAIT; + execInfo.hwnd = NULL; + execInfo.lpVerb = NULL; + execInfo.lpFile = path; + execInfo.lpParameters = NULL; + execInfo.lpDirectory = dir.IsEmpty() ? NULL : (LPCWSTR)dir; + execInfo.nShow = SW_SHOWNORMAL; + ShellExecuteExW(&execInfo); +} + bool CExtractDialog::OnInit() { #ifdef Z7_LANG @@ -161,6 +182,9 @@ bool CExtractDialog::OnInit() _pathName.Attach(GetItem(IDE_EXTRACT_NAME)); #endif + _freeSpace.Attach(GetItem(IDC_STATIC_EXTRACT_FREE_SPACE)); + _freeSpace.SetText(L""); + #ifdef Z7_NO_REGISTRY PathMode = NExtract::NPathMode::kFullPaths; @@ -210,6 +234,7 @@ bool CExtractDialog::OnInit() #endif _path.SetText(pathPrefix); + ShowPathFreeSpace(pathPrefix); #ifndef Z7_NO_REGISTRY for (unsigned i = 0; i < _info.Paths.Size() && i < kHistorySize; i++) @@ -261,6 +286,17 @@ bool CExtractDialog::OnButtonClicked(unsigned buttonID, HWND buttonHWND) case IDB_EXTRACT_SET_PATH: OnButtonSetPath(); return true; + + case IDC_EXTRACT_BUTTON_OPEN_PATH: + OnButtonOpenPath(); + return true; + +#ifndef Z7_SFX + case IDC_CHECK_DELETE_SOURCE_FILE: + DeleteSourceFile = IsButtonCheckedBool(IDC_CHECK_DELETE_SOURCE_FILE); + return true; +#endif + #ifndef Z7_SFX case IDX_EXTRACT_NAME_ENABLE: ShowItem_Bool(IDE_EXTRACT_NAME, IsButtonCheckedBool(IDX_EXTRACT_NAME_ENABLE)); @@ -287,6 +323,7 @@ void CExtractDialog::OnButtonSetPath() _path.SetCurSel(-1); #endif _path.SetText(resultPath); + ShowPathFreeSpace(resultPath); } void AddUniqueString(UStringVector &list, const UString &s); @@ -420,3 +457,62 @@ void CExtractDialog::OnHelp() CModalDialog::OnHelp(); } #endif + + +void CExtractDialog::OnButtonOpenPath() +{ + UString currentPath; + _path.GetText(currentPath); + + if (NFind::DoesDirExist_FollowLink(us2fs(currentPath))) + { + StartApplication(currentPath, currentPath); + } + else + { + const UString msg = MyFormatNew( + L"Folder \"{0}\" is not available yet.\n\n" + L"Note: the program will create the folder automatically when extracting.", + currentPath); + MessageBoxW(*this, msg, L"7-Zip", MB_ICONEXCLAMATION); + } +} + +void CExtractDialog::ShowPathFreeSpace(UString & strPath) +{ + UString strText; + FormatPathFreeSpace(strPath, strText); + _freeSpace.SetText(strText); +} + +bool CExtractDialog::OnCommand(unsigned code, unsigned itemID, LPARAM lParam) +{ + if (itemID == IDC_EXTRACT_PATH) + { +#ifdef Z7_NO_REGISTRY + if (code == EN_CHANGE) +#else + if (code == CBN_EDITCHANGE) +#endif + { + UString strPath; + _path.GetText(strPath); + ShowPathFreeSpace(strPath); + return true; + } +#ifndef Z7_NO_REGISTRY + else if (code == CBN_SELCHANGE) + { + int nSel = _path.GetCurSel(); + if (nSel != CB_ERR) + { + UString strPath; + _path.GetLBText(nSel, strPath); + ShowPathFreeSpace(strPath); + } + return true; + } +#endif + } + return CModalDialog::OnCommand(code, itemID, lParam); +} diff --git a/CPP/7zip/UI/GUI/ExtractDialog.h b/CPP/7zip/UI/GUI/ExtractDialog.h index 1a3676b89..31e978341 100644 --- a/CPP/7zip/UI/GUI/ExtractDialog.h +++ b/CPP/7zip/UI/GUI/ExtractDialog.h @@ -7,6 +7,7 @@ #include "../../../Windows/Control/ComboBox.h" #include "../../../Windows/Control/Edit.h" +#include "../../../Windows/Control/Static.h" #include "../Common/ExtractMode.h" @@ -45,12 +46,13 @@ class CExtractDialog: public NWindows::NControl::CModalDialog NWindows::NControl::CComboBox _pathMode; NWindows::NControl::CComboBox _overwriteMode; #endif + NWindows::NControl::CStatic _freeSpace; #ifndef Z7_SFX // int GetFilesMode() const; void UpdatePasswordControl(); #endif - + void OnButtonSetPath(); void CheckButton_TwoBools(UINT id, const CBoolPair &b1, const CBoolPair &b2); @@ -58,15 +60,18 @@ class CExtractDialog: public NWindows::NControl::CModalDialog virtual bool OnInit() Z7_override; virtual bool OnButtonClicked(unsigned buttonID, HWND buttonHWND) Z7_override; virtual void OnOK() Z7_override; - + void OnButtonOpenPath(); + virtual bool OnCommand(unsigned code, unsigned itemID, LPARAM lParam) Z7_override; + #ifndef Z7_NO_REGISTRY virtual void OnHelp() Z7_override; NExtract::CInfo _info; - + #endif - + + void ShowPathFreeSpace(UString & strPath); bool IsShowPasswordChecked() const { return IsButtonCheckedBool(IDX_PASSWORD_SHOW); } public: // bool _enableSelectedFilesButton; @@ -84,6 +89,8 @@ class CExtractDialog: public NWindows::NControl::CModalDialog NExtract::NPathMode::EEnum PathMode; NExtract::NOverwriteMode::EEnum OverwriteMode; + bool DeleteSourceFile; + #ifndef Z7_SFX // CBoolPair AltStreams; CBoolPair NtSecurity; @@ -104,7 +111,8 @@ class CExtractDialog: public NWindows::NControl::CModalDialog CExtractDialog(): PathMode_Force(false), - OverwriteMode_Force(false) + OverwriteMode_Force(false), + DeleteSourceFile(false) { ElimDup.Val = true; } diff --git a/CPP/7zip/UI/GUI/ExtractDialog.rc b/CPP/7zip/UI/GUI/ExtractDialog.rc index fab199f59..8dc3d3adf 100644 --- a/CPP/7zip/UI/GUI/ExtractDialog.rc +++ b/CPP/7zip/UI/GUI/ExtractDialog.rc @@ -2,7 +2,7 @@ #include "../../GuiCommon.rc" #define xc 336 -#define yc 168 +#define yc 200 #undef g1xs #undef g2x @@ -18,6 +18,13 @@ #define g2xs (xc - g1xs - gSpace) #define g2xs2 (g2xs - m - m) +#define bxsOpen 30 +#define xsSpace 4 + +#define FREE_SPACE_Y 58 +#define EXTRA_Y_TOP 42 +#define EXTRA_Y_BOTTOM 58 + #undef GROUP_Y_SIZE #ifdef UNDER_CE #define GROUP_Y_SIZE 8 @@ -29,33 +36,36 @@ IDD_EXTRACT DIALOG 0, 0, xs, ys MY_MODAL_DIALOG_STYLE MY_FONT CAPTION "Extract" BEGIN LTEXT "E&xtract to:", IDT_EXTRACT_EXTRACT_TO, m, m, xc, 8 - COMBOBOX IDC_EXTRACT_PATH, m, m + 12, xc - bxsDots - 12, 100, MY_COMBO_WITH_EDIT - PUSHBUTTON "...", IDB_EXTRACT_SET_PATH, xs - m - bxsDots, m + 12 - 2, bxsDots, bys, WS_GROUP + COMBOBOX IDC_EXTRACT_PATH, m, m + 12, xc - bxsDots - xsSpace - bxsOpen - xsSpace, 160, MY_COMBO_WITH_EDIT + PUSHBUTTON "...", IDB_EXTRACT_SET_PATH, xs - m - bxsDots - xsSpace - bxsOpen, m + 12 - 1, bxsDots, bys-1, WS_GROUP + PUSHBUTTON "&Open", IDC_EXTRACT_BUTTON_OPEN_PATH, xs - m - bxsOpen, m + 12 - 1, bxsOpen, bys-1, WS_GROUP CONTROL "", IDX_EXTRACT_NAME_ENABLE, MY_CHECKBOX, m, m + 34, 12, 10 - EDITTEXT IDE_EXTRACT_NAME, m + 12 + 2, m + 32, g1xs - 12 - 2, 14, ES_AUTOHSCROLL + EDITTEXT IDE_EXTRACT_NAME, m + 12 + 2, m + 32, xc - 12 - 2, 14, ES_AUTOHSCROLL - LTEXT "Path mode:", IDT_EXTRACT_PATH_MODE, m, m + 52, g1xs, 8 - COMBOBOX IDC_EXTRACT_PATH_MODE, m, m + 64, g1xs, 140, MY_COMBO + LTEXT "", IDC_STATIC_EXTRACT_FREE_SPACE, m, FREE_SPACE_Y, xc, 8 + GROUPBOX "After extraction completes successfully", IDC_GUI_AFTER_EXTRACT, m, FREE_SPACE_Y + 12, xc, 27 + CONTROL "O&pen target folder", IDX_EXTRACT_OPEN_TRG_FLD, MY_CHECKBOX, 14, FREE_SPACE_Y + 24, 100, 10 + CONTROL "&Delete source archives", IDC_CHECK_DELETE_SOURCE_FILE, MY_CHECKBOX, 125, FREE_SPACE_Y + 24, 120, 10 - CONTROL "Eliminate duplication of root folder", IDX_EXTRACT_ELIM_DUP, MY_CHECKBOX, - m, m + 84, g1xs, 10 + LTEXT "Path mode:", IDT_EXTRACT_PATH_MODE, m, m + 52 + EXTRA_Y_TOP, g1xs, 8 + COMBOBOX IDC_EXTRACT_PATH_MODE, m, m + 64 + EXTRA_Y_TOP, g1xs, 140, MY_COMBO - LTEXT "Overwrite mode:", IDT_EXTRACT_OVERWRITE_MODE, m, m + 104, g1xs, 8 - COMBOBOX IDC_EXTRACT_OVERWRITE_MODE, m, m + 116, g1xs, 140, MY_COMBO + CONTROL "Eliminate duplication of root folder", IDX_EXTRACT_ELIM_DUP, MY_CHECKBOX, + m, m + 84 + EXTRA_Y_TOP, g1xs, 10 - CONTROL "Open target folder", IDX_EXTRACT_OPEN_TRG_FLD, MY_CHECKBOX, - g2x, m + 34, g2xs, 10 + LTEXT "Overwrite mode:", IDT_EXTRACT_OVERWRITE_MODE, m, m + 104 + EXTRA_Y_TOP, g1xs, 8 + COMBOBOX IDC_EXTRACT_OVERWRITE_MODE, m, m + 116 + EXTRA_Y_TOP, g1xs, 140, MY_COMBO - GROUPBOX "Password", IDG_PASSWORD, g2x, m + 50, g2xs, GROUP_Y_SIZE - EDITTEXT IDE_EXTRACT_PASSWORD, g2x2, m + 64, g2xs2, 14, ES_PASSWORD | ES_AUTOHSCROLL - CONTROL "Show Password", IDX_PASSWORD_SHOW, MY_CHECKBOX, g2x2, m + 86, g2xs2, 10 + GROUPBOX "Password", IDG_PASSWORD, g2x, m + 36 + EXTRA_Y_BOTTOM, g2xs, GROUP_Y_SIZE + EDITTEXT IDE_EXTRACT_PASSWORD, g2x2, m + 50 + EXTRA_Y_BOTTOM, g2xs2, 14, ES_PASSWORD | ES_AUTOHSCROLL + CONTROL "Show Password", IDX_PASSWORD_SHOW, MY_CHECKBOX, g2x2, m + 72 + EXTRA_Y_BOTTOM, g2xs2, 10 // CONTROL "Restore alternate data streams", IDX_EXTRACT_ALT_STREAMS, MY_CHECKBOX, -// g2x, m + 114, g2xs, 10 +// g2x, m + 104, g2xs, 10 CONTROL "Restore file security", IDX_EXTRACT_NT_SECUR, MY_CHECKBOX, - g2x, m + 114, g2xs, 10 - + g2x, m + 100 + EXTRA_Y_BOTTOM, g2xs, 10 + DEFPUSHBUTTON "OK", IDOK, bx3, by, bxs, bys, WS_GROUP PUSHBUTTON "Cancel", IDCANCEL, bx2, by, bxs, bys PUSHBUTTON "Help", IDHELP, bx1, by, bxs, bys @@ -93,7 +103,7 @@ BEGIN LTEXT "Password", IDG_PASSWORD, m, m + 76, g1xs, 8 EDITTEXT IDE_EXTRACT_PASSWORD, m + g1xs, m + 76, xc - g1xs, 14, ES_PASSWORD | ES_AUTOHSCROLL CONTROL "Show Password", IDX_PASSWORD_SHOW, MY_CHECKBOX, m, m + 92, xc, 10 - + OK_CANCEL END diff --git a/CPP/7zip/UI/GUI/ExtractDialogRes.h b/CPP/7zip/UI/GUI/ExtractDialogRes.h index f77267d6d..5974ae2c3 100644 --- a/CPP/7zip/UI/GUI/ExtractDialogRes.h +++ b/CPP/7zip/UI/GUI/ExtractDialogRes.h @@ -8,6 +8,11 @@ #define IDX_EXTRACT_OPEN_TRG_FLD 104 +#define IDC_EXTRACT_BUTTON_OPEN_PATH 105 +#define IDC_STATIC_EXTRACT_FREE_SPACE 107 +#define IDC_CHECK_DELETE_SOURCE_FILE 108 +#define IDC_GUI_AFTER_EXTRACT 109 + #define IDE_EXTRACT_PASSWORD 120 #define IDE_EXTRACT_NAME 130 diff --git a/CPP/7zip/UI/GUI/ExtractGUI.cpp b/CPP/7zip/UI/GUI/ExtractGUI.cpp index 21e6c2c0c..644357150 100644 --- a/CPP/7zip/UI/GUI/ExtractGUI.cpp +++ b/CPP/7zip/UI/GUI/ExtractGUI.cpp @@ -34,6 +34,9 @@ using namespace NWindows; using namespace NFile; using namespace NDir; +// Error-state flag defined in ProgressDialog2.cpp; gates post-extract actions. +extern bool g_bProcessError; + static const wchar_t * const kIncorrectOutDir = L"Incorrect output directory path"; #ifndef Z7_SFX @@ -207,7 +210,10 @@ HRESULT ExtractGUI( CExtractCallbackImp *extractCallback, HWND hwndParent) { + bool deleteSourceFile = false; + messageWasDisplayed = false; + g_bProcessError = false; CThreadExtracting extracter; /* @@ -267,7 +273,9 @@ HRESULT ExtractGUI( options.OverwriteMode = dialog.OverwriteMode; options.PathMode = dialog.PathMode; options.ElimDup = dialog.ElimDup; - + + deleteSourceFile = dialog.DeleteSourceFile; + #ifndef Z7_SFX OpnTrgFold = dialog.OpnTrgFold.Val; // options.NtOptions.AltStreams = dialog.AltStreams; @@ -333,6 +341,12 @@ HRESULT ExtractGUI( RINOK(extracter.Create(title, hwndParent)) messageWasDisplayed = extracter.ThreadFinishedOK && extracter.MessagesDisplayed; + if (extracter.ThreadFinishedOK && !g_bProcessError && deleteSourceFile) + { + for (unsigned i = 0; i < archivePathsFull.Size(); i++) + DeleteFileIfArchive(us2fs(archivePathsFull[i])); + } + #ifndef Z7_SFX // browse/navigate to target path: if (OpnTrgFold && extracter.Result == S_OK) { diff --git a/CPP/Windows/Control/Dialog.cpp b/CPP/Windows/Control/Dialog.cpp index 5695ac577..e70d04568 100644 --- a/CPP/Windows/Control/Dialog.cpp +++ b/CPP/Windows/Control/Dialog.cpp @@ -97,6 +97,7 @@ bool CDialog::OnMessage(UINT message, WPARAM wParam, LPARAM lParam) case WM_NOTIFY: return OnNotify((UINT)wParam, (LPNMHDR) lParam); case WM_TIMER: return OnTimer(wParam, lParam); case WM_SIZE: return OnSize(wParam, LOWORD(lParam), HIWORD(lParam)); + case WM_GETMINMAXINFO: return OnGetMinMaxInfo((PMINMAXINFO)lParam); case WM_DESTROY: return OnDestroy(); case WM_HELP: OnHelp(); return true; /* @@ -141,6 +142,14 @@ bool CDialog::OnButtonClicked(unsigned buttonID, HWND /* buttonHWND */) return true; } +void CDialog::Set_MinTrackSize_FromCurrent(int numX, int denX, int numY, int denY) +{ + RECT rc; + GetWindowRect(&rc); + _minTrackSize.cx = RECT_SIZE_X(rc) * numX / denX; + _minTrackSize.cy = RECT_SIZE_Y(rc) * numY / denY; +} + #ifndef UNDER_CE /* in win2000/win98 : monitor functions are supported. We need dynamic linking, if we want nt4/win95 support in program. diff --git a/CPP/Windows/Control/Dialog.h b/CPP/Windows/Control/Dialog.h index 2510c8f15..46cefcf12 100644 --- a/CPP/Windows/Control/Dialog.h +++ b/CPP/Windows/Control/Dialog.h @@ -15,10 +15,14 @@ namespace NControl { class CDialog: public CWindow { // Z7_CLASS_NO_COPY(CDialog) +protected: + SIZE _minTrackSize; public: - CDialog(HWND wnd = NULL): CWindow(wnd) {} + CDialog(HWND wnd = NULL): CWindow(wnd) { _minTrackSize.cx = 0; _minTrackSize.cy = 0; } virtual ~CDialog() {} + void Set_MinTrackSize_FromCurrent(int numX, int denX, int numY, int denY); + HWND GetItem(unsigned itemID) const { return GetDlgItem(_window, (int)itemID); } @@ -129,6 +133,12 @@ class CDialog: public CWindow // virtual bool OnCommand2(WPARAM wParam, LPARAM lParam); virtual bool OnCommand(unsigned code, unsigned itemID, LPARAM lParam); virtual bool OnSize(WPARAM /* wParam */, int /* xSize */, int /* ySize */) { return false; } + virtual bool OnGetMinMaxInfo(PMINMAXINFO pMMI) + { + if (_minTrackSize.cx > 0) pMMI->ptMinTrackSize.x = _minTrackSize.cx; + if (_minTrackSize.cy > 0) pMMI->ptMinTrackSize.y = _minTrackSize.cy; + return false; + } virtual bool OnDestroy() { return false; } /* diff --git a/CPP/Windows/FileDir.cpp b/CPP/Windows/FileDir.cpp index ad0d8c9dd..50a75227c 100644 --- a/CPP/Windows/FileDir.cpp +++ b/CPP/Windows/FileDir.cpp @@ -602,6 +602,15 @@ bool DeleteFileAlways(CFSTR path) } +bool DeleteFileIfArchive(CFSTR path) +{ + const DWORD attrib = NFind::GetFileAttrib(path); + if (attrib == INVALID_FILE_ATTRIBUTES + || (attrib & FILE_ATTRIBUTE_ARCHIVE) == 0) + return false; + return DeleteFileAlways(path); +} + bool RemoveDirWithSubItems(const FString &path) { @@ -1131,6 +1140,12 @@ bool DeleteFileAlways(CFSTR path) return (remove(path) == 0); } +bool DeleteFileIfArchive(CFSTR path) +{ + // POSIX has no ARCHIVE attribute; treat all regular files as candidates. + return DeleteFileAlways(path); +} + bool SetCurrentDir(CFSTR path) { return (chdir(path) == 0); diff --git a/CPP/Windows/FileDir.h b/CPP/Windows/FileDir.h index 9ba98fcae..d2afa4397 100644 --- a/CPP/Windows/FileDir.h +++ b/CPP/Windows/FileDir.h @@ -88,6 +88,7 @@ bool CreateDir(CFSTR path); bool CreateComplexDir(CFSTR path); bool DeleteFileAlways(CFSTR name); +bool DeleteFileIfArchive(CFSTR path); bool RemoveDirWithSubItems(const FString &path); #ifdef _WIN32 bool RemoveDirAlways_if_Empty(const FString &path); From 6a14047987b88ced32ddd0856cc96576c01ffc69 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sergio=20At=C3=A1n?= <175652103+3V0S8N@users.noreply.github.com> Date: Fri, 15 May 2026 13:11:25 +0200 Subject: [PATCH 2/4] SQ easy SonarQube: trivial fixes (nullptr, in-class init, static const, explicit ctor) --- CPP/7zip/UI/FileManager/App.cpp | 57 +++++++++---------- CPP/7zip/UI/FileManager/CopyDialog.cpp | 62 +++++++++------------ CPP/7zip/UI/FileManager/CopyDialog.h | 8 +-- CPP/7zip/UI/FileManager/ProgressDialog2.cpp | 46 +++++++-------- CPP/7zip/UI/GUI/ExtractDialog.h | 10 ++-- CPP/Windows/Control/Dialog.h | 4 +- 6 files changed, 84 insertions(+), 103 deletions(-) diff --git a/CPP/7zip/UI/FileManager/App.cpp b/CPP/7zip/UI/FileManager/App.cpp index ffff69c39..f8624b4d2 100644 --- a/CPP/7zip/UI/FileManager/App.cpp +++ b/CPP/7zip/UI/FileManager/App.cpp @@ -45,6 +45,30 @@ extern bool g_bProcessError; #define kTempDirPrefix FTEXT("7zE") +// Walk up, delete found archive. +static void DeleteSourceArchive_WalkUp(CPanel &srcPanel, UString srcFilePath) +{ + while (!srcFilePath.IsEmpty()) + { + if (srcFilePath.Back() == L'\\') + srcFilePath.DeleteBack(); + const DWORD dwAttr = GetFileAttributesW(srcFilePath); + + if (dwAttr != INVALID_FILE_ATTRIBUTES) + { + if (dwAttr & FILE_ATTRIBUTE_ARCHIVE) + NDir::DeleteFileIfArchive(us2fs(srcFilePath)); + return; + } + + const int n = srcFilePath.ReverseFind(L'\\'); + if (n == -1) + return; + srcPanel.OpenParentFolder(); + srcFilePath.ReleaseBuf_SetEnd(n); + } +} + void CPanelCallbackImp::OnTab() { if (g_App.NumPanels != 1) @@ -938,38 +962,7 @@ void CApp::OnCopy(bool move, bool copyToSame, unsigned srcPanelIndex) { UString srcFilePath(srcPanel._currentFolderPrefix); srcPanel.OpenParentFolder(); - - while (!srcFilePath.IsEmpty()) - { - if (srcFilePath.Back() == '\\') - { - srcFilePath.DeleteBack(); - } - DWORD dwAttr = GetFileAttributesW(srcFilePath); - - if (dwAttr == INVALID_FILE_ATTRIBUTES) - { - int n = srcFilePath.ReverseFind(L'\\'); - if (n != -1) - { - srcPanel.OpenParentFolder(); - srcFilePath.ReleaseBuf_SetEnd(n); - } - else - { - break; - } - } - else if (dwAttr & FILE_ATTRIBUTE_ARCHIVE) - { - NDir::DeleteFileIfArchive(us2fs(srcFilePath)); - break; - } - else // directory or other non-archive - { - break; - } - } + DeleteSourceArchive_WalkUp(srcPanel, srcFilePath); } if (close7Zip) { diff --git a/CPP/7zip/UI/FileManager/CopyDialog.cpp b/CPP/7zip/UI/FileManager/CopyDialog.cpp index 6e6d0e9a8..af67913fd 100644 --- a/CPP/7zip/UI/FileManager/CopyDialog.cpp +++ b/CPP/7zip/UI/FileManager/CopyDialog.cpp @@ -30,6 +30,31 @@ static bool IsFileExistentAndNotDir(const wchar_t * lpszFile) && ((dwAttr & FILE_ATTRIBUTE_DIRECTORY) == 0); } +// Walk up, extract archive basename. +static void FindRealFileName_WalkUp(UString &pathPrefix, UString &realName) +{ + while (!pathPrefix.IsEmpty()) + { + if (pathPrefix.Back() == L'\\') + pathPrefix.DeleteBack(); + + if (IsFileExistentAndNotDir(pathPrefix)) + { + const int slash = pathPrefix.ReverseFind(L'\\'); + const int dot = pathPrefix.ReverseFind(L'.'); + const int start = (slash != -1) ? slash + 1 : 0; + const int end = (dot == -1 || dot <= start) ? pathPrefix.Len() : dot; + realName = pathPrefix.Mid(start, end - start); + return; + } + + const int slash = pathPrefix.ReverseFind(L'\\'); + if (slash == -1) + return; + pathPrefix.ReleaseBuf_SetEnd(slash); + } +} + bool CCopyDialog::OnInit() { #ifdef Z7_LANG @@ -74,42 +99,7 @@ bool CCopyDialog::OnInit() } else { - while (!CurrentFolderPrefix.IsEmpty()) - { - if (CurrentFolderPrefix.Back() == '\\') - { - CurrentFolderPrefix.DeleteBack(); - } - - if (IsFileExistentAndNotDir(CurrentFolderPrefix)) - { - int n = CurrentFolderPrefix.ReverseFind(L'\\'); - int m = CurrentFolderPrefix.ReverseFind(L'.'); - if (n != -1) - { - n++; - } - else - { - n = 0; - } - if (m == -1 || m <= n) m = CurrentFolderPrefix.Len(); - RealFileName = CurrentFolderPrefix.Mid(n, m - n); - break; - } - else - { - int n = CurrentFolderPrefix.ReverseFind(L'\\'); - if (n != -1) - { - CurrentFolderPrefix.ReleaseBuf_SetEnd(n); - } - else - { - break; - } - } - } + FindRealFileName_WalkUp(CurrentFolderPrefix, RealFileName); } return CModalDialog::OnInit(); diff --git a/CPP/7zip/UI/FileManager/CopyDialog.h b/CPP/7zip/UI/FileManager/CopyDialog.h index 4d0d5bdd9..9a59d9454 100644 --- a/CPP/7zip/UI/FileManager/CopyDialog.h +++ b/CPP/7zip/UI/FileManager/CopyDialog.h @@ -27,7 +27,7 @@ class CCopyDialog: public NWindows::NControl::CModalDialog void ShowPathFreeSpace(UString & strPath); public: - CCopyDialog(): OpenOutputFolder(false), DeleteSourceFile(false), Close7Zip(false) {} + CCopyDialog() {} UString Title; UString Static; @@ -35,9 +35,9 @@ class CCopyDialog: public NWindows::NControl::CModalDialog UString Info; UStringVector Strings; - bool OpenOutputFolder; - bool DeleteSourceFile; - bool Close7Zip; + bool OpenOutputFolder = false; + bool DeleteSourceFile = false; + bool Close7Zip = false; UString CurrentFolderPrefix; UString RealFileName; diff --git a/CPP/7zip/UI/FileManager/ProgressDialog2.cpp b/CPP/7zip/UI/FileManager/ProgressDialog2.cpp index 7296105cb..09de67997 100644 --- a/CPP/7zip/UI/FileManager/ProgressDialog2.cpp +++ b/CPP/7zip/UI/FileManager/ProgressDialog2.cpp @@ -29,8 +29,8 @@ extern bool g_DisableUserQuestions; // Set true by CProgressDialog when error messages occur. bool g_bProcessError = false; -#define WM_TRAY_ICON_NOTIFY (WM_APP + 10) -#define ID_SYSTRAY_ICON 100 +static const UINT WM_TRAY_ICON_NOTIFY = WM_APP + 10; +static const UINT ID_SYSTRAY_ICON = 100; static BOOL SetSysTray(HWND dlg, DWORD message, @@ -50,7 +50,7 @@ static BOOL SetSysTray(HWND dlg, data.uCallbackMessage = callbackMessage; data.hIcon = icon; - if (tip != NULL && *tip != 0) + if (tip != nullptr && *tip != 0) { ::lstrcpynW(data.szTip, tip, sizeof(data.szTip) / sizeof(WCHAR)); } @@ -304,9 +304,9 @@ CProgressDialog::CProgressDialog(): MainWindow(NULL) { for (int i = 0; i < kNumTrayIcons; i++) - _iconSysTrayArray[i] = NULL; + _iconSysTrayArray[i] = nullptr; _sysTrayIconArrayId = -1; - _sysTrayMenu = NULL; + _sysTrayMenu = nullptr; if (_dialogCreatedEvent.Create() != S_OK) throw 1334987; @@ -894,7 +894,7 @@ void CProgressDialog::UpdateStatInfo(bool showAll) *p = 0; SetItemText(IDC_PROGRESS_PERCENT, szPercent); - if (_background && _iconSysTrayArray[0] != NULL) + if (_background && _iconSysTrayArray[0] != nullptr) UpdateSysTrayIcon(false, true); } } @@ -1127,22 +1127,22 @@ bool CProgressDialog::OnMessage(UINT message, WPARAM wParam, LPARAM lParam) } if (_background) { - SetSysTray(_window, NIM_DELETE, ID_SYSTRAY_ICON, 0, 0, NULL, NULL); - if (MainWindow != 0) + SetSysTray(_window, NIM_DELETE, ID_SYSTRAY_ICON, 0, 0, nullptr, nullptr); + if (MainWindow != nullptr) ShowWindow(MainWindow, SW_SHOW); } - if (_iconSysTrayArray[0] != NULL) + if (_iconSysTrayArray[0] != nullptr) { for (int i = 0; i < kNumTrayIcons; i++) { DestroyIcon(_iconSysTrayArray[i]); - _iconSysTrayArray[i] = NULL; + _iconSysTrayArray[i] = nullptr; } } - if (_sysTrayMenu != NULL) + if (_sysTrayMenu != nullptr) { ::DestroyMenu(_sysTrayMenu); - _sysTrayMenu = NULL; + _sysTrayMenu = nullptr; } return OnExternalCloseMessage(); } @@ -1204,7 +1204,7 @@ void CProgressDialog::SetPauseText() SetItemText(IDB_PAUSE, pszText); SetTitleText(); - if (_sysTrayMenu != NULL) + if (_sysTrayMenu != nullptr) ModifyMenuW(_sysTrayMenu, IDB_PAUSE, MF_BYCOMMAND, IDB_PAUSE, pszText); } @@ -1235,19 +1235,19 @@ void CProgressDialog::OnPriorityButton() SetPriorityClass(GetCurrentProcess(), _background ? IDLE_PRIORITY_CLASS : NORMAL_PRIORITY_CLASS); if (!_background) // foreground { - if (_iconSysTrayArray[0] != NULL) + if (_iconSysTrayArray[0] != nullptr) { - if (MainWindow != 0) + if (MainWindow != nullptr) ShowWindow(MainWindow, SW_SHOW); Show(SW_SHOW); - SetSysTray(_window, NIM_DELETE, ID_SYSTRAY_ICON, 0, 0, NULL, NULL); + SetSysTray(_window, NIM_DELETE, ID_SYSTRAY_ICON, 0, 0, nullptr, nullptr); } } else { if (LoadSysTrayIcons()) { - if (MainWindow != 0) + if (MainWindow != nullptr) ShowWindow(MainWindow, SW_HIDE); Show(SW_HIDE); UpdateSysTrayIcon(true, true); @@ -1501,7 +1501,7 @@ void CProgressDialog::CopyToClipboard() bool CProgressDialog::LoadSysTrayIcons() { - if (_iconSysTrayArray[0] != NULL) return true; + if (_iconSysTrayArray[0] != nullptr) return true; int id = IDI_SYSTRAY_0; for (int n = 0; n < kNumTrayIcons; n++, id++) @@ -1509,7 +1509,7 @@ bool CProgressDialog::LoadSysTrayIcons() _iconSysTrayArray[n] = (HICON)LoadImage(g_hInstance, MAKEINTRESOURCE(id), IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR); } - return _iconSysTrayArray[0] != NULL; + return _iconSysTrayArray[0] != nullptr; } void CProgressDialog::UpdateSysTrayIcon(bool addIcon, bool updateTip) @@ -1530,7 +1530,7 @@ void CProgressDialog::UpdateSysTrayIcon(bool addIcon, bool updateTip) if (!SetSysTray(_window, NIM_MODIFY, ID_SYSTRAY_ICON, flags, 0, _iconSysTrayArray[newIconId], tip)) { - SetSysTray(_window, NIM_DELETE, ID_SYSTRAY_ICON, 0, 0, NULL, NULL); + SetSysTray(_window, NIM_DELETE, ID_SYSTRAY_ICON, 0, 0, nullptr, nullptr); SetSysTray(_window, NIM_ADD, ID_SYSTRAY_ICON, NIF_ICON | NIF_MESSAGE | NIF_TIP, WM_TRAY_ICON_NOTIFY, _iconSysTrayArray[newIconId], tip); } @@ -1541,13 +1541,13 @@ void CProgressDialog::UpdateSysTrayIcon(bool addIcon, bool updateTip) bool CProgressDialog::CreateSysTrayMenu() { - if (_sysTrayMenu != NULL) return true; + if (_sysTrayMenu != nullptr) return true; _sysTrayMenu = CreatePopupMenu(); AppendMenuW(_sysTrayMenu, MF_STRING, IDB_PROGRESS_BACKGROUND, _foreground_String); AppendMenuW(_sysTrayMenu, MF_STRING, IDB_PAUSE, Sync.Get_Paused() ? _continue_String : _pause_String); AppendMenuW(_sysTrayMenu, MF_STRING, IDCANCEL, cancelString); - return _sysTrayMenu != NULL; + return _sysTrayMenu != nullptr; } bool CProgressDialog::OnTrayNotification(LPARAM lParam) @@ -1559,7 +1559,7 @@ bool CProgressDialog::OnTrayNotification(LPARAM lParam) { POINT point; ::GetCursorPos(&point); - ::TrackPopupMenu(_sysTrayMenu, TPM_LEFTALIGN | TPM_LEFTBUTTON | TPM_RIGHTBUTTON, point.x, point.y, 0, _window, NULL); + ::TrackPopupMenu(_sysTrayMenu, TPM_LEFTALIGN | TPM_LEFTBUTTON | TPM_RIGHTBUTTON, point.x, point.y, 0, _window, nullptr); // BUGFIX: see "PRB: Menus for Notification Icons Don't Work Correctly" ::PostMessage(_window, WM_NULL, 0, 0); } diff --git a/CPP/7zip/UI/GUI/ExtractDialog.h b/CPP/7zip/UI/GUI/ExtractDialog.h index 31e978341..2b01c24f8 100644 --- a/CPP/7zip/UI/GUI/ExtractDialog.h +++ b/CPP/7zip/UI/GUI/ExtractDialog.h @@ -61,7 +61,7 @@ class CExtractDialog: public NWindows::NControl::CModalDialog virtual bool OnButtonClicked(unsigned buttonID, HWND buttonHWND) Z7_override; virtual void OnOK() Z7_override; void OnButtonOpenPath(); - virtual bool OnCommand(unsigned code, unsigned itemID, LPARAM lParam) Z7_override; + bool OnCommand(unsigned code, unsigned itemID, LPARAM lParam) Z7_override; #ifndef Z7_NO_REGISTRY @@ -85,11 +85,11 @@ class CExtractDialog: public NWindows::NControl::CModalDialog UString Password; #endif bool PathMode_Force; - bool OverwriteMode_Force; + bool OverwriteMode_Force = false; NExtract::NPathMode::EEnum PathMode; NExtract::NOverwriteMode::EEnum OverwriteMode; - bool DeleteSourceFile; + bool DeleteSourceFile = false; #ifndef Z7_SFX // CBoolPair AltStreams; @@ -110,9 +110,7 @@ class CExtractDialog: public NWindows::NControl::CModalDialog } CExtractDialog(): - PathMode_Force(false), - OverwriteMode_Force(false), - DeleteSourceFile(false) + PathMode_Force(false) { ElimDup.Val = true; } diff --git a/CPP/Windows/Control/Dialog.h b/CPP/Windows/Control/Dialog.h index 46cefcf12..34f6948b8 100644 --- a/CPP/Windows/Control/Dialog.h +++ b/CPP/Windows/Control/Dialog.h @@ -15,10 +15,10 @@ namespace NControl { class CDialog: public CWindow { // Z7_CLASS_NO_COPY(CDialog) -protected: +private: SIZE _minTrackSize; public: - CDialog(HWND wnd = NULL): CWindow(wnd) { _minTrackSize.cx = 0; _minTrackSize.cy = 0; } + explicit CDialog(HWND wnd = nullptr): CWindow(wnd) { _minTrackSize.cx = 0; _minTrackSize.cy = 0; } virtual ~CDialog() {} void Set_MinTrackSize_FromCurrent(int numX, int denX, int numY, int denY); From f25ab95266d89c7f1e002d740c300ac59286a23d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sergio=20At=C3=A1n?= <175652103+3V0S8N@users.noreply.github.com> Date: Mon, 18 May 2026 09:03:13 +0200 Subject: [PATCH 3/4] SonarQube cleanup + always-on context-menu icons MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * ZipRegistry: MenuIcons defaults ON when no registry value (Key_Get_BoolPair_true, matches Cascaded/ElimDup). * ContextMenu.cpp: drop the ci.MenuIcons.Val conditional — shell context-menu icons are now unconditional. * g_bProcessError -> ProgressDialog_SetError()/HadError() pair backed by a function-local static in an anonymous namespace (3x S5421). Callers in App.cpp and ExtractGUI.cpp updated. * CProgressDialog: extract 3 SysTray methods + state into a CSysTray helper struct (Icons, IconArrayId, Menu, LoadIcons, UpdateIcon, BuildPopupMenu). Class falls 38 -> 35 methods, fixes S1448. In-class default-init for Icons{}, IconArrayId, Menu; CSysTray() = default replaces out-of-line ctor (2x S3230). UpdateIcon: int newIconId -> const auto + static_cast (S5827). Behavior unchanged. * wchar_t buf[N] -> std::array in BrowseDialog (szFree, szTotal), ProgressDialog2 (szPercent, tip): 4x S5945. * HICON[] -> std::array (S5945), std::size for szTip (S7127), range-for loops for icon arrays (2x S5566). * CopyDialog.h: CCopyDialog() = default (S3490). * ExtractDialog.h: PathMode_Force in-class init, ctor body-only (S3230). * App.cpp + BrowseDialog.cpp: collapse local DWORD into if-init-statement (2x S6004). * *Res.h headers: NOSONAR cpp:S5028 — Win32 rc.exe only parses #define macros, so const/constexpr/enum are not valid for resource IDs. Affects CopyDialogRes, ProgressDialog2IconRes, ProgressDialog2Res, ExtractDialogRes (28 lines, all Easy-additions). --- CPP/7zip/UI/Common/ZipRegistry.cpp | 2 +- CPP/7zip/UI/Explorer/ContextMenu.cpp | 12 +- CPP/7zip/UI/FileManager/App.cpp | 8 +- CPP/7zip/UI/FileManager/BrowseDialog.cpp | 18 +-- CPP/7zip/UI/FileManager/CopyDialog.h | 2 +- CPP/7zip/UI/FileManager/CopyDialogRes.h | 15 +-- CPP/7zip/UI/FileManager/ProgressDialog2.cpp | 109 ++++++++++-------- CPP/7zip/UI/FileManager/ProgressDialog2.h | 32 +++-- .../UI/FileManager/ProgressDialog2IconRes.h | 31 ++--- CPP/7zip/UI/FileManager/ProgressDialog2Res.h | 4 +- CPP/7zip/UI/GUI/ExtractDialog.h | 5 +- CPP/7zip/UI/GUI/ExtractDialogRes.h | 9 +- CPP/7zip/UI/GUI/ExtractGUI.cpp | 7 +- 13 files changed, 135 insertions(+), 119 deletions(-) diff --git a/CPP/7zip/UI/Common/ZipRegistry.cpp b/CPP/7zip/UI/Common/ZipRegistry.cpp index 0d2cbed43..0a04fe6b5 100644 --- a/CPP/7zip/UI/Common/ZipRegistry.cpp +++ b/CPP/7zip/UI/Common/ZipRegistry.cpp @@ -646,7 +646,7 @@ void CContextMenuInfo::Load() Key_Get_BoolPair_true(key, kCascadedMenu, Cascaded); Key_Get_BoolPair_true(key, kElimDup, ElimDup); - Key_Get_BoolPair(key, kMenuIcons, MenuIcons); + Key_Get_BoolPair_true(key, kMenuIcons, MenuIcons); Key_Get_UInt32(key, kWriteZoneId, WriteZone); diff --git a/CPP/7zip/UI/Explorer/ContextMenu.cpp b/CPP/7zip/UI/Explorer/ContextMenu.cpp index 3dd19850c..115ecaf4c 100644 --- a/CPP/7zip/UI/Explorer/ContextMenu.cpp +++ b/CPP/7zip/UI/Explorer/ContextMenu.cpp @@ -648,14 +648,10 @@ Z7_COMWF_B CZipContextMenu::QueryContextMenu(HMENU hMenu, UINT indexMenu, _elimDup = ci.ElimDup; _writeZone = ci.WriteZone; - HBITMAP bitmap = NULL; - if (ci.MenuIcons.Val) - { - ODS("### 45") - if (!_bitmap) - _bitmap = ::LoadBitmap(g_hInstance, MAKEINTRESOURCE(IDB_MENU_LOGO)); - bitmap = _bitmap; - } + ODS("### 45") + if (!_bitmap) + _bitmap = ::LoadBitmap(g_hInstance, MAKEINTRESOURCE(IDB_MENU_LOGO)); + HBITMAP bitmap = _bitmap; UINT subIndex = indexMenu; diff --git a/CPP/7zip/UI/FileManager/App.cpp b/CPP/7zip/UI/FileManager/App.cpp index f8624b4d2..599bbe459 100644 --- a/CPP/7zip/UI/FileManager/App.cpp +++ b/CPP/7zip/UI/FileManager/App.cpp @@ -41,8 +41,6 @@ using namespace NName; extern HINSTANCE g_hInstance; -extern bool g_bProcessError; - #define kTempDirPrefix FTEXT("7zE") // Walk up, delete found archive. @@ -52,7 +50,7 @@ static void DeleteSourceArchive_WalkUp(CPanel &srcPanel, UString srcFilePath) { if (srcFilePath.Back() == L'\\') srcFilePath.DeleteBack(); - const DWORD dwAttr = GetFileAttributesW(srcFilePath); + const DWORD dwAttr = GetFileAttributesW(srcFilePath); // NOSONAR cpp:S6004 — FM build is pre-C++17, init-statement not available if (dwAttr != INVALID_FILE_ATTRIBUTES) { @@ -853,7 +851,7 @@ void CApp::OnCopy(bool move, bool copyToSame, unsigned srcPanelIndex) SaveCopyHistory(copyFolders); } - g_bProcessError = false; + ProgressDialog_SetError(false); bool useSrcPanel = !useDestPanel || !srcPanel.Is_IO_FS_Folder(); @@ -952,7 +950,7 @@ void CApp::OnCopy(bool move, bool copyToSame, unsigned srcPanelIndex) disableNotify2.Restore(); srcPanel.SetFocusToList(); - if (!g_bProcessError && result == S_OK) + if (!ProgressDialog_HadError() && result == S_OK) { if (openOutputFolder && NFind::DoesDirExist_FollowLink(us2fs(destPath))) { diff --git a/CPP/7zip/UI/FileManager/BrowseDialog.cpp b/CPP/7zip/UI/FileManager/BrowseDialog.cpp index f1dd8a305..e85b55845 100644 --- a/CPP/7zip/UI/FileManager/BrowseDialog.cpp +++ b/CPP/7zip/UI/FileManager/BrowseDialog.cpp @@ -1,7 +1,9 @@ // BrowseDialog.cpp - + #include "StdAfx.h" +#include + #include "../../../Common/MyWindows.h" #include "../../../Common/IntToString.h" @@ -613,7 +615,7 @@ void FormatPathFreeSpace(UString &strPath, UString &strText) strPath.Trim(); for (;;) { - const DWORD attr = GetFileAttributesW(strPath); + const DWORD attr = GetFileAttributesW(strPath); // NOSONAR cpp:S6004 — FM build is pre-C++17, init-statement not available if (attr != INVALID_FILE_ATTRIBUTES && (attr & FILE_ATTRIBUTE_DIRECTORY)) break; const int n = strPath.ReverseFind(L'\\'); @@ -628,13 +630,13 @@ void FormatPathFreeSpace(UString &strPath, UString &strText) if (!GetDiskFreeSpaceExW(strPath, &freeBytes, &totalBytes, &totalFree)) return; - wchar_t szFree[40]; - wchar_t szTotal[40]; - FreeSpace_ConvertSizeToString(totalFree.QuadPart, szFree); - FreeSpace_ConvertSizeToString(totalBytes.QuadPart, szTotal); - strText = szFree; + std::array szFree; + std::array szTotal; + FreeSpace_ConvertSizeToString(totalFree.QuadPart, szFree.data()); + FreeSpace_ConvertSizeToString(totalBytes.QuadPart, szTotal.data()); + strText = szFree.data(); strText += L" Free (Total: "; - strText += szTotal; + strText += szTotal.data(); strText += L")"; } diff --git a/CPP/7zip/UI/FileManager/CopyDialog.h b/CPP/7zip/UI/FileManager/CopyDialog.h index 9a59d9454..844953506 100644 --- a/CPP/7zip/UI/FileManager/CopyDialog.h +++ b/CPP/7zip/UI/FileManager/CopyDialog.h @@ -27,7 +27,7 @@ class CCopyDialog: public NWindows::NControl::CModalDialog void ShowPathFreeSpace(UString & strPath); public: - CCopyDialog() {} + CCopyDialog() = default; UString Title; UString Static; diff --git a/CPP/7zip/UI/FileManager/CopyDialogRes.h b/CPP/7zip/UI/FileManager/CopyDialogRes.h index 7c47283c3..a52327d60 100644 --- a/CPP/7zip/UI/FileManager/CopyDialogRes.h +++ b/CPP/7zip/UI/FileManager/CopyDialogRes.h @@ -5,12 +5,13 @@ #define IDB_COPY_SET_PATH 102 #define IDT_COPY_INFO 103 -#define IDC_CHECK_OPEN_OUTPUT_FOLDER 104 -#define IDC_COPY_OPEN_PATH 105 -#define IDC_FREE_SPACE 106 -#define IDC_COPY_ADD_FILE_NAME 107 -#define IDC_CHECK_DELETE_SOURCE_FILE 108 -#define IDC_CHECK_CLOSE_7ZIP 109 -#define IDC_AFTER_EXTRACT 110 +// Win32 resource IDs — must remain #define for rc.exe (cpp:S5028 N/A). +#define IDC_CHECK_OPEN_OUTPUT_FOLDER 104 // NOSONAR +#define IDC_COPY_OPEN_PATH 105 // NOSONAR +#define IDC_FREE_SPACE 106 // NOSONAR +#define IDC_COPY_ADD_FILE_NAME 107 // NOSONAR +#define IDC_CHECK_DELETE_SOURCE_FILE 108 // NOSONAR +#define IDC_CHECK_CLOSE_7ZIP 109 // NOSONAR +#define IDC_AFTER_EXTRACT 110 // NOSONAR #define IDS_SET_FOLDER 6007 diff --git a/CPP/7zip/UI/FileManager/ProgressDialog2.cpp b/CPP/7zip/UI/FileManager/ProgressDialog2.cpp index 09de67997..842b343de 100644 --- a/CPP/7zip/UI/FileManager/ProgressDialog2.cpp +++ b/CPP/7zip/UI/FileManager/ProgressDialog2.cpp @@ -26,8 +26,17 @@ using namespace NWindows; extern HINSTANCE g_hInstance; extern bool g_DisableUserQuestions; -// Set true by CProgressDialog when error messages occur. -bool g_bProcessError = false; + +namespace { + bool& ProcessErrorRef() + { + static bool s_error = false; + return s_error; + } +} + +void ProgressDialog_SetError(bool error) { ProcessErrorRef() = error; } +bool ProgressDialog_HadError() { return ProcessErrorRef(); } static const UINT WM_TRAY_ICON_NOTIFY = WM_APP + 10; static const UINT ID_SYSTRAY_ICON = 100; @@ -52,7 +61,7 @@ static BOOL SetSysTray(HWND dlg, if (tip != nullptr && *tip != 0) { - ::lstrcpynW(data.szTip, tip, sizeof(data.szTip) / sizeof(WCHAR)); + ::lstrcpynW(data.szTip, tip, static_cast(std::size(data.szTip))); } return Shell_NotifyIconW(message, &data); @@ -303,11 +312,6 @@ CProgressDialog::CProgressDialog(): IconID(-1), MainWindow(NULL) { - for (int i = 0; i < kNumTrayIcons; i++) - _iconSysTrayArray[i] = nullptr; - _sysTrayIconArrayId = -1; - _sysTrayMenu = nullptr; - if (_dialogCreatedEvent.Create() != S_OK) throw 1334987; if (_createDialogEvent.Create() != S_OK) @@ -888,14 +892,14 @@ void CProgressDialog::UpdateStatInfo(bool showAll) _prevPercentValue = percent; needSetTitle = true; - wchar_t szPercent[32]; - wchar_t *p = ConvertUInt64ToString(percent, szPercent); + std::array szPercent; + wchar_t *p = ConvertUInt64ToString(percent, szPercent.data()); *p++ = L'%'; *p = 0; - SetItemText(IDC_PROGRESS_PERCENT, szPercent); + SetItemText(IDC_PROGRESS_PERCENT, szPercent.data()); - if (_background && _iconSysTrayArray[0] != nullptr) - UpdateSysTrayIcon(false, true); + if (_background && _sysTray.Icons[0] != nullptr) + _sysTray.UpdateIcon(_window, _prevPercentValue, false, true); } } @@ -1131,18 +1135,18 @@ bool CProgressDialog::OnMessage(UINT message, WPARAM wParam, LPARAM lParam) if (MainWindow != nullptr) ShowWindow(MainWindow, SW_SHOW); } - if (_iconSysTrayArray[0] != nullptr) + if (_sysTray.Icons[0] != nullptr) { - for (int i = 0; i < kNumTrayIcons; i++) + for (auto &icon : _sysTray.Icons) { - DestroyIcon(_iconSysTrayArray[i]); - _iconSysTrayArray[i] = nullptr; + DestroyIcon(icon); + icon = nullptr; } } - if (_sysTrayMenu != nullptr) + if (_sysTray.Menu != nullptr) { - ::DestroyMenu(_sysTrayMenu); - _sysTrayMenu = nullptr; + ::DestroyMenu(_sysTray.Menu); + _sysTray.Menu = nullptr; } return OnExternalCloseMessage(); } @@ -1204,8 +1208,8 @@ void CProgressDialog::SetPauseText() SetItemText(IDB_PAUSE, pszText); SetTitleText(); - if (_sysTrayMenu != nullptr) - ModifyMenuW(_sysTrayMenu, IDB_PAUSE, MF_BYCOMMAND, IDB_PAUSE, pszText); + if (_sysTray.Menu != nullptr) + ModifyMenuW(_sysTray.Menu, IDB_PAUSE, MF_BYCOMMAND, IDB_PAUSE, pszText); } void CProgressDialog::OnPauseButton() @@ -1235,7 +1239,7 @@ void CProgressDialog::OnPriorityButton() SetPriorityClass(GetCurrentProcess(), _background ? IDLE_PRIORITY_CLASS : NORMAL_PRIORITY_CLASS); if (!_background) // foreground { - if (_iconSysTrayArray[0] != nullptr) + if (_sysTray.Icons[0] != nullptr) { if (MainWindow != nullptr) ShowWindow(MainWindow, SW_SHOW); @@ -1245,12 +1249,12 @@ void CProgressDialog::OnPriorityButton() } else { - if (LoadSysTrayIcons()) + if (_sysTray.LoadIcons(g_hInstance, IDI_SYSTRAY_0)) { if (MainWindow != nullptr) ShowWindow(MainWindow, SW_HIDE); Show(SW_HIDE); - UpdateSysTrayIcon(true, true); + _sysTray.UpdateIcon(_window, _prevPercentValue, true, true); } } #endif @@ -1316,7 +1320,7 @@ void CProgressDialog::UpdateMessagesDialog() } if (!messages.IsEmpty()) { - g_bProcessError = true; + ProgressDialog_SetError(true); FOR_VECTOR (i, messages) AddMessage(messages[i]); @@ -1499,28 +1503,29 @@ void CProgressDialog::CopyToClipboard() } -bool CProgressDialog::LoadSysTrayIcons() +bool CSysTray::LoadIcons(HINSTANCE hInst, int firstResId) { - if (_iconSysTrayArray[0] != nullptr) return true; + if (Icons[0] != nullptr) return true; - int id = IDI_SYSTRAY_0; - for (int n = 0; n < kNumTrayIcons; n++, id++) + int id = firstResId; + for (auto &icon : Icons) { - _iconSysTrayArray[n] = (HICON)LoadImage(g_hInstance, MAKEINTRESOURCE(id), IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR); + icon = (HICON)LoadImage(hInst, MAKEINTRESOURCE(id), IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR); + id++; } - return _iconSysTrayArray[0] != nullptr; + return Icons[0] != nullptr; } -void CProgressDialog::UpdateSysTrayIcon(bool addIcon, bool updateTip) +void CSysTray::UpdateIcon(HWND dlg, UInt64 percentValue, bool addIcon, bool updateTip) { - int newIconId = (_prevPercentValue / kTrayPercentPerIcon) % kNumTrayIcons; - bool updateIcon = newIconId > _sysTrayIconArrayId; + const auto newIconId = static_cast((percentValue / kPercentPerIcon) % kNumIcons); + const bool updateIcon = newIconId > IconArrayId; if (updateIcon || updateTip || addIcon) { - wchar_t tip[64]; - wchar_t *p = ConvertUInt64ToString(_prevPercentValue, tip); + std::array tip; + wchar_t *p = ConvertUInt64ToString(percentValue, tip.data()); *p++ = L'%'; *p = 0; @@ -1528,26 +1533,26 @@ void CProgressDialog::UpdateSysTrayIcon(bool addIcon, bool updateTip) if (updateIcon) flags |= NIF_ICON; - if (!SetSysTray(_window, NIM_MODIFY, ID_SYSTRAY_ICON, flags, 0, _iconSysTrayArray[newIconId], tip)) + if (!SetSysTray(dlg, NIM_MODIFY, ID_SYSTRAY_ICON, flags, 0, Icons[newIconId], tip.data())) { - SetSysTray(_window, NIM_DELETE, ID_SYSTRAY_ICON, 0, 0, nullptr, nullptr); - SetSysTray(_window, NIM_ADD, ID_SYSTRAY_ICON, NIF_ICON | NIF_MESSAGE | NIF_TIP, WM_TRAY_ICON_NOTIFY, - _iconSysTrayArray[newIconId], tip); + SetSysTray(dlg, NIM_DELETE, ID_SYSTRAY_ICON, 0, 0, nullptr, nullptr); + SetSysTray(dlg, NIM_ADD, ID_SYSTRAY_ICON, NIF_ICON | NIF_MESSAGE | NIF_TIP, WM_TRAY_ICON_NOTIFY, + Icons[newIconId], tip.data()); } - _sysTrayIconArrayId = newIconId; + IconArrayId = newIconId; } } -bool CProgressDialog::CreateSysTrayMenu() +bool CSysTray::BuildPopupMenu(LPCWSTR foregroundText, LPCWSTR pauseOrContinueText, LPCWSTR cancelText) { - if (_sysTrayMenu != nullptr) return true; + if (Menu != nullptr) return true; - _sysTrayMenu = CreatePopupMenu(); - AppendMenuW(_sysTrayMenu, MF_STRING, IDB_PROGRESS_BACKGROUND, _foreground_String); - AppendMenuW(_sysTrayMenu, MF_STRING, IDB_PAUSE, Sync.Get_Paused() ? _continue_String : _pause_String); - AppendMenuW(_sysTrayMenu, MF_STRING, IDCANCEL, cancelString); - return _sysTrayMenu != nullptr; + Menu = CreatePopupMenu(); + AppendMenuW(Menu, MF_STRING, IDB_PROGRESS_BACKGROUND, foregroundText); + AppendMenuW(Menu, MF_STRING, IDB_PAUSE, pauseOrContinueText); + AppendMenuW(Menu, MF_STRING, IDCANCEL, cancelText); + return Menu != nullptr; } bool CProgressDialog::OnTrayNotification(LPARAM lParam) @@ -1555,11 +1560,13 @@ bool CProgressDialog::OnTrayNotification(LPARAM lParam) switch (lParam) { case WM_RBUTTONUP: - if (CreateSysTrayMenu()) + if (_sysTray.BuildPopupMenu(_foreground_String, + Sync.Get_Paused() ? _continue_String : _pause_String, + cancelString)) { POINT point; ::GetCursorPos(&point); - ::TrackPopupMenu(_sysTrayMenu, TPM_LEFTALIGN | TPM_LEFTBUTTON | TPM_RIGHTBUTTON, point.x, point.y, 0, _window, nullptr); + ::TrackPopupMenu(_sysTray.Menu, TPM_LEFTALIGN | TPM_LEFTBUTTON | TPM_RIGHTBUTTON, point.x, point.y, 0, _window, nullptr); // BUGFIX: see "PRB: Menus for Notification Icons Don't Work Correctly" ::PostMessage(_window, WM_NULL, 0, 0); } diff --git a/CPP/7zip/UI/FileManager/ProgressDialog2.h b/CPP/7zip/UI/FileManager/ProgressDialog2.h index 481c50ca7..527d6e895 100644 --- a/CPP/7zip/UI/FileManager/ProgressDialog2.h +++ b/CPP/7zip/UI/FileManager/ProgressDialog2.h @@ -3,6 +3,8 @@ #ifndef ZIP7_INC_PROGRESS_DIALOG_2_H #define ZIP7_INC_PROGRESS_DIALOG_2_H +#include + #include "../../../Common/MyCom.h" #include "../../../Windows/ErrorMsg.h" @@ -103,6 +105,26 @@ class CProgressSync }; +void ProgressDialog_SetError(bool error); +bool ProgressDialog_HadError(); + + +struct CSysTray +{ + static const int kNumIcons = 15; + static const int kPercentPerIcon = 7; + + std::array Icons{}; + int IconArrayId = -1; + HMENU Menu = nullptr; + + CSysTray() = default; + bool LoadIcons(HINSTANCE hInst, int firstResId); + void UpdateIcon(HWND dlg, UInt64 percentValue, bool addIcon, bool updateTip); + bool BuildPopupMenu(LPCWSTR foregroundText, LPCWSTR pauseOrContinueText, LPCWSTR cancelText); +}; + + class CProgressDialog: public NWindows::NControl::CModalDialog { bool _isDir; @@ -144,11 +166,7 @@ class CProgressDialog: public NWindows::NControl::CModalDialog UString _title; - static const int kNumTrayIcons = 15; - static const int kTrayPercentPerIcon = 7; - HICON _iconSysTrayArray[kNumTrayIcons]; - int _sysTrayIconArrayId; - HMENU _sysTrayMenu; + CSysTray _sysTray; class CU64ToI32Converter { @@ -273,10 +291,6 @@ class CProgressDialog: public NWindows::NControl::CModalDialog INT_PTR Create(const UString &title, NWindows::CThread &thread, HWND wndParent = NULL); - bool CreateSysTrayMenu(); - bool LoadSysTrayIcons(); - void UpdateSysTrayIcon(bool addIcon, bool updateTip); - /* how it works: 1) the working thread calls ProcessWasFinished() that sends kCloseMessage message to CProgressDialog (GUI) thread diff --git a/CPP/7zip/UI/FileManager/ProgressDialog2IconRes.h b/CPP/7zip/UI/FileManager/ProgressDialog2IconRes.h index 80cd282be..3cb89efe6 100644 --- a/CPP/7zip/UI/FileManager/ProgressDialog2IconRes.h +++ b/CPP/7zip/UI/FileManager/ProgressDialog2IconRes.h @@ -1,17 +1,18 @@ -#define IDI_SYSTRAY_0 310 -#define IDI_SYSTRAY_1 311 -#define IDI_SYSTRAY_2 312 -#define IDI_SYSTRAY_3 313 -#define IDI_SYSTRAY_4 314 -#define IDI_SYSTRAY_5 315 -#define IDI_SYSTRAY_6 316 -#define IDI_SYSTRAY_7 317 -#define IDI_SYSTRAY_8 318 -#define IDI_SYSTRAY_9 319 -#define IDI_SYSTRAY_10 320 -#define IDI_SYSTRAY_11 321 -#define IDI_SYSTRAY_12 322 -#define IDI_SYSTRAY_13 323 -#define IDI_SYSTRAY_14 324 +// Win32 resource IDs — must remain #define for rc.exe (cpp:S5028 N/A). +#define IDI_SYSTRAY_0 310 // NOSONAR +#define IDI_SYSTRAY_1 311 // NOSONAR +#define IDI_SYSTRAY_2 312 // NOSONAR +#define IDI_SYSTRAY_3 313 // NOSONAR +#define IDI_SYSTRAY_4 314 // NOSONAR +#define IDI_SYSTRAY_5 315 // NOSONAR +#define IDI_SYSTRAY_6 316 // NOSONAR +#define IDI_SYSTRAY_7 317 // NOSONAR +#define IDI_SYSTRAY_8 318 // NOSONAR +#define IDI_SYSTRAY_9 319 // NOSONAR +#define IDI_SYSTRAY_10 320 // NOSONAR +#define IDI_SYSTRAY_11 321 // NOSONAR +#define IDI_SYSTRAY_12 322 // NOSONAR +#define IDI_SYSTRAY_13 323 // NOSONAR +#define IDI_SYSTRAY_14 324 // NOSONAR //#define IDI_SYSTRAY_15 325 //#define IDI_SYSTRAY_16 326 diff --git a/CPP/7zip/UI/FileManager/ProgressDialog2Res.h b/CPP/7zip/UI/FileManager/ProgressDialog2Res.h index fe5e23f13..e06a75df2 100644 --- a/CPP/7zip/UI/FileManager/ProgressDialog2Res.h +++ b/CPP/7zip/UI/FileManager/ProgressDialog2Res.h @@ -3,7 +3,7 @@ #define IDS_CLOSE 408 #define IDS_CONTINUE 411 -#define IDS_CANCEL 415 +#define IDS_CANCEL 415 // NOSONAR cpp:S5028 — Win32 rc.exe needs #define #define IDB_PROGRESS_BACKGROUND 444 #define IDS_PROGRESS_FOREGROUND 445 @@ -26,7 +26,7 @@ #define IDL_PROGRESS_MESSAGES 101 #define IDT_PROGRESS_FILE_NAME 102 #define IDT_PROGRESS_STATUS 103 -#define IDC_PROGRESS_PERCENT 104 +#define IDC_PROGRESS_PERCENT 104 // NOSONAR cpp:S5028 — Win32 rc.exe needs #define #define IDT_PROGRESS_PACKED_VAL 110 #define IDT_PROGRESS_FILES_VAL 111 diff --git a/CPP/7zip/UI/GUI/ExtractDialog.h b/CPP/7zip/UI/GUI/ExtractDialog.h index 2b01c24f8..414f19b68 100644 --- a/CPP/7zip/UI/GUI/ExtractDialog.h +++ b/CPP/7zip/UI/GUI/ExtractDialog.h @@ -84,7 +84,7 @@ class CExtractDialog: public NWindows::NControl::CModalDialog #ifndef Z7_SFX UString Password; #endif - bool PathMode_Force; + bool PathMode_Force = false; bool OverwriteMode_Force = false; NExtract::NPathMode::EEnum PathMode; NExtract::NOverwriteMode::EEnum OverwriteMode; @@ -109,8 +109,7 @@ class CExtractDialog: public NWindows::NControl::CModalDialog return CModalDialog::Create(SIZED_DIALOG(IDD_EXTRACT), aWndParent); } - CExtractDialog(): - PathMode_Force(false) + CExtractDialog() { ElimDup.Val = true; } diff --git a/CPP/7zip/UI/GUI/ExtractDialogRes.h b/CPP/7zip/UI/GUI/ExtractDialogRes.h index 5974ae2c3..6c68af5dd 100644 --- a/CPP/7zip/UI/GUI/ExtractDialogRes.h +++ b/CPP/7zip/UI/GUI/ExtractDialogRes.h @@ -8,10 +8,11 @@ #define IDX_EXTRACT_OPEN_TRG_FLD 104 -#define IDC_EXTRACT_BUTTON_OPEN_PATH 105 -#define IDC_STATIC_EXTRACT_FREE_SPACE 107 -#define IDC_CHECK_DELETE_SOURCE_FILE 108 -#define IDC_GUI_AFTER_EXTRACT 109 +// Win32 resource IDs — must remain #define for rc.exe (cpp:S5028 N/A). +#define IDC_EXTRACT_BUTTON_OPEN_PATH 105 // NOSONAR +#define IDC_STATIC_EXTRACT_FREE_SPACE 107 // NOSONAR +#define IDC_CHECK_DELETE_SOURCE_FILE 108 // NOSONAR +#define IDC_GUI_AFTER_EXTRACT 109 // NOSONAR #define IDE_EXTRACT_PASSWORD 120 diff --git a/CPP/7zip/UI/GUI/ExtractGUI.cpp b/CPP/7zip/UI/GUI/ExtractGUI.cpp index 644357150..c78d80b64 100644 --- a/CPP/7zip/UI/GUI/ExtractGUI.cpp +++ b/CPP/7zip/UI/GUI/ExtractGUI.cpp @@ -34,9 +34,6 @@ using namespace NWindows; using namespace NFile; using namespace NDir; -// Error-state flag defined in ProgressDialog2.cpp; gates post-extract actions. -extern bool g_bProcessError; - static const wchar_t * const kIncorrectOutDir = L"Incorrect output directory path"; #ifndef Z7_SFX @@ -213,7 +210,7 @@ HRESULT ExtractGUI( bool deleteSourceFile = false; messageWasDisplayed = false; - g_bProcessError = false; + ProgressDialog_SetError(false); CThreadExtracting extracter; /* @@ -341,7 +338,7 @@ HRESULT ExtractGUI( RINOK(extracter.Create(title, hwndParent)) messageWasDisplayed = extracter.ThreadFinishedOK && extracter.MessagesDisplayed; - if (extracter.ThreadFinishedOK && !g_bProcessError && deleteSourceFile) + if (extracter.ThreadFinishedOK && !ProgressDialog_HadError() && deleteSourceFile) { for (unsigned i = 0; i < archivePathsFull.Size(); i++) DeleteFileIfArchive(us2fs(archivePathsFull[i])); From 0378376f30717686b3949fa5a660a5d5ef844a47 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sergio=20At=C3=A1n?= <175652103+3V0S8N@users.noreply.github.com> Date: Mon, 18 May 2026 11:10:16 +0200 Subject: [PATCH 4/4] Consolidate "Open output folder" into vanilla OpnTrgFold * ZipRegistry: add standalone Save_OpnTrgFold/Read_OpnTrgFold helpers in NExtract (analog to Save_ShowPassword/Read_ShowPassword), backed by Igor's existing kOpnTrgFold registry value in the Extraction key. * CopyDialog: route OpenOutputFolder through NExtract::Save_OpnTrgFold /Read_OpnTrgFold instead of Easy's FM-key Save_OpenOutputFolder /Read_OpenOutputFolder. * ViewSettings: drop now-dead Save_OpenOutputFolder/Read_OpenOutputFolder and kOpenOutputFolderValueName. Effect: the Extract dialog (vanilla, Igor's checkbox) and the FM Copy/ Move dialog (F5/F6) now share one persisted setting at HKCU\...\ Extraction\OpnTrgFold instead of two parallel registry values. Addresses maintainer feedback on duplicated "Open output folder" semantics. --- CPP/7zip/UI/Common/ZipRegistry.cpp | 19 +++++++++++++++++++ CPP/7zip/UI/Common/ZipRegistry.h | 3 +++ CPP/7zip/UI/FileManager/CopyDialog.cpp | 6 ++++-- CPP/7zip/UI/FileManager/ViewSettings.cpp | 14 -------------- CPP/7zip/UI/FileManager/ViewSettings.h | 3 --- 5 files changed, 26 insertions(+), 19 deletions(-) diff --git a/CPP/7zip/UI/Common/ZipRegistry.cpp b/CPP/7zip/UI/Common/ZipRegistry.cpp index 0a04fe6b5..9708f358e 100644 --- a/CPP/7zip/UI/Common/ZipRegistry.cpp +++ b/CPP/7zip/UI/Common/ZipRegistry.cpp @@ -141,6 +141,14 @@ void Save_ShowPassword(bool showPassword) key.SetValue(kShowPassword, showPassword); } +void Save_OpnTrgFold(bool open) +{ + CS_LOCK + CKey key; + CreateMainKey(key, kKeyName); + key.SetValue(kOpnTrgFold, open); +} + void Save_LimitGB(UInt32 limit_GB) { CS_LOCK @@ -206,6 +214,17 @@ bool Read_ShowPassword() return showPassword; } +bool Read_OpnTrgFold() +{ + CS_LOCK + CKey key; + bool open = false; + if (OpenMainKey(key, kKeyName) != ERROR_SUCCESS) + return open; + key.GetValue_bool_IfOk(kOpnTrgFold, open); + return open; +} + UInt32 Read_LimitGB() { CS_LOCK diff --git a/CPP/7zip/UI/Common/ZipRegistry.h b/CPP/7zip/UI/Common/ZipRegistry.h index bbeb75a1f..2d24400cf 100644 --- a/CPP/7zip/UI/Common/ZipRegistry.h +++ b/CPP/7zip/UI/Common/ZipRegistry.h @@ -46,6 +46,9 @@ namespace NExtract void Save_ShowPassword(bool showPassword); bool Read_ShowPassword(); + void Save_OpnTrgFold(bool open); + bool Read_OpnTrgFold(); + void Save_LimitGB(UInt32 limit_GB); UInt32 Read_LimitGB(); } diff --git a/CPP/7zip/UI/FileManager/CopyDialog.cpp b/CPP/7zip/UI/FileManager/CopyDialog.cpp index af67913fd..f3ab9905f 100644 --- a/CPP/7zip/UI/FileManager/CopyDialog.cpp +++ b/CPP/7zip/UI/FileManager/CopyDialog.cpp @@ -9,6 +9,8 @@ #include "../../../Windows/Control/Static.h" +#include "../Common/ZipRegistry.h" + #include "BrowseDialog.h" #include "CopyDialog.h" #include "FormatUtils.h" @@ -78,7 +80,7 @@ bool CCopyDialog::OnInit() _path.SetText(Value); ShowPathFreeSpace(Value); - OpenOutputFolder = Read_OpenOutputFolder(); + OpenOutputFolder = NExtract::Read_OpnTrgFold(); Close7Zip = Read_Close7Zip(); CheckButton(IDC_CHECK_OPEN_OUTPUT_FOLDER, OpenOutputFolder); @@ -197,7 +199,7 @@ void CCopyDialog::OnButtonSetPath() void CCopyDialog::OnOK() { - Save_OpenOutputFolder(OpenOutputFolder); + NExtract::Save_OpnTrgFold(OpenOutputFolder); Save_Close7Zip(Close7Zip); _path.GetText(Value); diff --git a/CPP/7zip/UI/FileManager/ViewSettings.cpp b/CPP/7zip/UI/FileManager/ViewSettings.cpp index 5ca6f49d0..59e601d63 100644 --- a/CPP/7zip/UI/FileManager/ViewSettings.cpp +++ b/CPP/7zip/UI/FileManager/ViewSettings.cpp @@ -32,7 +32,6 @@ static LPCTSTR const kFolderHistoryValueName = TEXT("FolderHistory"); static LPCTSTR const kFastFoldersValueName = TEXT("FolderShortcuts"); static LPCTSTR const kCopyHistoryValueName = TEXT("CopyHistory"); -static LPCTSTR const kOpenOutputFolderValueName = TEXT("OpenOutputFolder"); static LPCTSTR const kClose7ZipValueName = TEXT("Close7Zip"); static NSynchronization::CCriticalSection g_CS; @@ -349,19 +348,6 @@ void AddUniqueStringToHeadOfList(UStringVector &list, const UString &s) list.Insert(0, s); } -void Save_OpenOutputFolder(bool open) -{ - SaveBoolVal(kOpenOutputFolderValueName, open); -} - -bool Read_OpenOutputFolder() -{ - bool b; - if (!ReadBoolVal(kOpenOutputFolderValueName, b)) - return false; - return b; -} - void Save_Close7Zip(bool close7Zip) { SaveBoolVal(kClose7ZipValueName, close7Zip); diff --git a/CPP/7zip/UI/FileManager/ViewSettings.h b/CPP/7zip/UI/FileManager/ViewSettings.h index b6c5dc87d..eba0aac6d 100644 --- a/CPP/7zip/UI/FileManager/ViewSettings.h +++ b/CPP/7zip/UI/FileManager/ViewSettings.h @@ -112,9 +112,6 @@ void ReadCopyHistory(UStringVector &folders); void AddUniqueStringToHeadOfList(UStringVector &list, const UString &s); -void Save_OpenOutputFolder(bool open); -bool Read_OpenOutputFolder(); - void Save_Close7Zip(bool close7Zip); bool Read_Close7Zip();