⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 contextmenu.cpp

📁 免费压缩软件7zip的源码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// ContextMenu.cpp

#include "StdAfx.h"

#include "ContextMenu.h"

#include "Common/StringConvert.h"
#include "Common/MyCom.h"

#include "Windows/Shell.h"
#include "Windows/Memory.h"
#include "Windows/COM.h"
#include "Windows/FileFind.h"
#include "Windows/FileDir.h"
#include "Windows/FileName.h"
#include "Windows/Thread.h"
#include "Windows/Window.h"

#include "Windows/Menu.h"
#include "Windows/ResourceString.h"

#include "../../FileManager/FormatUtils.h"
#include "../../FileManager/ProgramLocation.h"

#include "../Common/ZipRegistry.h"
#include "../Common/ArchiveName.h"

#ifdef LANG        
#include "../../FileManager/LangUtils.h"
#endif

#include "resource.h"
#include "ContextMenuFlags.h"

// #include "ExtractEngine.h"
// #include "TestEngine.h"
// #include "CompressEngine.h"
#include "MyMessages.h"

#include "../Resource/Extract/resource.h"
#include "../Common/CompressCall.h"

using namespace NWindows;

static LPCTSTR kFileClassIDString = TEXT("SevenZip");

///////////////////////////////
// IShellExtInit

HRESULT CZipContextMenu::GetFileNames(LPDATAOBJECT dataObject, 
    CSysStringVector &fileNames)
{
  fileNames.Clear();
  if(dataObject == NULL)
    return E_FAIL;
  FORMATETC fmte = {CF_HDROP,  NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL};
  NCOM::CStgMedium stgMedium;
  HRESULT result = dataObject->GetData(&fmte, &stgMedium);
  if (result != S_OK)
    return result;
  stgMedium._mustBeReleased = true;

  NShell::CDrop drop(false);
  NMemory::CGlobalLock globalLock(stgMedium->hGlobal);
  drop.Attach((HDROP)globalLock.GetPointer());
  drop.QueryFileNames(fileNames);

  return S_OK;
}

STDMETHODIMP CZipContextMenu::Initialize(LPCITEMIDLIST pidlFolder, 
    LPDATAOBJECT dataObject, HKEY hkeyProgID)
{
  /*
  m_IsFolder = false;
  if (pidlFolder == 0)
  */
  // pidlFolder is NULL :(
  CSysStringVector sysFileNames;
  RINOK(GetFileNames(dataObject, sysFileNames));
  _fileNames.Clear();
  _fileNames.Reserve(sysFileNames.Size());
  for (int i = 0; i < sysFileNames.Size(); i++)
    _fileNames.Add(GetUnicodeString(sysFileNames[i]));
  return S_OK;
}

STDMETHODIMP CZipContextMenu::InitContextMenu(const wchar_t *folder, 
    const wchar_t **names, UINT32 numFiles)
{
  _fileNames.Clear();
  for (UINT32 i = 0; i < numFiles; i++)
    _fileNames.Add(names[i]);
  return S_OK;
}


/////////////////////////////
// IContextMenu

static LPCWSTR kMainVerb = L"SevenZip";

/*
static LPCTSTR kOpenVerb = TEXT("SevenOpen");
static LPCTSTR kExtractVerb = TEXT("SevenExtract");
static LPCTSTR kExtractHereVerb = TEXT("SevenExtractHere");
static LPCTSTR kExtractToVerb = TEXT("SevenExtractTo");
static LPCTSTR kTestVerb = TEXT("SevenTest");
static LPCTSTR kCompressVerb = TEXT("SevenCompress");
static LPCTSTR kCompressToVerb = TEXT("SevenCompressTo");
static LPCTSTR kCompressEmailVerb = TEXT("SevenCompressEmail");
static LPCTSTR kCompressToEmailVerb = TEXT("SevenCompressToEmail");
*/

