This commit is contained in:
Igor Pavlov
2018-05-02 22:28:04 +01:00
committed by Kornel
parent f19b649c73
commit 18dc2b4161
121 changed files with 3523 additions and 1866 deletions

View File

@@ -5,6 +5,13 @@
<dependency>
<dependentAssembly><assemblyIdentity type="win32" name="Microsoft.Windows.Common-Controls" version="6.0.0.0" processorArchitecture="*" publicKeyToken="6595b64144ccf1df" language="*"/></dependentAssembly>
</dependency>
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1"><application>
<!-- Vista --> <supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"/>
<!-- Win 7 --> <supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>
<!-- Win 8 --> <supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/>
<!-- Win 8.1 --> <supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/>
<!-- Win 10 --> <supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"/>
</application></compatibility>
<asmv3:application>
<asmv3:windowsSettings xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">
<dpiAware>true</dpiAware>

View File

@@ -0,0 +1,57 @@
// EditDialog.cpp
#include "StdAfx.h"
#include "EditDialog.h"
#ifdef LANG
#include "LangUtils.h"
#endif
bool CEditDialog::OnInit()
{
#ifdef LANG
LangSetDlgItems(*this, NULL, 0);
#endif
_edit.Attach(GetItem(IDE_EDIT));
SetText(Title);
_edit.SetText(Text);
NormalizeSize();
return CModalDialog::OnInit();
}
// #define MY_CLOSE_BUTTON__ID IDCANCEL
#define MY_CLOSE_BUTTON__ID IDCLOSE
bool CEditDialog::OnSize(WPARAM /* wParam */, int xSize, int ySize)
{
int mx, my;
GetMargins(8, mx, my);
int bx1, by;
GetItemSizes(MY_CLOSE_BUTTON__ID, bx1, by);
// int bx2;
// GetItemSizes(IDOK, bx2, by);
int y = ySize - my - by;
int x = xSize - mx - bx1;
/*
RECT rect;
GetClientRect(&rect);
rect.top = y - my;
InvalidateRect(&rect);
*/
InvalidateRect(NULL);
MoveItem(MY_CLOSE_BUTTON__ID, x, y, bx1, by);
// MoveItem(IDOK, x - mx - bx2, y, bx2, by);
/*
if (wParam == SIZE_MAXSHOW || wParam == SIZE_MAXIMIZED || wParam == SIZE_MAXHIDE)
mx = 0;
*/
_edit.Move(mx, my, xSize - mx * 2, y - my * 2);
return false;
}

View File

@@ -0,0 +1,25 @@
// EditDialog.h
#ifndef __EDIT_DIALOG_H
#define __EDIT_DIALOG_H
#include "../../../Windows/Control/Dialog.h"
#include "../../../Windows/Control/Edit.h"
#include "EditDialogRes.h"
class CEditDialog: public NWindows::NControl::CModalDialog
{
NWindows::NControl::CEdit _edit;
virtual bool OnInit();
virtual bool OnSize(WPARAM wParam, int xSize, int ySize);
public:
UString Title;
UString Text;
INT_PTR Create(HWND wndParent = 0) { return CModalDialog::Create(IDD_EDIT_DLG, wndParent); }
CEditDialog() {}
};
#endif

View File

@@ -0,0 +1,15 @@
#include "EditDialogRes.h"
#include "../../GuiCommon.rc"
#define xc 320
#define yc 240
IDD_EDIT_DLG DIALOG 0, 0, xs, ys MY_MODAL_RESIZE_DIALOG_STYLE MY_FONT
CAPTION "Edit"
{
// OK_CANCEL
MY_BUTTON__CLOSE
EDITTEXT IDE_EDIT, m, m, xc, yc - bys - m,
ES_MULTILINE | ES_READONLY | WS_VSCROLL | WS_HSCROLL | ES_WANTRETURN
}

View File

@@ -0,0 +1,2 @@
#define IDD_EDIT_DLG 94
#define IDE_EDIT 100

View File

@@ -383,6 +383,7 @@ static void SetMemoryLock()
NSecurity::AddLockMemoryPrivilege();
if (ReadLockMemoryEnable())
if (NSecurity::Get_LargePages_RiskLevel() == 0)
{
// note: child processes can inherit that Privilege
g_LargePagesMode = NSecurity::EnablePrivilege_LockMemory();

View File

@@ -491,6 +491,14 @@ SOURCE=.\DialogSize.h
# End Source File
# Begin Source File
SOURCE=.\EditDialog.cpp
# End Source File
# Begin Source File
SOURCE=.\EditDialog.h
# End Source File
# Begin Source File
SOURCE=.\LinkDialog.cpp
# End Source File
# Begin Source File

View File

@@ -46,6 +46,7 @@ FM_OBJS = \
$O\AboutDialog.obj \
$O\ComboDialog.obj \
$O\CopyDialog.obj \
$O\EditDialog.obj \
$O\EditPage.obj \
$O\LangPage.obj \
$O\ListViewDialog.obj \

View File

@@ -58,6 +58,7 @@ static const CIDLangPair kLangPairs[] =
{ IDCANCEL, 402 },
{ IDYES, 406 },
{ IDNO, 407 },
{ IDCLOSE, 408 },
{ IDHELP, 409 }
};

View File

