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

📄 panel.cpp

📁 7-Zip 是一款号称有着现今最高压缩比的压缩软件
💻 CPP
📖 第 1 页 / 共 2 页
字号:
    _headerToolBar.GetMaxSize(&size);
    
    REBARBANDINFO rbBand;
    rbBand.cbSize = sizeof(REBARBANDINFO);  // Required
    rbBand.fMask  = RBBIM_STYLE | RBBIM_CHILD | RBBIM_CHILDSIZE | RBBIM_SIZE;
    rbBand.fStyle = RBBS_NOGRIPPER;
    rbBand.cxMinChild = size.cx;
    rbBand.cyMinChild = size.cy;
    rbBand.cyChild = size.cy;
    rbBand.cx = size.cx;
    rbBand.hwndChild  = _headerToolBar;
    _headerReBar.InsertBand(-1, &rbBand);

    RECT rc;
    ::GetWindowRect(_headerComboBox, &rc);
    rbBand.cxMinChild = 30;
    rbBand.cyMinChild = rc.bottom - rc.top;
    rbBand.cx = 1000;
    rbBand.hwndChild  = _headerComboBox;
    _headerReBar.InsertBand(-1, &rbBand);
    // _headerReBar.MaximizeBand(1, false);
  }

  _statusBar.Create(WS_CHILD | WS_VISIBLE, L"Status", (*this), _statusBarID);
  // _statusBar2.Create(WS_CHILD | WS_VISIBLE, L"Status", (*this), _statusBarID + 1);

  int sizes[] = {150, 250, 350, -1};
  _statusBar.SetParts(4, sizes);
  // _statusBar2.SetParts(5, sizes);

  /*
  RECT rect;
  GetClientRect(&rect);
  OnSize(0, rect.right - rect.left, rect.top - rect.bottom);
  */

  SetTimer(kTimerID, kTimerElapse);

  // InitListCtrl();
  RefreshListCtrl();
  RefreshStatusBar();
  
  return true;
}

void CPanel::OnDestroy()
{
  SaveListViewInfo();
  CWindow2::OnDestroy();
}

void CPanel::ChangeWindowSize(int xSize, int ySize)
{
  int kHeaderSize;
  int kStatusBarSize;
  // int kStatusBar2Size;
  RECT rect;
  if (_headerReBar)
    _headerReBar.GetWindowRect(&rect);
  else
    _headerToolBar.GetWindowRect(&rect);

  kHeaderSize = rect.bottom - rect.top;

  _statusBar.GetWindowRect(&rect);
  kStatusBarSize = rect.bottom - rect.top;
  
  // _statusBar2.GetWindowRect(&rect);
  // kStatusBar2Size = rect.bottom - rect.top;
 
  int yListViewSize = MyMax(ySize - kHeaderSize - kStatusBarSize, 0);
  const int kStartXPos = 32;
  if (_headerReBar)
  {
  }
  else
  {
    _headerToolBar.Move(0, 0, xSize, 0);
    _headerComboBox.Move(kStartXPos, 2,
        MyMax(xSize - kStartXPos - 10, kStartXPos), 0);
  }
  _listView.Move(0, kHeaderSize, xSize, yListViewSize);
  _statusBar.Move(0, kHeaderSize + yListViewSize, xSize, kStatusBarSize);
  // _statusBar2.MoveWindow(0, kHeaderSize + yListViewSize + kStatusBarSize, xSize, kStatusBar2Size);
  // _statusBar.MoveWindow(0, 100, xSize, kStatusBarSize);
  // _statusBar2.MoveWindow(0, 200, xSize, kStatusBar2Size);
}

bool CPanel::OnSize(WPARAM /* wParam */, int xSize, int ySize)
{
  if (_headerReBar)
    _headerReBar.Move(0, 0, xSize, 0);
  ChangeWindowSize(xSize, ySize);
  return true;
}

bool CPanel::OnNotifyReBar(LPNMHDR header, LRESULT & /* result */)
{
  switch(header->code)
  {
    case RBN_HEIGHTCHANGE:
    {
      RECT rect;
      GetWindowRect(&rect);
      ChangeWindowSize(rect.right - rect.left, rect.bottom - rect.top);
      return false;
    }
  }
  return false;
}