struct CContextMenuCommand
{
  UINT32 flag;
  CZipContextMenu::ECommandInternalID CommandInternalID;
  LPCWSTR Verb;
  UINT ResourceID;
  UINT ResourceHelpID;
  UINT32 LangID;
};

static CContextMenuCommand g_Commands[] = 
{
  { 
    NContextMenuFlags::kOpen,
    CZipContextMenu::kOpen, 
    L"Open", 
    IDS_CONTEXT_OPEN, 
    IDS_CONTEXT_OPEN_HELP, 
    0x02000103
  },
  { 
    NContextMenuFlags::kExtract, 
    CZipContextMenu::kExtract, 
    L"Extract", 
    IDS_CONTEXT_EXTRACT, 
    IDS_CONTEXT_EXTRACT_HELP, 
    0x02000105 
  },
  { 
    NContextMenuFlags::kExtractHere, 
    CZipContextMenu::kExtractHere, 
    L"ExtractHere", 
    IDS_CONTEXT_EXTRACT_HERE, 
    IDS_CONTEXT_EXTRACT_HERE_HELP, 
    0x0200010B
  },
  { 
    NContextMenuFlags::kExtractTo, 
    CZipContextMenu::kExtractTo, 
    L"ExtractTo", 
    IDS_CONTEXT_EXTRACT_TO, 
    IDS_CONTEXT_EXTRACT_TO_HELP, 
    0x0200010D
  },
  { 
    NContextMenuFlags::kTest, 
    CZipContextMenu::kTest, 
    L"Test", 
    IDS_CONTEXT_TEST, 
    IDS_CONTEXT_TEST_HELP, 
    0x02000109
  },
  { 
    NContextMenuFlags::kCompress, 
    CZipContextMenu::kCompress, 
    L"Compress", 
    IDS_CONTEXT_COMPRESS, 
    IDS_CONTEXT_COMPRESS_HELP, 
    0x02000107, 
  },
  { 
    NContextMenuFlags::kCompressTo, 
    CZipContextMenu::kCompressTo, 
    L"CompressTo", 
    IDS_CONTEXT_COMPRESS_TO, 
    IDS_CONTEXT_COMPRESS_TO_HELP, 
    0x0200010F
  },
  { 
    NContextMenuFlags::kCompressEmail, 
    CZipContextMenu::kCompressEmail, 
    L"CompressEmail", 
    IDS_CONTEXT_COMPRESS_EMAIL, 
    IDS_CONTEXT_COMPRESS_EMAIL_HELP, 
    0x02000111
  },
  { 
    NContextMenuFlags::kCompressToEmail, 
    CZipContextMenu::kCompressToEmail, 
    L"CompressToEmail", 
    IDS_CONTEXT_COMPRESS_TO_EMAIL, 
    IDS_CONTEXT_COMPRESS_TO_EMAIL_HELP, 
    0x02000113
  }
};

int FindCommand(CZipContextMenu::ECommandInternalID &id)
{
  for (int i = 0; i < sizeof(g_Commands) / sizeof(g_Commands[0]); i++)
    if (g_Commands[i].CommandInternalID == id)
      return i;
  return -1;
}

void CZipContextMenu::FillCommand(ECommandInternalID id, 
    UString &mainString, CCommandMapItem &commandMapItem)
{
  int i = FindCommand(id);
  if (i < 0)
    return;
  const CContextMenuCommand &command = g_Commands[i];
  commandMapItem.CommandInternalID = command.CommandInternalID;
  commandMapItem.Verb = command.Verb;
  commandMapItem.HelpString = LangLoadStringW(command.ResourceHelpID, command.LangID + 1);
  mainString = LangLoadStringW(command.ResourceID, command.LangID); 
}

void CZipContextMenu::FillCommand2(ECommandInternalID id, 
    UString &mainString, CCommandMapItem &commandMapItem)
{
  int i = FindCommand(id);
  if (i < 0)
    return;
  const CContextMenuCommand &command = g_Commands[i];
  commandMapItem.CommandInternalID = command.CommandInternalID;
  commandMapItem.Verb = command.Verb;
  commandMapItem.HelpString = LangLoadStringW(command.ResourceHelpID, command.LangID + 1);
  mainString = LangLoadStringW(command.ResourceID, command.LangID); 
}