@@ -2,6 +2,9 @@
#include "StdAfx.h"
#include "../../../Windows/Clipboard.h"
#include "EditDialog.h"
#include "ListViewDialog.h"
#include "RegistryUtils.h"
@@ -11,6 +14,23 @@
using namespace NWindows;
static const unsigned kOneStringMaxSize = 1024;
static void ListView_GetSelected(NControl::CListView &listView, CUIntVector &vector)
{
vector.Clear();
int index = -1;
for (;;)
{
index = listView.GetNextSelectedItem(index);
if (index < 0)
break;
vector.Add(index);
}
}
bool CListViewDialog::OnInit()
{
#ifdef LANG
@@ -18,28 +38,92 @@ bool CListViewDialog::OnInit()
#endif
_listView.Attach(GetItem(IDL_LISTVIEW));
if (NumColumns > 1)
{
LONG_PTR style = _listView.GetStyle();
style &= ~(LONG_PTR)LVS_NOCOLUMNHEADER;
_listView.SetStyle(style);
}
CFmSettings st;
st.Load();
DWORD exStyle = 0;
if (st.SingleClick)
_listView.SetExtendedListViewStyle(LVS_EX_ONECLICKACTIVATE | LVS_EX_TRACKSELECT);
exStyle |= LVS_EX_ONECLICKACTIVATE | LVS_EX_TRACKSELECT;
exStyle |= LVS_EX_FULLROWSELECT;
if (exStyle != 0)
_listView.SetExtendedListViewStyle(exStyle);
SetText(Title);
const int kWidth = 400;
LVCOLUMN columnInfo;
columnInfo.mask = LVCF_FMT | LVCF_WIDTH | LVCF_SUBITEM;
columnInfo.fmt = LVCFMT_LEFT;
columnInfo.iSubItem = 0;
columnInfo.cx = 200;
columnInfo.cx = kWidth;
columnInfo.pszText = NULL; // (TCHAR *)(const TCHAR *)""; // "Property"
_listView.InsertColumn(0, &columnInfo);
if (NumColumns > 1)
{
columnInfo.cx = 100;
/*
// Windows always uses LVCFMT_LEFT for first column.
// if we need LVCFMT_RIGHT, we can create dummy column and then remove it
// columnInfo.mask |= LVCF_TEXT;
_listView.InsertColumn(0, &columnInfo);
columnInfo.iSubItem = 1;
columnInfo.fmt = LVCFMT_RIGHT;
_listView.InsertColumn(1, &columnInfo);
_listView.DeleteColumn(0);
*/
}
// else
_listView.InsertColumn(0, &columnInfo);
if (NumColumns > 1)
{
// columnInfo.fmt = LVCFMT_LEFT;
columnInfo.cx = kWidth - columnInfo.cx;
columnInfo.iSubItem = 1;
// columnInfo.pszText = NULL; // (TCHAR *)(const TCHAR *)""; // "Value"
_listView.InsertColumn(1, &columnInfo);
}
UString s;
FOR_VECTOR (i, Strings)
{
_listView.InsertItem(i, Strings[i]);
if (Strings.Size() > 0)
if (NumColumns > 1 && i < Values.Size())
{
s = Values[i];
if (s.Len() > kOneStringMaxSize)
{
s.DeleteFrom(kOneStringMaxSize);
s += " ...";
}
s.Replace(L"\r\n", L" ");
s.Replace(L"\n", L" ");
_listView.SetSubItem(i, 1, s);
}
}
if (SelectFirst && Strings.Size() > 0)
_listView.SetItemState_FocusedSelected(0);
_listView.SetColumnWidthAuto(0);
if (NumColumns > 1)
_listView.SetColumnWidthAuto(1);
StringsWereChanged = false;
NormalizeSize();
@@ -74,8 +158,97 @@ bool CListViewDialog::OnSize(WPARAM /* wParam */, int xSize, int ySize)
return false;
}
extern bool g_LVN_ITEMACTIVATE_Support;
void CListViewDialog::CopyToClipboard()
{
CUIntVector indexes;
ListView_GetSelected(_listView, indexes);
UString s;
FOR_VECTOR (i, indexes)
{
unsigned index = indexes[i];
s += Strings[index];
if (NumColumns > 1 && index < Values.Size())
{
const UString &v = Values[index];
// if (!v.IsEmpty())
{
s += ": ";
s += v;
}
}
// if (indexes.Size() > 1)
{
s +=
#ifdef _WIN32
"\r\n"
#else
"\n"
#endif
;
}
}
ClipboardSetText(*this, s);
}
void CListViewDialog::ShowItemInfo()
{
CUIntVector indexes;
ListView_GetSelected(_listView, indexes);
if (indexes.Size() != 1)
return;
unsigned index = indexes[0];
CEditDialog dlg;
if (NumColumns == 1)
dlg.Text = Strings[index];
else
{
dlg.Title = Strings[index];
if (index < Values.Size())
dlg.Text = Values[index];
}
dlg.Create(*this);
}
void CListViewDialog::DeleteItems()
{
for (;;)
{
int index = _listView.GetNextSelectedItem(-1);
if (index < 0)
break;
StringsWereChanged = true;
_listView.DeleteItem(index);
if ((unsigned)index < Strings.Size())
Strings.Delete(index);
if ((unsigned)index < Values.Size())
Values.Delete(index);
}
int focusedIndex = _listView.GetFocusedItem();
if (focusedIndex >= 0)
_listView.SetItemState_FocusedSelected(focusedIndex);
_listView.SetColumnWidthAuto(0);
}
void CListViewDialog::OnEnter()
{
if (IsKeyDown(VK_MENU)
|| NumColumns > 1)
{
ShowItemInfo();
return;
}
OnOK();
}
bool CListViewDialog::OnNotify(UINT /* controlID */, LPNMHDR header)
{
if (header->hwndFrom != _listView)
@@ -85,7 +258,7 @@ bool CListViewDialog::OnNotify(UINT /* controlID */, LPNMHDR header)
case LVN_ITEMACTIVATE:
if (g_LVN_ITEMACTIVATE_Support)
{
OnOK();
OnEnter();
return true;
}
break;
@@ -93,7 +266,7 @@ bool CListViewDialog::OnNotify(UINT /* controlID */, LPNMHDR header)
case NM_RETURN: // probabably it's unused
if (!g_LVN_ITEMACTIVATE_Support)
{
OnOK();
OnEnter();
return true;
}
break;
@@ -107,19 +280,7 @@ bool CListViewDialog::OnNotify(UINT /* controlID */, LPNMHDR header)
{
if (!DeleteIsAllowed)
return false;
for (;;)
{
int index = _listView.GetNextSelectedItem(-1);
if (index < 0)
break;
StringsWereChanged = true;
_listView.DeleteItem(index);
Strings.Delete(index);
}
int focusedIndex = _listView.GetFocusedItem();
if (focusedIndex >= 0)
_listView.SetItemState_FocusedSelected(focusedIndex);
_listView.SetColumnWidthAuto(0);
DeleteItems();
return true;
}
case 'A':
@@ -129,6 +290,17 @@ bool CListViewDialog::OnNotify(UINT /* controlID */, LPNMHDR header)
_listView.SelectAll();
return true;
}
break;
}
case VK_INSERT:
case 'C':
{
if (IsKeyDown(VK_CONTROL))
{
CopyToClipboard();
return true;
}
break;
}
}
}

View File

@@ -15,16 +15,32 @@ class CListViewDialog: public NWindows::NControl::CModalDialog
virtual bool OnInit();
virtual bool OnSize(WPARAM wParam, int xSize, int ySize);
virtual bool OnNotify(UINT controlID, LPNMHDR header);
void CopyToClipboard();
void DeleteItems();
void ShowItemInfo();
void OnEnter();
public:
UString Title;
bool SelectFirst;
bool DeleteIsAllowed;
bool StringsWereChanged;
UStringVector Strings;
UStringVector Values;
int FocusedItemIndex;
unsigned NumColumns;
INT_PTR Create(HWND wndParent = 0) { return CModalDialog::Create(IDD_LISTVIEW, wndParent); }
CListViewDialog(): DeleteIsAllowed(false) {}
CListViewDialog():
SelectFirst(false),
DeleteIsAllowed(false),
StringsWereChanged(false),
FocusedItemIndex(-1),
NumColumns(1)
{}
};
#endif

View File

@@ -1,8 +1,8 @@
#include "ListViewDialogRes.h"
#include "../../GuiCommon.rc"
#define xc 320
#define yc 240
#define xc 440
#define yc 320
IDD_LISTVIEW DIALOG 0, 0, xs, ys MY_MODAL_RESIZE_DIALOG_STYLE MY_FONT
CAPTION "ListView"

View File

