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

📄 panelmenu.cpp

📁 7z一个高压缩比的压缩程序源代码,重要的是里面的算法值得学习
💻 CPP
📖 第 1 页 / 共 2 页
字号:
#include "StdAfx.h"

#include "Common/StringConvert.h"
#include "Windows/Menu.h"
#include "Windows/COM.h"
#include "Windows/PropVariant.h"
#include "Windows/Clipboard.h"
#include "Windows/PropVariantConversions.h"
#include "../Common/PropIDUtils.h"
#include "../../PropID.h"

#include "Panel.h"
#include "PluginInterface.h"
#include "MyLoadMenu.h"
#include "App.h"
#include "LangUtils.h"
#include "resource.h"
#include "PropertyName.h"
#include "PropertyNameRes.h"

using namespace NWindows;

// {23170F69-40C1-278A-1000-000100020000}
DEFINE_GUID(CLSID_CZipContextMenu,
0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00);

static const UINT kSevenZipStartMenuID = kPluginMenuStartID ;
static const UINT kSystemStartMenuID = kPluginMenuStartID + 100;

void CPanel::InvokeSystemCommand(const char *command)
{
  NCOM::CComInitializer comInitializer;
  if (!IsFSFolder() && !IsFSDrivesFolder())
    return;
  CRecordVector<UInt32> operatedIndices;
  GetOperatedItemIndices(operatedIndices);
  if (operatedIndices.IsEmpty())
    return;
  CMyComPtr<IContextMenu> contextMenu;
  if (CreateShellContextMenu(operatedIndices, contextMenu) != S_OK)
    return;

  CMINVOKECOMMANDINFO ci;
  ZeroMemory(&ci, sizeof(ci));
  ci.cbSize = sizeof(CMINVOKECOMMANDINFO);
  ci.hwnd = GetParent();
  ci.lpVerb = command;
  contextMenu->InvokeCommand(&ci);
}

static const wchar_t *kSeparator = L"--------------------------------------\n";
static const wchar_t *kPropValueSeparator = L": ";

extern UString ConvertSizeToString(UInt64 value);

static void AddPropertyString(PROPID propID, const wchar_t *nameBSTR,
    const NCOM::CPropVariant &prop, UString &s)
{
  if (prop.vt != VT_EMPTY)
  {
    const UString name = GetNameOfProperty(propID, nameBSTR);
    UString val;

    if ((
        propID == kpidSize ||
        propID == kpidPackSize ||
        propID == kpidNumSubDirs ||
        propID == kpidNumSubFiles ||
        propID == kpidNumBlocks ||
        propID == kpidPhySize ||
        propID == kpidHeadersSize ||
        propID == kpidClusterSize
        ) && (prop.vt == VT_UI8 || prop.vt == VT_UI4))
      val = ConvertSizeToString(ConvertPropVariantToUInt64(prop));
    else
      val = ConvertPropertyToString(prop, propID);

    if (!val.IsEmpty())
    {
      s += name;
      s += kPropValueSeparator;
      /*
      if (propID == kpidComment)
        s += L'\n';
      */
      s += val;
      s += L'\n';
    }
  }
}

void CPanel::Properties()
{
  CMyComPtr<IGetFolderArchiveProperties> getFolderArchiveProperties;
  _folder.QueryInterface(IID_IGetFolderArchiveProperties, &getFolderArchiveProperties);
  if (!getFolderArchiveProperties)
  {
    InvokeSystemCommand("properties");
    return;
  }
  
  {
    UString message;

    CRecordVector<UInt32> operatedIndices;
    GetOperatedItemIndices(operatedIndices);
    if (operatedIndices.Size() == 1)
    {
      UInt32 index = operatedIndices[0];
      // message += L"Item:\n";
      UInt32 numProps;
      if (_folder->GetNumberOfProperties(&numProps) == S_OK)
      {
        for (UInt32 i = 0; i < numProps; i++)
        {
          CMyComBSTR name;
          PROPID propID;
          VARTYPE varType;
          
          if (_folder->GetPropertyInfo(i, &name, &propID, &varType) != S_OK)
            continue;
          
          NCOM::CPropVariant prop;
          if (_folder->GetProperty(index, propID, &prop) != S_OK)
            continue;
          AddPropertyString(propID, name, prop, message);
        }
      }
      message += kSeparator;
    }
        
    message += LangString(IDS_PROPERTY_FILE_TYPE, 0x02000214);
    message += kPropValueSeparator;
    message += GetFolderTypeID();
    message += L"\n";

    {
      NCOM::CPropVariant prop;
      if (_folder->GetFolderProperty(kpidPath, &prop) == S_OK)
      {
        AddPropertyString(kpidName, L"Path", prop, message);
      }
    }

    CMyComPtr<IFolderProperties> folderProperties;
    _folder.QueryInterface(IID_IFolderProperties, &folderProperties);
    if (folderProperties)
    {
      UInt32 numProps;
      if (folderProperties->GetNumberOfFolderProperties(&numProps) == S_OK)
      {
        for (UInt32 i = 0; i < numProps; i++)
        {
          CMyComBSTR name;
          PROPID propID;
          VARTYPE vt;
          if (folderProperties->GetFolderPropertyInfo(i, &name, &propID, &vt) != S_OK)
            continue;
          NCOM::CPropVariant prop;
          if (_folder->GetFolderProperty(propID, &prop) != S_OK)
            continue;
          AddPropertyString(propID, name, prop, message);
        }
      }
    }

    CMyComPtr<IGetFolderArchiveProperties> getFolderArchiveProperties;
    _folder.QueryInterface(IID_IGetFolderArchiveProperties, &getFolderArchiveProperties);
    if (getFolderArchiveProperties)
    {
      CMyComPtr<IFolderArchiveProperties> getProps;
      getFolderArchiveProperties->GetFolderArchiveProperties(&getProps);
      if (getProps)
      {
        UInt32 numProps;
        if (getProps->GetNumberOfArchiveProperties(&numProps) == S_OK)
        {
          if (numProps > 0)
            message += kSeparator;
          for (UInt32 i = 0; i < numProps; i++)
          {
            CMyComBSTR name;
            PROPID propID;
            VARTYPE vt;
            if (getProps->GetArchivePropertyInfo(i, &name, &propID, &vt) != S_OK)
              continue;
            NCOM::CPropVariant prop;
            if (getProps->GetArchiveProperty(propID, &prop) != S_OK)
              continue;
            AddPropertyString(propID, name, prop, message);
          }
        }
      }
    }
    ::MessageBoxW(*(this), message, LangString(IDS_PROPERTIES, 0x03020900), MB_OK);
  }
}

void CPanel::EditCut()
{
  // InvokeSystemCommand("cut");
}

void CPanel::EditCopy()
{
  /*
  CMyComPtr<IGetFolderArchiveProperties> getFolderArchiveProperties;
  _folder.QueryInterface(IID_IGetFolderArchiveProperties, &getFolderArchiveProperties);
  if (!getFolderArchiveProperties)
  {
    InvokeSystemCommand("copy");
    return;
  }
  */
  UString s;
  CRecordVector<UInt32> indices;
  GetSelectedItemsIndices(indices);
  for (int i = 0; i < indices.Size(); i++)
  {
    if (i > 0)
      s += L"\xD\n";
    s += GetItemName(indices[i]);
  }
  ClipboardSetText(_mainWindow, s);
}

void CPanel::EditPaste()
{
  /*
  UStringVector names;
  ClipboardGetFileNames(names);
  CopyFromNoAsk(names);
  UString s;
  for (int i = 0; i < names.Size(); i++)
  {
    s += L" ";
    s += names[i];
  }

  MessageBoxW(0, s, L"", 0);
  */

  // InvokeSystemCommand("paste");
}

HRESULT CPanel::CreateShellContextMenu(
    const CRecordVector<UInt32> &operatedIndices,
    CMyComPtr<IContextMenu> &systemContextMenu)
{
  systemContextMenu.Release();
  UString folderPath = GetFsPath();

  CMyComPtr<IShellFolder> desktopFolder;
  RINOK(::SHGetDesktopFolder(&desktopFolder));
  if (!desktopFolder)
  {
    // ShowMessage("Failed to get Desktop folder.");
    return E_FAIL;
  }
  
  // Separate the file from the folder.

  
  // Get a pidl for the folder the file
  // is located in.
  LPITEMIDLIST parentPidl;
  DWORD eaten;
  RINOK(desktopFolder->ParseDisplayName(
      GetParent(), 0, (wchar_t *)(const wchar_t *)folderPath,
      &eaten, &parentPidl, 0));
  
  // Get an IShellFolder for the folder
  // the file is located in.
  CMyComPtr<IShellFolder> parentFolder;
  RINOK(desktopFolder->BindToObject(parentPidl,
      0, IID_IShellFolder, (void**)&parentFolder));
  if (!parentFolder)
  {
    // ShowMessage("Invalid file name.");
    return E_FAIL;
  }
  
  // Get a pidl for the file itself.
  CRecordVector<LPITEMIDLIST> pidls;
  pidls.Reserve(operatedIndices.Size());
  for (int i = 0; i < operatedIndices.Size(); i++)
  {
    LPITEMIDLIST pidl;
    UString fileName = GetItemRelPath(operatedIndices[i]);
    if (IsFSDrivesFolder())
      fileName += WCHAR_PATH_SEPARATOR;
    RINOK(parentFolder->ParseDisplayName(GetParent(), 0,
      (wchar_t *)(const wchar_t *)fileName, &eaten, &pidl, 0));
    pidls.Add(pidl);
  }

  ITEMIDLIST temp;
  if (pidls.Size() == 0)
  {
    temp.mkid.cb = 0;
    /*
    LPITEMIDLIST pidl;
    HRESULT result = parentFolder->ParseDisplayName(GetParent(), 0,
      L"." WSTRING_PATH_SEPARATOR, &eaten, &pidl, 0);
    if (result != NOERROR)
      return;
    */

⌨️ 快捷键说明

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