/*
CSysString GetExtractPath(const CSysString &archiveName)
{
  CSysString s;
  int dotPos = s.ReverseFind('.');
  if (dotPos < 0)
    return archiveName;
  return archiveName.Left(dotPos);
}
*/

static BOOL MyInsertMenu(HMENU hMenu, int pos, UINT id, LPCTSTR s)
{
  MENUITEMINFO menuItem;
  menuItem.cbSize = sizeof(menuItem);
  menuItem.fType = MFT_STRING;
  menuItem.fMask = MIIM_TYPE | MIIM_ID;
  menuItem.wID = id; 
  menuItem.dwTypeData = (LPTSTR)(LPCTSTR)s;
  return ::InsertMenuItem(hMenu, pos++, TRUE, &menuItem);
}

static UString GetSubFolderNameForExtract(const UString &archiveName)
{
  int dotPos = archiveName.ReverseFind('.');
  if (dotPos >= 0)
  {
    UString res = archiveName.Left(dotPos);
    res.TrimRight();
    return res;
  }
  return archiveName + UString(L"~");
}

STDMETHODIMP CZipContextMenu::QueryContextMenu(HMENU hMenu, UINT indexMenu,
      UINT commandIDFirst, UINT commandIDLast, UINT flags)
{
  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;

  bool cascadedMenu = ReadCascadedMenu();
  MENUITEMINFO menuItem;
  UINT subIndex = indexMenu;
  if (cascadedMenu)
  {
    CCommandMapItem commandMapItem;
    if(!popupMenu.CreatePopup())
      throw 210503;
    menuDestroyer.Attach(popupMenu);
    commandMapItem.CommandInternalID = kCommandNULL;
    commandMapItem.Verb = kMainVerb;
    commandMapItem.HelpString = LangLoadStringW(IDS_CONTEXT_CAPTION_HELP, 0x02000102);
    _commandMap.push_back(commandMapItem);
    
    menuItem.wID = currentCommandID++; 
    subIndex = 0;
  }
  else
  {
    popupMenu.Attach(hMenu);
  }

  UINT32 contextMenuFlags;
  if (!ReadContextMenuStatus(contextMenuFlags))
    contextMenuFlags = NContextMenuFlags::GetDefaultFlags();

  int subMenuIndex = 0;
  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 (!NFile::NFind::FindFile(fileName, fileInfo))
      return E_FAIL;
    if (!fileInfo.IsDirectory())
    {
      // Open
      if ((contextMenuFlags & NContextMenuFlags::kOpen) != 0)
      {
        CCommandMapItem commandMapItem;
        FillCommand(kOpen, mainString, commandMapItem);
        MyInsertMenu(popupMenu, subIndex++, currentCommandID++, GetSystemString(mainString)); 
        _commandMap.push_back(commandMapItem);
      }
    }
  }

  if(_fileNames.Size() > 0 && currentCommandID + 10 <= commandIDLast)
  {
    bool thereAreFolders = false;
    for(int i = 0; i < _fileNames.Size(); i++)
    {
      NFile::NFind::CFileInfoW fileInfo;
      if (!NFile::NFind::FindFile(_fileNames[i], fileInfo))
        return E_FAIL;
      if (fileInfo.IsDirectory())
        thereAreFolders = true;
    }
    const UString &fileName = _fileNames.Front();
    if (!thereAreFolders)
    {
      UString folderPrefix;
      NFile::NDirectory::GetOnlyDirPrefix(fileName, folderPrefix);
      NFile::NFind::CFileInfoW fileInfo;
      if (!NFile::NFind::FindFile(fileName, fileInfo))
        return E_FAIL;
      // Extract
      if ((contextMenuFlags & NContextMenuFlags::kExtract) != 0)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -