Compress-Deflate7
view release on metacpan or search on metacpan
7zip/CPP/7zip/UI/Explorer/ContextMenu.cpp view on Meta::CPAN
" def dep dlg dsp dsw"
" eps"
" f f77 f90 f95 fla flac frm"
" gif"
" h hpp hta htm html hxx"
" ico idl inc ini inl"
" java jpeg jpg js"
" la"
" mak manifest wmv mov mp3 mp4 mpe mpeg mpg m4a"
" ofr ogg"
" pac pas pdf php php3 php4 php5 phptml pl pm png ps py pyo"
" ra rb rc reg rka rm rtf"
" sed sh shn shtml sln sql srt swa"
" tcl tex tiff tta txt"
" vb vcproj vbs"
" wav wma wv"
" xml xsd xsl xslt"
" ";
static const char *kNoOpenAsExtensions =
" 7z arj bz2 cab chm cpio dmg flv gz lha lzh lzma rar swm tar tbz2 tgz wim xar xz z zip ";
static bool FindExt(const char *p, const UString &name)
{
int extPos = name.ReverseFind('.');
if (extPos < 0)
return false;
UString ext = name.Mid(extPos + 1);
ext.MakeLower();
AString ext2 = UnicodeStringToMultiByte(ext);
for (int i = 0; p[i] != 0;)
{
int j;
for (j = i; p[j] != ' '; j++);
if (ext2.Length() == j - i && memcmp(p + i, (const char *)ext2, ext2.Length()) == 0)
return true;
i = j + 1;
}
return false;
}
static bool DoNeedExtract(const UString &name)
{
return !FindExt(kExtractExludeExtensions, name);
}
STDMETHODIMP CZipContextMenu::QueryContextMenu(HMENU hMenu, UINT indexMenu,
UINT commandIDFirst, UINT commandIDLast, UINT flags)
{
LoadLangOneTime();
if (_fileNames.Size() == 0)
return E_FAIL;
UINT currentCommandID = commandIDFirst;
if ((flags & 0x000F) != CMF_NORMAL &&
(flags & CMF_VERBSONLY) == 0 &&
(flags & CMF_EXPLORE) == 0)
return MAKE_HRESULT(SEVERITY_SUCCESS, 0, currentCommandID);
_commandMap.Clear();
CMenu popupMenu;
CMenuDestroyer menuDestroyer;
CContextMenuInfo ci;
ci.Load();
MENUITEMINFO menuItem;
UINT subIndex = indexMenu;
if (ci.Cascaded)
{
CCommandMapItem commandMapItem;
if (!popupMenu.CreatePopup())
return E_FAIL;
menuDestroyer.Attach(popupMenu);
commandMapItem.CommandInternalID = kCommandNULL;
commandMapItem.Verb = kMainVerb;
commandMapItem.HelpString = LangString(IDS_CONTEXT_CAPTION_HELP, 0x02000102);
_commandMap.Add(commandMapItem);
menuItem.wID = currentCommandID++;
subIndex = 0;
}
else
{
popupMenu.Attach(hMenu);
}
UInt32 contextMenuFlags = ci.Flags;
UString mainString;
if (_fileNames.Size() == 1 && currentCommandID + 6 <= commandIDLast)
{
const UString &fileName = _fileNames.Front();
UString folderPrefix;
NFile::NDirectory::GetOnlyDirPrefix(fileName, folderPrefix);
NFile::NFind::CFileInfoW fileInfo;
if (!fileInfo.Find(fileName))
return E_FAIL;
if (!fileInfo.IsDir() && DoNeedExtract(fileInfo.Name))
{
// Open
bool thereIsMainOpenItem = ((contextMenuFlags & NContextMenuFlags::kOpen) != 0);
if (thereIsMainOpenItem)
{
CCommandMapItem commandMapItem;
FillCommand(kOpen, mainString, commandMapItem);
MyInsertMenu(popupMenu, subIndex++, currentCommandID++, mainString);
_commandMap.Add(commandMapItem);
}
if ((contextMenuFlags & NContextMenuFlags::kOpenAs) != 0 &&
(!thereIsMainOpenItem || !FindExt(kNoOpenAsExtensions, fileInfo.Name)))
{
CMenu subMenu;
if (subMenu.CreatePopup())
{
CCommandMapItem commandMapItem;
CMenuItem menuItem;
menuItem.fType = MFT_STRING;
menuItem.fMask = MIIM_SUBMENU | MIIM_TYPE | MIIM_ID;
menuItem.wID = currentCommandID++;
menuItem.hSubMenu = subMenu;
menuItem.StringValue = LangString(IDS_CONTEXT_OPEN, 0x02000103);
popupMenu.InsertItem(subIndex++, true, menuItem);
commandMapItem.CommandInternalID = kCommandNULL;
commandMapItem.Verb = kMainVerb;
commandMapItem.HelpString = LangString(IDS_CONTEXT_OPEN_HELP, 0x02000104);
_commandMap.Add(commandMapItem);
UINT subIndex2 = 0;
const wchar_t *exts[] = { L"", L"*", L"7z", L"zip", L"cab", L"rar" };
for (int i = (thereIsMainOpenItem ? 1 : 0); i < sizeof(exts) / sizeof(exts[0]); i++)
{
CCommandMapItem commandMapItem;
if (i == 0)
FillCommand(kOpen, mainString, commandMapItem);
else
{
mainString = exts[i];
commandMapItem.CommandInternalID = kOpen;
commandMapItem.Verb = (UString)kMainVerb + L".Open." + mainString;
commandMapItem.HelpString = mainString;
commandMapItem.ArcType = mainString;
}
MyInsertMenu(subMenu, subIndex2++, currentCommandID++, mainString);
_commandMap.Add(commandMapItem);
}
subMenu.Detach();
}
}
}
}
if (_fileNames.Size() > 0 && currentCommandID + 10 <= commandIDLast)
{
bool needExtract = false;
for(int i = 0; i < _fileNames.Size(); i++)
{
NFile::NFind::CFileInfoW fileInfo;
if (!fileInfo.Find(_fileNames[i]))
return E_FAIL;
if (!fileInfo.IsDir() && DoNeedExtract(fileInfo.Name))
needExtract = true;
}
const UString &fileName = _fileNames.Front();
if (needExtract)
{
UString folderPrefix;
NFile::NDirectory::GetOnlyDirPrefix(fileName, folderPrefix);
NFile::NFind::CFileInfoW fileInfo;
if (!fileInfo.Find(fileName))
return E_FAIL;
// Extract
if ((contextMenuFlags & NContextMenuFlags::kExtract) != 0)
{
CCommandMapItem commandMapItem;
FillCommand(kExtract, mainString, commandMapItem);
if (_dropMode)
commandMapItem.Folder = _dropPath;
else
commandMapItem.Folder = folderPrefix;
commandMapItem.Folder += GetSubFolderNameForExtract(fileInfo.Name) + UString(WCHAR_PATH_SEPARATOR);
MyInsertMenu(popupMenu, subIndex++, currentCommandID++, mainString);
_commandMap.Add(commandMapItem);
}
// Extract Here
if ((contextMenuFlags & NContextMenuFlags::kExtractHere) != 0)
{
CCommandMapItem commandMapItem;
FillCommand(kExtractHere, mainString, commandMapItem);
MyInsertMenu(popupMenu, subIndex++, currentCommandID++, mainString);
if (_dropMode)
commandMapItem.Folder = _dropPath;
else
commandMapItem.Folder = folderPrefix;
_commandMap.Add(commandMapItem);
}
// Extract To
if ((contextMenuFlags & NContextMenuFlags::kExtractTo) != 0)
{
CCommandMapItem commandMapItem;
UString s;
FillCommand(kExtractTo, s, commandMapItem);
UString folder;
if (_fileNames.Size() == 1)
folder = GetSubFolderNameForExtract(fileInfo.Name);
else
folder = L'*';
if (_dropMode)
commandMapItem.Folder = _dropPath;
else
commandMapItem.Folder = folderPrefix;
commandMapItem.Folder += folder;
s = MyFormatNew(s, GetQuotedReducedString(folder + UString(WCHAR_PATH_SEPARATOR)));
MyInsertMenu(popupMenu, subIndex++, currentCommandID++, s);
_commandMap.Add(commandMapItem);
}
// Test
if ((contextMenuFlags & NContextMenuFlags::kTest) != 0)
{
CCommandMapItem commandMapItem;
FillCommand(kTest, mainString, commandMapItem);
MyInsertMenu(popupMenu, subIndex++, currentCommandID++, mainString);
_commandMap.Add(commandMapItem);
}
}
UString archiveName = CreateArchiveName(fileName, _fileNames.Size() > 1, false);
UString archiveName7z = archiveName + L".7z";
UString archiveNameZip = archiveName + L".zip";
UString archivePathPrefix;
NFile::NDirectory::GetOnlyDirPrefix(fileName, archivePathPrefix);
// Compress
if ((contextMenuFlags & NContextMenuFlags::kCompress) != 0)
{
CCommandMapItem commandMapItem;
if (_dropMode)
commandMapItem.Folder = _dropPath;
else
commandMapItem.Folder = archivePathPrefix;
commandMapItem.ArcName = archiveName;
FillCommand(kCompress, mainString, commandMapItem);
MyInsertMenu(popupMenu, subIndex++, currentCommandID++, mainString);
_commandMap.Add(commandMapItem);
}
#ifdef EMAIL_SUPPORT
// CompressEmail
if ((contextMenuFlags & NContextMenuFlags::kCompressEmail) != 0 && !_dropMode)
{
CCommandMapItem commandMapItem;
commandMapItem.ArcName = archiveName;
FillCommand(kCompressEmail, mainString, commandMapItem);
MyInsertMenu(popupMenu, subIndex++, currentCommandID++, mainString);
_commandMap.Add(commandMapItem);
}
#endif
// CompressTo7z
if (contextMenuFlags & NContextMenuFlags::kCompressTo7z)
{
CCommandMapItem commandMapItem;
UString s;
FillCommand(kCompressTo7z, s, commandMapItem);
if (_dropMode)
commandMapItem.Folder = _dropPath;
else
commandMapItem.Folder = archivePathPrefix;
commandMapItem.ArcName = archiveName7z;
commandMapItem.ArcType = L"7z";
s = MyFormatNew(s, GetQuotedReducedString(archiveName7z));
MyInsertMenu(popupMenu, subIndex++, currentCommandID++, s);
_commandMap.Add(commandMapItem);
}
#ifdef EMAIL_SUPPORT
// CompressTo7zEmail
if ((contextMenuFlags & NContextMenuFlags::kCompressTo7zEmail) != 0 && !_dropMode)
{
CCommandMapItem commandMapItem;
UString s;
FillCommand(kCompressTo7zEmail, s, commandMapItem);
commandMapItem.ArcName = archiveName7z;
commandMapItem.ArcType = L"7z";
s = MyFormatNew(s, GetQuotedReducedString(archiveName7z));
MyInsertMenu(popupMenu, subIndex++, currentCommandID++, s);
_commandMap.Add(commandMapItem);
}
#endif
// CompressToZip
if (contextMenuFlags & NContextMenuFlags::kCompressToZip)
{
CCommandMapItem commandMapItem;
UString s;
FillCommand(kCompressToZip, s, commandMapItem);
if (_dropMode)
commandMapItem.Folder = _dropPath;
else
commandMapItem.Folder = archivePathPrefix;
commandMapItem.ArcName = archiveNameZip;
commandMapItem.ArcType = L"zip";
s = MyFormatNew(s, GetQuotedReducedString(archiveNameZip));
MyInsertMenu(popupMenu, subIndex++, currentCommandID++, s);
_commandMap.Add(commandMapItem);
}
#ifdef EMAIL_SUPPORT
// CompressToZipEmail
if ((contextMenuFlags & NContextMenuFlags::kCompressToZipEmail) != 0 && !_dropMode)
{
CCommandMapItem commandMapItem;
UString s;
FillCommand(kCompressToZipEmail, s, commandMapItem);
commandMapItem.ArcName = archiveNameZip;
commandMapItem.ArcType = L"zip";
s = MyFormatNew(s, GetQuotedReducedString(archiveNameZip));
MyInsertMenu(popupMenu, subIndex++, currentCommandID++, s);
_commandMap.Add(commandMapItem);
}
#endif
}
// don't use InsertMenu: See MSDN:
// PRB: Duplicate Menu Items In the File Menu For a Shell Context Menu Extension
// ID: Q214477
if (ci.Cascaded)
{
CMenuItem menuItem;
menuItem.fType = MFT_STRING;
menuItem.fMask = MIIM_SUBMENU | MIIM_TYPE | MIIM_ID;
menuItem.wID = currentCommandID++;
menuItem.hSubMenu = popupMenu.Detach();
menuDestroyer.Disable();
menuItem.StringValue = LangString(IDS_CONTEXT_POPUP_CAPTION, 0x02000101);
CMenu menu;
menu.Attach(hMenu);
menu.InsertItem(indexMenu++, true, menuItem);
}
return MAKE_HRESULT(SEVERITY_SUCCESS, 0, currentCommandID - commandIDFirst);
}
int CZipContextMenu::FindVerb(const UString &verb)
{
for(int i = 0; i < _commandMap.Size(); i++)
if (_commandMap[i].Verb.Compare(verb) == 0)
return i;
return -1;
}
static UString Get7zFmPath()
{
UString path;
GetProgramFolderPath(path);
return path + L"7zFM.exe";
}
STDMETHODIMP CZipContextMenu::InvokeCommand(LPCMINVOKECOMMANDINFO commandInfo)
{
// ::OutputDebugStringA("1");
int commandOffset;
// It's fix for bug: crashing in XP. See example in MSDN: "Creating Context Menu Handlers".
#ifndef UNDER_CE
if (commandInfo->cbSize == sizeof(CMINVOKECOMMANDINFOEX) &&
(commandInfo->fMask & CMIC_MASK_UNICODE) != 0)
{
LPCMINVOKECOMMANDINFOEX commandInfoEx = (LPCMINVOKECOMMANDINFOEX)commandInfo;
if (HIWORD(commandInfoEx->lpVerbW) == 0)
commandOffset = LOWORD(commandInfo->lpVerb);
else
commandOffset = FindVerb(commandInfoEx->lpVerbW);
}
else
#endif
if (HIWORD(commandInfo->lpVerb) == 0)
commandOffset = LOWORD(commandInfo->lpVerb);
else
commandOffset = FindVerb(GetUnicodeString(commandInfo->lpVerb));
if (commandOffset < 0 || commandOffset >= _commandMap.Size())
return E_FAIL;
const CCommandMapItem commandMapItem = _commandMap[commandOffset];
ECommandInternalID cmdID = commandMapItem.CommandInternalID;
try
{
switch(cmdID)
{
( run in 1.671 second using v1.01-cache-2.11-cpan-364913b4093 )