bool CPanel::OnNotify(UINT /* controlID */, LPNMHDR header, LRESULT &result)
{
  if (!_processNotify)
    return false;
  if (header->hwndFrom == _headerComboBox)
    return OnNotifyComboBox(header, result);
  else if (header->hwndFrom == _headerReBar)
    return OnNotifyReBar(header, result);
  // if (header->hwndFrom == _listView)
  else if (header->hwndFrom == _listView)
    return OnNotifyList(header, result);
  else if (::GetParent(header->hwndFrom) == _listView &&
      header->code == NM_RCLICK)
    return OnRightClick((LPNMITEMACTIVATE)header, result);
  return false;
}

bool CPanel::OnCommand(int code, int itemID, LPARAM lParam, LRESULT &result)
{
  if (itemID == kParentFolderID)
  {
    OpenParentFolder();
    result = 0;
    return true;
  }
  /*
  if (itemID == kCreateFolderID)
  {
    CreateFolder();
    result = 0;
    return true;
  }
  */
  if (itemID == _comboBoxID)
  {
    if (OnComboBoxCommand(code, lParam, result))
      return true;
  }
  return CWindow2::OnCommand(code, itemID, lParam, result);
}

void CPanel::MessageBoxInfo(LPCWSTR message, LPCWSTR caption)
  { ::MessageBoxW(HWND(*this), message, caption, MB_OK); }
void CPanel::MessageBox(LPCWSTR message, LPCWSTR caption)
  { ::MessageBoxW(HWND(*this), message, caption, MB_OK | MB_ICONSTOP); }
void CPanel::MessageBox(LPCWSTR message)
  { MessageBox(message, L"7-Zip"); }
void CPanel::MessageBoxMyError(LPCWSTR message)
  { MessageBox(message, L"Error"); }
void CPanel::MessageBoxError(HRESULT errorCode, LPCWSTR caption)
{
  UString message;
  if (errorCode == E_OUTOFMEMORY)
    message = LangString(IDS_MEM_ERROR, 0x0200060B);
  else
    if (!NError::MyFormatMessage(errorCode, message))
      message = L"Error";
  MessageBox(message, caption);
}

void CPanel::MessageBoxError(HRESULT errorCode)
  { MessageBoxError(errorCode, L"7-Zip"); }
void CPanel::MessageBoxLastError(LPCWSTR caption)
  { MessageBoxError(::GetLastError(), caption); }
void CPanel::MessageBoxLastError()
  { MessageBoxLastError(L"Error"); }

void CPanel::MessageBoxErrorLang(UINT resourceID, UInt32 langID)
  { MessageBox(LangString(resourceID, langID)); }


void CPanel::SetFocusToList()
{
  _listView.SetFocus();
  // SetCurrentPathText();
}

void CPanel::SetFocusToLastRememberedItem()
{
  if (_lastFocusedIsList)
    SetFocusToList();
  else
    _headerComboBox.SetFocus();
}

UString CPanel::GetFolderTypeID() const
{
  NCOM::CPropVariant prop;
  if (_folder->GetFolderProperty(kpidType, &prop) == S_OK)
    if (prop.vt == VT_BSTR)
      return (const wchar_t *)prop.bstrVal;
  return L"";
}

bool CPanel::IsRootFolder() const
{
  return (GetFolderTypeID() == L"RootFolder");
}

bool CPanel::IsFSFolder() const
{
  return (GetFolderTypeID() == L"FSFolder");
}

bool CPanel::IsFSDrivesFolder() const
{
  return (GetFolderTypeID() == L"FSDrives");
}

UString CPanel::GetFsPath() const
{
  if (IsFSDrivesFolder())
    return UString();
  return _currentFolderPrefix;
}

UString CPanel::GetDriveOrNetworkPrefix() const
{
  if (!IsFSFolder())
    return UString();
  UString drive = GetFsPath();
  if (drive.Length() < 3)
    return UString();
  if (drive[0] == L'\\' && drive[1] == L'\\')
  {
    // if network
    int pos = drive.Find(L'\\', 2);
    if (pos < 0)
      return UString();
    pos = drive.Find(L'\\', pos + 1);
    if (pos < 0)
      return UString();
    return drive.Left(pos + 1);
  }
  if (drive[1] != L':' || drive[2] != L'\\')
    return UString();
  return drive.Left(3);
}

