mirror of
https://github.com/Xevion/easy7zip.git
synced 2025-12-06 05:15:00 -06:00
15.13
This commit is contained in:
committed by
Kornel Lesiński
parent
5de23c1deb
commit
9608215ad8
@@ -567,14 +567,17 @@ static const char *g_Exts =
|
||||
" iso bin nrg mdf img pdi tar cpio xpi"
|
||||
" vfd vhd vud vmc vsv"
|
||||
" vmdk dsk nvram vmem vmsd vmsn vmss vmtm"
|
||||
" inl inc idl acf asa h hpp hxx c cpp cxx rc java cs pas bas vb cls ctl frm dlg def"
|
||||
" inl inc idl acf asa"
|
||||
" h hpp hxx c cpp cxx m mm go swift"
|
||||
" rc java cs rs pas bas vb cls ctl frm dlg def"
|
||||
" f77 f f90 f95"
|
||||
" asm sql manifest dep"
|
||||
" asm s"
|
||||
" sql manifest dep"
|
||||
" mak clw csproj vcproj sln dsp dsw"
|
||||
" class"
|
||||
" bat cmd"
|
||||
" bat cmd bash sh"
|
||||
" xml xsd xsl xslt hxk hxc htm html xhtml xht mht mhtml htw asp aspx css cgi jsp shtml"
|
||||
" awk sed hta js php php3 php4 php5 phptml pl pm py pyo rb sh tcl vbs"
|
||||
" awk sed hta js json php php3 php4 php5 phptml pl pm py pyo rb tcl ts vbs"
|
||||
" text txt tex ans asc srt reg ini doc docx mcw dot rtf hlp xls xlr xlt xlw ppt pdf"
|
||||
" sxc sxd sxi sxg sxw stc sti stw stm odt ott odg otg odp otp ods ots odf"
|
||||
" abw afp cwk lwp wpd wps wpt wrf wri"
|
||||
|
||||
@@ -781,6 +781,7 @@ HRESULT CFolderOutStream::Write2(const void *data, UInt32 size, UInt32 *processe
|
||||
realProcessed += size;
|
||||
if (processedSize)
|
||||
*processedSize = realProcessed;
|
||||
m_PosInFolder += size;
|
||||
return S_OK;
|
||||
// return E_FAIL;
|
||||
}
|
||||
@@ -843,7 +844,7 @@ HRESULT CFolderOutStream::FlushCorrupted(unsigned folderIndex)
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
const unsigned kBufSize = (1 << 10);
|
||||
const unsigned kBufSize = (1 << 12);
|
||||
Byte buf[kBufSize];
|
||||
for (unsigned i = 0; i < kBufSize; i++)
|
||||
buf[i] = 0;
|
||||
@@ -937,8 +938,15 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
||||
|
||||
CRecordVector<bool> extractStatuses;
|
||||
|
||||
for (i = 0; i < numItems;)
|
||||
for (i = 0;;)
|
||||
{
|
||||
lps->OutSize = totalUnPacked;
|
||||
lps->InSize = totalPacked;
|
||||
RINOK(lps->SetCur());
|
||||
|
||||
if (i >= numItems)
|
||||
break;
|
||||
|
||||
unsigned index = allFilesMode ? i : indices[i];
|
||||
|
||||
const CMvItem &mvItem = m_Database.Items[index];
|
||||
@@ -1003,10 +1011,6 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
||||
curUnpack = item.GetEndOffset();
|
||||
}
|
||||
|
||||
lps->OutSize = totalUnPacked;
|
||||
lps->InSize = totalPacked;
|
||||
RINOK(lps->SetCur());
|
||||
|
||||
CFolderOutStream *cabFolderOutStream = new CFolderOutStream;
|
||||
CMyComPtr<ISequentialOutStream> outStream(cabFolderOutStream);
|
||||
|
||||
|
||||
@@ -67,6 +67,7 @@ void CInArchive::ReadOtherArc(COtherArc &oa)
|
||||
ReadName(oa.DiskName);
|
||||
}
|
||||
|
||||
|
||||
struct CSignatureFinder
|
||||
{
|
||||
Byte *Buf;
|
||||
@@ -100,6 +101,7 @@ struct CSignatureFinder
|
||||
HRESULT Find();
|
||||
};
|
||||
|
||||
|
||||
HRESULT CSignatureFinder::Find()
|
||||
{
|
||||
for (;;)
|
||||
@@ -156,6 +158,7 @@ HRESULT CSignatureFinder::Find()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool CInArcInfo::Parse(const Byte *p)
|
||||
{
|
||||
if (Get32(p + 0x0C) != 0 ||
|
||||
@@ -177,6 +180,7 @@ bool CInArcInfo::Parse(const Byte *p)
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
HRESULT CInArchive::Open2(CDatabaseEx &db, const UInt64 *searchHeaderSizeLimit)
|
||||
{
|
||||
IsArc = false;
|
||||
@@ -286,7 +290,9 @@ HRESULT CInArchive::Open2(CDatabaseEx &db, const UInt64 *searchHeaderSizeLimit)
|
||||
if (ai.IsThereNext()) ReadOtherArc(ai.NextArc);
|
||||
|
||||
UInt32 i;
|
||||
|
||||
db.Folders.ClearAndReserve(ai.NumFolders);
|
||||
|
||||
for (i = 0; i < ai.NumFolders; i++)
|
||||
{
|
||||
Read(p, 8);
|
||||
@@ -311,6 +317,7 @@ HRESULT CInArchive::Open2(CDatabaseEx &db, const UInt64 *searchHeaderSizeLimit)
|
||||
}
|
||||
|
||||
db.Items.ClearAndReserve(ai.NumFiles);
|
||||
|
||||
for (i = 0; i < ai.NumFiles; i++)
|
||||
{
|
||||
Read(p, 16);
|
||||
@@ -324,6 +331,7 @@ HRESULT CInArchive::Open2(CDatabaseEx &db, const UInt64 *searchHeaderSizeLimit)
|
||||
item.Attributes = Get16(p + 14);
|
||||
|
||||
ReadName(item.Name);
|
||||
|
||||
if (item.GetFolderIndex(db.Folders.Size()) >= (int)db.Folders.Size())
|
||||
{
|
||||
HeaderError = true;
|
||||
@@ -336,6 +344,7 @@ HRESULT CInArchive::Open2(CDatabaseEx &db, const UInt64 *searchHeaderSizeLimit)
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
HRESULT CInArchive::Open(CDatabaseEx &db, const UInt64 *searchHeaderSizeLimit)
|
||||
{
|
||||
try
|
||||
@@ -370,6 +379,7 @@ static int CompareMvItems(const CMvItem *p1, const CMvItem *p2, void *param)
|
||||
return MyCompare(p1->ItemIndex, p2->ItemIndex);
|
||||
}
|
||||
|
||||
|
||||
bool CMvDatabaseEx::AreItemsEqual(unsigned i1, unsigned i2)
|
||||
{
|
||||
const CMvItem *p1 = &Items[i1];
|
||||
@@ -384,12 +394,15 @@ bool CMvDatabaseEx::AreItemsEqual(unsigned i1, unsigned i2)
|
||||
&& item1.Name == item2.Name;
|
||||
}
|
||||
|
||||
|
||||
void CMvDatabaseEx::FillSortAndShrink()
|
||||
{
|
||||
Items.Clear();
|
||||
StartFolderOfVol.Clear();
|
||||
FolderStartFileIndex.Clear();
|
||||
|
||||
int offset = 0;
|
||||
|
||||
FOR_VECTOR (v, Volumes)
|
||||
{
|
||||
const CDatabaseEx &db = Volumes[v];
|
||||
@@ -422,11 +435,12 @@ void CMvDatabaseEx::FillSortAndShrink()
|
||||
FOR_VECTOR (i, Items)
|
||||
{
|
||||
int folderIndex = GetFolderIndex(&Items[i]);
|
||||
if (folderIndex >= (int)FolderStartFileIndex.Size())
|
||||
while (folderIndex >= (int)FolderStartFileIndex.Size())
|
||||
FolderStartFileIndex.Add(i);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool CMvDatabaseEx::Check()
|
||||
{
|
||||
for (unsigned v = 1; v < Volumes.Size(); v++)
|
||||
@@ -444,9 +458,11 @@ bool CMvDatabaseEx::Check()
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
UInt32 beginPos = 0;
|
||||
UInt64 endPos = 0;
|
||||
int prevFolder = -2;
|
||||
|
||||
FOR_VECTOR (i, Items)
|
||||
{
|
||||
const CMvItem &mvItem = Items[i];
|
||||
@@ -456,15 +472,19 @@ bool CMvDatabaseEx::Check()
|
||||
const CItem &item = Volumes[mvItem.VolumeIndex].Items[mvItem.ItemIndex];
|
||||
if (item.IsDir())
|
||||
continue;
|
||||
|
||||
int folderIndex = GetFolderIndex(&mvItem);
|
||||
|
||||
if (folderIndex != prevFolder)
|
||||
prevFolder = folderIndex;
|
||||
else if (item.Offset < endPos &&
|
||||
(item.Offset != beginPos || item.GetEndOffset() != endPos))
|
||||
return false;
|
||||
|
||||
beginPos = item.Offset;
|
||||
endPos = item.GetEndOffset();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -25,6 +25,7 @@ struct COtherArc
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
struct CArchInfo
|
||||
{
|
||||
Byte VersionMinor; // cabinet file format version, minor
|
||||
@@ -65,6 +66,7 @@ struct CArchInfo
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
struct CInArcInfo: public CArchInfo
|
||||
{
|
||||
UInt32 Size; // size of this cabinet file in bytes
|
||||
@@ -105,17 +107,20 @@ struct CDatabase
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
struct CDatabaseEx: public CDatabase
|
||||
{
|
||||
CMyComPtr<IInStream> Stream;
|
||||
};
|
||||
|
||||
|
||||
struct CMvItem
|
||||
{
|
||||
unsigned VolumeIndex;
|
||||
unsigned ItemIndex;
|
||||
};
|
||||
|
||||
|
||||
class CMvDatabaseEx
|
||||
{
|
||||
bool AreItemsEqual(unsigned i1, unsigned i2);
|
||||
|
||||
@@ -571,6 +571,7 @@ HRESULT CDatabase::Open(IInStream *inStream)
|
||||
RINOK(AddNode(-1, root.SonDid));
|
||||
|
||||
unsigned numCabs = 0;
|
||||
|
||||
FOR_VECTOR (i, Refs)
|
||||
{
|
||||
const CItem &item = Items[Refs[i].Did];
|
||||
@@ -578,16 +579,20 @@ HRESULT CDatabase::Open(IInStream *inStream)
|
||||
continue;
|
||||
bool isMsiName;
|
||||
UString msiName = ConvertName(item.Name, isMsiName);
|
||||
if (isMsiName)
|
||||
if (isMsiName && !msiName.IsEmpty())
|
||||
{
|
||||
bool isThereExt = (msiName.Find(L'.') >= 0);
|
||||
bool isMsiSpec = (msiName[0] == k_Msi_SpecChar);
|
||||
if (msiName.Len() >= 4 && StringsAreEqualNoCase_Ascii(msiName.RightPtr(4), ".cab")
|
||||
|| msiName.Len() >= 3 && msiName[0] != k_Msi_SpecChar && StringsAreEqualNoCase_Ascii(msiName.RightPtr(3), "exe"))
|
||||
|| !isMsiSpec && msiName.Len() >= 3 && StringsAreEqualNoCase_Ascii(msiName.RightPtr(3), "exe")
|
||||
|| !isMsiSpec && !isThereExt)
|
||||
{
|
||||
numCabs++;
|
||||
MainSubfile = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (numCabs > 1)
|
||||
MainSubfile = -1;
|
||||
|
||||
|
||||
@@ -1118,7 +1118,7 @@ HRESULT CHandler::SeekAndRead(IInStream *inStream, UInt64 block, Byte *data, siz
|
||||
{
|
||||
if (block == 0 || block >= _h.NumBlocks)
|
||||
return S_FALSE;
|
||||
if (((size + (1 << _h.BlockBits) + 1) >> _h.BlockBits) > _h.NumBlocks - block)
|
||||
if (((size + ((size_t)1 << _h.BlockBits) - 1) >> _h.BlockBits) > _h.NumBlocks - block)
|
||||
return S_FALSE;
|
||||
RINOK(inStream->Seek((UInt64)block << _h.BlockBits, STREAM_SEEK_SET, NULL));
|
||||
_totalRead += size;
|
||||
@@ -1167,6 +1167,9 @@ HRESULT CHandler::Open2(IInStream *inStream)
|
||||
RINOK(_openCallback->SetTotal(NULL, &_phySize));
|
||||
}
|
||||
|
||||
UInt64 fileSize = 0;
|
||||
RINOK(inStream->Seek(0, STREAM_SEEK_END, &fileSize));
|
||||
|
||||
CRecordVector<CGroupDescriptor> groups;
|
||||
|
||||
{
|
||||
@@ -1213,6 +1216,21 @@ HRESULT CHandler::Open2(IInStream *inStream)
|
||||
|
||||
if (_h.NumInodes < _h.NumFreeInodes)
|
||||
return S_FALSE;
|
||||
|
||||
UInt32 numNodes = _h.InodesPerGroup;
|
||||
if (numNodes > _h.NumInodes)
|
||||
numNodes = _h.NumInodes;
|
||||
size_t nodesDataSize = (size_t)numNodes * _h.InodeSize;
|
||||
|
||||
if (nodesDataSize / _h.InodeSize != numNodes)
|
||||
return S_FALSE;
|
||||
|
||||
// that code to reduce false detecting cases
|
||||
if (nodesDataSize > fileSize)
|
||||
{
|
||||
if (numNodes > (1 << 24))
|
||||
return S_FALSE;
|
||||
}
|
||||
|
||||
UInt32 numReserveInodes = _h.NumInodes - _h.NumFreeInodes + 1;
|
||||
// numReserveInodes = _h.NumInodes + 1;
|
||||
@@ -1222,13 +1240,6 @@ HRESULT CHandler::Open2(IInStream *inStream)
|
||||
_refs.Reserve(numReserveInodes);
|
||||
}
|
||||
|
||||
UInt32 numNodes = _h.InodesPerGroup;
|
||||
if (numNodes > _h.NumInodes)
|
||||
numNodes = _h.NumInodes;
|
||||
size_t nodesDataSize = numNodes * _h.InodeSize;
|
||||
if (nodesDataSize / _h.InodeSize != numNodes)
|
||||
return S_FALSE;
|
||||
|
||||
CByteBuffer nodesData;
|
||||
nodesData.Alloc(nodesDataSize);
|
||||
|
||||
|
||||
@@ -160,10 +160,13 @@ bool CHeader::Parse(const Byte *p)
|
||||
if (NumFats < 1 || NumFats > 4)
|
||||
return false;
|
||||
|
||||
// we also support images that contain 0 in offset field.
|
||||
bool isOkOffset = (codeOffset == 0 || (p[0] == 0xEB && p[1] == 0));
|
||||
|
||||
UInt16 numRootDirEntries = Get16(p + 17);
|
||||
if (numRootDirEntries == 0)
|
||||
{
|
||||
if (codeOffset < 90)
|
||||
if (codeOffset < 90 && !isOkOffset)
|
||||
return false;
|
||||
NumFatBits = 32;
|
||||
NumRootDirSectors = 0;
|
||||
@@ -171,7 +174,7 @@ bool CHeader::Parse(const Byte *p)
|
||||
else
|
||||
{
|
||||
// Some FAT12s don't contain VolFields
|
||||
if (codeOffset < 62 - 24)
|
||||
if (codeOffset < 62 - 24 && !isOkOffset)
|
||||
return false;
|
||||
NumFatBits = 0;
|
||||
UInt32 mask = (1 << (SectorSizeLog - 5)) - 1;
|
||||
|
||||
@@ -170,7 +170,7 @@ struct CBootInitialEntry
|
||||
// Partition Table found in the boot image.
|
||||
UInt16 SectorCount; // This is the number of virtual/emulated sectors the system
|
||||
// will store at Load Segment during the initial boot procedure.
|
||||
UInt32 LoadRBA; // This is the start address of the virtual disk. CD<EFBFBD>s use
|
||||
UInt32 LoadRBA; // This is the start address of the virtual disk. CDs use
|
||||
// Relative/Logical block addressing.
|
||||
|
||||
Byte VendorSpec[20];
|
||||
|
||||
@@ -347,18 +347,24 @@ struct CSection
|
||||
|
||||
CSection(): IsRealSect(false), IsDebug(false), IsAdditionalSection(false) {}
|
||||
|
||||
// const UInt32 GetSize() const { return PSize; }
|
||||
const UInt32 GetSize() const { return MyMin(PSize, VSize); }
|
||||
|
||||
void UpdateTotalSize(UInt32 &totalSize) const
|
||||
{
|
||||
UInt32 t = Pa + PSize;
|
||||
if (totalSize < t)
|
||||
totalSize = t;
|
||||
}
|
||||
|
||||
void Parse(const Byte *p);
|
||||
|
||||
int Compare(const CSection &s) const
|
||||
{
|
||||
RINOZ(MyCompare(Pa, s.Pa));
|
||||
return MyCompare(PSize, s.PSize);
|
||||
UInt32 size1 = GetSize();
|
||||
UInt32 size2 = s.GetSize();
|
||||
return MyCompare(size1, size2);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1039,7 +1045,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
|
||||
switch (propID)
|
||||
{
|
||||
case kpidPath: prop = MultiByteToUnicodeString(item.Name); break;
|
||||
case kpidSize: prop = (UInt64)MyMin(item.PSize, item.VSize); break;
|
||||
case kpidSize: prop = (UInt64)item.GetSize(); break;
|
||||
case kpidPackSize: prop = (UInt64)item.PSize; break;
|
||||
case kpidVirtualSize: prop = (UInt64)item.VSize; break;
|
||||
case kpidOffset: prop = item.Pa; break;
|
||||
@@ -1883,14 +1889,17 @@ static bool ParseVersion(const Byte *p, UInt32 size, CTextFile &f, CObjectVector
|
||||
}
|
||||
f.CloseBlock(2);
|
||||
}
|
||||
|
||||
f.CloseBlock(0);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
HRESULT CHandler::OpenResources(unsigned sectionIndex, IInStream *stream, IArchiveOpenCallback *callback)
|
||||
{
|
||||
const CSection § = _sections[sectionIndex];
|
||||
size_t fileSize = sect.PSize; // Maybe we need sect.VSize here !!!
|
||||
const size_t fileSize = sect.GetSize();
|
||||
|
||||
if (fileSize > kFileSizeMax)
|
||||
return S_FALSE;
|
||||
{
|
||||
@@ -2031,8 +2040,8 @@ HRESULT CHandler::OpenResources(unsigned sectionIndex, IInStream *stream, IArchi
|
||||
{
|
||||
UInt32 mask = (1 << numBits) - 1;
|
||||
size_t end = ((maxOffset + mask) & ~mask);
|
||||
// 9.29: we use only PSize. PSize can be larger than VSize
|
||||
if (/* end < sect.VSize && */ end <= sect.PSize)
|
||||
|
||||
if (/* end < sect.VSize && */ end <= sect.GetSize())
|
||||
{
|
||||
CSection sect2;
|
||||
sect2.Flags = 0;
|
||||
@@ -2050,7 +2059,8 @@ HRESULT CHandler::OpenResources(unsigned sectionIndex, IInStream *stream, IArchi
|
||||
|
||||
// 9.29: we use sect.PSize instead of sect.VSize to support some CAB-SFX
|
||||
// the code for .rsrc_2 is commented.
|
||||
sect2.PSize = sect.PSize - (UInt32)maxOffset;
|
||||
sect2.PSize = sect.GetSize() - (UInt32)maxOffset;
|
||||
|
||||
if (sect2.PSize != 0)
|
||||
{
|
||||
sect2.VSize = sect2.PSize;
|
||||
@@ -2463,7 +2473,7 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
||||
else if (mixItem.ResourceIndex >= 0)
|
||||
size = _items[mixItem.ResourceIndex].GetSize();
|
||||
else
|
||||
size = _sections[mixItem.SectionIndex].PSize;
|
||||
size = _sections[mixItem.SectionIndex].GetSize();
|
||||
totalSize += size;
|
||||
}
|
||||
extractCallback->SetTotal(totalSize);
|
||||
@@ -2539,7 +2549,7 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
||||
}
|
||||
else
|
||||
{
|
||||
currentItemSize = sect.PSize;
|
||||
currentItemSize = sect.GetSize();
|
||||
if (!testMode && !outStream)
|
||||
continue;
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* PpmdHandler.c -- PPMd format handler
|
||||
2010-03-10 : Igor Pavlov : Public domain
|
||||
/* PpmdHandler.cpp -- PPMd format handler
|
||||
2015-11-30 : Igor Pavlov : Public domain
|
||||
This code is based on:
|
||||
PPMd var.H (2001) / var.I (2002): Dmitry Shkarin : Public domain
|
||||
Carryless rangecoder (1999): Dmitry Subbotin : Public domain */
|
||||
@@ -349,6 +349,7 @@ struct CPpmdCpp
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
||||
Int32 testMode, IArchiveExtractCallback *extractCallback)
|
||||
{
|
||||
@@ -386,13 +387,17 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
||||
CPpmdCpp ppmd(_item.Ver);
|
||||
if (!ppmd.Alloc(_item.MemInMB))
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
Int32 opRes = NExtract::NOperationResult::kUnsupportedMethod;
|
||||
|
||||
if (_item.IsSupported())
|
||||
{
|
||||
opRes = NExtract::NOperationResult::kDataError;
|
||||
|
||||
ppmd.Init(_item.Order, _item.Restor);
|
||||
inBuf.Init();
|
||||
UInt64 outSize = 0;
|
||||
|
||||
if (ppmd.InitRc(&inBuf) && !inBuf.Extra && inBuf.Res == S_OK)
|
||||
for (;;)
|
||||
{
|
||||
@@ -431,6 +436,13 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
||||
{
|
||||
RINOK(WriteStream(realOutStream, outBuf.Buf, i));
|
||||
}
|
||||
|
||||
if (inBuf.Extra)
|
||||
{
|
||||
opRes = NExtract::NOperationResult::kUnexpectedEnd;
|
||||
break;
|
||||
}
|
||||
|
||||
if (sym < 0)
|
||||
{
|
||||
if (sym == -1 && ppmd.IsFinishedOK())
|
||||
@@ -438,12 +450,15 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
RINOK(inBuf.Res);
|
||||
}
|
||||
|
||||
realOutStream.Release();
|
||||
return extractCallback->SetOperationResult(opRes);
|
||||
}
|
||||
|
||||
|
||||
static const Byte k_Signature[] = { 0x8F, 0xAF, 0xAC, 0x84 };
|
||||
|
||||
REGISTER_ARC_I(
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
|
||||
#include "../../../Common/ComTry.h"
|
||||
#include "../../../Common/IntToString.h"
|
||||
#include "../../../Common/StringConvert.h"
|
||||
|
||||
#include "../../../Windows/PropVariant.h"
|
||||
#include "../../../Windows/TimeUtils.h"
|
||||
@@ -241,12 +242,14 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
|
||||
COM_TRY_BEGIN
|
||||
NWindows::NCOM::CPropVariant prop;
|
||||
const CItemEx &item = m_Items[index];
|
||||
const CExtraBlock &extra = item.GetMainExtra();
|
||||
|
||||
switch (propID)
|
||||
{
|
||||
case kpidPath:
|
||||
{
|
||||
UString res;
|
||||
item.GetUnicodeString(item.Name, res, _forceCodePage, _specifiedCodePage);
|
||||
item.GetUnicodeString(res, item.Name, false, _forceCodePage, _specifiedCodePage);
|
||||
NItemName::ConvertToOSName2(res);
|
||||
prop = res;
|
||||
break;
|
||||
@@ -261,9 +264,9 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
|
||||
FILETIME ft;
|
||||
UInt32 unixTime;
|
||||
UInt32 type;
|
||||
if (item.CentralExtra.GetNtfsTime(NFileHeader::NNtfsExtra::kMTime, ft))
|
||||
if (extra.GetNtfsTime(NFileHeader::NNtfsExtra::kMTime, ft))
|
||||
type = NFileTimeType::kWindows;
|
||||
else if (item.CentralExtra.GetUnixTime(true, NFileHeader::NUnixTime::kMTime, unixTime))
|
||||
else if (extra.GetUnixTime(true, NFileHeader::NUnixTime::kMTime, unixTime))
|
||||
type = NFileTimeType::kUnix;
|
||||
else
|
||||
type = NFileTimeType::kDOS;
|
||||
@@ -274,7 +277,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
|
||||
case kpidCTime:
|
||||
{
|
||||
FILETIME ft;
|
||||
if (item.CentralExtra.GetNtfsTime(NFileHeader::NNtfsExtra::kCTime, ft))
|
||||
if (extra.GetNtfsTime(NFileHeader::NNtfsExtra::kCTime, ft))
|
||||
prop = ft;
|
||||
break;
|
||||
}
|
||||
@@ -282,7 +285,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
|
||||
case kpidATime:
|
||||
{
|
||||
FILETIME ft;
|
||||
if (item.CentralExtra.GetNtfsTime(NFileHeader::NNtfsExtra::kATime, ft))
|
||||
if (extra.GetNtfsTime(NFileHeader::NNtfsExtra::kATime, ft))
|
||||
prop = ft;
|
||||
break;
|
||||
}
|
||||
@@ -291,10 +294,10 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
|
||||
{
|
||||
FILETIME utc;
|
||||
bool defined = true;
|
||||
if (!item.CentralExtra.GetNtfsTime(NFileHeader::NNtfsExtra::kMTime, utc))
|
||||
if (!extra.GetNtfsTime(NFileHeader::NNtfsExtra::kMTime, utc))
|
||||
{
|
||||
UInt32 unixTime = 0;
|
||||
if (item.CentralExtra.GetUnixTime(true, NFileHeader::NUnixTime::kMTime, unixTime))
|
||||
if (extra.GetUnixTime(true, NFileHeader::NUnixTime::kMTime, unixTime))
|
||||
NTime::UnixTimeToFileTime(unixTime, utc);
|
||||
else
|
||||
{
|
||||
@@ -328,7 +331,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
|
||||
if (item.Comment.Size() != 0)
|
||||
{
|
||||
UString res;
|
||||
item.GetUnicodeString(BytesToString(item.Comment), res, _forceCodePage, _specifiedCodePage);
|
||||
item.GetUnicodeString(res, BytesToString(item.Comment), true, _forceCodePage, _specifiedCodePage);
|
||||
prop = res;
|
||||
}
|
||||
break;
|
||||
@@ -347,7 +350,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
|
||||
{
|
||||
m += kMethod_AES;
|
||||
CWzAesExtra aesField;
|
||||
if (item.CentralExtra.GetWzAes(aesField))
|
||||
if (extra.GetWzAes(aesField))
|
||||
{
|
||||
char s[16];
|
||||
s[0] = '-';
|
||||
@@ -360,7 +363,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
|
||||
{
|
||||
CStrongCryptoExtra f;
|
||||
f.AlgId = 0;
|
||||
if (item.CentralExtra.GetStrongCrypto(f))
|
||||
if (extra.GetStrongCrypto(f))
|
||||
{
|
||||
const char *s = FindNameForId(k_StrongCryptoPairs, ARRAY_SIZE(k_StrongCryptoPairs), f.AlgId);
|
||||
if (s)
|
||||
@@ -427,6 +430,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
|
||||
prop = (UInt32)item.ExtractVersion.Version;
|
||||
break;
|
||||
}
|
||||
|
||||
prop.Detach(value);
|
||||
return S_OK;
|
||||
COM_TRY_END
|
||||
@@ -617,7 +621,7 @@ HRESULT CZipDecoder::Decode(
|
||||
if (!pkAesMode && id == NFileHeader::NCompressionMethod::kWzAES)
|
||||
{
|
||||
CWzAesExtra aesField;
|
||||
if (item.CentralExtra.GetWzAes(aesField))
|
||||
if (item.GetMainExtra().GetWzAes(aesField))
|
||||
{
|
||||
wzAesMode = true;
|
||||
needCRC = aesField.NeedCrc();
|
||||
@@ -653,7 +657,7 @@ HRESULT CZipDecoder::Decode(
|
||||
if (wzAesMode)
|
||||
{
|
||||
CWzAesExtra aesField;
|
||||
if (!item.CentralExtra.GetWzAes(aesField))
|
||||
if (!item.GetMainExtra().GetWzAes(aesField))
|
||||
return S_OK;
|
||||
id = aesField.Method;
|
||||
if (!_wzAesDecoder)
|
||||
|
||||
@@ -84,6 +84,8 @@ namespace NFileHeader
|
||||
kNTFS = 0x0A,
|
||||
kStrongEncrypt = 0x17,
|
||||
kUnixTime = 0x5455,
|
||||
kIzUnicodeComment = 0x6375,
|
||||
kIzUnicodeName = 0x7075,
|
||||
kWzAES = 0x9901
|
||||
};
|
||||
}
|
||||
|
||||
@@ -203,7 +203,8 @@ API_FUNC_IsArc IsArc_Zip(const Byte *p, size_t size)
|
||||
const Byte *p2 = p + kLocalHeaderSize;
|
||||
for (size_t i = 0; i < rem; i++)
|
||||
if (p2[i] == 0)
|
||||
return k_IsArc_Res_NO;
|
||||
if (i != nameSize - 1)
|
||||
return k_IsArc_Res_NO;
|
||||
}
|
||||
|
||||
if (size < extraOffset)
|
||||
|
||||
@@ -3,8 +3,10 @@
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "../../../../C/CpuArch.h"
|
||||
#include "../../../../C/7zCrc.h"
|
||||
|
||||
#include "../../../Common/MyLinux.h"
|
||||
#include "../../../Common/StringConvert.h"
|
||||
|
||||
#include "../Common/ItemNameUtils.h"
|
||||
|
||||
@@ -80,6 +82,30 @@ bool CExtraSubBlock::ExtractUnixTime(bool isCentral, unsigned index, UInt32 &res
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool CExtraBlock::GetNtfsTime(unsigned index, FILETIME &ft) const
|
||||
{
|
||||
FOR_VECTOR (i, SubBlocks)
|
||||
{
|
||||
const CExtraSubBlock &sb = SubBlocks[i];
|
||||
if (sb.ID == NFileHeader::NExtraID::kNTFS)
|
||||
return sb.ExtractNtfsTime(index, ft);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CExtraBlock::GetUnixTime(bool isCentral, unsigned index, UInt32 &res) const
|
||||
{
|
||||
FOR_VECTOR (i, SubBlocks)
|
||||
{
|
||||
const CExtraSubBlock &sb = SubBlocks[i];
|
||||
if (sb.ID == NFileHeader::NExtraID::kUnixTime)
|
||||
return sb.ExtractUnixTime(isCentral, index, res);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool CLocalItem::IsDir() const
|
||||
{
|
||||
return NItemName::HasTailSlash(Name, GetCodePage());
|
||||
@@ -89,12 +115,29 @@ bool CItem::IsDir() const
|
||||
{
|
||||
if (NItemName::HasTailSlash(Name, GetCodePage()))
|
||||
return true;
|
||||
|
||||
Byte hostOS = GetHostOS();
|
||||
|
||||
if (Size == 0 && PackSize == 0 && !Name.IsEmpty() && Name.Back() == '\\')
|
||||
{
|
||||
// do we need to use CharPrevExA?
|
||||
// .NET Framework 4.5 : System.IO.Compression::CreateFromDirectory() probably writes backslashes to headers?
|
||||
// so we support that case
|
||||
switch (hostOS)
|
||||
{
|
||||
case NHostOS::kFAT:
|
||||
case NHostOS::kNTFS:
|
||||
case NHostOS::kHPFS:
|
||||
case NHostOS::kVFAT:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!FromCentral)
|
||||
return false;
|
||||
|
||||
UInt16 highAttrib = (UInt16)((ExternalAttrib >> 16 ) & 0xFFFF);
|
||||
|
||||
Byte hostOS = GetHostOS();
|
||||
switch (hostOS)
|
||||
{
|
||||
case NHostOS::kAMIGA:
|
||||
@@ -158,4 +201,53 @@ bool CItem::GetPosixAttrib(UInt32 &attrib) const
|
||||
return false;
|
||||
}
|
||||
|
||||
void CItem::GetUnicodeString(UString &res, const AString &s, bool isComment, bool useSpecifiedCodePage, UINT codePage) const
|
||||
{
|
||||
bool isUtf8 = IsUtf8();
|
||||
bool ignore_Utf8_Errors = true;
|
||||
|
||||
if (!isUtf8)
|
||||
{
|
||||
{
|
||||
const unsigned id = isComment ?
|
||||
NFileHeader::NExtraID::kIzUnicodeComment:
|
||||
NFileHeader::NExtraID::kIzUnicodeName;
|
||||
const CObjectVector<CExtraSubBlock> &subBlocks = GetMainExtra().SubBlocks;
|
||||
|
||||
FOR_VECTOR (i, subBlocks)
|
||||
{
|
||||
const CExtraSubBlock &sb = subBlocks[i];
|
||||
if (sb.ID == id)
|
||||
{
|
||||
AString utf;
|
||||
if (sb.ExtractIzUnicode(CrcCalc(s, s.Len()), utf))
|
||||
if (ConvertUTF8ToUnicode(utf, res))
|
||||
return;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (useSpecifiedCodePage)
|
||||
isUtf8 = (codePage == CP_UTF8);
|
||||
#ifdef _WIN32
|
||||
else if (GetHostOS() == NFileHeader::NHostOS::kUnix)
|
||||
{
|
||||
/* Some ZIP archives in Unix use UTF-8 encoding without Utf8 flag in header.
|
||||
We try to get name as UTF-8.
|
||||
Do we need to do it in POSIX version also? */
|
||||
isUtf8 = true;
|
||||
ignore_Utf8_Errors = false;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
if (isUtf8)
|
||||
if (ConvertUTF8ToUnicode(s, res) || ignore_Utf8_Errors)
|
||||
return;
|
||||
|
||||
MultiByteToUnicodeString2(res, s, useSpecifiedCodePage ? codePage : GetCodePage());
|
||||
}
|
||||
|
||||
}}
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
|
||||
#include "../../../Common/MyBuffer.h"
|
||||
#include "../../../Common/MyString.h"
|
||||
#include "../../../Common/StringConvert.h"
|
||||
#include "../../../Common/UTFConvert.h"
|
||||
|
||||
#include "ZipHeader.h"
|
||||
@@ -28,6 +27,23 @@ struct CExtraSubBlock
|
||||
|
||||
bool ExtractNtfsTime(unsigned index, FILETIME &ft) const;
|
||||
bool ExtractUnixTime(bool isCentral, unsigned index, UInt32 &res) const;
|
||||
|
||||
bool ExtractIzUnicode(UInt32 crc, AString &name) const
|
||||
{
|
||||
unsigned size = (unsigned)Data.Size();
|
||||
if (size < 1 + 4)
|
||||
return false;
|
||||
const Byte *p = (const Byte *)Data;
|
||||
if (p[0] > 1)
|
||||
return false;
|
||||
if (crc != GetUi32(p + 1))
|
||||
return false;
|
||||
size -= 5;
|
||||
name.SetFrom_CalcLen((const char *)p + 5, size);
|
||||
if (size != name.Len())
|
||||
return false;
|
||||
return CheckUTF8(name, false);
|
||||
}
|
||||
};
|
||||
|
||||
const unsigned k_WzAesExtra_Size = 7;
|
||||
@@ -157,27 +173,8 @@ struct CExtraBlock
|
||||
}
|
||||
*/
|
||||
|
||||
bool GetNtfsTime(unsigned index, FILETIME &ft) const
|
||||
{
|
||||
FOR_VECTOR (i, SubBlocks)
|
||||
{
|
||||
const CExtraSubBlock &sb = SubBlocks[i];
|
||||
if (sb.ID == NFileHeader::NExtraID::kNTFS)
|
||||
return sb.ExtractNtfsTime(index, ft);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool GetUnixTime(bool isCentral, unsigned index, UInt32 &res) const
|
||||
{
|
||||
FOR_VECTOR (i, SubBlocks)
|
||||
{
|
||||
const CExtraSubBlock &sb = SubBlocks[i];
|
||||
if (sb.ID == NFileHeader::NExtraID::kUnixTime)
|
||||
return sb.ExtractUnixTime(isCentral, index, res);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
bool GetNtfsTime(unsigned index, FILETIME &ft) const;
|
||||
bool GetUnixTime(bool isCentral, unsigned index, UInt32 &res) const;
|
||||
|
||||
void RemoveUnknownSubBlocks()
|
||||
{
|
||||
@@ -274,45 +271,22 @@ public:
|
||||
MadeByVersion.HostOS = 0;
|
||||
}
|
||||
|
||||
const CExtraBlock &GetMainExtra() const { return *(FromCentral ? &CentralExtra : &LocalExtra); }
|
||||
|
||||
bool IsDir() const;
|
||||
UInt32 GetWinAttrib() const;
|
||||
bool GetPosixAttrib(UInt32 &attrib) const;
|
||||
|
||||
Byte GetHostOS() const { return FromCentral ? MadeByVersion.HostOS : ExtractVersion.HostOS; }
|
||||
|
||||
void GetUnicodeString(const AString &s, UString &res, bool useSpecifiedCodePage, UINT codePage) const
|
||||
{
|
||||
bool isUtf8 = IsUtf8();
|
||||
bool ignore_Utf8_Errors = true;
|
||||
|
||||
#ifdef _WIN32
|
||||
if (!isUtf8)
|
||||
{
|
||||
if (useSpecifiedCodePage)
|
||||
isUtf8 = (codePage == CP_UTF8);
|
||||
else if (GetHostOS() == NFileHeader::NHostOS::kUnix)
|
||||
{
|
||||
/* Some ZIP archives in Unix use UTF-8 encoding without Utf8 flag in header.
|
||||
We try to get name as UTF-8.
|
||||
Do we need to do it in POSIX version also? */
|
||||
isUtf8 = true;
|
||||
ignore_Utf8_Errors = false;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (isUtf8)
|
||||
if (ConvertUTF8ToUnicode(s, res) || ignore_Utf8_Errors)
|
||||
return;
|
||||
MultiByteToUnicodeString2(res, s, useSpecifiedCodePage ? codePage : GetCodePage());
|
||||
}
|
||||
void GetUnicodeString(UString &res, const AString &s, bool isComment, bool useSpecifiedCodePage, UINT codePage) const;
|
||||
|
||||
bool IsThereCrc() const
|
||||
{
|
||||
if (Method == NFileHeader::NCompressionMethod::kWzAES)
|
||||
{
|
||||
CWzAesExtra aesField;
|
||||
if (CentralExtra.GetWzAes(aesField))
|
||||
if (GetMainExtra().GetWzAes(aesField))
|
||||
return aesField.NeedCrc();
|
||||
}
|
||||
return (Crc != 0 || !IsDir());
|
||||
@@ -322,8 +296,10 @@ public:
|
||||
{
|
||||
Byte hostOS = GetHostOS();
|
||||
return (UINT)((
|
||||
hostOS == NFileHeader::NHostOS::kFAT ||
|
||||
hostOS == NFileHeader::NHostOS::kNTFS) ? CP_OEMCP : CP_ACP);
|
||||
hostOS == NFileHeader::NHostOS::kFAT
|
||||
|| hostOS == NFileHeader::NHostOS::kNTFS
|
||||
|| hostOS == NFileHeader::NHostOS::kUnix // do we need it?
|
||||
) ? CP_OEMCP : CP_ACP);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -325,14 +325,6 @@ SOURCE=..\..\UI\FileManager\ComboDialog.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\UI\FileManager\MessagesDialog.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\UI\FileManager\MessagesDialog.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\UI\FileManager\OverwriteDialog.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
@@ -917,7 +917,7 @@ void CArcCmdLineParser::Parse1(const UStringVector &commandStrings,
|
||||
|
||||
if (parser[NKey::kAffinity].ThereIs)
|
||||
{
|
||||
const UString &s = us2fs(parser[NKey::kAffinity].PostStrings[0]);
|
||||
const UString &s = parser[NKey::kAffinity].PostStrings[0];
|
||||
if (!s.IsEmpty())
|
||||
{
|
||||
UInt32 v = 0;
|
||||
|
||||
@@ -1265,7 +1265,7 @@ if (askExtractMode == NArchive::NExtract::NAskMode::kExtract && !_testMode)
|
||||
CReparseAttr attr;
|
||||
if (!attr.Parse(data, data.Size()))
|
||||
{
|
||||
RINOK(SendMessageError("Internal error for symbolic link file", _item.Path));
|
||||
RINOK(SendMessageError("Internal error for symbolic link file", us2fs(_item.Path)));
|
||||
// return E_FAIL;
|
||||
}
|
||||
else
|
||||
|
||||
@@ -2487,7 +2487,7 @@ HRESULT Bench(
|
||||
#ifdef USE_WIN_FILE
|
||||
|
||||
NFile::NIO::CInFile file;
|
||||
if (!file.Open(property.Value))
|
||||
if (!file.Open(us2fs(property.Value)))
|
||||
return E_INVALIDARG;
|
||||
UInt64 len;
|
||||
if (!file.GetLength(len))
|
||||
|
||||
@@ -39,7 +39,7 @@
|
||||
#endif
|
||||
|
||||
// increase it, if you need to support larger SFX stubs
|
||||
static const UInt64 kMaxCheckStartPosition = 1 << 22;
|
||||
static const UInt64 kMaxCheckStartPosition = 1 << 23;
|
||||
|
||||
/*
|
||||
Open:
|
||||
|
||||
@@ -42,6 +42,12 @@ static void Key_Get_BoolPair(CKey &key, LPCTSTR name, CBoolPair &b)
|
||||
b.Def = (key.GetValue_IfOk(name, b.Val) == ERROR_SUCCESS);
|
||||
}
|
||||
|
||||
static void Key_Get_BoolPair_true(CKey &key, LPCTSTR name, CBoolPair &b)
|
||||
{
|
||||
b.Val = true;
|
||||
b.Def = (key.GetValue_IfOk(name, b.Val) == ERROR_SUCCESS);
|
||||
}
|
||||
|
||||
namespace NExtract
|
||||
{
|
||||
|
||||
@@ -112,9 +118,8 @@ void CInfo::Load()
|
||||
OverwriteMode_Force = true;
|
||||
}
|
||||
|
||||
Key_Get_BoolPair(key, kSplitDest, SplitDest);
|
||||
if (!SplitDest.Def)
|
||||
SplitDest.Val = 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);
|
||||
@@ -348,27 +353,45 @@ void CInfo::Load()
|
||||
static const TCHAR *kCascadedMenu = TEXT("CascadedMenu");
|
||||
static const TCHAR *kContextMenu = TEXT("ContextMenu");
|
||||
static const TCHAR *kMenuIcons = TEXT("MenuIcons");
|
||||
static const TCHAR *kElimDup = TEXT("ElimDupExtract");
|
||||
|
||||
void CContextMenuInfo::Save() const
|
||||
{
|
||||
CS_LOCK
|
||||
CKey key;
|
||||
CreateMainKey(key, kOptionsInfoKeyName);
|
||||
key.SetValue(kCascadedMenu, Cascaded);
|
||||
key.SetValue(kMenuIcons, MenuIcons);
|
||||
key.SetValue(kContextMenu, Flags);
|
||||
|
||||
Key_Set_BoolPair(key, kCascadedMenu, Cascaded);
|
||||
Key_Set_BoolPair(key, kMenuIcons, MenuIcons);
|
||||
Key_Set_BoolPair(key, kElimDup, ElimDup);
|
||||
|
||||
if (Flags_Def)
|
||||
key.SetValue(kContextMenu, Flags);
|
||||
}
|
||||
|
||||
void CContextMenuInfo::Load()
|
||||
{
|
||||
MenuIcons = false;
|
||||
Cascaded = true;
|
||||
Cascaded.Val = true;
|
||||
Cascaded.Def = false;
|
||||
|
||||
MenuIcons.Val = false;
|
||||
MenuIcons.Def = false;
|
||||
|
||||
ElimDup.Val = true;
|
||||
ElimDup.Def = false;
|
||||
|
||||
Flags = (UInt32)(Int32)-1;
|
||||
Flags_Def = false;
|
||||
|
||||
CS_LOCK
|
||||
|
||||
CKey key;
|
||||
if (OpenMainKey(key, kOptionsInfoKeyName) != ERROR_SUCCESS)
|
||||
return;
|
||||
key.GetValue_IfOk(kCascadedMenu, Cascaded);
|
||||
key.GetValue_IfOk(kMenuIcons, MenuIcons);
|
||||
key.GetValue_IfOk(kContextMenu, Flags);
|
||||
|
||||
Key_Get_BoolPair_true(key, kCascadedMenu, Cascaded);
|
||||
Key_Get_BoolPair_true(key, kElimDup, ElimDup);
|
||||
Key_Get_BoolPair(key, kMenuIcons, MenuIcons);
|
||||
|
||||
Flags_Def = (key.GetValue_IfOk(kContextMenu, Flags) == ERROR_SUCCESS);
|
||||
}
|
||||
|
||||
@@ -111,8 +111,11 @@ namespace NWorkDir
|
||||
|
||||
struct CContextMenuInfo
|
||||
{
|
||||
bool Cascaded;
|
||||
bool MenuIcons;
|
||||
CBoolPair Cascaded;
|
||||
CBoolPair MenuIcons;
|
||||
CBoolPair ElimDup;
|
||||
|
||||
bool Flags_Def;
|
||||
UInt32 Flags;
|
||||
|
||||
void Save() const;
|
||||
|
||||
@@ -241,7 +241,7 @@ static const CHashCommand g_HashCommands[] =
|
||||
|
||||
static int FindCommand(CZipContextMenu::ECommandInternalID &id)
|
||||
{
|
||||
for (int i = 0; i < ARRAY_SIZE(g_Commands); i++)
|
||||
for (unsigned i = 0; i < ARRAY_SIZE(g_Commands); i++)
|
||||
if (g_Commands[i].CommandInternalID == id)
|
||||
return i;
|
||||
return -1;
|
||||
@@ -287,12 +287,10 @@ static const char * const kArcExts[] =
|
||||
, "zip"
|
||||
};
|
||||
|
||||
static bool IsItArcExt(const UString &ext2)
|
||||
static bool IsItArcExt(const UString &ext)
|
||||
{
|
||||
UString ext = ext2;
|
||||
ext.MakeLower_Ascii();
|
||||
for (unsigned i = 0; i < ARRAY_SIZE(kArcExts); i++)
|
||||
if (ext.IsEqualTo(kArcExts[i]))
|
||||
if (ext.IsEqualTo_Ascii_NoCase(kArcExts[i]))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
@@ -429,6 +427,7 @@ void CZipContextMenu::AddMapItem_ForSubMenu(const wchar_t *verb)
|
||||
_commandMap.Add(commandMapItem);
|
||||
}
|
||||
|
||||
|
||||
STDMETHODIMP CZipContextMenu::QueryContextMenu(HMENU hMenu, UINT indexMenu,
|
||||
UINT commandIDFirst, UINT commandIDLast, UINT flags)
|
||||
{
|
||||
@@ -451,12 +450,15 @@ STDMETHODIMP CZipContextMenu::QueryContextMenu(HMENU hMenu, UINT indexMenu,
|
||||
CContextMenuInfo ci;
|
||||
ci.Load();
|
||||
|
||||
_elimDup = ci.ElimDup;
|
||||
|
||||
HBITMAP bitmap = NULL;
|
||||
if (ci.MenuIcons)
|
||||
if (ci.MenuIcons.Val)
|
||||
bitmap = _bitmap;
|
||||
|
||||
UINT subIndex = indexMenu;
|
||||
if (ci.Cascaded)
|
||||
|
||||
if (ci.Cascaded.Val)
|
||||
{
|
||||
if (!popupMenu.CreatePopup())
|
||||
return E_FAIL;
|
||||
@@ -473,15 +475,21 @@ STDMETHODIMP CZipContextMenu::QueryContextMenu(HMENU hMenu, UINT indexMenu,
|
||||
else
|
||||
{
|
||||
popupMenu.Attach(hMenu);
|
||||
CMenuItem mi;
|
||||
mi.fType = MFT_SEPARATOR;
|
||||
mi.fMask = MIIM_TYPE;
|
||||
popupMenu.InsertItem(subIndex++, true, mi);
|
||||
}
|
||||
|
||||
UInt32 contextMenuFlags = ci.Flags;
|
||||
|
||||
NFind::CFileInfo fi0;
|
||||
FString folderPrefix;
|
||||
|
||||
if (_fileNames.Size() > 0)
|
||||
{
|
||||
const UString &fileName = _fileNames.Front();
|
||||
|
||||
#if defined(_WIN32) && !defined(UNDER_CE)
|
||||
if (NName::IsDevicePath(us2fs(fileName)))
|
||||
{
|
||||
@@ -505,6 +513,7 @@ STDMETHODIMP CZipContextMenu::QueryContextMenu(HMENU hMenu, UINT indexMenu,
|
||||
}
|
||||
|
||||
UString mainString;
|
||||
|
||||
if (_fileNames.Size() == 1 && currentCommandID + 14 <= commandIDLast)
|
||||
{
|
||||
if (!fi0.IsDir() && DoNeedExtract(fi0.Name))
|
||||
@@ -565,6 +574,7 @@ STDMETHODIMP CZipContextMenu::QueryContextMenu(HMENU hMenu, UINT indexMenu,
|
||||
if (_fileNames.Size() > 0 && currentCommandID + 10 <= commandIDLast)
|
||||
{
|
||||
bool needExtract = (!fi0.IsDir() && DoNeedExtract(fi0.Name));
|
||||
|
||||
if (!needExtract)
|
||||
{
|
||||
FOR_VECTOR (i, _fileNames)
|
||||
@@ -579,7 +589,9 @@ STDMETHODIMP CZipContextMenu::QueryContextMenu(HMENU hMenu, UINT indexMenu,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const UString &fileName = _fileNames.Front();
|
||||
|
||||
if (needExtract)
|
||||
{
|
||||
// Extract
|
||||
@@ -629,6 +641,7 @@ STDMETHODIMP CZipContextMenu::QueryContextMenu(HMENU hMenu, UINT indexMenu,
|
||||
MyInsertMenu(popupMenu, subIndex++, currentCommandID++, s, bitmap);
|
||||
_commandMap.Add(commandMapItem);
|
||||
}
|
||||
|
||||
// Test
|
||||
if ((contextMenuFlags & NContextMenuFlags::kTest) != 0)
|
||||
{
|
||||
@@ -644,6 +657,7 @@ STDMETHODIMP CZipContextMenu::QueryContextMenu(HMENU hMenu, UINT indexMenu,
|
||||
arcName = CreateArchiveName(fi0, false);
|
||||
else
|
||||
arcName = CreateArchiveName(fileName, _fileNames.Size() > 1, false);
|
||||
|
||||
UString arcName7z = arcName + L".7z";
|
||||
UString arcNameZip = arcName + L".zip";
|
||||
|
||||
@@ -745,7 +759,7 @@ STDMETHODIMP CZipContextMenu::QueryContextMenu(HMENU hMenu, UINT indexMenu,
|
||||
// PRB: Duplicate Menu Items In the File Menu For a Shell Context Menu Extension
|
||||
// ID: Q214477
|
||||
|
||||
if (ci.Cascaded)
|
||||
if (ci.Cascaded.Val)
|
||||
{
|
||||
CMenuItem mi;
|
||||
mi.fType = MFT_STRING;
|
||||
@@ -756,12 +770,20 @@ STDMETHODIMP CZipContextMenu::QueryContextMenu(HMENU hMenu, UINT indexMenu,
|
||||
mi.hSubMenu = popupMenu.Detach();
|
||||
mi.StringValue.SetFromAscii("7-Zip"); // LangString(IDS_CONTEXT_POPUP_CAPTION);
|
||||
mi.hbmpUnchecked = bitmap;
|
||||
|
||||
CMenu menu;
|
||||
menu.Attach(hMenu);
|
||||
menuDestroyer.Disable();
|
||||
menu.InsertItem(indexMenu++, true, mi);
|
||||
|
||||
AddMapItem_ForSubMenu(kMainVerb);
|
||||
}
|
||||
else
|
||||
{
|
||||
popupMenu.Detach();
|
||||
indexMenu = subIndex;
|
||||
}
|
||||
|
||||
|
||||
if (!_isMenuForFM &&
|
||||
((contextMenuFlags & NContextMenuFlags::kCRC) != 0
|
||||
@@ -771,6 +793,7 @@ STDMETHODIMP CZipContextMenu::QueryContextMenu(HMENU hMenu, UINT indexMenu,
|
||||
// CMenuDestroyer menuDestroyer_CRC;
|
||||
|
||||
UINT subIndex_CRC = 0;
|
||||
|
||||
if (subMenu.CreatePopup())
|
||||
{
|
||||
// menuDestroyer_CRC.Attach(subMenu);
|
||||
@@ -783,13 +806,15 @@ STDMETHODIMP CZipContextMenu::QueryContextMenu(HMENU hMenu, UINT indexMenu,
|
||||
mi.hSubMenu = subMenu;
|
||||
mi.StringValue.SetFromAscii("CRC SHA");
|
||||
mi.hbmpUnchecked = bitmap;
|
||||
|
||||
CMenu menu;
|
||||
menu.Attach(hMenu);
|
||||
// menuDestroyer_CRC.Disable();
|
||||
menu.InsertItem(indexMenu++, true, mi);
|
||||
|
||||
AddMapItem_ForSubMenu(kCheckSumCascadedVerb);
|
||||
|
||||
for (int i = 0; i < ARRAY_SIZE(g_HashCommands); i++)
|
||||
for (unsigned i = 0; i < ARRAY_SIZE(g_HashCommands); i++)
|
||||
{
|
||||
const CHashCommand &hc = g_HashCommands[i];
|
||||
CCommandMapItem commandMapItem;
|
||||
@@ -799,6 +824,7 @@ STDMETHODIMP CZipContextMenu::QueryContextMenu(HMENU hMenu, UINT indexMenu,
|
||||
MyInsertMenu(subMenu, subIndex_CRC++, currentCommandID++, hc.UserName, bitmap);
|
||||
_commandMap.Add(commandMapItem);
|
||||
}
|
||||
|
||||
subMenu.Detach();
|
||||
}
|
||||
}
|
||||
@@ -872,7 +898,7 @@ STDMETHODIMP CZipContextMenu::InvokeCommand(LPCMINVOKECOMMANDINFO commandInfo)
|
||||
{
|
||||
ExtractArchives(_fileNames, commandMapItem.Folder,
|
||||
(cmdID == kExtract), // showDialog
|
||||
(cmdID == kExtractTo) // elimDup
|
||||
(cmdID == kExtractTo) && _elimDup.Val // elimDup
|
||||
);
|
||||
break;
|
||||
}
|
||||
@@ -902,12 +928,14 @@ STDMETHODIMP CZipContextMenu::InvokeCommand(LPCMINVOKECOMMANDINFO commandInfo)
|
||||
_fileNames, email, showDialog, false);
|
||||
break;
|
||||
}
|
||||
|
||||
case kHash_CRC32:
|
||||
case kHash_CRC64:
|
||||
case kHash_SHA1:
|
||||
case kHash_SHA256:
|
||||
case kHash_All:
|
||||
for (int i = 0; i < ARRAY_SIZE(g_HashCommands); i++)
|
||||
{
|
||||
for (unsigned i = 0; i < ARRAY_SIZE(g_HashCommands); i++)
|
||||
{
|
||||
const CHashCommand &hc = g_HashCommands[i];
|
||||
if (hc.CommandInternalID == cmdID)
|
||||
@@ -917,6 +945,7 @@ STDMETHODIMP CZipContextMenu::InvokeCommand(LPCMINVOKECOMMANDINFO commandInfo)
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch(...)
|
||||
|
||||
@@ -74,6 +74,8 @@ private:
|
||||
|
||||
HBITMAP _bitmap;
|
||||
|
||||
CBoolPair _elimDup;
|
||||
|
||||
HRESULT GetFileNames(LPDATAOBJECT dataObject, UStringVector &fileNames);
|
||||
int FindVerb(const UString &verb);
|
||||
bool FillCommand(ECommandInternalID id, UString &mainString, CCommandMapItem &commandMapItem);
|
||||
|
||||
@@ -10,13 +10,11 @@
|
||||
|
||||
#include "../../../Common/MyWindows.h"
|
||||
|
||||
#include <ShlGuid.h>
|
||||
#include <OleCtl.h>
|
||||
|
||||
#include "../../../Common/MyInitGuid.h"
|
||||
|
||||
#include "../../../Common/ComTry.h"
|
||||
#include "../../../Common/StringConvert.h"
|
||||
|
||||
#include "../../../Windows/DLL.h"
|
||||
#include "../../../Windows/ErrorMsg.h"
|
||||
@@ -24,11 +22,15 @@
|
||||
#include "../../../Windows/Registry.h"
|
||||
|
||||
#include "../FileManager/IFolder.h"
|
||||
#include "../FileManager/LangUtils.h"
|
||||
|
||||
#include "ContextMenu.h"
|
||||
|
||||
static LPCTSTR k_ShellExtName = TEXT("7-Zip Shell Extension");
|
||||
static LPCTSTR k_Approved = TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Shell Extensions\\Approved");
|
||||
|
||||
// {23170F69-40C1-278A-1000-000100020000}
|
||||
static LPCTSTR k_Clsid = TEXT("{23170F69-40C1-278A-1000-000100020000}");
|
||||
|
||||
DEFINE_GUID(CLSID_CZipContextMenu,
|
||||
k_7zip_GUID_Data1,
|
||||
k_7zip_GUID_Data2,
|
||||
@@ -42,10 +44,6 @@ HWND g_HWND = 0;
|
||||
|
||||
LONG g_DllRefCount = 0; // Reference count of this DLL.
|
||||
|
||||
static LPCWSTR kShellExtName = L"7-Zip Shell Extension";
|
||||
static LPCTSTR kClsidMask = TEXT("CLSID\\%s");
|
||||
static LPCTSTR kClsidInprocMask = TEXT("CLSID\\%s\\InprocServer32");
|
||||
static LPCTSTR kApprovedKeyPath = TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Shell Extensions\\Approved");
|
||||
|
||||
// #define ODS(sz) OutputDebugString(L#sz)
|
||||
|
||||
@@ -77,7 +75,7 @@ STDMETHODIMP CShellExtClassFactory::CreateInstance(LPUNKNOWN pUnkOuter,
|
||||
shellExt = new CZipContextMenu();
|
||||
}
|
||||
catch(...) { return E_OUTOFMEMORY; }
|
||||
if (shellExt == NULL)
|
||||
if (!shellExt)
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
HRESULT res = shellExt->QueryInterface(riid, ppvObj);
|
||||
@@ -117,7 +115,7 @@ BOOL WINAPI DllMain(
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Used to determine whether the DLL can be unloaded by OLE
|
||||
|
||||
STDAPI DllCanUnloadNow(void)
|
||||
@@ -138,7 +136,7 @@ STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv)
|
||||
cf = new CShellExtClassFactory;
|
||||
}
|
||||
catch(...) { return E_OUTOFMEMORY; }
|
||||
if (cf == 0)
|
||||
if (!cf)
|
||||
return E_OUTOFMEMORY;
|
||||
HRESULT res = cf->QueryInterface(riid, ppv);
|
||||
if (res != S_OK)
|
||||
@@ -149,66 +147,28 @@ STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv)
|
||||
// return _Module.GetClassObject(rclsid, riid, ppv);
|
||||
}
|
||||
|
||||
static BOOL GetStringFromIID(CLSID clsid, LPTSTR s, int size)
|
||||
{
|
||||
LPWSTR pwsz;
|
||||
if (StringFromIID(clsid, &pwsz) != S_OK)
|
||||
return FALSE;
|
||||
if (!pwsz)
|
||||
return FALSE;
|
||||
#ifdef UNICODE
|
||||
for (int i = 0; i < size; i++)
|
||||
{
|
||||
s[i] = pwsz[i];
|
||||
if (pwsz[i] == 0)
|
||||
break;
|
||||
}
|
||||
s[size - 1] = 0;
|
||||
#else
|
||||
WideCharToMultiByte(CP_ACP, 0, pwsz, -1, s, size, NULL, NULL);
|
||||
#endif
|
||||
CoTaskMemFree(pwsz);
|
||||
s[size - 1] = 0;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
typedef struct
|
||||
static BOOL RegisterServer()
|
||||
{
|
||||
HKEY hRootKey;
|
||||
LPCTSTR SubKey;
|
||||
LPCWSTR ValueName;
|
||||
LPCWSTR Data;
|
||||
} CRegItem;
|
||||
|
||||
static BOOL RegisterServer(CLSID clsid, LPCWSTR title)
|
||||
{
|
||||
TCHAR clsidString[MAX_PATH];
|
||||
if (!GetStringFromIID(clsid, clsidString, MAX_PATH))
|
||||
return FALSE;
|
||||
|
||||
FString modulePath;
|
||||
if (!NDLL::MyGetModuleFileName(modulePath))
|
||||
return FALSE;
|
||||
UString modulePathU = fs2us(modulePath);
|
||||
const UString modulePathU = fs2us(modulePath);
|
||||
|
||||
CRegItem clsidEntries[] =
|
||||
{
|
||||
HKEY_CLASSES_ROOT, kClsidMask, NULL, title,
|
||||
HKEY_CLASSES_ROOT, kClsidInprocMask, NULL, modulePathU,
|
||||
HKEY_CLASSES_ROOT, kClsidInprocMask, L"ThreadingModel", L"Apartment",
|
||||
NULL, NULL, NULL, NULL
|
||||
};
|
||||
CSysString clsidString = k_Clsid;
|
||||
CSysString s = TEXT("CLSID\\");
|
||||
s += clsidString;
|
||||
|
||||
//register the CLSID entries
|
||||
for (int i = 0; clsidEntries[i].hRootKey; i++)
|
||||
{
|
||||
TCHAR subKey[MAX_PATH];
|
||||
const CRegItem &r = clsidEntries[i];
|
||||
wsprintf(subKey, r.SubKey, clsidString);
|
||||
NRegistry::CKey key;
|
||||
if (key.Create(r.hRootKey, subKey, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE) != NOERROR)
|
||||
if (key.Create(HKEY_CLASSES_ROOT, s, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE) != NOERROR)
|
||||
return FALSE;
|
||||
key.SetValue(clsidEntries[i].ValueName, clsidEntries[i].Data);
|
||||
key.SetValue(NULL, k_ShellExtName);
|
||||
NRegistry::CKey keyInproc;
|
||||
if (keyInproc.Create(key, TEXT("InprocServer32"), NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE) != NOERROR)
|
||||
return FALSE;
|
||||
keyInproc.SetValue(NULL, modulePathU);
|
||||
keyInproc.SetValue(TEXT("ThreadingModel"), TEXT("Apartment"));
|
||||
}
|
||||
|
||||
#if !defined(_WIN64) && !defined(UNDER_CE)
|
||||
@@ -216,46 +176,45 @@ static BOOL RegisterServer(CLSID clsid, LPCWSTR title)
|
||||
#endif
|
||||
{
|
||||
NRegistry::CKey key;
|
||||
if (key.Create(HKEY_LOCAL_MACHINE, kApprovedKeyPath, NULL,
|
||||
REG_OPTION_NON_VOLATILE, KEY_WRITE) == NOERROR)
|
||||
key.SetValue(GetUnicodeString(clsidString), title);
|
||||
if (key.Create(HKEY_LOCAL_MACHINE, k_Approved, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE) == NOERROR)
|
||||
key.SetValue(clsidString, k_ShellExtName);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
STDAPI DllRegisterServer(void)
|
||||
{
|
||||
return RegisterServer(CLSID_CZipContextMenu, kShellExtName) ? S_OK: SELFREG_E_CLASS;
|
||||
return RegisterServer() ? S_OK: SELFREG_E_CLASS;
|
||||
}
|
||||
|
||||
static BOOL UnregisterServer(CLSID clsid)
|
||||
static BOOL UnregisterServer()
|
||||
{
|
||||
TCHAR clsidString[MAX_PATH];
|
||||
if (!GetStringFromIID(clsid, clsidString, MAX_PATH))
|
||||
return FALSE;
|
||||
const CSysString clsidString = k_Clsid;
|
||||
CSysString s = TEXT("CLSID\\");
|
||||
s += clsidString;
|
||||
CSysString s2 = s;
|
||||
s2.AddAscii("\\InprocServer32");
|
||||
|
||||
TCHAR subKey[MAX_PATH];
|
||||
wsprintf(subKey, kClsidInprocMask, clsidString);
|
||||
RegDeleteKey(HKEY_CLASSES_ROOT, subKey);
|
||||
|
||||
wsprintf (subKey, kClsidMask, clsidString);
|
||||
RegDeleteKey(HKEY_CLASSES_ROOT, subKey);
|
||||
RegDeleteKey(HKEY_CLASSES_ROOT, s2);
|
||||
RegDeleteKey(HKEY_CLASSES_ROOT, s);
|
||||
|
||||
#if !defined(_WIN64) && !defined(UNDER_CE)
|
||||
if (IsItWindowsNT())
|
||||
#endif
|
||||
{
|
||||
HKEY hKey;
|
||||
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, kApprovedKeyPath, 0, KEY_SET_VALUE, &hKey) == NOERROR)
|
||||
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, k_Approved, 0, KEY_SET_VALUE, &hKey) == NOERROR)
|
||||
{
|
||||
RegDeleteValue(hKey, clsidString);
|
||||
RegCloseKey(hKey);
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
STDAPI DllUnregisterServer(void)
|
||||
{
|
||||
return UnregisterServer(CLSID_CZipContextMenu) ? S_OK: SELFREG_E_CLASS;
|
||||
return UnregisterServer() ? S_OK: SELFREG_E_CLASS;
|
||||
}
|
||||
|
||||
@@ -538,13 +538,5 @@ SOURCE=".\7-zip.dll.manifest"
|
||||
|
||||
SOURCE=.\ContextMenuFlags.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\RegistryContextMenu.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\RegistryContextMenu.h
|
||||
# End Source File
|
||||
# End Target
|
||||
# End Project
|
||||
|
||||
@@ -2,114 +2,218 @@
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "../../../Common/StringConvert.h"
|
||||
|
||||
#include "../../../Windows/Registry.h"
|
||||
#include "../../../Windows/Synchronization.h"
|
||||
|
||||
#include "RegistryContextMenu.h"
|
||||
|
||||
using namespace NWindows;
|
||||
using namespace NRegistry;
|
||||
|
||||
namespace NZipRootRegistry {
|
||||
|
||||
#ifndef UNDER_CE
|
||||
|
||||
static NSynchronization::CCriticalSection g_CS;
|
||||
|
||||
static const TCHAR *kContextMenuKeyName = TEXT("\\shellex\\ContextMenuHandlers\\7-Zip");
|
||||
static const TCHAR *kDragDropMenuKeyName = TEXT("\\shellex\\DragDropHandlers\\7-Zip");
|
||||
// does extension can work, if Approved is removed ?
|
||||
// CLISID (and Approved ?) items are separated for 32-bit and 64-bit code.
|
||||
// shellex items shared by 32-bit and 64-bit code?
|
||||
|
||||
static const TCHAR *kExtensionCLSID = TEXT("{23170F69-40C1-278A-1000-000100020000}");
|
||||
static LPCTSTR k_Clsid = TEXT("{23170F69-40C1-278A-1000-000100020000}");
|
||||
static LPCTSTR k_ShellExtName = TEXT("7-Zip Shell Extension");
|
||||
|
||||
static const TCHAR *kRootKeyNameForFile = TEXT("*");
|
||||
static const TCHAR *kRootKeyNameForFolder = TEXT("Folder");
|
||||
static const TCHAR *kRootKeyNameForDirectory = TEXT("Directory");
|
||||
static const TCHAR *kRootKeyNameForDrive = TEXT("Drive");
|
||||
static LPCTSTR k_Approved = TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Shell Extensions\\Approved");
|
||||
static LPCTSTR k_Inproc = TEXT("InprocServer32");
|
||||
|
||||
static CSysString GetFullContextMenuKeyName(const CSysString &keyName)
|
||||
{ return (keyName + kContextMenuKeyName); }
|
||||
static LPCTSTR k_KeyPostfix_ContextMenu = TEXT("\\shellex\\ContextMenuHandlers\\7-Zip");
|
||||
static LPCTSTR k_KeyPostfix_DragDrop = TEXT("\\shellex\\DragDropHandlers\\7-Zip");
|
||||
|
||||
static CSysString GetFullDragDropMenuKeyName(const CSysString &keyName)
|
||||
{ return (keyName + kDragDropMenuKeyName); }
|
||||
static LPCTSTR k_KeyName_File = TEXT("*");
|
||||
static LPCTSTR k_KeyName_Folder = TEXT("Folder");
|
||||
static LPCTSTR k_KeyName_Directory = TEXT("Directory");
|
||||
static LPCTSTR k_KeyName_Drive = TEXT("Drive");
|
||||
|
||||
static bool CheckHandlerCommon(const CSysString &keyName)
|
||||
static LPCTSTR const k_shellex_Prefixes[] =
|
||||
{
|
||||
k_KeyName_File,
|
||||
k_KeyName_Folder,
|
||||
k_KeyName_Directory,
|
||||
k_KeyName_Drive
|
||||
};
|
||||
|
||||
static const bool k_shellex_Statuses[2][4] =
|
||||
{
|
||||
{ true, true, true, false },
|
||||
{ false, false, true, true }
|
||||
};
|
||||
|
||||
|
||||
// can we use static RegDeleteKeyExW in _WIN64 mode?
|
||||
// is it supported by Windows 2003 x64?
|
||||
|
||||
/*
|
||||
#ifdef _WIN64
|
||||
|
||||
#define INIT_REG_WOW
|
||||
|
||||
#else
|
||||
*/
|
||||
|
||||
typedef WINADVAPI LONG (APIENTRY *Func_RegDeleteKeyExW)(HKEY hKey, LPCWSTR lpSubKey, REGSAM samDesired, DWORD Reserved);
|
||||
static Func_RegDeleteKeyExW func_RegDeleteKeyExW;
|
||||
|
||||
static void Init_RegDeleteKeyExW()
|
||||
{
|
||||
if (!func_RegDeleteKeyExW)
|
||||
func_RegDeleteKeyExW = (Func_RegDeleteKeyExW)
|
||||
GetProcAddress(GetModuleHandleW(L"advapi32.dll"), "RegDeleteKeyExW");
|
||||
}
|
||||
|
||||
#define INIT_REG_WOW if (wow != 0) Init_RegDeleteKeyExW();
|
||||
|
||||
// #endif
|
||||
|
||||
static LONG MyRegistry_DeleteKey(HKEY parentKey, LPCTSTR name, UInt32 wow)
|
||||
{
|
||||
if (wow == 0)
|
||||
return RegDeleteKey(parentKey, name);
|
||||
|
||||
/*
|
||||
#ifdef _WIN64
|
||||
return RegDeleteKeyExW
|
||||
#else
|
||||
*/
|
||||
if (!func_RegDeleteKeyExW)
|
||||
return E_NOTIMPL;
|
||||
return func_RegDeleteKeyExW
|
||||
// #endif
|
||||
(parentKey, GetUnicodeString(name), wow, 0);
|
||||
}
|
||||
|
||||
static LONG MyRegistry_DeleteKey_HKCR(LPCTSTR name, UInt32 wow)
|
||||
{
|
||||
return MyRegistry_DeleteKey(HKEY_CLASSES_ROOT, name, wow);
|
||||
}
|
||||
|
||||
// static NSynchronization::CCriticalSection g_CS;
|
||||
|
||||
static CSysString Get_ContextMenuHandler_KeyName(const CSysString &keyName)
|
||||
{ return (keyName + k_KeyPostfix_ContextMenu); }
|
||||
|
||||
/*
|
||||
static CSysString Get_DragDropHandler_KeyName(const CSysString &keyName)
|
||||
{ return (keyName + k_KeyPostfix_DragDrop); }
|
||||
*/
|
||||
|
||||
static bool CheckHandlerCommon(const CSysString &keyName, UInt32 wow)
|
||||
{
|
||||
NSynchronization::CCriticalSectionLock lock(g_CS);
|
||||
CKey key;
|
||||
if (key.Open(HKEY_CLASSES_ROOT, keyName, KEY_READ) != ERROR_SUCCESS)
|
||||
if (key.Open(HKEY_CLASSES_ROOT, keyName, KEY_READ | wow) != ERROR_SUCCESS)
|
||||
return false;
|
||||
CSysString value;
|
||||
if (key.QueryValue(NULL, value) != ERROR_SUCCESS)
|
||||
return false;
|
||||
return StringsAreEqualNoCase_Ascii(value, kExtensionCLSID);
|
||||
return StringsAreEqualNoCase_Ascii(value, k_Clsid);
|
||||
}
|
||||
|
||||
bool CheckContextMenuHandler()
|
||||
bool CheckContextMenuHandler(const UString &path, UInt32 wow)
|
||||
{
|
||||
// NSynchronization::CCriticalSectionLock lock(g_CS);
|
||||
|
||||
CSysString s = TEXT("CLSID\\");
|
||||
s += k_Clsid;
|
||||
s.AddAscii("\\InprocServer32");
|
||||
|
||||
{
|
||||
NRegistry::CKey key;
|
||||
if (key.Open(HKEY_CLASSES_ROOT, s, KEY_READ | wow) != ERROR_SUCCESS)
|
||||
return false;
|
||||
UString regPath;
|
||||
if (key.QueryValue(NULL, regPath) != ERROR_SUCCESS)
|
||||
return false;
|
||||
if (!path.IsEqualTo_NoCase(regPath))
|
||||
return false;
|
||||
}
|
||||
|
||||
return
|
||||
// CheckHandlerCommon(GetFullContextMenuKeyName(kRootKeyNameForFolder)) &&
|
||||
CheckHandlerCommon(GetFullContextMenuKeyName(kRootKeyNameForDirectory)) &&
|
||||
CheckHandlerCommon(GetFullContextMenuKeyName(kRootKeyNameForFile)) &&
|
||||
CheckHandlerCommon(GetFullDragDropMenuKeyName(kRootKeyNameForDirectory)) &&
|
||||
CheckHandlerCommon(GetFullDragDropMenuKeyName(kRootKeyNameForDrive));
|
||||
CheckHandlerCommon(Get_ContextMenuHandler_KeyName(k_KeyName_File), wow);
|
||||
/*
|
||||
&& CheckHandlerCommon(Get_ContextMenuHandler_KeyName(k_KeyName_Directory), wow)
|
||||
// && CheckHandlerCommon(Get_ContextMenuHandler_KeyName(k_KeyName_Folder))
|
||||
|
||||
&& CheckHandlerCommon(Get_DragDropHandler_KeyName(k_KeyName_Directory), wow)
|
||||
&& CheckHandlerCommon(Get_DragDropHandler_KeyName(k_KeyName_Drive), wow);
|
||||
*/
|
||||
}
|
||||
|
||||
static void DeleteContextMenuHandlerCommon(const CSysString &keyName)
|
||||
|
||||
static LONG MyCreateKey(CKey &key, HKEY parentKey, LPCTSTR keyName, UInt32 wow)
|
||||
{
|
||||
CKey rootKey;
|
||||
rootKey.Attach(HKEY_CLASSES_ROOT);
|
||||
rootKey.RecurseDeleteKey(GetFullContextMenuKeyName(keyName));
|
||||
rootKey.Detach();
|
||||
return key.Create(parentKey, keyName, REG_NONE,
|
||||
REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS | wow);
|
||||
}
|
||||
|
||||
static void DeleteDragDropMenuHandlerCommon(const CSysString &keyName)
|
||||
LONG SetContextMenuHandler(bool setMode, const UString &path, UInt32 wow)
|
||||
{
|
||||
CKey rootKey;
|
||||
rootKey.Attach(HKEY_CLASSES_ROOT);
|
||||
rootKey.RecurseDeleteKey(GetFullDragDropMenuKeyName(keyName));
|
||||
rootKey.Detach();
|
||||
}
|
||||
// NSynchronization::CCriticalSectionLock lock(g_CS);
|
||||
|
||||
void DeleteContextMenuHandler()
|
||||
{
|
||||
DeleteContextMenuHandlerCommon(kRootKeyNameForFile);
|
||||
DeleteContextMenuHandlerCommon(kRootKeyNameForFolder);
|
||||
DeleteContextMenuHandlerCommon(kRootKeyNameForDirectory);
|
||||
DeleteContextMenuHandlerCommon(kRootKeyNameForDrive);
|
||||
DeleteDragDropMenuHandlerCommon(kRootKeyNameForFile);
|
||||
DeleteDragDropMenuHandlerCommon(kRootKeyNameForFolder);
|
||||
DeleteDragDropMenuHandlerCommon(kRootKeyNameForDirectory);
|
||||
DeleteDragDropMenuHandlerCommon(kRootKeyNameForDrive);
|
||||
}
|
||||
INIT_REG_WOW
|
||||
|
||||
static void AddContextMenuHandlerCommon(const CSysString &keyName)
|
||||
{
|
||||
DeleteContextMenuHandlerCommon(keyName);
|
||||
NSynchronization::CCriticalSectionLock lock(g_CS);
|
||||
CKey key;
|
||||
key.Create(HKEY_CLASSES_ROOT, GetFullContextMenuKeyName(keyName));
|
||||
key.SetValue(NULL, kExtensionCLSID);
|
||||
}
|
||||
CSysString s = TEXT("CLSID\\");
|
||||
s += k_Clsid;
|
||||
|
||||
static void AddDragDropMenuHandlerCommon(const CSysString &keyName)
|
||||
{
|
||||
DeleteDragDropMenuHandlerCommon(keyName);
|
||||
NSynchronization::CCriticalSectionLock lock(g_CS);
|
||||
CKey key;
|
||||
key.Create(HKEY_CLASSES_ROOT, GetFullDragDropMenuKeyName(keyName));
|
||||
key.SetValue(NULL, kExtensionCLSID);
|
||||
}
|
||||
LONG res;
|
||||
if (setMode)
|
||||
{
|
||||
{
|
||||
CKey key;
|
||||
res = MyCreateKey(key, HKEY_CLASSES_ROOT, s, wow);
|
||||
if (res == ERROR_SUCCESS)
|
||||
{
|
||||
key.SetValue(NULL, k_ShellExtName);
|
||||
CKey keyInproc;
|
||||
res = MyCreateKey(keyInproc, key, k_Inproc, wow);
|
||||
if (res == ERROR_SUCCESS)
|
||||
{
|
||||
res = keyInproc.SetValue(NULL, path);
|
||||
keyInproc.SetValue(TEXT("ThreadingModel"), TEXT("Apartment"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
CKey key;
|
||||
if (MyCreateKey(key, HKEY_LOCAL_MACHINE, k_Approved, wow) == ERROR_SUCCESS)
|
||||
key.SetValue(k_Clsid, k_ShellExtName);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
CSysString s2 = s;
|
||||
s2.AddAscii("\\InprocServer32");
|
||||
|
||||
void AddContextMenuHandler()
|
||||
{
|
||||
AddContextMenuHandlerCommon(kRootKeyNameForFile);
|
||||
// AddContextMenuHandlerCommon(kRootKeyNameForFolder);
|
||||
AddContextMenuHandlerCommon(kRootKeyNameForDirectory);
|
||||
MyRegistry_DeleteKey_HKCR(s2, wow);
|
||||
res = MyRegistry_DeleteKey_HKCR(s, wow);
|
||||
}
|
||||
|
||||
AddDragDropMenuHandlerCommon(kRootKeyNameForDirectory);
|
||||
AddDragDropMenuHandlerCommon(kRootKeyNameForDrive);
|
||||
// shellex items probably are shared beween 32-bit and 64-bit apps. So we don't delete items for delete operation.
|
||||
if (setMode)
|
||||
for (unsigned i = 0; i < 2; i++)
|
||||
{
|
||||
for (unsigned k = 0; k < ARRAY_SIZE(k_shellex_Prefixes); k++)
|
||||
{
|
||||
CSysString s = k_shellex_Prefixes[k];
|
||||
s += (i == 0 ? k_KeyPostfix_ContextMenu : k_KeyPostfix_DragDrop);
|
||||
if (k_shellex_Statuses[i][k])
|
||||
{
|
||||
CKey key;
|
||||
MyCreateKey(key, HKEY_CLASSES_ROOT, s, wow);
|
||||
key.SetValue(NULL, k_Clsid);
|
||||
}
|
||||
else
|
||||
MyRegistry_DeleteKey_HKCR(s, wow);
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
@@ -3,14 +3,11 @@
|
||||
#ifndef __REGISTRY_CONTEXT_MENU_H
|
||||
#define __REGISTRY_CONTEXT_MENU_H
|
||||
|
||||
namespace NZipRootRegistry {
|
||||
|
||||
#ifndef UNDER_CE
|
||||
bool CheckContextMenuHandler();
|
||||
void AddContextMenuHandler();
|
||||
void DeleteContextMenuHandler();
|
||||
#endif
|
||||
|
||||
}
|
||||
bool CheckContextMenuHandler(const UString &path, UInt32 wow = 0);
|
||||
LONG SetContextMenuHandler(bool setMode, const UString &path, UInt32 wow = 0);
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
@@ -14,7 +14,6 @@ EXPLORER_OBJS = \
|
||||
$O\DllExportsExplorer.obj \
|
||||
$O\ContextMenu.obj \
|
||||
$O\MyMessages.obj \
|
||||
$O\RegistryContextMenu.obj \
|
||||
|
||||
COMMON_OBJS = \
|
||||
$O\IntToString.obj \
|
||||
|
||||
@@ -448,7 +448,7 @@ int PrintErrorMessage(const char *message, const char *text)
|
||||
}
|
||||
|
||||
|
||||
static void ReduceString(UString &s, unsigned size)
|
||||
void ReduceString(UString &s, unsigned size)
|
||||
{
|
||||
if (s.Len() > size)
|
||||
{
|
||||
|
||||
@@ -190,6 +190,8 @@ int ShowLastErrorMessage();
|
||||
|
||||
bool WasEscPressed();
|
||||
|
||||
void ReduceString(UString &s, unsigned size);
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -68,8 +68,17 @@ NResult::EEnum Execute(const CFileInfo &oldFileInfo, const CFileInfo &newFileInf
|
||||
SetFileInfoStrings(oldFileInfo, oldFileInfoStrings);
|
||||
SetFileInfoStrings(newFileInfo, newFileInfoStrings);
|
||||
|
||||
AString oldName = UnicodeStringToMultiByte(oldFileInfo.Name, CP_OEMCP);
|
||||
AString newName = UnicodeStringToMultiByte(newFileInfo.Name, CP_OEMCP);
|
||||
UString oldName2 = oldFileInfo.Name;
|
||||
UString newName2 = newFileInfo.Name;
|
||||
|
||||
{
|
||||
const unsigned maxNameLen = kXSize - 9 - 2;
|
||||
ReduceString(oldName2, maxNameLen);
|
||||
ReduceString(newName2, maxNameLen);
|
||||
}
|
||||
|
||||
AString oldName = UnicodeStringToMultiByte(oldName2);
|
||||
AString newName = UnicodeStringToMultiByte(newName2);
|
||||
|
||||
struct CInitDialogItem initItems[]={
|
||||
{ DI_DOUBLEBOX, 3, 1, kXSize - 4, kYSize - 2, false, false, 0, false, NMessageID::kOverwriteTitle, NULL, NULL },
|
||||
|
||||
@@ -72,17 +72,18 @@ void CApp::ReloadLang()
|
||||
|
||||
void CApp::SetListSettings()
|
||||
{
|
||||
bool showDots = ReadShowDots();
|
||||
bool showRealFileIcons = ReadShowRealFileIcons();
|
||||
CFmSettings st;
|
||||
st.Load();
|
||||
|
||||
ShowSystemMenu = st.ShowSystemMenu;
|
||||
|
||||
DWORD extendedStyle = LVS_EX_HEADERDRAGDROP;
|
||||
if (ReadFullRow())
|
||||
if (st.FullRow)
|
||||
extendedStyle |= LVS_EX_FULLROWSELECT;
|
||||
if (ReadShowGrid())
|
||||
if (st.ShowGrid)
|
||||
extendedStyle |= LVS_EX_GRIDLINES;
|
||||
bool mySelectionMode = ReadAlternativeSelection();
|
||||
|
||||
if (ReadSingleClick())
|
||||
if (st.SingleClick)
|
||||
{
|
||||
extendedStyle |= LVS_EX_ONECLICKACTIVATE | LVS_EX_TRACKSELECT;
|
||||
/*
|
||||
@@ -91,16 +92,16 @@ void CApp::SetListSettings()
|
||||
*/
|
||||
}
|
||||
|
||||
for (int i = 0; i < kNumPanelsMax; i++)
|
||||
for (unsigned i = 0; i < kNumPanelsMax; i++)
|
||||
{
|
||||
CPanel &panel = Panels[i];
|
||||
panel._mySelectMode = mySelectionMode;
|
||||
panel._showDots = showDots;
|
||||
panel._showRealFileIcons = showRealFileIcons;
|
||||
panel._mySelectMode = st.AlternativeSelection;
|
||||
panel._showDots = st.ShowDots;
|
||||
panel._showRealFileIcons = st.ShowRealFileIcons;
|
||||
panel._exStyle = extendedStyle;
|
||||
|
||||
DWORD style = (DWORD)panel._listView.GetStyle();
|
||||
if (mySelectionMode)
|
||||
if (st.AlternativeSelection)
|
||||
style |= LVS_SINGLESEL;
|
||||
else
|
||||
style &= ~LVS_SINGLESEL;
|
||||
@@ -109,11 +110,6 @@ void CApp::SetListSettings()
|
||||
}
|
||||
}
|
||||
|
||||
void CApp::SetShowSystemMenu()
|
||||
{
|
||||
ShowSystemMenu = Read_ShowSystemMenu();
|
||||
}
|
||||
|
||||
#ifndef ILC_COLOR32
|
||||
#define ILC_COLOR32 0x0020
|
||||
#endif
|
||||
@@ -179,7 +175,7 @@ struct CButtonInfo
|
||||
UString GetText() const { return LangString(StringResID); }
|
||||
};
|
||||
|
||||
static CButtonInfo g_StandardButtons[] =
|
||||
static const CButtonInfo g_StandardButtons[] =
|
||||
{
|
||||
{ IDM_COPY_TO, IDB_COPY, IDB_COPY2, IDS_BUTTON_COPY },
|
||||
{ IDM_MOVE_TO, IDB_MOVE, IDB_MOVE2, IDS_BUTTON_MOVE },
|
||||
@@ -187,16 +183,16 @@ static CButtonInfo g_StandardButtons[] =
|
||||
{ IDM_PROPERTIES, IDB_INFO, IDB_INFO2, IDS_BUTTON_INFO }
|
||||
};
|
||||
|
||||
static CButtonInfo g_ArchiveButtons[] =
|
||||
static const CButtonInfo g_ArchiveButtons[] =
|
||||
{
|
||||
{ kMenuCmdID_Toolbar_Add, IDB_ADD, IDB_ADD2, IDS_ADD },
|
||||
{ kMenuCmdID_Toolbar_Extract, IDB_EXTRACT, IDB_EXTRACT2, IDS_EXTRACT },
|
||||
{ kMenuCmdID_Toolbar_Test, IDB_TEST, IDB_TEST2, IDS_TEST }
|
||||
};
|
||||
|
||||
static bool SetButtonText(int commandID, CButtonInfo *buttons, int numButtons, UString &s)
|
||||
static bool SetButtonText(int commandID, const CButtonInfo *buttons, unsigned numButtons, UString &s)
|
||||
{
|
||||
for (int i = 0; i < numButtons; i++)
|
||||
for (unsigned i = 0; i < numButtons; i++)
|
||||
{
|
||||
const CButtonInfo &b = buttons[i];
|
||||
if (b.CommandID == commandID)
|
||||
@@ -218,7 +214,7 @@ static void SetButtonText(int commandID, UString &s)
|
||||
static void AddButton(
|
||||
NControl::CImageList &imageList,
|
||||
NControl::CToolBar &toolBar,
|
||||
CButtonInfo &butInfo, bool showText, bool large)
|
||||
const CButtonInfo &butInfo, bool showText, bool large)
|
||||
{
|
||||
TBBUTTON but;
|
||||
but.iBitmap = 0;
|
||||
@@ -258,7 +254,7 @@ void CApp::ReloadToolbars()
|
||||
if (ShowArchiveToolbar || ShowStandardToolbar)
|
||||
{
|
||||
CreateToolbar(_window, _buttonsImageList, _toolBar, LargeButtons);
|
||||
int i;
|
||||
unsigned i;
|
||||
if (ShowArchiveToolbar)
|
||||
for (i = 0; i < ARRAY_SIZE(g_ArchiveButtons); i++)
|
||||
AddButton(_buttonsImageList, _toolBar, g_ArchiveButtons[i], ShowButtonsLables, LargeButtons);
|
||||
@@ -282,10 +278,13 @@ void MyLoadMenu();
|
||||
HRESULT CApp::Create(HWND hwnd, const UString &mainPath, const UString &arcFormat, int xSizes[2], bool &archiveIsOpened, bool &encrypted)
|
||||
{
|
||||
_window.Attach(hwnd);
|
||||
|
||||
#ifdef UNDER_CE
|
||||
_commandBar.Create(g_hInstance, hwnd, 1);
|
||||
#endif
|
||||
|
||||
MyLoadMenu();
|
||||
|
||||
#ifdef UNDER_CE
|
||||
_commandBar.AutoSize();
|
||||
#endif
|
||||
@@ -298,14 +297,16 @@ HRESULT CApp::Create(HWND hwnd, const UString &mainPath, const UString &arcForma
|
||||
PanelsCreated[i] = false;
|
||||
|
||||
AppState.Read();
|
||||
|
||||
SetListSettings();
|
||||
SetShowSystemMenu();
|
||||
|
||||
if (LastFocusedPanel >= kNumPanelsMax)
|
||||
LastFocusedPanel = 0;
|
||||
// ShowDeletedFiles = Read_ShowDeleted();
|
||||
|
||||
CListMode listMode;
|
||||
listMode.Read();
|
||||
|
||||
for (i = 0; i < kNumPanelsMax; i++)
|
||||
{
|
||||
CPanel &panel = Panels[i];
|
||||
@@ -313,6 +314,7 @@ HRESULT CApp::Create(HWND hwnd, const UString &mainPath, const UString &arcForma
|
||||
panel._xSize = xSizes[i];
|
||||
panel._flatModeForArc = ReadFlatView(i);
|
||||
}
|
||||
|
||||
for (i = 0; i < kNumPanelsMax; i++)
|
||||
if (NumPanels > 1 || i == LastFocusedPanel)
|
||||
{
|
||||
@@ -328,6 +330,7 @@ HRESULT CApp::Create(HWND hwnd, const UString &mainPath, const UString &arcForma
|
||||
encrypted = encrypted2;
|
||||
}
|
||||
}
|
||||
|
||||
SetFocusedPanel(LastFocusedPanel);
|
||||
Panels[LastFocusedPanel].SetFocusToList();
|
||||
return S_OK;
|
||||
@@ -357,7 +360,8 @@ void CApp::Save()
|
||||
{
|
||||
AppState.Save();
|
||||
CListMode listMode;
|
||||
for (int i = 0; i < kNumPanelsMax; i++)
|
||||
|
||||
for (unsigned i = 0; i < kNumPanelsMax; i++)
|
||||
{
|
||||
const CPanel &panel = Panels[i];
|
||||
UString path;
|
||||
@@ -370,6 +374,7 @@ void CApp::Save()
|
||||
listMode.Panels[i] = panel.GetListViewMode();
|
||||
SaveFlatView(i, panel._flatModeForArc);
|
||||
}
|
||||
|
||||
listMode.Save();
|
||||
// Save_ShowDeleted(ShowDeletedFiles);
|
||||
}
|
||||
@@ -377,7 +382,7 @@ void CApp::Save()
|
||||
void CApp::Release()
|
||||
{
|
||||
// It's for unloading COM dll's: don't change it.
|
||||
for (int i = 0; i < kNumPanelsMax; i++)
|
||||
for (unsigned i = 0; i < kNumPanelsMax; i++)
|
||||
Panels[i].Release();
|
||||
}
|
||||
|
||||
@@ -467,6 +472,7 @@ UString CPanel::GetItemsInfoString(const CRecordVector<UInt32> &indices)
|
||||
UString info;
|
||||
UInt64 numDirs, numFiles, filesSize, foldersSize;
|
||||
numDirs = numFiles = filesSize = foldersSize = 0;
|
||||
|
||||
unsigned i;
|
||||
for (i = 0; i < indices.Size(); i++)
|
||||
{
|
||||
|
||||
@@ -258,7 +258,6 @@ public:
|
||||
*/
|
||||
|
||||
void SetListSettings();
|
||||
void SetShowSystemMenu();
|
||||
HRESULT SwitchOnOffOnePanel();
|
||||
|
||||
bool GetFlatMode() { return Panels[LastFocusedPanel].GetFlatMode(); }
|
||||
|
||||
@@ -197,9 +197,11 @@ bool CBrowseDialog::OnInit()
|
||||
#endif
|
||||
|
||||
#ifndef _SFX
|
||||
if (ReadSingleClick())
|
||||
CFmSettings st;
|
||||
st.Load();
|
||||
if (st.SingleClick)
|
||||
_list.SetExtendedListViewStyle(LVS_EX_ONECLICKACTIVATE | LVS_EX_TRACKSELECT);
|
||||
_showDots = ReadShowDots();
|
||||
_showDots = st.ShowDots;
|
||||
#endif
|
||||
|
||||
{
|
||||
@@ -999,11 +1001,13 @@ bool CorrectFsPath(const UString &relBase, const UString &path2, UString &result
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
bool CorrectFsPath(const UString & /* relBase */, const UString &path, UString &result)
|
||||
{
|
||||
result = path;
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
bool Dlg_CreateFolder(HWND wnd, UString &destName)
|
||||
|
||||
@@ -27,48 +27,50 @@ static LPCWSTR kEditTopic = L"FM/options.htm#editor";
|
||||
|
||||
bool CEditPage::OnInit()
|
||||
{
|
||||
_initMode = true;
|
||||
|
||||
LangSetDlgItems(*this, kLangIDs, ARRAY_SIZE(kLangIDs));
|
||||
LangSetDlgItems_Colon(*this, kLangIDs_Colon, ARRAY_SIZE(kLangIDs_Colon));
|
||||
|
||||
_viewer.Attach(GetItem(IDE_EDIT_VIEWER));
|
||||
_editor.Attach(GetItem(IDE_EDIT_EDITOR));
|
||||
_diff.Attach(GetItem(IDE_EDIT_DIFF));
|
||||
|
||||
_ctrls[0].Ctrl = IDE_EDIT_VIEWER; _ctrls[0].Button = IDB_EDIT_VIEWER;
|
||||
_ctrls[1].Ctrl = IDE_EDIT_EDITOR; _ctrls[1].Button = IDB_EDIT_EDITOR;
|
||||
_ctrls[2].Ctrl = IDE_EDIT_DIFF; _ctrls[2].Button = IDB_EDIT_DIFF;
|
||||
|
||||
for (unsigned i = 0; i < 3; i++)
|
||||
{
|
||||
CEditPageCtrl &c = _ctrls[i];
|
||||
c.WasChanged = false;
|
||||
c.Edit.Attach(GetItem(c.Ctrl));
|
||||
UString path;
|
||||
ReadRegEditor(false, path);
|
||||
_viewer.SetText(path);
|
||||
}
|
||||
{
|
||||
UString path;
|
||||
ReadRegEditor(true, path);
|
||||
_editor.SetText(path);
|
||||
}
|
||||
{
|
||||
UString path;
|
||||
ReadRegDiff(path);
|
||||
_diff.SetText(path);
|
||||
if (i < 2)
|
||||
ReadRegEditor(i > 0, path);
|
||||
else
|
||||
ReadRegDiff(path);
|
||||
c.Edit.SetText(path);
|
||||
}
|
||||
|
||||
_initMode = false;
|
||||
|
||||
return CPropertyPage::OnInit();
|
||||
}
|
||||
|
||||
LONG CEditPage::OnApply()
|
||||
{
|
||||
for (unsigned i = 0; i < 3; i++)
|
||||
{
|
||||
UString path;
|
||||
_viewer.GetText(path);
|
||||
SaveRegEditor(false, path);
|
||||
}
|
||||
{
|
||||
UString path;
|
||||
_editor.GetText(path);
|
||||
SaveRegEditor(true, path);
|
||||
}
|
||||
{
|
||||
UString path;
|
||||
_diff.GetText(path);
|
||||
SaveRegDiff(path);
|
||||
CEditPageCtrl &c = _ctrls[i];
|
||||
if (c.WasChanged)
|
||||
{
|
||||
UString path;
|
||||
c.Edit.GetText(path);
|
||||
if (i < 2)
|
||||
SaveRegEditor(i > 0, path);
|
||||
else
|
||||
SaveRegDiff(path);
|
||||
c.WasChanged = false;
|
||||
}
|
||||
}
|
||||
|
||||
return PSNRET_NOERROR;
|
||||
}
|
||||
|
||||
@@ -91,24 +93,34 @@ static void Edit_BrowseForFile(NWindows::NControl::CEdit &edit, HWND hwnd)
|
||||
|
||||
bool CEditPage::OnButtonClicked(int buttonID, HWND buttonHWND)
|
||||
{
|
||||
switch (buttonID)
|
||||
for (unsigned i = 0; i < 3; i++)
|
||||
{
|
||||
case IDB_EDIT_VIEWER: Edit_BrowseForFile(_viewer, *this); return true;
|
||||
case IDB_EDIT_EDITOR: Edit_BrowseForFile(_editor, *this); return true;
|
||||
case IDB_EDIT_DIFF: Edit_BrowseForFile(_diff, *this); return true;
|
||||
CEditPageCtrl &c = _ctrls[i];
|
||||
if (buttonID == c.Button)
|
||||
{
|
||||
Edit_BrowseForFile(c.Edit, *this);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return CPropertyPage::OnButtonClicked(buttonID, buttonHWND);
|
||||
}
|
||||
|
||||
bool CEditPage::OnCommand(int code, int itemID, LPARAM param)
|
||||
{
|
||||
if (code == EN_CHANGE && (
|
||||
itemID == IDE_EDIT_VIEWER ||
|
||||
itemID == IDE_EDIT_EDITOR ||
|
||||
itemID == IDE_EDIT_DIFF))
|
||||
if (!_initMode && code == EN_CHANGE)
|
||||
{
|
||||
Changed();
|
||||
return true;
|
||||
for (unsigned i = 0; i < 3; i++)
|
||||
{
|
||||
CEditPageCtrl &c = _ctrls[i];
|
||||
if (itemID == c.Ctrl)
|
||||
{
|
||||
c.WasChanged = true;
|
||||
Changed();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return CPropertyPage::OnCommand(code, itemID, param);
|
||||
}
|
||||
|
||||
@@ -6,11 +6,19 @@
|
||||
#include "../../../Windows/Control/PropertyPage.h"
|
||||
#include "../../../Windows/Control/Edit.h"
|
||||
|
||||
struct CEditPageCtrl
|
||||
{
|
||||
NWindows::NControl::CEdit Edit;
|
||||
bool WasChanged;
|
||||
int Ctrl;
|
||||
int Button;
|
||||
};
|
||||
|
||||
class CEditPage: public NWindows::NControl::CPropertyPage
|
||||
{
|
||||
NWindows::NControl::CEdit _viewer;
|
||||
NWindows::NControl::CEdit _editor;
|
||||
NWindows::NControl::CEdit _diff;
|
||||
CEditPageCtrl _ctrls[3];
|
||||
|
||||
bool _initMode;
|
||||
public:
|
||||
virtual bool OnInit();
|
||||
virtual void OnNotifyHelp();
|
||||
|
||||
@@ -324,42 +324,44 @@ static void GetCommands(const UString &aCommandLine, UString &aCommands)
|
||||
}
|
||||
*/
|
||||
|
||||
/*
|
||||
#ifndef _WIN64
|
||||
typedef BOOL (WINAPI *LPFN_ISWOW64PROCESS) (HANDLE, PBOOL);
|
||||
#if defined(_WIN32) && !defined(_WIN64) && !defined(UNDER_CE)
|
||||
|
||||
static bool IsWow64()
|
||||
bool g_Is_Wow64;
|
||||
|
||||
typedef BOOL (WINAPI *Func_IsWow64Process)(HANDLE, PBOOL);
|
||||
|
||||
static void Set_Wow64()
|
||||
{
|
||||
LPFN_ISWOW64PROCESS fnIsWow64Process = (LPFN_ISWOW64PROCESS)GetProcAddress(
|
||||
GetModuleHandle("kernel32"), "IsWow64Process");
|
||||
if (fnIsWow64Process == NULL)
|
||||
return false;
|
||||
BOOL isWow;
|
||||
if (!fnIsWow64Process(GetCurrentProcess(),&isWow))
|
||||
return false;
|
||||
return isWow != FALSE;
|
||||
g_Is_Wow64 = false;
|
||||
Func_IsWow64Process fnIsWow64Process = (Func_IsWow64Process)GetProcAddress(
|
||||
GetModuleHandleA("kernel32.dll"), "IsWow64Process");
|
||||
if (fnIsWow64Process)
|
||||
{
|
||||
BOOL isWow;
|
||||
if (fnIsWow64Process(GetCurrentProcess(), &isWow))
|
||||
g_Is_Wow64 = (isWow != FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
*/
|
||||
|
||||
|
||||
bool IsLargePageSupported()
|
||||
{
|
||||
#ifdef _WIN64
|
||||
return true;
|
||||
#else
|
||||
OSVERSIONINFO versionInfo;
|
||||
versionInfo.dwOSVersionInfoSize = sizeof(versionInfo);
|
||||
if (!::GetVersionEx(&versionInfo))
|
||||
OSVERSIONINFO vi;
|
||||
vi.dwOSVersionInfoSize = sizeof(vi);
|
||||
if (!::GetVersionEx(&vi))
|
||||
return false;
|
||||
if (versionInfo.dwPlatformId != VER_PLATFORM_WIN32_NT || versionInfo.dwMajorVersion < 5)
|
||||
if (vi.dwPlatformId != VER_PLATFORM_WIN32_NT)
|
||||
return false;
|
||||
if (versionInfo.dwMajorVersion > 5)
|
||||
return true;
|
||||
if (versionInfo.dwMinorVersion < 1)
|
||||
return false;
|
||||
if (versionInfo.dwMinorVersion > 1)
|
||||
return true;
|
||||
// return IsWow64();
|
||||
if (vi.dwMajorVersion < 5) return false;
|
||||
if (vi.dwMajorVersion > 5) return true;
|
||||
if (vi.dwMinorVersion < 1) return false;
|
||||
if (vi.dwMinorVersion > 1) return true;
|
||||
// return g_Is_Wow64;
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
@@ -382,11 +384,11 @@ bool g_SymLink_Supported = false;
|
||||
static void Set_SymLink_Supported()
|
||||
{
|
||||
g_SymLink_Supported = false;
|
||||
OSVERSIONINFO versionInfo;
|
||||
versionInfo.dwOSVersionInfoSize = sizeof(versionInfo);
|
||||
if (!::GetVersionEx(&versionInfo))
|
||||
OSVERSIONINFO vi;
|
||||
vi.dwOSVersionInfoSize = sizeof(vi);
|
||||
if (!::GetVersionEx(&vi))
|
||||
return;
|
||||
if (versionInfo.dwPlatformId != VER_PLATFORM_WIN32_NT || versionInfo.dwMajorVersion < 6)
|
||||
if (vi.dwPlatformId != VER_PLATFORM_WIN32_NT || vi.dwMajorVersion < 6)
|
||||
return;
|
||||
g_SymLink_Supported = true;
|
||||
// if (g_SymLink_Supported)
|
||||
@@ -468,6 +470,11 @@ static int WINAPI WinMain2(int nCmdShow)
|
||||
g_LVN_ITEMACTIVATE_Support = (g_ComCtl32Version >= MAKELONG(71, 4));
|
||||
#endif
|
||||
|
||||
#if defined(_WIN32) && !defined(_WIN64) && !defined(UNDER_CE)
|
||||
Set_Wow64();
|
||||
#endif
|
||||
|
||||
|
||||
g_IsSmallScreen = !NWindows::NControl::IsDialogSizeOK(200, 200);
|
||||
|
||||
// OleInitialize is required for drag and drop.
|
||||
@@ -635,7 +642,15 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE /* hPrevInstance */,
|
||||
|
||||
try
|
||||
{
|
||||
return WinMain2(nCmdShow);
|
||||
try
|
||||
{
|
||||
return WinMain2(nCmdShow);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
g_ExitEventLauncher.Exit(true);
|
||||
throw;
|
||||
}
|
||||
}
|
||||
catch(const CNewException &)
|
||||
{
|
||||
@@ -855,15 +870,14 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
g_App.Save();
|
||||
g_App.Release();
|
||||
SaveWindowInfo(hWnd);
|
||||
|
||||
g_ExitEventLauncher.Exit(true);
|
||||
PostQuitMessage(0);
|
||||
break;
|
||||
}
|
||||
/*
|
||||
case WM_MOVE:
|
||||
{
|
||||
break;
|
||||
}
|
||||
*/
|
||||
|
||||
// case WM_MOVE: break;
|
||||
|
||||
case WM_LBUTTONDOWN:
|
||||
g_StartCaptureMousePos = LOWORD(lParam);
|
||||
g_StartCaptureSplitterPos = g_Splitter.GetPos();
|
||||
@@ -993,6 +1007,7 @@ void CApp::MoveSubWindows()
|
||||
if (xSize == 0)
|
||||
return;
|
||||
int headerSize = 0;
|
||||
|
||||
#ifdef UNDER_CE
|
||||
_commandBar.AutoSize();
|
||||
{
|
||||
@@ -1000,6 +1015,7 @@ void CApp::MoveSubWindows()
|
||||
headerSize += _commandBar.Height();
|
||||
}
|
||||
#endif
|
||||
|
||||
if (_toolBar)
|
||||
{
|
||||
_toolBar.AutoSize();
|
||||
@@ -1009,6 +1025,7 @@ void CApp::MoveSubWindows()
|
||||
#endif
|
||||
headerSize += Window_GetRealHeight(_toolBar);
|
||||
}
|
||||
|
||||
int ySize = MyMax((int)(rect.bottom - headerSize), 0);
|
||||
|
||||
if (NumPanels > 1)
|
||||
|
||||
@@ -208,7 +208,6 @@ struct CCopyState
|
||||
{
|
||||
CProgressInfo ProgressInfo;
|
||||
IFolderOperationsExtractCallback *Callback;
|
||||
UInt64 TotalSize;
|
||||
bool MoveMode;
|
||||
bool UseReadWriteMode;
|
||||
|
||||
@@ -423,7 +422,7 @@ static HRESULT CopyFile_Ask(
|
||||
NFsFolder::CCopyStateIO state2;
|
||||
state2.Progress = state.Callback;
|
||||
state2.DeleteSrcFile = state.MoveMode;
|
||||
state2.TotalSize = state.TotalSize;
|
||||
state2.TotalSize = state.ProgressInfo.TotalSize;
|
||||
state2.StartPos = state.ProgressInfo.StartPos;
|
||||
RINOK(state2.MyCopyFile(srcPath, destPathNew));
|
||||
if (state2.ErrorFileIndex >= 0)
|
||||
@@ -460,10 +459,10 @@ static HRESULT CopyFile_Ask(
|
||||
}
|
||||
else
|
||||
{
|
||||
if (state.TotalSize >= srcFileInfo.Size)
|
||||
if (state.ProgressInfo.TotalSize >= srcFileInfo.Size)
|
||||
{
|
||||
state.TotalSize -= srcFileInfo.Size;
|
||||
RINOK(state.ProgressInfo.Progress->SetTotal(state.TotalSize));
|
||||
state.ProgressInfo.TotalSize -= srcFileInfo.Size;
|
||||
RINOK(state.ProgressInfo.Progress->SetTotal(state.ProgressInfo.TotalSize));
|
||||
}
|
||||
}
|
||||
return state.CallProgress();
|
||||
|
||||
@@ -27,10 +27,13 @@ static const int kWorkModeButtons[] =
|
||||
IDR_FOLDERS_WORK_SPECIFIED
|
||||
};
|
||||
|
||||
static const int kNumWorkModeButtons = ARRAY_SIZE(kWorkModeButtons);
|
||||
static const unsigned kNumWorkModeButtons = ARRAY_SIZE(kWorkModeButtons);
|
||||
|
||||
bool CFoldersPage::OnInit()
|
||||
{
|
||||
_initMode = true;
|
||||
_needSave = false;
|
||||
|
||||
LangSetDlgItems(*this, kLangIDs, ARRAY_SIZE(kLangIDs));
|
||||
m_WorkDirInfo.Load();
|
||||
|
||||
@@ -40,18 +43,18 @@ bool CFoldersPage::OnInit()
|
||||
kWorkModeButtons[m_WorkDirInfo.Mode]);
|
||||
|
||||
m_WorkPath.Init(*this, IDE_FOLDERS_WORK_PATH);
|
||||
m_ButtonSetWorkPath.Init(*this, IDB_FOLDERS_WORK_PATH);
|
||||
|
||||
m_WorkPath.SetText(fs2us(m_WorkDirInfo.Path));
|
||||
|
||||
MyEnableControls();
|
||||
|
||||
_initMode = false;
|
||||
return CPropertyPage::OnInit();
|
||||
}
|
||||
|
||||
int CFoldersPage::GetWorkMode() const
|
||||
{
|
||||
for (int i = 0; i < kNumWorkModeButtons; i++)
|
||||
for (unsigned i = 0; i < kNumWorkModeButtons; i++)
|
||||
if (IsButtonCheckedBool(kWorkModeButtons[i]))
|
||||
return i;
|
||||
throw 0;
|
||||
@@ -61,7 +64,7 @@ void CFoldersPage::MyEnableControls()
|
||||
{
|
||||
bool enablePath = (GetWorkMode() == NWorkDir::NMode::kSpecified);
|
||||
m_WorkPath.Enable(enablePath);
|
||||
m_ButtonSetWorkPath.Enable(enablePath);
|
||||
EnableItem(IDB_FOLDERS_WORK_PATH, enablePath);
|
||||
}
|
||||
|
||||
void CFoldersPage::GetWorkDir(NWorkDir::CInfo &workDirInfo)
|
||||
@@ -86,7 +89,11 @@ bool CFoldersPage::WasChanged()
|
||||
|
||||
void CFoldersPage::ModifiedEvent()
|
||||
{
|
||||
Changed();
|
||||
if (!_initMode)
|
||||
{
|
||||
_needSave = true;
|
||||
Changed();
|
||||
}
|
||||
/*
|
||||
if (WasChanged())
|
||||
Changed();
|
||||
@@ -97,23 +104,25 @@ void CFoldersPage::ModifiedEvent()
|
||||
|
||||
bool CFoldersPage::OnButtonClicked(int buttonID, HWND buttonHWND)
|
||||
{
|
||||
for (int i = 0; i < kNumWorkModeButtons; i++)
|
||||
for (unsigned i = 0; i < kNumWorkModeButtons; i++)
|
||||
if (buttonID == kWorkModeButtons[i])
|
||||
{
|
||||
MyEnableControls();
|
||||
ModifiedEvent();
|
||||
return true;
|
||||
}
|
||||
|
||||
switch (buttonID)
|
||||
{
|
||||
case IDB_FOLDERS_WORK_PATH:
|
||||
OnFoldersWorkButtonPath();
|
||||
break;
|
||||
return true;
|
||||
case IDX_FOLDERS_WORK_FOR_REMOVABLE:
|
||||
break;
|
||||
default:
|
||||
return CPropertyPage::OnButtonClicked(buttonID, buttonHWND);
|
||||
}
|
||||
|
||||
ModifiedEvent();
|
||||
return true;
|
||||
}
|
||||
@@ -140,8 +149,12 @@ void CFoldersPage::OnFoldersWorkButtonPath()
|
||||
|
||||
LONG CFoldersPage::OnApply()
|
||||
{
|
||||
GetWorkDir(m_WorkDirInfo);
|
||||
m_WorkDirInfo.Save();
|
||||
if (_needSave)
|
||||
{
|
||||
GetWorkDir(m_WorkDirInfo);
|
||||
m_WorkDirInfo.Save();
|
||||
_needSave = false;
|
||||
}
|
||||
return PSNRET_NOERROR;
|
||||
}
|
||||
|
||||
|
||||
@@ -10,11 +10,14 @@
|
||||
class CFoldersPage : public NWindows::NControl::CPropertyPage
|
||||
{
|
||||
NWorkDir::CInfo m_WorkDirInfo;
|
||||
NWindows::NControl::CDialogChildControl m_WorkPath;
|
||||
|
||||
bool _needSave;
|
||||
bool _initMode;
|
||||
|
||||
void MyEnableControls();
|
||||
void ModifiedEvent();
|
||||
NWindows::NControl::CDialogChildControl m_WorkPath;
|
||||
NWindows::NControl::CDialogChildControl m_ButtonSetWorkPath;
|
||||
|
||||
void OnFoldersWorkButtonPath();
|
||||
int GetWorkMode() const;
|
||||
void GetWorkDir(NWorkDir::CInfo &workDirInfo);
|
||||
|
||||
@@ -84,14 +84,16 @@ bool CLangPage::OnInit()
|
||||
}
|
||||
|
||||
if (!error.IsEmpty())
|
||||
MessageBoxW(0, error, L"Error in Lang file", MB_OK | MB_ICONSTOP);
|
||||
MessageBoxW(0, error, L"Error in Lang file", MB_ICONERROR);
|
||||
return CPropertyPage::OnInit();
|
||||
}
|
||||
|
||||
LONG CLangPage::OnApply()
|
||||
{
|
||||
int pathIndex = (int)_langCombo.GetItemData_of_CurSel();
|
||||
SaveRegLang(_paths[pathIndex]);
|
||||
if (_needSave)
|
||||
SaveRegLang(_paths[pathIndex]);
|
||||
_needSave = false;
|
||||
ReloadLang();
|
||||
LangWasChanged = true;
|
||||
return PSNRET_NOERROR;
|
||||
@@ -106,6 +108,7 @@ bool CLangPage::OnCommand(int code, int itemID, LPARAM param)
|
||||
{
|
||||
if (code == CBN_SELCHANGE && itemID == IDC_LANG_LANG)
|
||||
{
|
||||
_needSave = true;
|
||||
Changed();
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -10,10 +10,12 @@ class CLangPage: public NWindows::NControl::CPropertyPage
|
||||
{
|
||||
NWindows::NControl::CComboBox _langCombo;
|
||||
UStringVector _paths;
|
||||
|
||||
bool _needSave;
|
||||
public:
|
||||
bool LangWasChanged;
|
||||
|
||||
CLangPage() { LangWasChanged = false; }
|
||||
CLangPage(): _needSave(false), LangWasChanged(false) {}
|
||||
virtual bool OnInit();
|
||||
virtual void OnNotifyHelp();
|
||||
virtual bool OnCommand(int code, int itemID, LPARAM param);
|
||||
|
||||
@@ -140,13 +140,18 @@ void LangString_OnlyFromLangFile(UInt32 langID, UString &dest)
|
||||
}
|
||||
|
||||
static const char *kLangs =
|
||||
"ar.bg.ca.zh.-tw.-cn.cs.da.de.el.en.es.fi.fr.he.hu.is.it.ja.ko.nl.no.=nb.=nn."
|
||||
"pl.pt.-br.rm.ro.ru.sr.=hr.-spl.-spc.sk.sq.sv.th.tr.ur.id.uk.be.sl.et.lv.lt.tg."
|
||||
"fa.vi.hy.az.eu.hsb.mk...tn..xh.zu.af.ka.fo.hi.mt.se.ga."
|
||||
".ms.kk.ky.sw.tk.uz.tt.bn.pa.-in.gu.or.ta.te.kn.ml.as.mr.sa.mn.=mn.=mng"
|
||||
"bo.cy.kh.lo..gl.kok..sd.syr.si..iu.am.tzm.ks.ne.fy.ps.fil."
|
||||
"dv...ha..yo.quz.nso.ba.lb.kl.ig...ti.....ii."
|
||||
".arn..moh..br..ug.mi.oc.co.gsw.sah.qut.rw.wo....prs.";
|
||||
"ar.bg.ca.zh.-tw.-cn.cs.da.de.el.en.es.fi.fr.he.hu.is."
|
||||
"it.ja.ko.nl.no.=nb.=nn.pl.pt.-br.rm.ro.ru.sr.=hr.-spl.-spc.sk.sq.sv.th.tr."
|
||||
"ur.id.uk.be.sl.et.lv.lt.tg.fa.vi.hy.az.eu.hsb.mk."
|
||||
"st.ts.tn.ve.xh.zu.af.ka.fo.hi.mt.se.ga.yi.ms.kk."
|
||||
"ky.sw.tk.uz.tt.bn.pa.-in.gu.or.ta.te.kn.ml.as.mr.sa."
|
||||
"mn.=mn.=mng.bo.cy.kh.lo.my.gl.kok..sd.syr.si..iu.am.tzm."
|
||||
"ks.ne.fy.ps.tl.dv..ff.ha..yo.qu.st.ba.lb.kl."
|
||||
"ig.kr.om.ti.gn..la.so.ii..arn..moh..br.."
|
||||
"ug.mi.oc.co."
|
||||
// "gsw.sah.qut.rw.wo....prs...."
|
||||
// ".gd."
|
||||
;
|
||||
|
||||
static void FindShortNames(UInt32 primeLang, UStringVector &names)
|
||||
{
|
||||
@@ -158,10 +163,10 @@ static void FindShortNames(UInt32 primeLang, UStringVector &names)
|
||||
bool isSub = (p[0] == '-' || p[0] == '=');
|
||||
if (!isSub)
|
||||
index++;
|
||||
if (index > primeLang)
|
||||
break;
|
||||
if (index == primeLang)
|
||||
if (index >= primeLang)
|
||||
{
|
||||
if (index > primeLang)
|
||||
break;
|
||||
UString s;
|
||||
if (isSub)
|
||||
{
|
||||
@@ -178,6 +183,33 @@ static void FindShortNames(UInt32 primeLang, UStringVector &names)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
#include "../../../Common/IntToString.h"
|
||||
|
||||
static struct CC1Lang
|
||||
{
|
||||
CC1Lang()
|
||||
{
|
||||
for (int i = 1; i < 150; i++)
|
||||
{
|
||||
UString s;
|
||||
char ttt[32];
|
||||
ConvertUInt32ToHex(i, ttt);
|
||||
s.AddAscii(ttt);
|
||||
UStringVector names;
|
||||
FindShortNames(i, names);
|
||||
|
||||
FOR_VECTOR (k, names)
|
||||
{
|
||||
s.Add_Space();
|
||||
s += names[k];
|
||||
}
|
||||
OutputDebugStringW(s);
|
||||
}
|
||||
}
|
||||
} g_cc1;
|
||||
*/
|
||||
|
||||
// typedef LANGID (WINAPI *GetUserDefaultUILanguageP)();
|
||||
|
||||
static void OpenDefaultLang()
|
||||
|
||||
@@ -18,7 +18,9 @@ bool CListViewDialog::OnInit()
|
||||
#endif
|
||||
_listView.Attach(GetItem(IDL_LISTVIEW));
|
||||
|
||||
if (ReadSingleClick())
|
||||
CFmSettings st;
|
||||
st.Load();
|
||||
if (st.SingleClick)
|
||||
_listView.SetExtendedListViewStyle(LVS_EX_ONECLICKACTIVATE | LVS_EX_TRACKSELECT);
|
||||
|
||||
SetText(Title);
|
||||
|
||||
@@ -4,25 +4,34 @@
|
||||
|
||||
#include "../Common/ZipRegistry.h"
|
||||
|
||||
#include "../../../Windows/DLL.h"
|
||||
#include "../../../Windows/ErrorMsg.h"
|
||||
#include "../../../Windows/FileFind.h"
|
||||
|
||||
#include "../Explorer/ContextMenuFlags.h"
|
||||
#include "../Explorer/RegistryContextMenu.h"
|
||||
#include "../Explorer/resource.h"
|
||||
|
||||
#include "../FileManager/PropertyNameRes.h"
|
||||
|
||||
#include "../GUI/ExtractDialogRes.h"
|
||||
|
||||
#include "FormatUtils.h"
|
||||
#include "HelpUtils.h"
|
||||
#include "LangUtils.h"
|
||||
#include "MenuPage.h"
|
||||
#include "MenuPageRes.h"
|
||||
#include "FormatUtils.h"
|
||||
|
||||
#include "../FileManager/PropertyNameRes.h"
|
||||
|
||||
using namespace NWindows;
|
||||
using namespace NContextMenuFlags;
|
||||
|
||||
static const UInt32 kLangIDs[] =
|
||||
{
|
||||
IDX_SYSTEM_INTEGRATE_TO_CONTEXT_MENU,
|
||||
IDX_SYSTEM_INTEGRATE_TO_MENU,
|
||||
IDX_SYSTEM_CASCADED_MENU,
|
||||
IDX_SYSTEM_ICON_IN_MENU,
|
||||
IDX_EXTRACT_ELIM_DUP,
|
||||
IDT_SYSTEM_CONTEXT_MENU_ITEMS
|
||||
};
|
||||
|
||||
@@ -34,64 +43,147 @@ struct CContextMenuItem
|
||||
UInt32 Flag;
|
||||
};
|
||||
|
||||
static CContextMenuItem kMenuItems[] =
|
||||
static const CContextMenuItem kMenuItems[] =
|
||||
{
|
||||
{ IDS_CONTEXT_OPEN, kOpen},
|
||||
{ IDS_CONTEXT_OPEN, kOpenAs},
|
||||
{ IDS_CONTEXT_EXTRACT, kExtract},
|
||||
{ IDS_CONTEXT_OPEN, kOpen },
|
||||
{ IDS_CONTEXT_OPEN, kOpenAs },
|
||||
{ IDS_CONTEXT_EXTRACT, kExtract },
|
||||
{ IDS_CONTEXT_EXTRACT_HERE, kExtractHere },
|
||||
{ IDS_CONTEXT_EXTRACT_TO, kExtractTo },
|
||||
|
||||
{ IDS_CONTEXT_TEST, kTest},
|
||||
{ IDS_CONTEXT_TEST, kTest },
|
||||
|
||||
{ IDS_CONTEXT_COMPRESS, kCompress },
|
||||
{ IDS_CONTEXT_COMPRESS_TO, kCompressTo7z },
|
||||
{ IDS_CONTEXT_COMPRESS_TO, kCompressToZip }
|
||||
{ IDS_CONTEXT_COMPRESS_TO, kCompressToZip },
|
||||
|
||||
#ifndef UNDER_CE
|
||||
,
|
||||
{ IDS_CONTEXT_COMPRESS_EMAIL, kCompressEmail },
|
||||
{ IDS_CONTEXT_COMPRESS_TO_EMAIL, kCompressTo7zEmail },
|
||||
{ IDS_CONTEXT_COMPRESS_TO_EMAIL, kCompressToZipEmail }
|
||||
{ IDS_CONTEXT_COMPRESS_TO_EMAIL, kCompressToZipEmail },
|
||||
#endif
|
||||
|
||||
, { IDS_PROP_CHECKSUM, kCRC }
|
||||
{ IDS_PROP_CHECKSUM, kCRC }
|
||||
};
|
||||
|
||||
|
||||
#if !defined(_WIN64)
|
||||
extern bool g_Is_Wow64;
|
||||
#endif
|
||||
|
||||
|
||||
bool CMenuPage::OnInit()
|
||||
{
|
||||
_initMode = true;
|
||||
|
||||
Clear_MenuChanged();
|
||||
|
||||
LangSetDlgItems(*this, kLangIDs, ARRAY_SIZE(kLangIDs));
|
||||
|
||||
#ifdef UNDER_CE
|
||||
EnableItem(IDX_SYSTEM_INTEGRATE_TO_CONTEXT_MENU, false);
|
||||
|
||||
HideItem(IDX_SYSTEM_INTEGRATE_TO_MENU);
|
||||
HideItem(IDX_SYSTEM_INTEGRATE_TO_MENU_2);
|
||||
|
||||
#else
|
||||
CheckButton(IDX_SYSTEM_INTEGRATE_TO_CONTEXT_MENU, NZipRootRegistry::CheckContextMenuHandler());
|
||||
|
||||
{
|
||||
UString s;
|
||||
{
|
||||
CWindow window(GetItem(IDX_SYSTEM_INTEGRATE_TO_MENU));
|
||||
window.GetText(s);
|
||||
}
|
||||
UString bit64 = LangString(IDS_PROP_BIT64);
|
||||
if (bit64.IsEmpty())
|
||||
bit64.SetFromAscii("64-bit");
|
||||
#ifdef _WIN64
|
||||
bit64.Replace(L"64", L"32");
|
||||
#endif
|
||||
s.Add_Space();
|
||||
s += L'(';
|
||||
s += bit64;
|
||||
s += L')';
|
||||
SetItemText(IDX_SYSTEM_INTEGRATE_TO_MENU_2, s);
|
||||
}
|
||||
|
||||
const FString prefix = NDLL::GetModuleDirPrefix();
|
||||
|
||||
_dlls[0].ctrl = IDX_SYSTEM_INTEGRATE_TO_MENU;
|
||||
_dlls[1].ctrl = IDX_SYSTEM_INTEGRATE_TO_MENU_2;
|
||||
|
||||
_dlls[0].wow = 0;
|
||||
_dlls[1].wow =
|
||||
#ifdef _WIN64
|
||||
KEY_WOW64_32KEY
|
||||
#else
|
||||
KEY_WOW64_64KEY
|
||||
#endif
|
||||
;
|
||||
|
||||
for (unsigned d = 0; d < 2; d++)
|
||||
{
|
||||
CShellDll &dll = _dlls[d];
|
||||
|
||||
dll.wasChanged = false;
|
||||
|
||||
#ifndef _WIN64
|
||||
if (d != 0 && !g_Is_Wow64)
|
||||
{
|
||||
HideItem(dll.ctrl);
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
|
||||
FString &path = dll.Path;
|
||||
path = prefix;
|
||||
path.AddAscii(d == 0 ? "7-zip.dll" :
|
||||
#ifdef _WIN64
|
||||
"7-zip32.dll"
|
||||
#else
|
||||
"7-zip64.dll"
|
||||
#endif
|
||||
);
|
||||
|
||||
|
||||
if (!NFile::NFind::DoesFileExist(path))
|
||||
{
|
||||
path.Empty();
|
||||
EnableItem(dll.ctrl, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
dll.prevValue = CheckContextMenuHandler(fs2us(path), dll.wow);
|
||||
CheckButton(dll.ctrl, dll.prevValue);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
CContextMenuInfo ci;
|
||||
ci.Load();
|
||||
|
||||
CheckButton(IDX_SYSTEM_CASCADED_MENU, ci.Cascaded);
|
||||
CheckButton(IDX_SYSTEM_ICON_IN_MENU, ci.MenuIcons);
|
||||
CheckButton(IDX_SYSTEM_CASCADED_MENU, ci.Cascaded.Val);
|
||||
CheckButton(IDX_SYSTEM_ICON_IN_MENU, ci.MenuIcons.Val);
|
||||
CheckButton(IDX_EXTRACT_ELIM_DUP, ci.ElimDup.Val);
|
||||
|
||||
_listView.Attach(GetItem(IDL_SYSTEM_OPTIONS));
|
||||
|
||||
UInt32 newFlags = LVS_EX_CHECKBOXES | LVS_EX_FULLROWSELECT;
|
||||
const UInt32 newFlags = LVS_EX_CHECKBOXES | LVS_EX_FULLROWSELECT;
|
||||
_listView.SetExtendedListViewStyle(newFlags, newFlags);
|
||||
|
||||
_listView.InsertColumn(0, L"", 100);
|
||||
_listView.InsertColumn(0, L"", 200);
|
||||
|
||||
for (int i = 0; i < ARRAY_SIZE(kMenuItems); i++)
|
||||
for (unsigned i = 0; i < ARRAY_SIZE(kMenuItems); i++)
|
||||
{
|
||||
CContextMenuItem &menuItem = kMenuItems[i];
|
||||
const CContextMenuItem &menuItem = kMenuItems[i];
|
||||
|
||||
UString s = LangString(menuItem.ControlID);
|
||||
if (menuItem.Flag == kCRC)
|
||||
s = L"CRC SHA";
|
||||
s.SetFromAscii("CRC SHA");
|
||||
if (menuItem.Flag == kOpenAs ||
|
||||
menuItem.Flag == kCRC)
|
||||
s += L" >";
|
||||
s.AddAscii(" >");
|
||||
|
||||
switch (menuItem.ControlID)
|
||||
{
|
||||
@@ -108,11 +200,11 @@ bool CMenuPage::OnInit()
|
||||
{
|
||||
case kCompressTo7z:
|
||||
case kCompressTo7zEmail:
|
||||
s2 += L".7z";
|
||||
s2.AddAscii(".7z");
|
||||
break;
|
||||
case kCompressToZip:
|
||||
case kCompressToZipEmail:
|
||||
s2 += L".zip";
|
||||
s2.AddAscii(".zip");
|
||||
break;
|
||||
}
|
||||
s = MyFormatNew(s, s2);
|
||||
@@ -126,39 +218,68 @@ bool CMenuPage::OnInit()
|
||||
|
||||
_listView.SetColumnWidthAuto(0);
|
||||
_initMode = false;
|
||||
|
||||
return CPropertyPage::OnInit();
|
||||
}
|
||||
|
||||
|
||||
#ifndef UNDER_CE
|
||||
STDAPI DllRegisterServer(void);
|
||||
STDAPI DllUnregisterServer(void);
|
||||
HWND g_MenuPageHWND = 0;
|
||||
|
||||
static void ShowMenuErrorMessage(const wchar_t *m, HWND hwnd)
|
||||
{
|
||||
MessageBoxW(hwnd, m, L"7-Zip", MB_ICONERROR);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
LONG CMenuPage::OnApply()
|
||||
{
|
||||
#ifndef UNDER_CE
|
||||
g_MenuPageHWND = *this;
|
||||
if (IsButtonCheckedBool(IDX_SYSTEM_INTEGRATE_TO_CONTEXT_MENU))
|
||||
|
||||
for (unsigned d = 2; d != 0;)
|
||||
{
|
||||
DllRegisterServer();
|
||||
NZipRootRegistry::AddContextMenuHandler();
|
||||
}
|
||||
else
|
||||
{
|
||||
DllUnregisterServer();
|
||||
NZipRootRegistry::DeleteContextMenuHandler();
|
||||
d--;
|
||||
CShellDll &dll = _dlls[d];
|
||||
if (dll.wasChanged && !dll.Path.IsEmpty())
|
||||
{
|
||||
bool newVal = IsButtonCheckedBool(dll.ctrl);
|
||||
LONG res = SetContextMenuHandler(newVal, fs2us(dll.Path), dll.wow);
|
||||
if (res != ERROR_SUCCESS && (dll.prevValue != newVal || newVal))
|
||||
ShowMenuErrorMessage(NError::MyFormatMessage(res), *this);
|
||||
dll.prevValue = CheckContextMenuHandler(fs2us(dll.Path), dll.wow);
|
||||
CheckButton(dll.ctrl, dll.prevValue);
|
||||
dll.wasChanged = false;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
CContextMenuInfo ci;
|
||||
ci.Cascaded = IsButtonCheckedBool(IDX_SYSTEM_CASCADED_MENU);
|
||||
ci.MenuIcons = IsButtonCheckedBool(IDX_SYSTEM_ICON_IN_MENU);
|
||||
ci.Flags = 0;
|
||||
for (int i = 0; i < ARRAY_SIZE(kMenuItems); i++)
|
||||
if (_listView.GetCheckState(i))
|
||||
ci.Flags |= kMenuItems[i].Flag;
|
||||
ci.Save();
|
||||
if (_cascaded_Changed || _menuIcons_Changed || _elimDup_Changed || _flags_Changed)
|
||||
{
|
||||
CContextMenuInfo ci;
|
||||
ci.Cascaded.Val = IsButtonCheckedBool(IDX_SYSTEM_CASCADED_MENU);
|
||||
ci.Cascaded.Def = _cascaded_Changed;
|
||||
|
||||
ci.MenuIcons.Val = IsButtonCheckedBool(IDX_SYSTEM_ICON_IN_MENU);
|
||||
ci.MenuIcons.Def = _menuIcons_Changed;
|
||||
|
||||
ci.ElimDup.Val = IsButtonCheckedBool(IDX_EXTRACT_ELIM_DUP);
|
||||
ci.ElimDup.Def = _elimDup_Changed;
|
||||
|
||||
ci.Flags = 0;
|
||||
|
||||
for (unsigned i = 0; i < ARRAY_SIZE(kMenuItems); i++)
|
||||
if (_listView.GetCheckState(i))
|
||||
ci.Flags |= kMenuItems[i].Flag;
|
||||
|
||||
ci.Flags_Def = _flags_Changed;
|
||||
ci.Save();
|
||||
|
||||
Clear_MenuChanged();
|
||||
}
|
||||
|
||||
// UnChanged();
|
||||
|
||||
return PSNRET_NOERROR;
|
||||
}
|
||||
@@ -172,14 +293,30 @@ bool CMenuPage::OnButtonClicked(int buttonID, HWND buttonHWND)
|
||||
{
|
||||
switch (buttonID)
|
||||
{
|
||||
case IDX_SYSTEM_INTEGRATE_TO_CONTEXT_MENU:
|
||||
case IDX_SYSTEM_CASCADED_MENU:
|
||||
case IDX_SYSTEM_ICON_IN_MENU:
|
||||
Changed();
|
||||
return true;
|
||||
}
|
||||
return CPropertyPage::OnButtonClicked(buttonID, buttonHWND);
|
||||
#ifndef UNDER_CE
|
||||
case IDX_SYSTEM_INTEGRATE_TO_MENU:
|
||||
case IDX_SYSTEM_INTEGRATE_TO_MENU_2:
|
||||
{
|
||||
for (unsigned d = 0; d < 2; d++)
|
||||
{
|
||||
CShellDll &dll = _dlls[d];
|
||||
if (buttonID == dll.ctrl && !dll.Path.IsEmpty())
|
||||
dll.wasChanged = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
case IDX_SYSTEM_CASCADED_MENU: _cascaded_Changed = true; break;
|
||||
case IDX_SYSTEM_ICON_IN_MENU: _menuIcons_Changed = true; break;
|
||||
case IDX_EXTRACT_ELIM_DUP: _elimDup_Changed = true; break;
|
||||
|
||||
default:
|
||||
return CPropertyPage::OnButtonClicked(buttonID, buttonHWND);
|
||||
}
|
||||
|
||||
Changed();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CMenuPage::OnNotify(UINT controlID, LPNMHDR lParam)
|
||||
@@ -205,7 +342,10 @@ bool CMenuPage::OnItemChanged(const NMLISTVIEW *info)
|
||||
UINT oldState = info->uOldState & LVIS_STATEIMAGEMASK;
|
||||
UINT newState = info->uNewState & LVIS_STATEIMAGEMASK;
|
||||
if (oldState != newState)
|
||||
{
|
||||
_flags_Changed = true;
|
||||
Changed();
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -6,11 +6,38 @@
|
||||
#include "../../../Windows/Control/PropertyPage.h"
|
||||
#include "../../../Windows/Control/ListView.h"
|
||||
|
||||
#include "../Common/LoadCodecs.h"
|
||||
struct CShellDll
|
||||
{
|
||||
FString Path;
|
||||
bool wasChanged;
|
||||
bool prevValue;
|
||||
int ctrl;
|
||||
UInt32 wow;
|
||||
|
||||
CShellDll(): wasChanged (false), prevValue(false), ctrl(0), wow(0) {}
|
||||
};
|
||||
|
||||
class CMenuPage: public NWindows::NControl::CPropertyPage
|
||||
{
|
||||
bool _initMode;
|
||||
|
||||
bool _cascaded_Changed;
|
||||
bool _menuIcons_Changed;
|
||||
bool _elimDup_Changed;
|
||||
bool _flags_Changed;
|
||||
|
||||
void Clear_MenuChanged()
|
||||
{
|
||||
_cascaded_Changed = false;
|
||||
_menuIcons_Changed = false;
|
||||
_elimDup_Changed = false;
|
||||
_flags_Changed = false;
|
||||
}
|
||||
|
||||
#ifndef UNDER_CE
|
||||
CShellDll _dlls[2];
|
||||
#endif
|
||||
|
||||
NWindows::NControl::CListView _listView;
|
||||
|
||||
virtual bool OnInit();
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
#include "../../GuiCommon.rc"
|
||||
|
||||
#define xc 240
|
||||
#define yc 196
|
||||
#define yc 224
|
||||
|
||||
IDD_MENU MY_PAGE
|
||||
#include "MenuPage2.rc"
|
||||
|
||||
@@ -1,12 +1,16 @@
|
||||
#define y 54
|
||||
#include "../GUI/ExtractDialogRes.h"
|
||||
|
||||
#define y 82
|
||||
|
||||
CAPTION "7-Zip"
|
||||
BEGIN
|
||||
CONTROL "Integrate 7-Zip to shell context menu", IDX_SYSTEM_INTEGRATE_TO_CONTEXT_MENU, MY_CHECKBOX, m, m, xc, 10
|
||||
CONTROL "Cascaded context menu", IDX_SYSTEM_CASCADED_MENU, MY_CHECKBOX, m, m + 14, xc, 10
|
||||
CONTROL "Icons in context menu", IDX_SYSTEM_ICON_IN_MENU, MY_CHECKBOX, m, m + 28, xc, 10
|
||||
CONTROL "Integrate 7-Zip to shell context menu", IDX_SYSTEM_INTEGRATE_TO_MENU, MY_CHECKBOX, m, m, xc, 10
|
||||
CONTROL "(32-bit)", IDX_SYSTEM_INTEGRATE_TO_MENU_2, MY_CHECKBOX, m, m + 14, xc, 10
|
||||
CONTROL "Cascaded context menu", IDX_SYSTEM_CASCADED_MENU, MY_CHECKBOX, m, m + 28, xc, 10
|
||||
CONTROL "Icons in context menu", IDX_SYSTEM_ICON_IN_MENU, MY_CHECKBOX, m, m + 42, xc, 10
|
||||
CONTROL "Eliminate duplication of root folder", IDX_EXTRACT_ELIM_DUP, MY_CHECKBOX, m, m + 56, xc, 10
|
||||
|
||||
LTEXT "Context menu items:", IDT_SYSTEM_CONTEXT_MENU_ITEMS, m, m + 42, xc, 8
|
||||
LTEXT "Context menu items:", IDT_SYSTEM_CONTEXT_MENU_ITEMS, m, m + 70, xc, 8
|
||||
CONTROL "List", IDL_SYSTEM_OPTIONS, "SysListView32",
|
||||
LVS_REPORT | LVS_SINGLESEL | LVS_NOCOLUMNHEADER | WS_BORDER | WS_TABSTOP,
|
||||
m, m + y, xc, yc - y
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
#define IDD_MENU 2300
|
||||
#define IDD_MENU_2 12300
|
||||
|
||||
#define IDX_SYSTEM_INTEGRATE_TO_CONTEXT_MENU 2301
|
||||
#define IDX_SYSTEM_CASCADED_MENU 2302
|
||||
#define IDT_SYSTEM_CONTEXT_MENU_ITEMS 2303
|
||||
#define IDX_SYSTEM_ICON_IN_MENU 2304
|
||||
#define IDX_SYSTEM_INTEGRATE_TO_MENU 2301
|
||||
#define IDX_SYSTEM_CASCADED_MENU 2302
|
||||
#define IDT_SYSTEM_CONTEXT_MENU_ITEMS 2303
|
||||
#define IDX_SYSTEM_ICON_IN_MENU 2304
|
||||
|
||||
#define IDX_SYSTEM_INTEGRATE_TO_MENU_2 2310
|
||||
|
||||
#define IDL_SYSTEM_OPTIONS 100
|
||||
|
||||
@@ -512,7 +512,8 @@ bool OnMenuCommand(HWND hWnd, int id)
|
||||
// File
|
||||
case IDCLOSE:
|
||||
SendMessage(hWnd, WM_ACTIVATE, MAKEWPARAM(WA_INACTIVE, 0), (LPARAM)hWnd);
|
||||
SendMessage (hWnd, WM_CLOSE, 0, 0);
|
||||
g_ExitEventLauncher.Exit(false);
|
||||
SendMessage(hWnd, WM_CLOSE, 0, 0);
|
||||
break;
|
||||
|
||||
// Edit
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#include "../../../Windows/Control/PropertyPage.h"
|
||||
|
||||
#include "DialogSize.h"
|
||||
|
||||
#include "EditPage.h"
|
||||
#include "EditPageRes.h"
|
||||
#include "FoldersPage.h"
|
||||
@@ -14,8 +15,6 @@
|
||||
#include "LangPageRes.h"
|
||||
#include "MenuPage.h"
|
||||
#include "MenuPageRes.h"
|
||||
// #include "PluginsPage.h"
|
||||
// #include "PluginsPageRes.h"
|
||||
#include "SettingsPage.h"
|
||||
#include "SettingsPageRes.h"
|
||||
#include "SystemPage.h"
|
||||
@@ -29,90 +28,38 @@
|
||||
|
||||
using namespace NWindows;
|
||||
|
||||
#ifndef UNDER_CE
|
||||
typedef UINT32 (WINAPI * DllRegisterServerPtr)();
|
||||
|
||||
extern HWND g_MenuPageHWND;
|
||||
|
||||
static void ShowMenuErrorMessage(const wchar_t *m)
|
||||
{
|
||||
MessageBoxW(g_MenuPageHWND, m, L"7-Zip", MB_ICONERROR);
|
||||
}
|
||||
|
||||
static int DllRegisterServer2(const char *name)
|
||||
{
|
||||
NDLL::CLibrary lib;
|
||||
|
||||
FString prefix = NDLL::GetModuleDirPrefix();
|
||||
if (!lib.Load(prefix + FTEXT("7-zip.dll")))
|
||||
{
|
||||
ShowMenuErrorMessage(L"7-Zip cannot load 7-zip.dll");
|
||||
return E_FAIL;
|
||||
}
|
||||
DllRegisterServerPtr f = (DllRegisterServerPtr)lib.GetProc(name);
|
||||
if (f == NULL)
|
||||
{
|
||||
ShowMenuErrorMessage(L"Incorrect plugin");
|
||||
return E_FAIL;
|
||||
}
|
||||
HRESULT res = f();
|
||||
if (res != S_OK)
|
||||
ShowMenuErrorMessage(HResultToMessage(res));
|
||||
return (int)res;
|
||||
}
|
||||
|
||||
STDAPI DllRegisterServer(void)
|
||||
{
|
||||
#ifdef UNDER_CE
|
||||
return S_OK;
|
||||
#else
|
||||
return DllRegisterServer2("DllRegisterServer");
|
||||
#endif
|
||||
}
|
||||
|
||||
STDAPI DllUnregisterServer(void)
|
||||
{
|
||||
#ifdef UNDER_CE
|
||||
return S_OK;
|
||||
#else
|
||||
return DllRegisterServer2("DllUnregisterServer");
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void OptionsDialog(HWND hwndOwner, HINSTANCE /* hInstance */)
|
||||
{
|
||||
CSystemPage systemPage;
|
||||
// CPluginsPage pluginsPage;
|
||||
CMenuPage menuPage;
|
||||
CFoldersPage foldersPage;
|
||||
CEditPage editPage;
|
||||
CSettingsPage settingsPage;
|
||||
CLangPage langPage;
|
||||
CMenuPage menuPage;
|
||||
CFoldersPage foldersPage;
|
||||
|
||||
CObjectVector<NControl::CPageInfo> pages;
|
||||
BIG_DIALOG_SIZE(200, 200);
|
||||
|
||||
UINT pageIDs[] = {
|
||||
const UINT pageIDs[] = {
|
||||
SIZED_DIALOG(IDD_SYSTEM),
|
||||
SIZED_DIALOG(IDD_MENU),
|
||||
SIZED_DIALOG(IDD_FOLDERS),
|
||||
SIZED_DIALOG(IDD_EDIT),
|
||||
SIZED_DIALOG(IDD_SETTINGS),
|
||||
SIZED_DIALOG(IDD_LANG) };
|
||||
NControl::CPropertyPage *pagePinters[] = { &systemPage, &menuPage, &foldersPage, &editPage, &settingsPage, &langPage };
|
||||
const int kNumPages = ARRAY_SIZE(pageIDs);
|
||||
for (int i = 0; i < kNumPages; i++)
|
||||
|
||||
NControl::CPropertyPage *pagePointers[] = { &systemPage, &menuPage, &foldersPage, &editPage, &settingsPage, &langPage };
|
||||
|
||||
for (unsigned i = 0; i < ARRAY_SIZE(pageIDs); i++)
|
||||
{
|
||||
NControl::CPageInfo page;
|
||||
NControl::CPageInfo &page = pages.AddNew();
|
||||
page.ID = pageIDs[i];
|
||||
LangString_OnlyFromLangFile(page.ID, page.Title);
|
||||
page.Page = pagePinters[i];
|
||||
pages.Add(page);
|
||||
page.Page = pagePointers[i];
|
||||
}
|
||||
|
||||
INT_PTR res = NControl::MyPropertySheet(pages, hwndOwner, LangString(IDS_OPTIONS));
|
||||
|
||||
if (res != -1 && res != 0)
|
||||
{
|
||||
if (langPage.LangWasChanged)
|
||||
@@ -120,9 +67,10 @@ void OptionsDialog(HWND hwndOwner, HINSTANCE /* hInstance */)
|
||||
// g_App._window.SetText(LangString(IDS_APP_TITLE, 0x03000000));
|
||||
MyLoadMenu();
|
||||
g_App.ReloadToolbars();
|
||||
g_App.MoveSubWindows();
|
||||
g_App.MoveSubWindows(); // we need it to change list window aafter _toolBar.AutoSize();
|
||||
g_App.ReloadLang();
|
||||
}
|
||||
|
||||
/*
|
||||
if (systemPage.WasChanged)
|
||||
{
|
||||
@@ -130,8 +78,8 @@ void OptionsDialog(HWND hwndOwner, HINSTANCE /* hInstance */)
|
||||
g_App.SysIconsWereChanged();
|
||||
}
|
||||
*/
|
||||
|
||||
g_App.SetListSettings();
|
||||
g_App.SetShowSystemMenu();
|
||||
g_App.RefreshAllPanels();
|
||||
// ::PostMessage(hwndOwner, kLangWasChangedMessage, 0 , 0);
|
||||
}
|
||||
|
||||
@@ -841,4 +841,28 @@ public:
|
||||
~CMyBuffer() { ::MidFree(_data); }
|
||||
};
|
||||
|
||||
class CExitEventLauncher
|
||||
{
|
||||
public:
|
||||
NWindows::NSynchronization::CManualResetEvent _exitEvent;
|
||||
bool _needExit;
|
||||
CRecordVector< ::CThread > _threads;
|
||||
unsigned _numActiveThreads;
|
||||
|
||||
CExitEventLauncher()
|
||||
{
|
||||
_needExit = false;
|
||||
if (_exitEvent.Create(false) != S_OK)
|
||||
throw 9387173;
|
||||
_needExit = true;
|
||||
_numActiveThreads = 0;
|
||||
};
|
||||
|
||||
~CExitEventLauncher() { Exit(true); }
|
||||
|
||||
void Exit(bool hardExit);
|
||||
};
|
||||
|
||||
extern CExitEventLauncher g_ExitEventLauncher;
|
||||
|
||||
#endif
|
||||
|
||||
@@ -209,7 +209,23 @@ STDMETHODIMP CDropSource::QueryContinueDrag(BOOL escapePressed, DWORD keyState)
|
||||
{
|
||||
CCopyToOptions options;
|
||||
options.folder = Folder;
|
||||
|
||||
// 15.13: fixed problem with mouse cursor for password window.
|
||||
// DoDragDrop() probably calls SetCapture() to some hidden window.
|
||||
// But it's problem, if we show some modal window, like MessageBox.
|
||||
// So we return capture to our window.
|
||||
// If you know better way to solve the problem, please notify 7-Zip developer.
|
||||
|
||||
// MessageBoxW(*Panel, L"test", L"test", 0);
|
||||
|
||||
/* HWND oldHwnd = */ SetCapture(*Panel);
|
||||
|
||||
Result = Panel->CopyTo(options, Indices, &Messages);
|
||||
|
||||
// do we need to restore capture?
|
||||
// ReleaseCapture();
|
||||
// oldHwnd = SetCapture(oldHwnd);
|
||||
|
||||
if (Result != S_OK || !Messages.IsEmpty())
|
||||
return DRAGDROP_S_CANCEL;
|
||||
}
|
||||
@@ -357,10 +373,14 @@ void CPanel::OnDrag(LPNMLISTVIEW /* nmListView */)
|
||||
effectsOK |= DROPEFFECT_MOVE;
|
||||
DWORD effect;
|
||||
_panelCallback->DragBegin();
|
||||
|
||||
HRESULT res = DoDragDrop(dataObject, dropSource, effectsOK, &effect);
|
||||
|
||||
_panelCallback->DragEnd();
|
||||
bool canceled = (res == DRAGDROP_S_CANCEL);
|
||||
|
||||
CDisableNotify disableNotify(*this);
|
||||
|
||||
if (res == DRAGDROP_S_DROP)
|
||||
{
|
||||
res = dropSourceSpec->Result;
|
||||
|
||||
@@ -6,6 +6,8 @@
|
||||
|
||||
#include <tlhelp32.h>
|
||||
|
||||
#include "../../../Common/IntToString.h"
|
||||
|
||||
#include "../../../Common/AutoPtr.h"
|
||||
#include "../../../Common/StringConvert.h"
|
||||
|
||||
@@ -24,6 +26,7 @@
|
||||
#include "FileFolderPluginOpen.h"
|
||||
#include "FormatUtils.h"
|
||||
#include "LangUtils.h"
|
||||
#include "PropertyNameRes.h"
|
||||
#include "RegistryUtils.h"
|
||||
#include "UpdateCallback100.h"
|
||||
|
||||
@@ -45,6 +48,20 @@ extern bool g_IsNT;
|
||||
|
||||
static CFSTR kTempDirPrefix = FTEXT("7zO");
|
||||
|
||||
// #define SHOW_DEBUG_INFO
|
||||
|
||||
#ifdef SHOW_DEBUG_INFO
|
||||
#define DEBUG_PRINT(s) OutputDebugStringA(s);
|
||||
#define DEBUG_PRINT_W(s) OutputDebugStringW(s);
|
||||
#define DEBUG_PRINT_NUM(s, num) { char ttt[32]; ConvertUInt32ToString(num, ttt); OutputDebugStringA(s); OutputDebugStringA(ttt); }
|
||||
#else
|
||||
#define DEBUG_PRINT(s)
|
||||
#define DEBUG_PRINT_W(s)
|
||||
#define DEBUG_PRINT_NUM(s, num)
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#ifndef UNDER_CE
|
||||
|
||||
class CProcessSnapshot
|
||||
@@ -76,90 +93,329 @@ public:
|
||||
|
||||
#endif
|
||||
|
||||
typedef DWORD (WINAPI *GetProcessIdFunc)(HANDLE process);
|
||||
|
||||
/*
|
||||
struct COpenExtProg
|
||||
{
|
||||
const char *Ext;
|
||||
const char *Prog;
|
||||
};
|
||||
|
||||
static const COpenExtProg g_Progs[] =
|
||||
{
|
||||
{ "jpeg jpg png bmp gif", "Microsoft.Photos.exe" },
|
||||
{ "html htm pdf", "MicrosoftEdge.exe" },
|
||||
// , { "rrr", "notepad.exe" }
|
||||
};
|
||||
|
||||
static bool FindExtProg(const char *exts, const char *ext)
|
||||
{
|
||||
unsigned len = (unsigned)strlen(ext);
|
||||
for (;;)
|
||||
{
|
||||
const char *p = exts;
|
||||
for (;; p++)
|
||||
{
|
||||
const char c = *p;
|
||||
if (c == 0 || c == ' ')
|
||||
break;
|
||||
}
|
||||
if (len == (unsigned)(p - exts) && IsString1PrefixedByString2(exts, ext))
|
||||
return true;
|
||||
if (*p == 0)
|
||||
return false;
|
||||
exts = p + 1;
|
||||
}
|
||||
}
|
||||
|
||||
class CPossibleProgs
|
||||
{
|
||||
public:
|
||||
AStringVector ProgNames;
|
||||
|
||||
void SetFromExtension(const char *ext) // ext must be low case
|
||||
{
|
||||
ProgNames.Clear();
|
||||
for (unsigned i = 0; i < ARRAY_SIZE(g_Progs); i++)
|
||||
if (FindExtProg(g_Progs[i].Ext, ext))
|
||||
{
|
||||
ProgNames.Add(g_Progs[i].Prog);
|
||||
}
|
||||
}
|
||||
|
||||
bool IsFromList(const UString &progName) const
|
||||
{
|
||||
FOR_VECTOR (i, ProgNames)
|
||||
if (progName.IsEqualTo_Ascii_NoCase(ProgNames[i]))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
};
|
||||
*/
|
||||
|
||||
|
||||
#ifndef UNDER_CE
|
||||
|
||||
EXTERN_C_BEGIN
|
||||
|
||||
/*
|
||||
GetProcessImageFileName
|
||||
returns the path in device form, rather than drive letters:
|
||||
\Device\HarddiskVolume1\WINDOWS\SysWOW64\notepad.exe
|
||||
|
||||
GetModuleFileNameEx works only after Sleep(something). Why?
|
||||
returns the path
|
||||
C:\WINDOWS\system32\NOTEPAD.EXE
|
||||
*/
|
||||
|
||||
/* Kernel32.dll: Win7, Win2008R2;
|
||||
Psapi.dll: (if PSAPI_VERSION=1) on Win7 and Win2008R2;
|
||||
Psapi.dll: XP, Win2003, Vista, 2008;
|
||||
*/
|
||||
|
||||
typedef DWORD (WINAPI *Func_GetProcessImageFileNameW)(
|
||||
HANDLE hProcess, LPWSTR lpFilename, DWORD nSize);
|
||||
|
||||
typedef DWORD (WINAPI *Func_GetModuleFileNameExW)(
|
||||
HANDLE hProcess, HMODULE hModule, LPWSTR lpFilename, DWORD nSize);
|
||||
|
||||
typedef DWORD (WINAPI *Func_GetProcessId)(HANDLE process);
|
||||
|
||||
EXTERN_C_END
|
||||
|
||||
|
||||
static HMODULE g_Psapi_dll_module;
|
||||
|
||||
/*
|
||||
static void My_GetProcessFileName_2(HANDLE hProcess, UString &path)
|
||||
{
|
||||
path.Empty();
|
||||
const unsigned maxPath = 1024;
|
||||
WCHAR temp[maxPath + 1];
|
||||
|
||||
const char *func_name = "GetModuleFileNameExW";
|
||||
Func_GetModuleFileNameExW my_func = (Func_GetModuleFileNameExW)
|
||||
::GetProcAddress(::GetModuleHandleA("kernel32.dll"), func_name);
|
||||
if (!my_func)
|
||||
{
|
||||
if (!g_Psapi_dll_module)
|
||||
g_Psapi_dll_module = LoadLibraryW(L"Psapi.dll");
|
||||
if (g_Psapi_dll_module)
|
||||
my_func = (Func_GetModuleFileNameExW)::GetProcAddress(g_Psapi_dll_module, func_name);
|
||||
}
|
||||
if (my_func)
|
||||
{
|
||||
// DWORD num = GetModuleFileNameEx(hProcess, NULL, temp, maxPath);
|
||||
DWORD num = my_func(hProcess, NULL, temp, maxPath);
|
||||
if (num != 0)
|
||||
path = temp;
|
||||
}
|
||||
// FreeLibrary(lib);
|
||||
}
|
||||
*/
|
||||
|
||||
static void My_GetProcessFileName(HANDLE hProcess, UString &path)
|
||||
{
|
||||
path.Empty();
|
||||
const unsigned maxPath = 1024;
|
||||
WCHAR temp[maxPath + 1];
|
||||
|
||||
const char *func_name = "GetProcessImageFileNameW";
|
||||
Func_GetProcessImageFileNameW my_func = (Func_GetProcessImageFileNameW)
|
||||
::GetProcAddress(::GetModuleHandleA("kernel32.dll"), func_name);
|
||||
|
||||
if (!my_func)
|
||||
{
|
||||
if (!g_Psapi_dll_module)
|
||||
g_Psapi_dll_module = LoadLibraryW(L"Psapi.dll");
|
||||
if (g_Psapi_dll_module)
|
||||
my_func = (Func_GetProcessImageFileNameW)::GetProcAddress(g_Psapi_dll_module, func_name);
|
||||
}
|
||||
|
||||
if (my_func)
|
||||
{
|
||||
// DWORD num = GetProcessImageFileNameW(hProcess, temp, maxPath);
|
||||
DWORD num = my_func(hProcess, temp, maxPath);
|
||||
if (num != 0)
|
||||
path = temp;
|
||||
}
|
||||
// FreeLibrary(lib);
|
||||
}
|
||||
|
||||
struct CSnapshotProcess
|
||||
{
|
||||
DWORD Id;
|
||||
DWORD ParentId;
|
||||
UString Name;
|
||||
};
|
||||
|
||||
static void GetSnapshot(CObjectVector<CSnapshotProcess> &items)
|
||||
{
|
||||
items.Clear();
|
||||
|
||||
CProcessSnapshot snapshot;
|
||||
if (!snapshot.Create())
|
||||
return;
|
||||
|
||||
DEBUG_PRINT("snapshot.Create() OK");
|
||||
PROCESSENTRY32 pe;
|
||||
CSnapshotProcess item;
|
||||
memset(&pe, 0, sizeof(pe));
|
||||
pe.dwSize = sizeof(pe);
|
||||
BOOL res = snapshot.GetFirstProcess(&pe);
|
||||
while (res)
|
||||
{
|
||||
item.Id = pe.th32ProcessID;
|
||||
item.ParentId = pe.th32ParentProcessID;
|
||||
item.Name = GetUnicodeString(pe.szExeFile);
|
||||
items.Add(item);
|
||||
res = snapshot.GetNextProcess(&pe);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
class CChildProcesses
|
||||
{
|
||||
#ifndef UNDER_CE
|
||||
CRecordVector<DWORD> _ids;
|
||||
#endif
|
||||
|
||||
public:
|
||||
// bool ProgsWereUsed;
|
||||
CRecordVector<HANDLE> Handles;
|
||||
CRecordVector<bool> NeedWait;
|
||||
// UStringVector Names;
|
||||
|
||||
#ifndef UNDER_CE
|
||||
UString Path;
|
||||
#endif
|
||||
|
||||
// CChildProcesses(): ProgsWereUsed(false) {}
|
||||
~CChildProcesses() { CloseAll(); }
|
||||
void DisableWait(unsigned index) { NeedWait[index] = false; }
|
||||
|
||||
void CloseAll()
|
||||
{
|
||||
FOR_VECTOR (i, Handles)
|
||||
FOR_VECTOR (i, Handles)
|
||||
{
|
||||
HANDLE h = Handles[i];
|
||||
if (h != NULL)
|
||||
CloseHandle(h);
|
||||
}
|
||||
|
||||
Handles.Clear();
|
||||
NeedWait.Clear();
|
||||
// Names.Clear();
|
||||
|
||||
#ifndef UNDER_CE
|
||||
// Path.Empty();
|
||||
_ids.Clear();
|
||||
#endif
|
||||
}
|
||||
|
||||
void AddProcess(HANDLE h)
|
||||
void SetMainProcess(HANDLE h)
|
||||
{
|
||||
#ifndef UNDER_CE
|
||||
GetProcessIdFunc func = (GetProcessIdFunc)::GetProcAddress(::GetModuleHandleA("kernel32.dll"), "GetProcessId");
|
||||
|
||||
Func_GetProcessId func = (Func_GetProcessId)::GetProcAddress(::GetModuleHandleA("kernel32.dll"), "GetProcessId");
|
||||
if (func)
|
||||
_ids.AddToUniqueSorted(func(h));
|
||||
{
|
||||
DWORD id = func(h);
|
||||
if (id != 0)
|
||||
_ids.AddToUniqueSorted(id);
|
||||
}
|
||||
|
||||
My_GetProcessFileName(h, Path);
|
||||
DEBUG_PRINT_W(Path);
|
||||
|
||||
#endif
|
||||
|
||||
Handles.Add(h);
|
||||
NeedWait.Add(true);
|
||||
}
|
||||
|
||||
void Update()
|
||||
#ifndef UNDER_CE
|
||||
|
||||
void Update(bool needFindProcessByPath /* , const CPossibleProgs &progs */)
|
||||
{
|
||||
#ifndef UNDER_CE
|
||||
CRecordVector<DWORD> ids, parents;
|
||||
{
|
||||
CProcessSnapshot snapshot;
|
||||
if (snapshot.Create())
|
||||
{
|
||||
PROCESSENTRY32 pe;
|
||||
memset(&pe, 0, sizeof(pe));
|
||||
pe.dwSize = sizeof(pe);
|
||||
BOOL res = snapshot.GetFirstProcess(&pe);
|
||||
while (res)
|
||||
{
|
||||
ids.Add(pe.th32ProcessID);
|
||||
parents.Add(pe.th32ParentProcessID);
|
||||
res = snapshot.GetNextProcess(&pe);
|
||||
}
|
||||
}
|
||||
}
|
||||
/*
|
||||
if (_ids.IsEmpty())
|
||||
return;
|
||||
*/
|
||||
|
||||
CObjectVector<CSnapshotProcess> sps;
|
||||
GetSnapshot(sps);
|
||||
|
||||
const int separ = Path.ReverseFind_PathSepar();
|
||||
const UString mainName = Path.Ptr(separ + 1);
|
||||
if (mainName.IsEmpty())
|
||||
needFindProcessByPath = false;
|
||||
|
||||
const DWORD currentProcessId = GetCurrentProcessId();
|
||||
|
||||
for (;;)
|
||||
{
|
||||
unsigned i;
|
||||
for (i = 0; i < ids.Size(); i++)
|
||||
bool wasAdded = false;
|
||||
|
||||
FOR_VECTOR (i, sps)
|
||||
{
|
||||
DWORD id = ids[i];
|
||||
if (_ids.FindInSorted(parents[i]) >= 0 &&
|
||||
_ids.FindInSorted(id) < 0)
|
||||
const CSnapshotProcess &sp = sps[i];
|
||||
const DWORD id = sp.Id;
|
||||
|
||||
if (id == currentProcessId)
|
||||
continue;
|
||||
if (_ids.FindInSorted(id) >= 0)
|
||||
continue;
|
||||
|
||||
bool isSameName = false;
|
||||
const UString &name = sp.Name;
|
||||
|
||||
if (needFindProcessByPath)
|
||||
isSameName = mainName.IsEqualTo_NoCase(name);
|
||||
|
||||
bool needAdd = false;
|
||||
// bool isFromProgs = false;
|
||||
|
||||
if (isSameName || _ids.FindInSorted(sp.ParentId) >= 0)
|
||||
needAdd = true;
|
||||
/*
|
||||
else if (progs.IsFromList(name))
|
||||
{
|
||||
needAdd = true;
|
||||
isFromProgs = true;
|
||||
}
|
||||
*/
|
||||
|
||||
if (needAdd)
|
||||
{
|
||||
DEBUG_PRINT("----- OpenProcess -----");
|
||||
DEBUG_PRINT_W(name);
|
||||
HANDLE hProcess = OpenProcess(SYNCHRONIZE, FALSE, id);
|
||||
if (hProcess)
|
||||
{
|
||||
_ids.AddToUniqueSorted(id);
|
||||
DEBUG_PRINT("----- OpenProcess OK -----");
|
||||
// if (!isFromProgs)
|
||||
_ids.AddToUniqueSorted(id);
|
||||
Handles.Add(hProcess);
|
||||
NeedWait.Add(true);
|
||||
break;
|
||||
// Names.Add(name);
|
||||
wasAdded = true;
|
||||
// ProgsWereUsed = isFromProgs;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (i == ids.Size())
|
||||
|
||||
if (!wasAdded)
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
struct CTmpProcessInfo: public CTempFileInfo
|
||||
{
|
||||
CChildProcesses Processes;
|
||||
@@ -168,9 +424,12 @@ struct CTmpProcessInfo: public CTempFileInfo
|
||||
bool UsePassword;
|
||||
UString Password;
|
||||
|
||||
CTmpProcessInfo(): UsePassword(false) {}
|
||||
bool ReadOnly;
|
||||
|
||||
CTmpProcessInfo(): UsePassword(false), ReadOnly(false) {}
|
||||
};
|
||||
|
||||
|
||||
class CTmpProcessInfoRelease
|
||||
{
|
||||
CTmpProcessInfo *_tmpProcessInfo;
|
||||
@@ -600,6 +859,9 @@ static HRESULT StartApplication(const UString &dir, const UString &path, HWND wi
|
||||
process.Attach(execInfo.hProcess);
|
||||
}
|
||||
|
||||
|
||||
DEBUG_PRINT_NUM("-- ShellExecuteEx -- execInfo.hInstApp = ", result)
|
||||
|
||||
if (result <= 32)
|
||||
{
|
||||
switch (result)
|
||||
@@ -610,6 +872,8 @@ static HRESULT StartApplication(const UString &dir, const UString &path, HWND wi
|
||||
// L"There is no application associated with the given file name extension",
|
||||
L"7-Zip", MB_OK | MB_ICONSTOP);
|
||||
}
|
||||
|
||||
return E_FAIL; // fixed in 15.13. Can we use it for any Windows version?
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
@@ -800,6 +1064,8 @@ HRESULT CPanel::OnOpenItemChanged(UInt32 index, const wchar_t *fullFilePath,
|
||||
|
||||
LRESULT CPanel::OnOpenItemChanged(LPARAM lParam)
|
||||
{
|
||||
// DEBUG_PRINT_NUM("OnOpenItemChanged", GetCurrentThreadId());
|
||||
|
||||
CTmpProcessInfo &tpi = *(CTmpProcessInfo *)lParam;
|
||||
if (tpi.FullPathFolderPrefix != _currentFolderPrefix)
|
||||
return 0;
|
||||
@@ -834,24 +1100,75 @@ LRESULT CPanel::OnOpenItemChanged(LPARAM lParam)
|
||||
return 1;
|
||||
}
|
||||
|
||||
class CExitEventLauncher
|
||||
|
||||
CExitEventLauncher g_ExitEventLauncher;
|
||||
|
||||
void CExitEventLauncher::Exit(bool hardExit)
|
||||
{
|
||||
public:
|
||||
NWindows::NSynchronization::CManualResetEvent _exitEvent;
|
||||
CExitEventLauncher()
|
||||
if (_needExit)
|
||||
{
|
||||
if (_exitEvent.Create(false) != S_OK)
|
||||
throw 9387173;
|
||||
};
|
||||
~CExitEventLauncher() { _exitEvent.Set(); }
|
||||
} g_ExitEventLauncher;
|
||||
_exitEvent.Set();
|
||||
_needExit = false;
|
||||
}
|
||||
|
||||
if (_numActiveThreads == 0)
|
||||
return;
|
||||
|
||||
FOR_VECTOR (i, _threads)
|
||||
{
|
||||
::CThread &th = _threads[i];
|
||||
DWORD wait = (hardExit ? 100 : INFINITE);
|
||||
if (Thread_WasCreated(&th))
|
||||
{
|
||||
DWORD waitResult = WaitForSingleObject(th, wait);
|
||||
// Thread_Wait(&th);
|
||||
if (waitResult == WAIT_TIMEOUT)
|
||||
wait = 1;
|
||||
if (!hardExit && waitResult != WAIT_OBJECT_0)
|
||||
continue;
|
||||
Thread_Close(&th);
|
||||
_numActiveThreads--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
static THREAD_FUNC_DECL MyThreadFunction(void *param)
|
||||
{
|
||||
DEBUG_PRINT("==== MyThreadFunction ====");
|
||||
|
||||
CMyAutoPtr<CTmpProcessInfo> tmpProcessInfoPtr((CTmpProcessInfo *)param);
|
||||
CTmpProcessInfo *tpi = tmpProcessInfoPtr.get();
|
||||
CChildProcesses &processes = tpi->Processes;
|
||||
|
||||
bool mainProcessWasSet = !processes.Handles.IsEmpty();
|
||||
|
||||
bool isComplexMode = true;
|
||||
|
||||
if (!processes.Handles.IsEmpty())
|
||||
{
|
||||
|
||||
const DWORD startTime = GetTickCount();
|
||||
|
||||
/*
|
||||
CPossibleProgs progs;
|
||||
{
|
||||
const UString &name = tpi->RelPath;
|
||||
int slashPos = name.ReverseFind_PathSepar();
|
||||
int dotPos = name.ReverseFind_Dot();
|
||||
if (dotPos > slashPos)
|
||||
{
|
||||
const UString ext = name.Ptr(dotPos + 1);
|
||||
AString extA = UnicodeStringToMultiByte(ext);
|
||||
extA.MakeLower_Ascii();
|
||||
progs.SetFromExtension(extA);
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
bool firstPass = true;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
CRecordVector<HANDLE> handles;
|
||||
@@ -859,6 +1176,8 @@ static THREAD_FUNC_DECL MyThreadFunction(void *param)
|
||||
|
||||
FOR_VECTOR (i, processes.Handles)
|
||||
{
|
||||
if (handles.Size() > 60)
|
||||
break;
|
||||
if (processes.NeedWait[i])
|
||||
{
|
||||
handles.Add(processes.Handles[i]);
|
||||
@@ -866,43 +1185,150 @@ static THREAD_FUNC_DECL MyThreadFunction(void *param)
|
||||
}
|
||||
}
|
||||
|
||||
bool needFindProcessByPath = false;
|
||||
|
||||
if (handles.IsEmpty())
|
||||
{
|
||||
if (!firstPass)
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
handles.Add(g_ExitEventLauncher._exitEvent);
|
||||
|
||||
DWORD waitResult = ::WaitForMultipleObjects(handles.Size(), &handles.Front(), FALSE, INFINITE);
|
||||
|
||||
waitResult -= WAIT_OBJECT_0;
|
||||
|
||||
if (waitResult >= handles.Size() - 1)
|
||||
{
|
||||
processes.CloseAll();
|
||||
/*
|
||||
if (waitResult == handles.Size() - 1)
|
||||
{
|
||||
// exit event
|
||||
// we want to delete temp files, if progs were used
|
||||
if (processes.ProgsWereUsed)
|
||||
break;
|
||||
}
|
||||
*/
|
||||
return waitResult >= (DWORD)handles.Size() ? 1 : 0;
|
||||
}
|
||||
|
||||
if (firstPass && indices.Size() == 1)
|
||||
{
|
||||
DWORD curTime = GetTickCount() - startTime;
|
||||
|
||||
/*
|
||||
if (curTime > 5 * 1000)
|
||||
progs.ProgNames.Clear();
|
||||
*/
|
||||
|
||||
needFindProcessByPath = (curTime < 2 * 1000);
|
||||
|
||||
if (needFindProcessByPath)
|
||||
{
|
||||
NFind::CFileInfo newFileInfo;
|
||||
if (newFileInfo.Find(tpi->FilePath))
|
||||
if (tpi->WasChanged(newFileInfo))
|
||||
needFindProcessByPath = false;
|
||||
}
|
||||
|
||||
DEBUG_PRINT_NUM(" -- firstPass -- time = ", curTime)
|
||||
}
|
||||
|
||||
processes.DisableWait(indices[waitResult]);
|
||||
}
|
||||
|
||||
firstPass = false;
|
||||
|
||||
// Sleep(300);
|
||||
#ifndef UNDER_CE
|
||||
processes.Update(needFindProcessByPath /* , progs */);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
DWORD curTime = GetTickCount() - startTime;
|
||||
|
||||
DEBUG_PRINT_NUM("after time = ", curTime)
|
||||
|
||||
processes.CloseAll();
|
||||
|
||||
isComplexMode = (curTime < 2 * 1000);
|
||||
|
||||
}
|
||||
|
||||
bool needCheckTimestamp = true;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
NFind::CFileInfo newFileInfo;
|
||||
|
||||
if (!newFileInfo.Find(tpi->FilePath))
|
||||
break;
|
||||
|
||||
handles.Add(g_ExitEventLauncher._exitEvent);
|
||||
|
||||
DWORD waitResult = ::WaitForMultipleObjects(handles.Size(), &handles.Front(), FALSE, INFINITE);
|
||||
|
||||
if (waitResult >= (DWORD)handles.Size() - 1)
|
||||
if (mainProcessWasSet)
|
||||
{
|
||||
processes.CloseAll();
|
||||
return waitResult >= (DWORD)handles.Size() ? 1 : 0;
|
||||
}
|
||||
processes.Update();
|
||||
processes.DisableWait(indices[waitResult]);
|
||||
}
|
||||
|
||||
NFind::CFileInfo newFileInfo;
|
||||
if (newFileInfo.Find(tpi->FilePath))
|
||||
{
|
||||
if (tpi->WasChanged(newFileInfo))
|
||||
{
|
||||
UString message = MyFormatNew(IDS_WANT_UPDATE_MODIFIED_FILE, tpi->RelPath);
|
||||
if (::MessageBoxW(g_HWND, message, L"7-Zip", MB_OKCANCEL | MB_ICONQUESTION) == IDOK)
|
||||
if (tpi->WasChanged(newFileInfo))
|
||||
{
|
||||
if (SendMessage(tpi->Window, kOpenItemChanged, 0, (LONG_PTR)tpi) != 1)
|
||||
UString m = MyFormatNew(IDS_CANNOT_UPDATE_FILE, fs2us(tpi->FilePath));
|
||||
if (tpi->ReadOnly)
|
||||
{
|
||||
::MessageBoxW(g_HWND, MyFormatNew(IDS_CANNOT_UPDATE_FILE,
|
||||
fs2us(tpi->FilePath)), L"7-Zip", MB_OK | MB_ICONSTOP);
|
||||
m.Add_LF();
|
||||
AddLangString(m, IDS_PROP_READ_ONLY);
|
||||
m.Add_LF();
|
||||
m += tpi->FullPathFolderPrefix;
|
||||
::MessageBoxW(g_HWND, m, L"7-Zip", MB_OK | MB_ICONSTOP);
|
||||
return 0;
|
||||
}
|
||||
{
|
||||
const UString message = MyFormatNew(IDS_WANT_UPDATE_MODIFIED_FILE, tpi->RelPath);
|
||||
if (::MessageBoxW(g_HWND, message, L"7-Zip", MB_OKCANCEL | MB_ICONQUESTION) == IDOK)
|
||||
{
|
||||
// DEBUG_PRINT_NUM("SendMessage", GetCurrentThreadId());
|
||||
if (SendMessage(tpi->Window, kOpenItemChanged, 0, (LONG_PTR)tpi) != 1)
|
||||
{
|
||||
::MessageBoxW(g_HWND, m, L"7-Zip", MB_OK | MB_ICONSTOP);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
needCheckTimestamp = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!isComplexMode)
|
||||
break;
|
||||
}
|
||||
|
||||
// DEBUG_PRINT("WaitForSingleObject");
|
||||
DWORD waitResult = ::WaitForSingleObject(g_ExitEventLauncher._exitEvent, INFINITE);
|
||||
// DEBUG_PRINT("---");
|
||||
|
||||
if (waitResult == WAIT_OBJECT_0)
|
||||
break;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
{
|
||||
NFind::CFileInfo newFileInfo;
|
||||
|
||||
bool finded = newFileInfo.Find(tpi->FilePath);
|
||||
|
||||
if (!needCheckTimestamp || !finded || !tpi->WasChanged(newFileInfo))
|
||||
{
|
||||
DEBUG_PRINT("Delete Temp file");
|
||||
tpi->DeleteDirAndFile();
|
||||
}
|
||||
}
|
||||
tpi->DeleteDirAndFile();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#if defined(_WIN32) && !defined(UNDER_CE)
|
||||
static const FChar *k_ZoneId_StreamName = FTEXT(":Zone.Identifier");
|
||||
#endif
|
||||
@@ -1284,6 +1710,7 @@ void CPanel::OpenItemInArchive(int index, bool tryInternal, bool tryExternal, bo
|
||||
tpi->NeedDelete = true;
|
||||
tpi->UsePassword = usePassword;
|
||||
tpi->Password = password;
|
||||
tpi->ReadOnly = IsThereReadOnlyFolder();
|
||||
|
||||
if (!tpi->FileInfo.Find(tempFilePath))
|
||||
return;
|
||||
@@ -1291,29 +1718,41 @@ void CPanel::OpenItemInArchive(int index, bool tryInternal, bool tryExternal, bo
|
||||
CTmpProcessInfoRelease tmpProcessInfoRelease(*tpi);
|
||||
|
||||
CProcess process;
|
||||
// HRESULT res;
|
||||
HRESULT res;
|
||||
if (editMode)
|
||||
/* res = */ StartEditApplication(fs2us(tempFilePath), useEditor, (HWND)*this, process);
|
||||
res = StartEditApplication(fs2us(tempFilePath), useEditor, (HWND)*this, process);
|
||||
else
|
||||
/* res = */ StartApplication(fs2us(tempDirNorm), fs2us(tempFilePath), (HWND)*this, process);
|
||||
res = StartApplication(fs2us(tempDirNorm), fs2us(tempFilePath), (HWND)*this, process);
|
||||
|
||||
if ((HANDLE)process == 0)
|
||||
return;
|
||||
if ((HANDLE)process == NULL)
|
||||
{
|
||||
// win7 / win10 work so for some extensions (pdf, html ..);
|
||||
DEBUG_PRINT("#### (HANDLE)process == 0");
|
||||
// return;
|
||||
if (res != SZ_OK)
|
||||
return;
|
||||
}
|
||||
|
||||
tpi->Window = (HWND)(*this);
|
||||
tpi->FullPathFolderPrefix = _currentFolderPrefix;
|
||||
tpi->FileIndex = index;
|
||||
tpi->RelPath = relPath;
|
||||
tpi->Processes.AddProcess(process.Detach());
|
||||
|
||||
if ((HANDLE)process != 0)
|
||||
tpi->Processes.SetMainProcess(process.Detach());
|
||||
|
||||
NWindows::CThread thread;
|
||||
if (thread.Create(MyThreadFunction, tpi) != S_OK)
|
||||
::CThread th;
|
||||
if (Thread_Create(&th, MyThreadFunction, tpi) != 0)
|
||||
throw 271824;
|
||||
g_ExitEventLauncher._threads.Add(th);
|
||||
g_ExitEventLauncher._numActiveThreads++;
|
||||
|
||||
tempDirectory.DisableDeleting();
|
||||
tmpProcessInfoPtr.release();
|
||||
tmpProcessInfoRelease._needDelete = false;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
static const UINT64 kTimeLimit = UINT64(10000000) * 3600 * 24;
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@ struct CVKeyPropIDPair
|
||||
PROPID PropID;
|
||||
};
|
||||
|
||||
static CVKeyPropIDPair g_VKeyPropIDPairs[] =
|
||||
static const CVKeyPropIDPair g_VKeyPropIDPairs[] =
|
||||
{
|
||||
{ VK_F3, kpidName },
|
||||
{ VK_F4, kpidExtension },
|
||||
|
||||
@@ -18,21 +18,24 @@ static const TCHAR *kCU_FMPath = REG_PATH_7Z TEXT(STRING_PATH_SEPARATOR) TEXT("F
|
||||
// static const TCHAR *kLM_Path = REG_PATH_7Z TEXT(STRING_PATH_SEPARATOR) TEXT("FM");
|
||||
|
||||
static const WCHAR *kLangValueName = L"Lang";
|
||||
|
||||
static const WCHAR *kViewer = L"Viewer";
|
||||
static const WCHAR *kEditor = L"Editor";
|
||||
static const WCHAR *kDiff = L"Diff";
|
||||
|
||||
static const TCHAR *kShowDots = TEXT("ShowDots");
|
||||
static const TCHAR *kShowRealFileIcons = TEXT("ShowRealFileIcons");
|
||||
static const TCHAR *kShowSystemMenu = TEXT("ShowSystemMenu");
|
||||
|
||||
static const TCHAR *kFullRow = TEXT("FullRow");
|
||||
static const TCHAR *kShowGrid = TEXT("ShowGrid");
|
||||
static const TCHAR *kAlternativeSelection = TEXT("AlternativeSelection");
|
||||
// static const TCHAR *kLockMemoryAdd = TEXT("LockMemoryAdd");
|
||||
static const TCHAR *kLargePagesEnable = TEXT("LargePages");
|
||||
static const TCHAR *kSingleClick = TEXT("SingleClick");
|
||||
static const TCHAR *kAlternativeSelection = TEXT("AlternativeSelection");
|
||||
// static const TCHAR *kUnderline = TEXT("Underline");
|
||||
|
||||
static const TCHAR *kShowSystemMenu = TEXT("ShowSystemMenu");
|
||||
|
||||
// static const TCHAR *kLockMemoryAdd = TEXT("LockMemoryAdd");
|
||||
static const TCHAR *kLargePages = TEXT("LargePages");
|
||||
|
||||
static const TCHAR *kFlatViewName = TEXT("FlatViewArc");
|
||||
// static const TCHAR *kShowDeletedFiles = TEXT("ShowDeleted");
|
||||
|
||||
@@ -86,16 +89,11 @@ static bool Read7ZipOption(const TCHAR *value, bool defaultValue)
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
static bool ReadOption(const TCHAR *value, bool defaultValue)
|
||||
static void ReadOption(CKey &key, const TCHAR *value, bool &dest)
|
||||
{
|
||||
CKey key;
|
||||
if (key.Open(HKEY_CURRENT_USER, kCU_FMPath, KEY_READ) == ERROR_SUCCESS)
|
||||
{
|
||||
bool enabled;
|
||||
if (key.QueryValue(value, enabled) == ERROR_SUCCESS)
|
||||
return enabled;
|
||||
}
|
||||
return defaultValue;
|
||||
bool enabled = false;
|
||||
if (key.QueryValue(value, enabled) == ERROR_SUCCESS)
|
||||
dest = enabled;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -119,37 +117,52 @@ static bool ReadLmOption(const TCHAR *value, bool defaultValue)
|
||||
}
|
||||
*/
|
||||
|
||||
void SaveShowDots(bool showDots) { SaveOption(kShowDots, showDots); }
|
||||
bool ReadShowDots() { return ReadOption(kShowDots, false); }
|
||||
void CFmSettings::Save() const
|
||||
{
|
||||
SaveOption(kShowDots, ShowDots);
|
||||
SaveOption(kShowRealFileIcons, ShowRealFileIcons);
|
||||
SaveOption(kFullRow, FullRow);
|
||||
SaveOption(kShowGrid, ShowGrid);
|
||||
SaveOption(kSingleClick, SingleClick);
|
||||
SaveOption(kAlternativeSelection, AlternativeSelection);
|
||||
// SaveOption(kUnderline, Underline);
|
||||
|
||||
void SaveShowRealFileIcons(bool show) { SaveOption(kShowRealFileIcons, show); }
|
||||
bool ReadShowRealFileIcons() { return ReadOption(kShowRealFileIcons, false); }
|
||||
SaveOption(kShowSystemMenu, ShowSystemMenu);
|
||||
}
|
||||
|
||||
void Save_ShowSystemMenu(bool show) { SaveOption(kShowSystemMenu, show); }
|
||||
bool Read_ShowSystemMenu(){ return ReadOption(kShowSystemMenu, false); }
|
||||
void CFmSettings::Load()
|
||||
{
|
||||
ShowDots = false;
|
||||
ShowRealFileIcons = false;
|
||||
FullRow = false;
|
||||
ShowGrid = false;
|
||||
SingleClick = false;
|
||||
AlternativeSelection = false;
|
||||
// Underline = false;
|
||||
|
||||
void SaveFullRow(bool enable) { SaveOption(kFullRow, enable); }
|
||||
bool ReadFullRow() { return ReadOption(kFullRow, false); }
|
||||
ShowSystemMenu = false;
|
||||
|
||||
void SaveShowGrid(bool enable) { SaveOption(kShowGrid, enable); }
|
||||
bool ReadShowGrid(){ return ReadOption(kShowGrid, false); }
|
||||
CKey key;
|
||||
if (key.Open(HKEY_CURRENT_USER, kCU_FMPath, KEY_READ) == ERROR_SUCCESS)
|
||||
{
|
||||
ReadOption(key, kShowDots, ShowDots);
|
||||
ReadOption(key, kShowRealFileIcons, ShowRealFileIcons);
|
||||
ReadOption(key, kFullRow, FullRow);
|
||||
ReadOption(key, kShowGrid, ShowGrid);
|
||||
ReadOption(key, kSingleClick, SingleClick);
|
||||
ReadOption(key, kAlternativeSelection, AlternativeSelection);
|
||||
// ReadOption(key, kUnderline, Underline);
|
||||
|
||||
void SaveAlternativeSelection(bool enable) { SaveOption(kAlternativeSelection, enable); }
|
||||
bool ReadAlternativeSelection(){ return ReadOption(kAlternativeSelection, false); }
|
||||
ReadOption(key, kShowSystemMenu, ShowSystemMenu );
|
||||
}
|
||||
}
|
||||
|
||||
void SaveSingleClick(bool enable) { SaveOption(kSingleClick, enable); }
|
||||
bool ReadSingleClick(){ return ReadOption(kSingleClick, false); }
|
||||
|
||||
/*
|
||||
void SaveUnderline(bool enable) { SaveOption(kUnderline, enable); }
|
||||
bool ReadUnderline(){ return ReadOption(kUnderline, false); }
|
||||
*/
|
||||
|
||||
// void SaveLockMemoryAdd(bool enable) { SaveLmOption(kLockMemoryAdd, enable); }
|
||||
// bool ReadLockMemoryAdd() { return ReadLmOption(kLockMemoryAdd, true); }
|
||||
|
||||
void SaveLockMemoryEnable(bool enable) { Save7ZipOption(kLargePagesEnable, enable); }
|
||||
bool ReadLockMemoryEnable() { return Read7ZipOption(kLargePagesEnable, false); }
|
||||
void SaveLockMemoryEnable(bool enable) { Save7ZipOption(kLargePages, enable); }
|
||||
bool ReadLockMemoryEnable() { return Read7ZipOption(kLargePages, false); }
|
||||
|
||||
static CSysString GetFlatViewName(UInt32 panelIndex)
|
||||
{
|
||||
@@ -159,7 +172,15 @@ static CSysString GetFlatViewName(UInt32 panelIndex)
|
||||
}
|
||||
|
||||
void SaveFlatView(UInt32 panelIndex, bool enable) { SaveOption(GetFlatViewName(panelIndex), enable); }
|
||||
bool ReadFlatView(UInt32 panelIndex) { return ReadOption(GetFlatViewName(panelIndex), false); }
|
||||
|
||||
bool ReadFlatView(UInt32 panelIndex)
|
||||
{
|
||||
bool enabled = false;
|
||||
CKey key;
|
||||
if (key.Open(HKEY_CURRENT_USER, kCU_FMPath, KEY_READ) == ERROR_SUCCESS)
|
||||
ReadOption(key, GetFlatViewName(panelIndex), enabled);
|
||||
return enabled;
|
||||
}
|
||||
|
||||
/*
|
||||
void Save_ShowDeleted(bool enable) { SaveOption(kShowDeletedFiles, enable); }
|
||||
|
||||
@@ -15,23 +15,21 @@ void ReadRegEditor(bool useEditor, UString &path);
|
||||
void SaveRegDiff(const UString &path);
|
||||
void ReadRegDiff(UString &path);
|
||||
|
||||
void SaveShowDots(bool showDots);
|
||||
bool ReadShowDots();
|
||||
struct CFmSettings
|
||||
{
|
||||
bool ShowDots;
|
||||
bool ShowRealFileIcons;
|
||||
bool FullRow;
|
||||
bool ShowGrid;
|
||||
bool SingleClick;
|
||||
bool AlternativeSelection;
|
||||
// bool Underline;
|
||||
|
||||
void SaveShowRealFileIcons(bool show);
|
||||
bool ReadShowRealFileIcons();
|
||||
bool ShowSystemMenu;
|
||||
|
||||
void Save_ShowSystemMenu(bool showSystemMenu);
|
||||
bool Read_ShowSystemMenu();
|
||||
|
||||
void SaveFullRow(bool enable);
|
||||
bool ReadFullRow();
|
||||
|
||||
void SaveShowGrid(bool enable);
|
||||
bool ReadShowGrid();
|
||||
|
||||
void SaveAlternativeSelection(bool enable);
|
||||
bool ReadAlternativeSelection();
|
||||
void Save() const;
|
||||
void Load();
|
||||
};
|
||||
|
||||
// void SaveLockMemoryAdd(bool enable);
|
||||
// bool ReadLockMemoryAdd();
|
||||
@@ -39,14 +37,6 @@ bool ReadAlternativeSelection();
|
||||
bool ReadLockMemoryEnable();
|
||||
void SaveLockMemoryEnable(bool enable);
|
||||
|
||||
void SaveSingleClick(bool enable);
|
||||
bool ReadSingleClick();
|
||||
|
||||
/*
|
||||
void SaveUnderline(bool enable);
|
||||
bool ReadUnderline();
|
||||
*/
|
||||
|
||||
void SaveFlatView(UInt32 panelIndex, bool enable);
|
||||
bool ReadFlatView(UInt32 panelIndex);
|
||||
|
||||
|
||||
@@ -35,21 +35,29 @@ extern bool IsLargePageSupported();
|
||||
|
||||
bool CSettingsPage::OnInit()
|
||||
{
|
||||
_wasChanged = false;
|
||||
_largePages_wasChanged = false;
|
||||
|
||||
LangSetDlgItems(*this, kLangIDs, ARRAY_SIZE(kLangIDs));
|
||||
|
||||
CheckButton(IDX_SETTINGS_SHOW_DOTS, ReadShowDots());
|
||||
CheckButton(IDX_SETTINGS_SHOW_SYSTEM_MENU, Read_ShowSystemMenu());
|
||||
CheckButton(IDX_SETTINGS_SHOW_REAL_FILE_ICONS, ReadShowRealFileIcons());
|
||||
CheckButton(IDX_SETTINGS_FULL_ROW, ReadFullRow());
|
||||
CheckButton(IDX_SETTINGS_SHOW_GRID, ReadShowGrid());
|
||||
CheckButton(IDX_SETTINGS_ALTERNATIVE_SELECTION, ReadAlternativeSelection());
|
||||
CFmSettings st;
|
||||
st.Load();
|
||||
|
||||
CheckButton(IDX_SETTINGS_SHOW_DOTS, st.ShowDots);
|
||||
CheckButton(IDX_SETTINGS_SHOW_REAL_FILE_ICONS, st.ShowRealFileIcons);
|
||||
CheckButton(IDX_SETTINGS_FULL_ROW, st.FullRow);
|
||||
CheckButton(IDX_SETTINGS_SHOW_GRID, st.ShowGrid);
|
||||
CheckButton(IDX_SETTINGS_SINGLE_CLICK, st.SingleClick);
|
||||
CheckButton(IDX_SETTINGS_ALTERNATIVE_SELECTION, st.AlternativeSelection);
|
||||
// CheckButton(IDX_SETTINGS_UNDERLINE, st.Underline);
|
||||
|
||||
CheckButton(IDX_SETTINGS_SHOW_SYSTEM_MENU, st.ShowSystemMenu);
|
||||
|
||||
if (IsLargePageSupported())
|
||||
CheckButton(IDX_SETTINGS_LARGE_PAGES, ReadLockMemoryEnable());
|
||||
else
|
||||
EnableItem(IDX_SETTINGS_LARGE_PAGES, false);
|
||||
CheckButton(IDX_SETTINGS_SINGLE_CLICK, ReadSingleClick());
|
||||
// CheckButton(IDX_SETTINGS_UNDERLINE, ReadUnderline());
|
||||
|
||||
|
||||
// EnableSubItems();
|
||||
|
||||
return CPropertyPage::OnInit();
|
||||
@@ -64,25 +72,37 @@ void CSettingsPage::EnableSubItems()
|
||||
|
||||
LONG CSettingsPage::OnApply()
|
||||
{
|
||||
SaveShowDots(IsButtonCheckedBool(IDX_SETTINGS_SHOW_DOTS));
|
||||
Save_ShowSystemMenu(IsButtonCheckedBool(IDX_SETTINGS_SHOW_SYSTEM_MENU));
|
||||
SaveShowRealFileIcons(IsButtonCheckedBool(IDX_SETTINGS_SHOW_REAL_FILE_ICONS));
|
||||
|
||||
SaveFullRow(IsButtonCheckedBool(IDX_SETTINGS_FULL_ROW));
|
||||
SaveShowGrid(IsButtonCheckedBool(IDX_SETTINGS_SHOW_GRID));
|
||||
SaveAlternativeSelection(IsButtonCheckedBool(IDX_SETTINGS_ALTERNATIVE_SELECTION));
|
||||
#ifndef UNDER_CE
|
||||
if (IsLargePageSupported())
|
||||
if (_wasChanged)
|
||||
{
|
||||
bool enable = IsButtonCheckedBool(IDX_SETTINGS_LARGE_PAGES);
|
||||
NSecurity::EnablePrivilege_LockMemory(enable);
|
||||
SaveLockMemoryEnable(enable);
|
||||
CFmSettings st;
|
||||
st.ShowDots = IsButtonCheckedBool(IDX_SETTINGS_SHOW_DOTS);
|
||||
st.ShowRealFileIcons = IsButtonCheckedBool(IDX_SETTINGS_SHOW_REAL_FILE_ICONS);
|
||||
st.FullRow = IsButtonCheckedBool(IDX_SETTINGS_FULL_ROW);
|
||||
st.ShowGrid = IsButtonCheckedBool(IDX_SETTINGS_SHOW_GRID);
|
||||
st.SingleClick = IsButtonCheckedBool(IDX_SETTINGS_SINGLE_CLICK);
|
||||
st.AlternativeSelection = IsButtonCheckedBool(IDX_SETTINGS_ALTERNATIVE_SELECTION);
|
||||
// st.Underline = IsButtonCheckedBool(IDX_SETTINGS_UNDERLINE);
|
||||
|
||||
st.ShowSystemMenu = IsButtonCheckedBool(IDX_SETTINGS_SHOW_SYSTEM_MENU);
|
||||
|
||||
st.Save();
|
||||
|
||||
_wasChanged = false;
|
||||
}
|
||||
|
||||
#ifndef UNDER_CE
|
||||
if (_largePages_wasChanged)
|
||||
{
|
||||
if (IsLargePageSupported())
|
||||
{
|
||||
bool enable = IsButtonCheckedBool(IDX_SETTINGS_LARGE_PAGES);
|
||||
NSecurity::EnablePrivilege_LockMemory(enable);
|
||||
SaveLockMemoryEnable(enable);
|
||||
}
|
||||
_largePages_wasChanged = false;
|
||||
}
|
||||
#endif
|
||||
|
||||
SaveSingleClick(IsButtonCheckedBool(IDX_SETTINGS_SINGLE_CLICK));
|
||||
// SaveUnderline(IsButtonCheckedBool(IDX_SETTINGS_UNDERLINE));
|
||||
|
||||
return PSNRET_NOERROR;
|
||||
}
|
||||
|
||||
@@ -106,9 +126,17 @@ bool CSettingsPage::OnButtonClicked(int buttonID, HWND buttonHWND)
|
||||
case IDX_SETTINGS_FULL_ROW:
|
||||
case IDX_SETTINGS_SHOW_GRID:
|
||||
case IDX_SETTINGS_ALTERNATIVE_SELECTION:
|
||||
_wasChanged = true;
|
||||
break;
|
||||
|
||||
case IDX_SETTINGS_LARGE_PAGES:
|
||||
Changed();
|
||||
return true;
|
||||
_largePages_wasChanged = true;
|
||||
break;
|
||||
|
||||
default:
|
||||
return CPropertyPage::OnButtonClicked(buttonID, buttonHWND);
|
||||
}
|
||||
return CPropertyPage::OnButtonClicked(buttonID, buttonHWND);
|
||||
|
||||
Changed();
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -8,6 +8,10 @@
|
||||
|
||||
class CSettingsPage: public NWindows::NControl::CPropertyPage
|
||||
{
|
||||
bool _wasChanged;
|
||||
|
||||
bool _largePages_wasChanged;
|
||||
|
||||
// void EnableSubItems();
|
||||
bool OnButtonClicked(int buttonID, HWND buttonHWND);
|
||||
public:
|
||||
|
||||
@@ -2,10 +2,12 @@ CAPTION "Settings"
|
||||
BEGIN
|
||||
CONTROL "Show "".."" item", IDX_SETTINGS_SHOW_DOTS, MY_CHECKBOX, m, 8, xc, 10
|
||||
CONTROL "Show real file &icons", IDX_SETTINGS_SHOW_REAL_FILE_ICONS, MY_CHECKBOX, m, 22, xc, 10
|
||||
CONTROL "Show system &menu", IDX_SETTINGS_SHOW_SYSTEM_MENU, MY_CHECKBOX, m, 36, xc, 10
|
||||
CONTROL "&Full row select", IDX_SETTINGS_FULL_ROW, MY_CHECKBOX, m, 50, xc, 10
|
||||
CONTROL "Show &grid lines", IDX_SETTINGS_SHOW_GRID, MY_CHECKBOX, m, 64, xc, 10
|
||||
CONTROL "&Single-click to open an item", IDX_SETTINGS_SINGLE_CLICK, MY_CHECKBOX, m, 78, xc, 10
|
||||
CONTROL "&Alternative selection mode", IDX_SETTINGS_ALTERNATIVE_SELECTION, MY_CHECKBOX, m, 92, xc, 10
|
||||
CONTROL "Use &large memory pages", IDX_SETTINGS_LARGE_PAGES, MY_CHECKBOX, m, 106, xc, 10
|
||||
CONTROL "&Full row select", IDX_SETTINGS_FULL_ROW, MY_CHECKBOX, m, 36, xc, 10
|
||||
CONTROL "Show &grid lines", IDX_SETTINGS_SHOW_GRID, MY_CHECKBOX, m, 50, xc, 10
|
||||
CONTROL "&Single-click to open an item", IDX_SETTINGS_SINGLE_CLICK, MY_CHECKBOX, m, 64, xc, 10
|
||||
CONTROL "&Alternative selection mode", IDX_SETTINGS_ALTERNATIVE_SELECTION, MY_CHECKBOX, m, 78, xc, 10
|
||||
|
||||
CONTROL "Show system &menu", IDX_SETTINGS_SHOW_SYSTEM_MENU, MY_CHECKBOX, m, 100, xc, 10
|
||||
|
||||
CONTROL "Use &large memory pages", IDX_SETTINGS_LARGE_PAGES, MY_CHECKBOX, m, 122, xc, 10
|
||||
END
|
||||
|
||||
@@ -6,8 +6,8 @@
|
||||
|
||||
#include <ShlObj.h>
|
||||
|
||||
#include "../../../Common/StringConvert.h"
|
||||
#include "../../../Common/Defs.h"
|
||||
#include "../../../Common/StringConvert.h"
|
||||
|
||||
#include "../../../Windows/DLL.h"
|
||||
#include "../../../Windows/ErrorMsg.h"
|
||||
@@ -43,13 +43,16 @@ CSysString CModifiedExtInfo::GetString() const
|
||||
return ProgramKey;
|
||||
};
|
||||
|
||||
|
||||
int CSystemPage::AddIcon(const UString &iconPath, int iconIndex)
|
||||
{
|
||||
if (iconPath.IsEmpty())
|
||||
return -1;
|
||||
if (iconIndex == -1)
|
||||
iconIndex = 0;
|
||||
|
||||
HICON hicon;
|
||||
|
||||
#ifdef UNDER_CE
|
||||
ExtractIconExW(iconPath, iconIndex, NULL, &hicon, 1);
|
||||
if (!hicon)
|
||||
@@ -65,12 +68,14 @@ int CSystemPage::AddIcon(const UString &iconPath, int iconIndex)
|
||||
if (num != 1 || !hicon)
|
||||
#endif
|
||||
return -1;
|
||||
|
||||
_imageList.AddIcon(hicon);
|
||||
DestroyIcon(hicon);
|
||||
return _numIcons++;
|
||||
}
|
||||
|
||||
void CSystemPage::RefreshListItem(int group, int listIndex)
|
||||
|
||||
void CSystemPage::RefreshListItem(unsigned group, unsigned listIndex)
|
||||
{
|
||||
const CAssoc &assoc = _items[GetRealIndex(listIndex)];
|
||||
_listView.SetSubItem(listIndex, group + 1, assoc.Pair[group].GetString());
|
||||
@@ -82,13 +87,14 @@ void CSystemPage::RefreshListItem(int group, int listIndex)
|
||||
_listView.SetItem(&newItem);
|
||||
}
|
||||
|
||||
void CSystemPage::ChangeState(int group, const CIntVector &indices)
|
||||
|
||||
void CSystemPage::ChangeState(unsigned group, const CUIntVector &indices)
|
||||
{
|
||||
if (indices.IsEmpty())
|
||||
return;
|
||||
|
||||
bool thereAreClearItems = false;
|
||||
int counters[3] = { 0, 0, 0 };
|
||||
unsigned counters[3] = { 0, 0, 0 };
|
||||
|
||||
unsigned i;
|
||||
for (i = 0; i < indices.Size(); i++)
|
||||
@@ -114,27 +120,34 @@ void CSystemPage::ChangeState(int group, const CIntVector &indices)
|
||||
|
||||
for (i = 0; i < indices.Size(); i++)
|
||||
{
|
||||
int listIndex = indices[i];
|
||||
unsigned listIndex = indices[i];
|
||||
CAssoc &assoc = _items[GetRealIndex(listIndex)];
|
||||
CModifiedExtInfo &mi = assoc.Pair[group];
|
||||
bool change = false;
|
||||
|
||||
switch (state)
|
||||
{
|
||||
case kExtState_Clear: change = true; break;
|
||||
case kExtState_Other: change = mi.Other; break;
|
||||
default: change = !(mi.Other && thereAreClearItems); break;
|
||||
}
|
||||
|
||||
if (change)
|
||||
{
|
||||
mi.State = state;
|
||||
RefreshListItem(group, listIndex);
|
||||
}
|
||||
}
|
||||
|
||||
_needSave = true;
|
||||
Changed();
|
||||
}
|
||||
|
||||
|
||||
bool CSystemPage::OnInit()
|
||||
{
|
||||
_needSave = false;
|
||||
|
||||
LangSetDlgItems(*this, kLangIDs, ARRAY_SIZE(kLangIDs));
|
||||
|
||||
_listView.Attach(GetItem(IDL_SYSTEM_ASSOCIATE));
|
||||
@@ -159,6 +172,7 @@ bool CSystemPage::OnInit()
|
||||
BOOL res;
|
||||
|
||||
DWORD size = kSize;
|
||||
|
||||
#ifndef _UNICODE
|
||||
if (!g_IsNT)
|
||||
{
|
||||
@@ -218,7 +232,7 @@ bool CSystemPage::OnInit()
|
||||
assoc.SevenZipImageIndex = AddIcon(plug.IconPath, plug.IconIndex);
|
||||
|
||||
CSysString texts[NUM_EXT_GROUPS];
|
||||
int g;
|
||||
unsigned g;
|
||||
for (g = 0; g < NUM_EXT_GROUPS; g++)
|
||||
{
|
||||
CModifiedExtInfo &mi = assoc.Pair[g];
|
||||
@@ -240,62 +254,83 @@ bool CSystemPage::OnInit()
|
||||
return CPropertyPage::OnInit();
|
||||
}
|
||||
|
||||
|
||||
static UString GetProgramCommand()
|
||||
{
|
||||
return L"\"" + fs2us(NDLL::GetModuleDirPrefix()) + L"7zFM.exe\" \"%1\"";
|
||||
UString s = L"\"";
|
||||
s += fs2us(NDLL::GetModuleDirPrefix());
|
||||
s.AddAscii("7zFM.exe\" \"%1\"");
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
LONG CSystemPage::OnApply()
|
||||
{
|
||||
if (!_needSave)
|
||||
return PSNRET_NOERROR;
|
||||
|
||||
const UString command = GetProgramCommand();
|
||||
|
||||
LONG res = 0;
|
||||
|
||||
FOR_VECTOR (listIndex, _extDB.Exts)
|
||||
{
|
||||
int realIndex = GetRealIndex(listIndex);
|
||||
unsigned realIndex = GetRealIndex(listIndex);
|
||||
const CExtPlugins &extInfo = _extDB.Exts[realIndex];
|
||||
CAssoc &assoc = _items[realIndex];
|
||||
|
||||
for (int g = 0; g < NUM_EXT_GROUPS; g++)
|
||||
for (unsigned g = 0; g < NUM_EXT_GROUPS; g++)
|
||||
{
|
||||
CModifiedExtInfo &mi = assoc.Pair[g];
|
||||
HKEY key = GetHKey(g);
|
||||
|
||||
if (mi.OldState != mi.State)
|
||||
{
|
||||
LONG res2 = 0;
|
||||
|
||||
if (mi.State == kExtState_7Zip)
|
||||
{
|
||||
UString title = extInfo.Ext + UString(L" Archive");
|
||||
UString title = extInfo.Ext;
|
||||
title.AddAscii(" Archive");
|
||||
const CPluginToIcon &plug = extInfo.Plugins[0];
|
||||
res2 = NRegistryAssoc::AddShellExtensionInfo(key, GetSystemString(extInfo.Ext),
|
||||
title, command, plug.IconPath, plug.IconIndex);
|
||||
}
|
||||
else if (mi.State == kExtState_Clear)
|
||||
res2 = NRegistryAssoc::DeleteShellExtensionInfo(key, GetSystemString(extInfo.Ext));
|
||||
|
||||
if (res == 0)
|
||||
res = res2;
|
||||
if (res2 == 0)
|
||||
mi.OldState = mi.State;
|
||||
|
||||
mi.State = mi.OldState;
|
||||
RefreshListItem(g, listIndex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef UNDER_CE
|
||||
SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST, NULL, NULL);
|
||||
WasChanged = true;
|
||||
#endif
|
||||
|
||||
WasChanged = true;
|
||||
|
||||
_needSave = false;
|
||||
|
||||
if (res != 0)
|
||||
MessageBoxW(*this, NError::MyFormatMessage(res), L"7-Zip", MB_ICONERROR);
|
||||
|
||||
return PSNRET_NOERROR;
|
||||
}
|
||||
|
||||
|
||||
void CSystemPage::OnNotifyHelp()
|
||||
{
|
||||
ShowHelpWindow(NULL, kSystemTopic);
|
||||
}
|
||||
|
||||
|
||||
bool CSystemPage::OnButtonClicked(int buttonID, HWND buttonHWND)
|
||||
{
|
||||
switch (buttonID)
|
||||
@@ -313,6 +348,7 @@ bool CSystemPage::OnButtonClicked(int buttonID, HWND buttonHWND)
|
||||
return CPropertyPage::OnButtonClicked(buttonID, buttonHWND);
|
||||
}
|
||||
|
||||
|
||||
bool CSystemPage::OnNotify(UINT controlID, LPNMHDR lParam)
|
||||
{
|
||||
if (lParam->hwndFrom == HWND(_listView))
|
||||
@@ -324,7 +360,7 @@ bool CSystemPage::OnNotify(UINT controlID, LPNMHDR lParam)
|
||||
ChangeState(0);
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
|
||||
case NM_CLICK:
|
||||
{
|
||||
#ifdef UNDER_CE
|
||||
@@ -334,12 +370,12 @@ bool CSystemPage::OnNotify(UINT controlID, LPNMHDR lParam)
|
||||
if (item->uKeyFlags == 0)
|
||||
#endif
|
||||
{
|
||||
int realIndex = GetRealIndex(item->iItem);
|
||||
if (realIndex >= 0)
|
||||
if (item->iItem >= 0)
|
||||
{
|
||||
// unsigned realIndex = GetRealIndex(item->iItem);
|
||||
if (item->iSubItem >= 1 && item->iSubItem <= 2)
|
||||
{
|
||||
CIntVector indices;
|
||||
CUIntVector indices;
|
||||
indices.Add(item->iItem);
|
||||
ChangeState(item->iSubItem < 2 ? 0 : 1, indices);
|
||||
}
|
||||
@@ -347,12 +383,14 @@ bool CSystemPage::OnNotify(UINT controlID, LPNMHDR lParam)
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case LVN_KEYDOWN:
|
||||
{
|
||||
if (OnListKeyDown(LPNMLVKEYDOWN(lParam)))
|
||||
return true;
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
case NM_RCLICK:
|
||||
case NM_DBLCLK:
|
||||
@@ -366,18 +404,23 @@ bool CSystemPage::OnNotify(UINT controlID, LPNMHDR lParam)
|
||||
return CPropertyPage::OnNotify(controlID, lParam);
|
||||
}
|
||||
|
||||
void CSystemPage::ChangeState(int group)
|
||||
|
||||
void CSystemPage::ChangeState(unsigned group)
|
||||
{
|
||||
CIntVector indices;
|
||||
CUIntVector indices;
|
||||
|
||||
int itemIndex = -1;
|
||||
while ((itemIndex = _listView.GetNextSelectedItem(itemIndex)) != -1)
|
||||
indices.Add(itemIndex);
|
||||
|
||||
if (indices.IsEmpty())
|
||||
FOR_VECTOR (i, _items)
|
||||
indices.Add(i);
|
||||
|
||||
ChangeState(group, indices);
|
||||
}
|
||||
|
||||
|
||||
bool CSystemPage::OnListKeyDown(LPNMLVKEYDOWN keyDownInfo)
|
||||
{
|
||||
bool ctrl = IsKeyDown(VK_CONTROL);
|
||||
@@ -386,8 +429,8 @@ bool CSystemPage::OnListKeyDown(LPNMLVKEYDOWN keyDownInfo)
|
||||
if (alt)
|
||||
return false;
|
||||
|
||||
if ((ctrl && keyDownInfo->wVKey == 'A') ||
|
||||
(!ctrl && keyDownInfo->wVKey == VK_MULTIPLY))
|
||||
if ((ctrl && keyDownInfo->wVKey == 'A')
|
||||
|| (!ctrl && keyDownInfo->wVKey == VK_MULTIPLY))
|
||||
{
|
||||
_listView.SelectAll();
|
||||
return true;
|
||||
@@ -400,15 +443,19 @@ bool CSystemPage::OnListKeyDown(LPNMLVKEYDOWN keyDownInfo)
|
||||
case VK_SUBTRACT:
|
||||
case VK_SEPARATOR:
|
||||
case VK_DIVIDE:
|
||||
|
||||
#ifndef UNDER_CE
|
||||
case VK_OEM_PLUS:
|
||||
case VK_OEM_MINUS:
|
||||
#endif
|
||||
|
||||
if (!ctrl)
|
||||
{
|
||||
ChangeState(keyDownInfo->wVKey == VK_SPACE ? 0 : 1);
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -59,7 +59,7 @@ struct CAssoc
|
||||
|
||||
int GetIconIndex() const
|
||||
{
|
||||
for (int i = 0; i < 2; i++)
|
||||
for (unsigned i = 0; i < 2; i++)
|
||||
{
|
||||
const CModifiedExtInfo &pair = Pair[i];
|
||||
if (pair.State == kExtState_Clear)
|
||||
@@ -84,11 +84,13 @@ class CSystemPage: public NWindows::NControl::CPropertyPage
|
||||
CExtDatabase _extDB;
|
||||
CObjectVector<CAssoc> _items;
|
||||
|
||||
int _numIcons;
|
||||
unsigned _numIcons;
|
||||
NWindows::NControl::CImageList _imageList;
|
||||
NWindows::NControl::CListView _listView;
|
||||
|
||||
const HKEY GetHKey(int
|
||||
bool _needSave;
|
||||
|
||||
const HKEY GetHKey(unsigned
|
||||
#if NUM_EXT_GROUPS != 1
|
||||
group
|
||||
#endif
|
||||
@@ -102,15 +104,16 @@ class CSystemPage: public NWindows::NControl::CPropertyPage
|
||||
}
|
||||
|
||||
int AddIcon(const UString &path, int iconIndex);
|
||||
int GetRealIndex(int listIndex) const { return listIndex; }
|
||||
void RefreshListItem(int group, int listIndex);
|
||||
void ChangeState(int group, const CIntVector &indices);
|
||||
void ChangeState(int group);
|
||||
unsigned GetRealIndex(unsigned listIndex) const { return listIndex; }
|
||||
void RefreshListItem(unsigned group, unsigned listIndex);
|
||||
void ChangeState(unsigned group, const CUIntVector &indices);
|
||||
void ChangeState(unsigned group);
|
||||
|
||||
bool OnListKeyDown(LPNMLVKEYDOWN keyDownInfo);
|
||||
|
||||
public:
|
||||
bool WasChanged;
|
||||
|
||||
CSystemPage(): WasChanged(false) {}
|
||||
|
||||
virtual bool OnInit();
|
||||
|
||||
@@ -303,7 +303,7 @@ public:
|
||||
void SetFrom_CalcLen(const char *s, unsigned len);
|
||||
// void SetFromAscii(const char *s) { operator+=(s); }
|
||||
|
||||
// AString Mid(unsigned startIndex, unsigned count) const { return AString(count, _chars + startIndex); }
|
||||
AString Mid(unsigned startIndex, unsigned count) const { return AString(count, _chars + startIndex); }
|
||||
AString Left(unsigned count) const { return AString(count, *this); }
|
||||
|
||||
// void MakeUpper() { MyStringUpper(_chars); }
|
||||
|
||||
@@ -4,23 +4,22 @@
|
||||
#define __WINDOWS_CONTROL_TRACKBAR_H
|
||||
|
||||
#include "../Window.h"
|
||||
#include "../Defs.h"
|
||||
|
||||
namespace NWindows {
|
||||
namespace NControl {
|
||||
|
||||
class CTrackbar1: public CWindow
|
||||
class CTrackbar: public CWindow
|
||||
{
|
||||
public:
|
||||
void SetRange(int minimum, int maximum, bool redraw = true)
|
||||
{ SendMessage(TBM_SETRANGE, BoolToBOOL(redraw), MAKELONG(minimum, maximum)); }
|
||||
{ SendMsg(TBM_SETRANGE, BoolToBOOL(redraw), MAKELONG(minimum, maximum)); }
|
||||
void SetPos(int pos, bool redraw = true)
|
||||
{ SendMessage(TBM_SETPOS, BoolToBOOL(redraw), pos); }
|
||||
{ SendMsg(TBM_SETPOS, BoolToBOOL(redraw), pos); }
|
||||
void SetTicFreq(int freq)
|
||||
{ SendMessage(TBM_SETTICFREQ, freq); }
|
||||
{ SendMsg(TBM_SETTICFREQ, freq); }
|
||||
|
||||
int GetPos()
|
||||
{ return (int)SendMessage(TBM_GETPOS); }
|
||||
{ return (int)SendMsg(TBM_GETPOS); }
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
Reference in New Issue
Block a user