@@ -16,7 +16,11 @@ using namespace NWindows;
class CPanelCopyThread: public CProgressThreadVirt
{
bool ResultsWereShown;
bool NeedShowRes;
HRESULT ProcessVirt();
virtual void ProcessWasFinished_GuiVirt();
public:
const CCopyToOptions *options;
CMyComPtr<IFolderOperations> FolderOperations;
@@ -28,11 +32,31 @@ public:
UString FirstFilePath;
HRESULT Result;
CPanelCopyThread(): Result(E_FAIL) {}
};
void ShowFinalResults(HWND hwnd);
CPanelCopyThread():
Result(E_FAIL),
ResultsWereShown(false),
NeedShowRes(false)
{}
};
void CPanelCopyThread::ShowFinalResults(HWND hwnd)
{
if (NeedShowRes)
if (!ResultsWereShown)
{
ResultsWereShown = true;
ShowHashResults(Hash, fs2us(FirstFilePath), hwnd);
}
}
void CPanelCopyThread::ProcessWasFinished_GuiVirt()
{
ShowFinalResults(*this);
}
HRESULT CPanelCopyThread::ProcessVirt()
{
/*
@@ -69,11 +93,15 @@ HRESULT CPanelCopyThread::ProcessVirt()
BoolToInt(options->replaceAltStreamChars),
options->folder, ExtractCallback);
if (Result == S_OK && !ExtractCallbackSpec->ThereAreMessageErrors &&
(!options->hashMethods.IsEmpty() || options->testMode))
if (Result == S_OK && !ExtractCallbackSpec->ThereAreMessageErrors)
{
CProgressMessageBoxPair &pair = GetMessagePair(false); // GetMessagePair(ExtractCallbackSpec->Hash.NumErrors != 0);
AddHashBundleRes(pair.Message, Hash, FirstFilePath);
if (!options->hashMethods.IsEmpty())
NeedShowRes = true;
else if (options->testMode)
{
CProgressMessageBoxPair &pair = GetMessagePair(false); // GetMessagePair(ExtractCallbackSpec->Hash.NumErrors != 0);
AddHashBundleRes(pair.Message, Hash, FirstFilePath);
}
}
return Result;
@@ -92,7 +120,6 @@ static void ThrowException_if_Error(HRESULT res)
#endif
*/
HRESULT CPanel::CopyTo(CCopyToOptions &options, const CRecordVector<UInt32> &indices,
UStringVector *messages,
bool &usePassword, UString &password)
@@ -102,7 +129,7 @@ HRESULT CPanel::CopyTo(CCopyToOptions &options, const CRecordVector<UInt32> &ind
UString errorMessage = LangString(IDS_OPERATION_IS_NOT_SUPPORTED);
if (options.showErrorMessages)
MessageBox_Error(errorMessage);
else if (messages != 0)
else if (messages)
messages->Add(errorMessage);
return E_FAIL;
}
@@ -124,8 +151,8 @@ HRESULT CPanel::CopyTo(CCopyToOptions &options, const CRecordVector<UInt32> &ind
extracter.ExtractCallback = extracter.ExtractCallbackSpec;
extracter.options = &options;
extracter.ExtractCallbackSpec->ProgressDialog = &extracter.ProgressDialog;
extracter.ProgressDialog.CompressingMode = false;
extracter.ExtractCallbackSpec->ProgressDialog = &extracter;
extracter.CompressingMode = false;
extracter.ExtractCallbackSpec->StreamMode = options.streamMode;
@@ -185,9 +212,9 @@ HRESULT CPanel::CopyTo(CCopyToOptions &options, const CRecordVector<UInt32> &ind
UString progressWindowTitle ("7-Zip"); // LangString(IDS_APP_TITLE);
extracter.ProgressDialog.MainWindow = GetParent();
extracter.ProgressDialog.MainTitle = progressWindowTitle;
extracter.ProgressDialog.MainAddTitle = title + L' ';
extracter.MainWindow = GetParent();
extracter.MainTitle = progressWindowTitle;
extracter.MainAddTitle = title + L' ';
extracter.ExtractCallbackSpec->OverwriteMode = NExtract::NOverwriteMode::kAsk;
extracter.ExtractCallbackSpec->Init();
@@ -199,8 +226,9 @@ HRESULT CPanel::CopyTo(CCopyToOptions &options, const CRecordVector<UInt32> &ind
RINOK(extracter.Create(title, GetParent()));
if (messages != 0)
*messages = extracter.ProgressDialog.Sync.Messages;
if (messages)
*messages = extracter.Sync.Messages;
res = extracter.Result;
if (res == S_OK && extracter.ExtractCallbackSpec->IsOK())
@@ -208,6 +236,9 @@ HRESULT CPanel::CopyTo(CCopyToOptions &options, const CRecordVector<UInt32> &ind
usePassword = extracter.ExtractCallbackSpec->PasswordIsDefined;
password = extracter.ExtractCallbackSpec->Password;
}
extracter.ShowFinalResults(_window);
}
RefreshTitleAlways();
@@ -296,8 +327,8 @@ HRESULT CPanel::CopyFrom(bool moveMode, const UString &folderPrefix, const UStri
NWindows::CThread thread;
RINOK(thread.Create(CThreadUpdate::MyThreadFunction, &updater));
updater.ProgressDialog.Create(title, thread, GetParent());
if (messages != 0)
if (messages)
*messages = updater.ProgressDialog.Sync.Messages;
res = updater.Result;
@@ -308,7 +339,7 @@ HRESULT CPanel::CopyFrom(bool moveMode, const UString &folderPrefix, const UStri
UString errorMessage = LangString(IDS_OPERATION_IS_NOT_SUPPORTED);
if (showErrorMessages)
MessageBox_Error(errorMessage);
else if (messages != 0)
else if (messages)
messages->Add(errorMessage);
return E_ABORT;
}

View File

@@ -139,18 +139,44 @@ DWORD CDirEnumerator::GetNextFile(NFind::CFileInfo &fi, bool &filled, FString &r
class CThreadCrc: public CProgressThreadVirt
{
bool ResultsWereShown;
bool WasFinished;
HRESULT ProcessVirt();
virtual void ProcessWasFinished_GuiVirt();
public:
CDirEnumerator Enumerator;
CHashBundle Hash;
FString FirstFilePath;
void SetStatus(const UString &s);
void AddErrorMessage(DWORD systemError, const FChar *name);
void ShowFinalResults(HWND hwnd);
CThreadCrc():
ResultsWereShown(false),
WasFinished(false)
{}
};
void CThreadCrc::ShowFinalResults(HWND hwnd)
{
if (WasFinished)
if (!ResultsWereShown)
{
ResultsWereShown = true;
ShowHashResults(Hash, fs2us(FirstFilePath), hwnd);
}
}
void CThreadCrc::ProcessWasFinished_GuiVirt()
{
ShowFinalResults(*this);
}
void CThreadCrc::AddErrorMessage(DWORD systemError, const FChar *name)
{
ProgressDialog.Sync.AddError_Code_Name(systemError, fs2us(Enumerator.BasePrefix + name));
Sync.AddError_Code_Name(systemError, fs2us(Enumerator.BasePrefix + name));
Hash.NumErrors++;
}
@@ -162,7 +188,7 @@ void CThreadCrc::SetStatus(const UString &s2)
s.Add_Space_if_NotEmpty();
s += fs2us(Enumerator.BasePrefix);
}
ProgressDialog.Sync.Set_Status(s);
Sync.Set_Status(s);
}
HRESULT CThreadCrc::ProcessVirt()
@@ -173,7 +199,7 @@ HRESULT CThreadCrc::ProcessVirt()
if (!buf.Allocate(kBufSize))
return E_OUTOFMEMORY;
CProgressSync &sync = ProgressDialog.Sync;
CProgressSync &sync = Sync;
SetStatus(LangString(IDS_SCANNING));
@@ -233,7 +259,6 @@ HRESULT CThreadCrc::ProcessVirt()
Enumerator.Init();
FString tempPath;
FString firstFilePath;
bool isFirstFile = true;
UInt64 errorsFilesSize = 0;
@@ -264,7 +289,7 @@ HRESULT CThreadCrc::ProcessVirt()
}
if (isFirstFile)
{
firstFilePath = path;
FirstFilePath = path;
isFirstFile = false;
}
sync.Set_FilePath(fs2us(path));
@@ -303,12 +328,13 @@ HRESULT CThreadCrc::ProcessVirt()
SetStatus(L"");
CProgressMessageBoxPair &pair = GetMessagePair(Hash.NumErrors != 0);
AddHashBundleRes(pair.Message, Hash, fs2us(firstFilePath));
WasFinished = true;
LangString(IDS_CHECKSUM_INFORMATION, pair.Title);
return S_OK;
}
HRESULT CApp::CalculateCrc2(const UString &methodName)
{
unsigned srcPanelIndex = GetFocusedPanelIndex();
@@ -338,6 +364,7 @@ HRESULT CApp::CalculateCrc2(const UString &methodName)
{
CThreadCrc t;
{
UStringVector methods;
methods.Add(methodName);
@@ -360,17 +387,20 @@ HRESULT CApp::CalculateCrc2(const UString &methodName)
t.Enumerator.EnterToDirs = !GetFlatMode();
t.ProgressDialog.ShowCompressionInfo = false;
t.ShowCompressionInfo = false;
UString title = LangString(IDS_CHECKSUM_CALCULATING);
t.ProgressDialog.MainWindow = _window;
t.ProgressDialog.MainTitle = "7-Zip"; // LangString(IDS_APP_TITLE);
t.ProgressDialog.MainAddTitle = title;
t.ProgressDialog.MainAddTitle.Add_Space();
t.MainWindow = _window;
t.MainTitle = "7-Zip"; // LangString(IDS_APP_TITLE);
t.MainAddTitle = title;
t.MainAddTitle.Add_Space();
RINOK(t.Create(title, _window));
t.ShowFinalResults(_window);
}
RefreshTitleAlways();
return S_OK;
}

View File

@@ -81,15 +81,17 @@ CDataObject::CDataObject()
STDMETHODIMP CDataObject::SetData(LPFORMATETC etc, STGMEDIUM *medium, BOOL /* release */)
{
if (etc->cfFormat == m_SetFolderFormat && etc->tymed == TYMED_HGLOBAL &&
etc->dwAspect == DVASPECT_CONTENT && medium->tymed == TYMED_HGLOBAL)
if (etc->cfFormat == m_SetFolderFormat
&& etc->tymed == TYMED_HGLOBAL
&& etc->dwAspect == DVASPECT_CONTENT
&& medium->tymed == TYMED_HGLOBAL)
{
Path.Empty();
if (medium->hGlobal == 0)
if (!medium->hGlobal)
return S_OK;
size_t size = GlobalSize(medium->hGlobal) / sizeof(wchar_t);
const wchar_t *src = (const wchar_t *)GlobalLock(medium->hGlobal);
if (src != 0)
if (src)
{
for (size_t i = 0; i < size; i++)
{
@@ -109,13 +111,13 @@ static HGLOBAL DuplicateGlobalMem(HGLOBAL srcGlobal)
{
SIZE_T size = GlobalSize(srcGlobal);
const void *src = GlobalLock(srcGlobal);
if (src == 0)
if (!src)
return 0;
HGLOBAL destGlobal = GlobalAlloc(GHND | GMEM_SHARE, size);
if (destGlobal != 0)
if (destGlobal)
{
void *dest = GlobalLock(destGlobal);
if (dest == 0)
if (!dest)
{
GlobalFree(destGlobal);
destGlobal = 0;
@@ -136,7 +138,7 @@ STDMETHODIMP CDataObject::GetData(LPFORMATETC etc, LPSTGMEDIUM medium)
medium->tymed = m_Etc.tymed;
medium->pUnkForRelease = 0;
medium->hGlobal = DuplicateGlobalMem(hGlobal);
if (medium->hGlobal == 0)
if (!medium->hGlobal)
return E_OUTOFMEMORY;
return S_OK;
}
@@ -261,7 +263,7 @@ static bool CopyNamesToHGlobal(NMemory::CGlobal &hgDrop, const UStringVector &na
NMemory::CGlobalLock dropLock(hgDrop);
DROPFILES* dropFiles = (DROPFILES*)dropLock.GetPointer();
if (dropFiles == 0)
if (!dropFiles)
return false;
dropFiles->fNC = FALSE;
dropFiles->pt.x = 0;
@@ -291,7 +293,7 @@ static bool CopyNamesToHGlobal(NMemory::CGlobal &hgDrop, const UStringVector &na
NMemory::CGlobalLock dropLock(hgDrop);
DROPFILES* dropFiles = (DROPFILES*)dropLock.GetPointer();
if (dropFiles == 0)
if (!dropFiles)
return false;
dropFiles->fNC = FALSE;
dropFiles->pt.x = 0;
@@ -336,7 +338,11 @@ void CPanel::OnDrag(LPNMLISTVIEW /* nmListView */)
dirPrefix = us2fs(GetFsPath());
else
{
tempDirectory.Create(kTempDirPrefix);
if (!tempDirectory.Create(kTempDirPrefix))
{
MessageBox_Error(L"Can't create temp folder");
return;
}
dirPrefix = tempDirectory.GetPath();
// dirPrefix2 = dirPrefix;
NFile::NName::NormalizeDirPathPrefix(dirPrefix);
@@ -394,11 +400,67 @@ void CPanel::OnDrag(LPNMLISTVIEW /* nmListView */)
dropSourceSpec->DataObjectSpec = dataObjectSpec;
dropSourceSpec->DataObject = dataObjectSpec;
bool moveIsAllowed = isFSFolder;
/*
CTime - file creation timestamp.
There are two operations in Windows with Drag and Drop:
COPY_OPERATION - icon with Plus sign - CTime will be set as current_time.
MOVE_OPERATION - icon without Plus sign - CTime will be preserved
Note: if we call DoDragDrop() with (effectsOK = DROPEFFECT_MOVE), then
it will use MOVE_OPERATION and CTime will be preserved.
But MoveFile() function doesn't preserve CTime, if different volumes are used.
Why it's so?
Does DoDragDrop() use some another function (not MoveFile())?
if (effectsOK == DROPEFFECT_COPY) it works as COPY_OPERATION
if (effectsOK == DROPEFFECT_MOVE) drag works as MOVE_OPERATION
if (effectsOK == (DROPEFFECT_COPY | DROPEFFECT_MOVE))
{
if we drag file to same volume, then Windows suggests:
CTRL - COPY_OPERATION
[default] - MOVE_OPERATION
if we drag file to another volume, then Windows suggests
[default] - COPY_OPERATION
SHIFT - MOVE_OPERATION
}
We want to use MOVE_OPERATION for extracting from archive (open in 7-Zip) to Explorer:
It has the following advantages:
1) it uses fast MOVE_OPERATION instead of slow COPY_OPERATION and DELETE, if same volume.
2) it preserved CTime
Some another programs support only COPY_OPERATION.
So we can use (DROPEFFECT_COPY | DROPEFFECT_MOVE)
Also another program can return from DoDragDrop() before
files using. But we delete temp folder after DoDragDrop(),
and another program can't open input files in that case.
We create objects:
IDropSource *dropSource
IDataObject *dataObject
if DropTarget is 7-Zip window, then 7-Zip's
IDropTarget::DragOver() sets Path in IDataObject.
and
IDropSource::QueryContinueDrag() sets NeedPostCopy, if Path is not epmty.
So we can detect destination path after DoDragDrop().
Now we don't know any good way to detect destination path for D&D to Explorer.
*/
bool moveIsAllowed = isFSFolder;
/*
DWORD effectsOK = DROPEFFECT_COPY;
if (moveIsAllowed)
effectsOK |= DROPEFFECT_MOVE;
*/
// 18.04: was changed
DWORD effectsOK = DROPEFFECT_MOVE | DROPEFFECT_COPY;
DWORD effect;
_panelCallback->DragBegin();
@@ -418,7 +480,8 @@ void CPanel::OnDrag(LPNMLISTVIEW /* nmListView */)
NFile::NName::NormalizeDirPathPrefix(dataObjectSpec->Path);
CCopyToOptions options;
options.folder = dataObjectSpec->Path;
options.moveMode = (effect == DROPEFFECT_MOVE);
// if MOVE is not allowed, we just use COPY operation
options.moveMode = (effect == DROPEFFECT_MOVE && moveIsAllowed);
res = CopyTo(options, indices, &dropSourceSpec->Messages);
}
/*
@@ -475,7 +538,7 @@ static void MySetDropHighlighted(HWND hWnd, int index, bool enable)
void CDropTarget::RemoveSelection()
{
if (m_SelectionIndex >= 0 && m_Panel != 0)
if (m_SelectionIndex >= 0 && m_Panel)
MySetDropHighlighted(m_Panel->_listView, m_SelectionIndex, false);
m_SelectionIndex = -1;
}
@@ -555,7 +618,7 @@ void CDropTarget::PositionCursor(POINTL ptl)
bool CDropTarget::IsFsFolderPath() const
{
if (!m_IsAppTarget && m_Panel != 0)
if (!m_IsAppTarget && m_Panel)
return (m_Panel->IsFSFolder() || (m_Panel->IsFSDrivesFolder() && m_SelectionIndex >= 0));
return false;
}
@@ -614,7 +677,7 @@ static void GetNamesFromDataObject(IDataObject *dataObject, UStringVector &names
size_t blockSize = GlobalSize(medium.hGlobal);
NMemory::CGlobalLock dropLock(medium.hGlobal);
const DROPFILES* dropFiles = (DROPFILES*)dropLock.GetPointer();
if (dropFiles == 0)
if (!dropFiles)
return;
if (blockSize < dropFiles->pFiles)
return;
@@ -629,7 +692,7 @@ static void GetNamesFromDataObject(IDataObject *dataObject, UStringVector &names
bool CDropTarget::IsItSameDrive() const
{
if (m_Panel == 0)
if (!m_Panel)
return false;
if (!IsFsFolderPath())
return false;
@@ -662,6 +725,21 @@ bool CDropTarget::IsItSameDrive() const
return true;
}
/*
There are 2 different actions, when we drag to 7-Zip:
1) Drag from any external program except of Explorer to "7-Zip" FS folder.
We want to create new archive for that operation.
2) all another operation work as usual file COPY/MOVE
- Drag from "7-Zip" FS to "7-Zip" FS.
COPY/MOVE are supported.
- Drag to open archive in 7-Zip.
We want to update archive.
We replace COPY to MOVE.
- Drag from "7-Zip" archive to "7-Zip" FS.
We replace COPY to MOVE.
*/
DWORD CDropTarget::GetEffect(DWORD keyState, POINTL /* pt */, DWORD allowedEffect)
{
if (!m_DropIsAllowed || !m_PanelDropIsAllowed)
@@ -671,10 +749,12 @@ DWORD CDropTarget::GetEffect(DWORD keyState, POINTL /* pt */, DWORD allowedEffec
allowedEffect &= ~DROPEFFECT_MOVE;
DWORD effect = 0;
if (keyState & MK_CONTROL)
effect = allowedEffect & DROPEFFECT_COPY;
else if (keyState & MK_SHIFT)
effect = allowedEffect & DROPEFFECT_MOVE;
if (effect == 0)
{
if (allowedEffect & DROPEFFECT_COPY)
@@ -716,10 +796,10 @@ bool CDropTarget::SetPath(bool enablePath) const
path = GetTargetPath();
size_t size = path.Len() + 1;
medium.hGlobal = GlobalAlloc(GHND | GMEM_SHARE, size * sizeof(wchar_t));
if (medium.hGlobal == 0)
if (!medium.hGlobal)
return false;
wchar_t *dest = (wchar_t *)GlobalLock(medium.hGlobal);
if (dest == 0)
if (!dest)
{
GlobalUnlock(medium.hGlobal);
return false;

View File

@@ -625,6 +625,7 @@ void CPanel::FoldersHistory()
{
CListViewDialog listViewDialog;
listViewDialog.DeleteIsAllowed = true;
listViewDialog.SelectFirst = true;
LangString(IDS_FOLDERS_HISTORY, listViewDialog.Title);
_appState->FolderHistory.GetList(listViewDialog.Strings);
if (listViewDialog.Create(GetParent()) != IDOK)

View File

@@ -674,7 +674,7 @@ static const char * const kStartExtensions =
#endif
" exe bat ps1 com"
" chm"
" msi doc xls ppt pps wps wpt wks xlr wdb vsd pub"
" msi doc dot xls ppt pps wps wpt wks xlr wdb vsd pub"
" docx docm dotx dotm xlsx xlsm xltx xltm xlsb xps"
" xlam pptx pptm potx potm ppam ppsx ppsm xsn"
@@ -1151,7 +1151,7 @@ HRESULT CPanel::OnOpenItemChanged(UInt32 index, const wchar_t *fullFilePath,
CThreadCopyFrom t;
t.UpdateCallbackSpec = new CUpdateCallback100Imp;
t.UpdateCallback = t.UpdateCallbackSpec;
t.UpdateCallbackSpec->ProgressDialog = &t.ProgressDialog;
t.UpdateCallbackSpec->ProgressDialog = &t;
t.ItemIndex = index;
t.FullPath = fullFilePath;
t.FolderOperations = _folderOperations;

View File

@@ -16,6 +16,7 @@
#include "App.h"
#include "FormatUtils.h"
#include "LangUtils.h"
#include "ListViewDialog.h"
#include "MyLoadMenu.h"
#include "PropertyName.h"
@@ -50,17 +51,40 @@ void CPanel::InvokeSystemCommand(const char *command)
contextMenu->InvokeCommand(&ci);
}
static const char * const kSeparator = "----------------------------\n";
static const char * const kSeparatorSmall = "----\n";
static const char * const kPropValueSeparator = ": ";
static const char * const kSeparator = "------------------------";
static const char * const kSeparatorSmall = "----------------";
extern UString ConvertSizeToString(UInt64 value) throw();
bool IsSizeProp(UINT propID) throw();
UString GetOpenArcErrorMessage(UInt32 errorFlags);
static void AddListAscii(CListViewDialog &dialog, const char *s)
{
dialog.Strings.Add((UString)s);
dialog.Values.AddNew();
}
static void AddSeparator(CListViewDialog &dialog)
{
AddListAscii(dialog, kSeparator);
}
static void AddSeparatorSmall(CListViewDialog &dialog)
{
AddListAscii(dialog, kSeparatorSmall);
}
static void AddPropertyPair(const UString &name, const UString &val, CListViewDialog &dialog)
{
dialog.Strings.Add(name);
dialog.Values.Add(val);
}
static void AddPropertyString(PROPID propID, const wchar_t *nameBSTR,
const NCOM::CPropVariant &prop, UString &s)
const NCOM::CPropVariant &prop, CListViewDialog &dialog)
{
if (prop.vt != VT_EMPTY)
{
@@ -87,23 +111,16 @@ static void AddPropertyString(PROPID propID, const wchar_t *nameBSTR,
if (!val.IsEmpty())
{
s += GetNameOfProperty(propID, nameBSTR);
s += kPropValueSeparator;
/*
if (propID == kpidComment)
s.Add_LF();
*/
s += val;
s.Add_LF();
AddPropertyPair(GetNameOfProperty(propID, nameBSTR), val, dialog);
}
}
}
static void AddPropertyString(PROPID propID, UInt64 val, UString &s)
static void AddPropertyString(PROPID propID, UInt64 val, CListViewDialog &dialog)
{
NCOM::CPropVariant prop = val;
AddPropertyString(propID, NULL, prop, s);
AddPropertyString(propID, NULL, prop, dialog);
}
@@ -137,7 +154,9 @@ void CPanel::Properties()
}
{
UString message;
CListViewDialog message;
// message.DeleteIsAllowed = false;
// message.SelectFirst = false;
CRecordVector<UInt32> operatedIndices;
GetOperatedItemIndices(operatedIndices);
@@ -205,15 +224,12 @@ void CPanel::Properties()
}
}
}
message += GetNameOfProperty(propID, name);
message += kPropValueSeparator;
message += s.Ptr();
message.Add_LF();
AddPropertyPair(GetNameOfProperty(propID, name), (UString)s.Ptr(), message);
}
}
}
message += kSeparator;
AddSeparator(message);
}
else if (operatedIndices.Size() >= 1)
{
@@ -239,8 +255,7 @@ void CPanel::Properties()
{
wchar_t temp[32];
ConvertUInt32ToString(operatedIndices.Size(), temp);
message += MyFormatNew(g_App.LangString_N_SELECTED_ITEMS, temp);
message.Add_LF();
AddPropertyPair(L"", MyFormatNew(g_App.LangString_N_SELECTED_ITEMS, temp), message);
}
if (numDirs != 0)
@@ -250,7 +265,7 @@ void CPanel::Properties()
AddPropertyString(kpidSize, unpackSize, message);
AddPropertyString(kpidPackSize, packSize, message);
message += kSeparator;
AddSeparator(message);
}
@@ -309,7 +324,7 @@ void CPanel::Properties()
{
const int kNumSpecProps = ARRAY_SIZE(kSpecProps);
message += kSeparator;
AddSeparator(message);
for (Int32 i = -(int)kNumSpecProps; i < (Int32)numProps; i++)
{
@@ -334,7 +349,7 @@ void CPanel::Properties()
UInt32 numProps;
if (getProps->GetArcNumProps2(level, &numProps) == S_OK)
{
message += kSeparatorSmall;
AddSeparatorSmall(message);
for (Int32 i = 0; i < (Int32)numProps; i++)
{
CMyComBSTR name;
@@ -352,10 +367,15 @@ void CPanel::Properties()
}
}
}
::MessageBoxW(*(this), message, LangString(IDS_PROPERTIES), MB_OK);
message.Title = LangString(IDS_PROPERTIES);
message.NumColumns = 2;
message.Create(GetParent());
}
}
void CPanel::EditCut()
{
// InvokeSystemCommand("cut");

View File

@@ -79,10 +79,10 @@ HRESULT CThreadFolderOperations::DoOperation(CPanel &panel, const UString &progr
{
UpdateCallbackSpec = new CUpdateCallback100Imp;
UpdateCallback = UpdateCallbackSpec;
UpdateCallbackSpec->ProgressDialog = &ProgressDialog;
UpdateCallbackSpec->ProgressDialog = this;
ProgressDialog.WaitMode = true;
ProgressDialog.Sync.FinalMessage.ErrorMessage.Title = titleError;
WaitMode = true;
Sync.FinalMessage.ErrorMessage.Title = titleError;
Result = S_OK;
UpdateCallbackSpec->Init();
@@ -95,11 +95,11 @@ HRESULT CThreadFolderOperations::DoOperation(CPanel &panel, const UString &progr
}
ProgressDialog.MainWindow = panel._mainWindow; // panel.GetParent()
ProgressDialog.MainTitle = "7-Zip"; // LangString(IDS_APP_TITLE);
ProgressDialog.MainAddTitle = progressTitle + L' ';
MainWindow = panel._mainWindow; // panel.GetParent()
MainTitle = "7-Zip"; // LangString(IDS_APP_TITLE);
MainAddTitle = progressTitle + L' ';
RINOK(Create(progressTitle, ProgressDialog.MainWindow));
RINOK(Create(progressTitle, MainWindow));
return Result;
}

View File

@@ -157,7 +157,7 @@ HRESULT CThreadSplit::ProcessVirt()
if (!inFile.GetLength(length))
return GetLastError();
CProgressSync &sync = ProgressDialog.Sync;
CProgressSync &sync = Sync;
sync.Set_NumBytesTotal(length);
UInt64 pos = 0;
@@ -306,7 +306,7 @@ void CApp::Split()
CThreadSplit spliter;
spliter.NumVolumes = numVolumes;
CProgressDialog &progressDialog = spliter.ProgressDialog;
CProgressDialog &progressDialog = spliter;
UString progressWindowTitle ("7-Zip"); // LangString(IDS_APP_TITLE, 0x03000000);
UString title = LangString(IDS_SPLITTING);
@@ -362,7 +362,7 @@ HRESULT CThreadCombine::ProcessVirt()
return res;
}
CProgressSync &sync = ProgressDialog.Sync;
CProgressSync &sync = Sync;
sync.Set_NumBytesTotal(TotalSize);
CMyBuffer bufferObject;
@@ -534,7 +534,7 @@ void CApp::Combine()
return;
}
CProgressDialog &progressDialog = combiner.ProgressDialog;
CProgressDialog &progressDialog = combiner;
progressDialog.ShowCompressionInfo = false;
UString progressWindowTitle ("7-Zip"); // LangString(IDS_APP_TITLE, 0x03000000);

View File

@@ -236,7 +236,10 @@ void CProgressSync::AddError_Code_Name(DWORD systemError, const wchar_t *name)
AddError_Message_Name(s, name);
}
CProgressDialog::CProgressDialog(): _timer(0), CompressingMode(true), MainWindow(0)
CProgressDialog::CProgressDialog():
_timer(0),
CompressingMode(true),
MainWindow(0)
{
_isDir = false;
@@ -974,7 +977,9 @@ bool CProgressDialog::OnExternalCloseMessage()
::SendMessage(GetItem(IDCANCEL), BM_SETSTYLE, BS_DEFPUSHBUTTON, MAKELPARAM(TRUE, 0));
HideItem(IDB_PROGRESS_BACKGROUND);
HideItem(IDB_PAUSE);
ProcessWasFinished_GuiVirt();
bool thereAreMessages;
CProgressFinalMessage fm;
{
@@ -982,6 +987,7 @@ bool CProgressDialog::OnExternalCloseMessage()
thereAreMessages = !Sync.Messages.IsEmpty();
fm = Sync.FinalMessage;
}
if (!fm.ErrorMessage.Message.IsEmpty())
{
MessagesDisplayed = true;
@@ -992,6 +998,7 @@ bool CProgressDialog::OnExternalCloseMessage()
else if (!thereAreMessages)
{
MessagesDisplayed = true;
if (!fm.OkMessage.Message.IsEmpty())
{
if (fm.OkMessage.Title.IsEmpty())
@@ -1245,11 +1252,24 @@ void CProgressDialog::ProcessWasFinished()
}
static THREAD_FUNC_DECL MyThreadFunction(void *param)
{
CProgressThreadVirt *p = (CProgressThreadVirt *)param;
try
{
p->Process();
p->ThreadFinishedOK = true;
}
catch (...) { p->Result = E_FAIL; }
return 0;
}
HRESULT CProgressThreadVirt::Create(const UString &title, HWND parentWindow)
{
NWindows::CThread thread;
RINOK(thread.Create(MyThreadFunction, this));
ProgressDialog.Create(title, thread, parentWindow);
CProgressDialog::Create(title, thread, parentWindow);
return S_OK;
}
@@ -1265,7 +1285,7 @@ static void AddMessageToString(UString &dest, const UString &src)
void CProgressThreadVirt::Process()
{
CProgressCloser closer(ProgressDialog);
CProgressCloser closer(*this);
UString m;
try { Result = ProcessVirt(); }
catch(const wchar_t *s) { m = s; }
@@ -1293,7 +1313,7 @@ void CProgressThreadVirt::Process()
}
}
CProgressSync &sync = ProgressDialog.Sync;
CProgressSync &sync = Sync;
NSynchronization::CCriticalSectionLock lock(sync._cs);
if (m.IsEmpty())
{

View File

@@ -261,7 +261,18 @@ public:
INT_PTR Create(const UString &title, NWindows::CThread &thread, HWND wndParent = 0);
/* how it works:
1) the working thread calls ProcessWasFinished()
that sends kCloseMessage message to CProgressDialog (GUI) thread
2) CProgressDialog (GUI) thread receives kCloseMessage message and
calls ProcessWasFinished_GuiVirt();
So we can implement ProcessWasFinished_GuiVirt() and show special
results window in GUI thread with CProgressDialog as parent window
*/
void ProcessWasFinished();
virtual void ProcessWasFinished_GuiVirt() {}
};
@@ -273,7 +284,8 @@ public:
~CProgressCloser() { _p->ProcessWasFinished(); }
};
class CProgressThreadVirt
class CProgressThreadVirt: public CProgressDialog
{
protected:
FStringVector ErrorPaths;
@@ -281,33 +293,59 @@ protected:
// error if any of HRESULT, ErrorMessage, ErrorPath
virtual HRESULT ProcessVirt() = 0;
void Process();
public:
HRESULT Result;
bool ThreadFinishedOK; // if there is no fatal exception
CProgressDialog ProgressDialog;
static THREAD_FUNC_DECL MyThreadFunction(void *param)
{
CProgressThreadVirt *p = (CProgressThreadVirt *)param;
try
{
p->Process();
p->ThreadFinishedOK = true;
}
catch (...) { p->Result = E_FAIL; }
return 0;
}
void Process();
void AddErrorPath(const FString &path) { ErrorPaths.Add(path); }
HRESULT Create(const UString &title, HWND parentWindow = 0);
CProgressThreadVirt(): Result(E_FAIL), ThreadFinishedOK(false) {}
CProgressMessageBoxPair &GetMessagePair(bool isError) { return isError ? FinalMessage.ErrorMessage : FinalMessage.OkMessage; }
};
UString HResultToMessage(HRESULT errorCode);
/*
how it works:
client code inherits CProgressThreadVirt and calls
CProgressThreadVirt::Create()
{
it creates new thread that calls CProgressThreadVirt::Process();
it creates modal progress dialog window with ProgressDialog.Create()
}
CProgressThreadVirt::Process()
{
{
ProcessVirt(); // virtual function that must implement real work
}
if (exceptions) or FinalMessage.ErrorMessage.Message
{
set message to ProgressDialog.Sync.FinalMessage.ErrorMessage.Message
}
else if (FinalMessage.OkMessage.Message)
{
set message to ProgressDialog.Sync.FinalMessage.OkMessage
}
PostMsg(kCloseMessage);
}
CProgressDialog::OnExternalCloseMessage()
{
if (ProgressDialog.Sync.FinalMessage)
{
WorkWasFinishedVirt();
Show (ProgressDialog.Sync.FinalMessage)
MessagesDisplayed = true;
}
}
*/
#endif

View File

@@ -247,6 +247,7 @@ END
#include "BrowseDialog.rc"
#include "ComboDialog.rc"
#include "CopyDialog.rc"
#include "EditDialog.rc"
#include "EditPage.rc"
#include "FoldersPage.rc"
#include "LangPage.rc"