bool CPanel::DoesItSupportOperations() const
{
  CMyComPtr<IFolderOperations> folderOperations;
  return _folder.QueryInterface(IID_IFolderOperations, &folderOperations) == S_OK;
}

void CPanel::SetListViewMode(UInt32 index)
{
  if (index >= 4)
    return;
  _ListViewMode = index;
  DWORD oldStyle = (DWORD)_listView.GetStyle();
  DWORD newStyle = kStyles[index];
  if ((oldStyle & LVS_TYPEMASK) != newStyle)
    _listView.SetStyle((oldStyle & ~LVS_TYPEMASK) | newStyle);
  // RefreshListCtrlSaveFocused();
}

void CPanel::ChangeFlatMode()
{
  _flatMode = !_flatMode;
  RefreshListCtrlSaveFocused();
}


void CPanel::RefreshStatusBar()
{
  PostMessage(kRefreshStatusBar);
}

void CPanel::AddToArchive()
{
  CRecordVector<UInt32> indices;
  GetOperatedItemIndices(indices);
  if (!IsFSFolder())
  {
    MessageBoxErrorLang(IDS_OPERATION_IS_NOT_SUPPORTED, 0x03020208);
    return;
  }
  if (indices.Size() == 0)
  {
    MessageBoxErrorLang(IDS_SELECT_FILES, 0x03020A03);
    return;
  }
  UStringVector names;
  for (int i = 0; i < indices.Size(); i++)
  {
    int index = indices[i];
    names.Add(_currentFolderPrefix + GetItemRelPath(index));
  }
  const UString archiveName = CreateArchiveName(
      names.Front(), (names.Size() > 1), false);
  HRESULT res = CompressFiles(_currentFolderPrefix, archiveName, L"", names, false, true, false);
  if (res != S_OK)
  {
    if (_currentFolderPrefix.Length() >= MAX_PATH)
      MessageBoxErrorLang(IDS_MESSAGE_UNSUPPORTED_OPERATION_FOR_LONG_PATH_FOLDER, 0x03020A01);
    else
      MessageBoxError(res);
  }
  // KillSelection();
}

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

void CPanel::GetFilePaths(const CRecordVector<UInt32> &indices, UStringVector &paths)
{
  for (int i = 0; i < indices.Size(); i++)
  {
    int index = indices[i];
    if (IsItemFolder(index))
    {
      paths.Clear();
      break;
    }
    paths.Add(_currentFolderPrefix + GetItemRelPath(index));
  }
  if (paths.Size() == 0)
  {
    MessageBoxErrorLang(IDS_SELECT_FILES, 0x03020A03);
    return;
  }
}

void CPanel::ExtractArchives()
{
  if (_parentFolders.Size() > 0)
  {
    _panelCallback->OnCopy(false, false);
    return;
  }
  CRecordVector<UInt32> indices;
  GetOperatedItemIndices(indices);
  UStringVector paths;
  GetFilePaths(indices, paths);
  if (paths.IsEmpty())
    return;
  UString folderName;
  if (indices.Size() == 1)
    folderName = GetSubFolderNameForExtract(GetItemRelPath(indices[0]));
  else
    folderName = L"*";
  ::ExtractArchives(paths, _currentFolderPrefix + folderName + UString(WCHAR_PATH_SEPARATOR), true);
}

struct CThreadTest
{
  CRecordVector<UInt32> Indices;
  CExtractCallbackImp *ExtractCallbackSpec;
  CMyComPtr<IFolderArchiveExtractCallback> ExtractCallback;
  CMyComPtr<IArchiveFolder> ArchiveFolder;
  HRESULT Result;

  void Test()
  {
    ExtractCallbackSpec->ProgressDialog.WaitCreating();
    Result = ArchiveFolder->Extract(&Indices[0], Indices.Size(),
        NExtract::NPathMode::kFullPathnames, NExtract::NOverwriteMode::kAskBefore,
        NULL, BoolToInt(true), ExtractCallback);
    ExtractCallbackSpec->ProgressDialog.MyClose();
  }
  
  static THREAD_FUNC_DECL MyThreadFunction(void *param)
  {
    ((CThreadTest*)param)->Test();
    return 0;
  }
};

static void AddValuePair(UINT resourceID, UInt32 langID, UInt64 value, UString &s)
{
  wchar_t sz[32];
  s += LangString(resourceID, langID);
  s += L" ";
  ConvertUInt64ToString(value, sz);
  s += sz;
  s += L"\n";
}

/*
static void AddSizePair(UINT resourceID, UInt32 langID, UInt64 value, UString &s)
{
  wchar_t sz[32];
  s += LangString(resourceID, langID);
  s += L" ";
  ConvertUInt64ToString(value, sz);
  s += sz;
  ConvertUInt64ToString(value >> 20, sz);
  s += L" (";
  s += sz;
  s += L" MB)";
  s += L"\n";
}
*/

void CPanel::TestArchives()
{
  CRecordVector<UInt32> indices;
  GetOperatedIndicesSmart(indices);
  CMyComPtr<IArchiveFolder> archiveFolder;
  _folder.QueryInterface(IID_IArchiveFolder, &archiveFolder);
  if (archiveFolder)
  {
    {
    CThreadTest extracter;

    extracter.ArchiveFolder = archiveFolder;
    extracter.ExtractCallbackSpec = new CExtractCallbackImp;
    extracter.ExtractCallback = extracter.ExtractCallbackSpec;
    extracter.ExtractCallbackSpec->ParentWindow = GetParent();
    extracter.ExtractCallbackSpec->ShowMessages = true;

    if (indices.IsEmpty())
      return;

    extracter.Indices = indices;
    
    UString title = LangString(IDS_PROGRESS_TESTING, 0x02000F90);
    UString progressWindowTitle = LangString(IDS_APP_TITLE, 0x03000000);
    
    extracter.ExtractCallbackSpec->ProgressDialog.CompressingMode = false;
    extracter.ExtractCallbackSpec->ProgressDialog.MainWindow = GetParent();
    extracter.ExtractCallbackSpec->ProgressDialog.MainTitle = progressWindowTitle;
    extracter.ExtractCallbackSpec->ProgressDialog.MainAddTitle = title + L" ";
    
    extracter.ExtractCallbackSpec->OverwriteMode = NExtract::NOverwriteMode::kAskBefore;
    extracter.ExtractCallbackSpec->Init();
    
    NWindows::CThread extractThread;
    if (extractThread.Create(CThreadTest::MyThreadFunction, &extracter) != S_OK)
      return;
    extracter.ExtractCallbackSpec->StartProgressDialog(title);
    
    if (extracter.ExtractCallbackSpec->Messages.IsEmpty() && extracter.Result == S_OK)
    {
      UString s;
      AddValuePair(IDS_FOLDERS_COLON, 0x02000321, extracter.ExtractCallbackSpec->NumFolders, s);
      AddValuePair(IDS_FILES_COLON, 0x02000320, extracter.ExtractCallbackSpec->NumFiles, s);
      // AddSizePair(IDS_SIZE_COLON, 0x02000322, extracter.Stat.UnpackSize, s);
      // AddSizePair(IDS_COMPRESSED_COLON, 0x02000323, extracter.Stat.PackSize, s);
      s += L"\n";
      s += LangString(IDS_MESSAGE_NO_ERRORS, 0x02000608);
      MessageBoxInfo(s, LangString(IDS_PROGRESS_TESTING, 0x02000F90));
    }
    else
    {
      if (extracter.Result != S_OK && extracter.Result != E_ABORT)
        MessageBoxError(extracter.Result, L"Testing Error");
    }
    }
    RefreshTitleAlways();
    return;
  }

  if (!IsFSFolder())
  {
    MessageBoxErrorLang(IDS_OPERATION_IS_NOT_SUPPORTED, 0x03020208);
    return;
  }
  UStringVector paths;
  GetFilePaths(indices, paths);
  if (paths.IsEmpty())
    return;
  ::TestArchives(paths);
}

⌨️ 快捷键说明

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