7z一个高压缩比的压缩程序源代码,重要的是里面的算法值得学习

源代码在线查看: panellistnotify.cpp

软件大小: 1199 K
上传用户: Lxb500
关键词: 压缩比 程序 源代码 算法
下载地址: 免注册下载 普通下载 VIP

相关代码

				// PanelListNotify.cpp
				
				#include "StdAfx.h"
				
				#include "resource.h"
				
				#include "Common/IntToString.h"
				#include "Common/StringConvert.h"
				
				#include "Windows/PropVariant.h"
				#include "Windows/PropVariantConversions.h"
				
				#include "../Common/PropIDUtils.h"
				#include "../../PropID.h"
				
				#include "Panel.h"
				#include "FormatUtils.h"
				
				using namespace NWindows;
				
				static UString ConvertSizeToStringShort(UInt64 value)
				{
				  wchar_t s[32];
				  wchar_t c, c2 = L'B';
				  if (value < (UInt64)10000)
				  {
				    c = L'B';
				    c2 = L'\0';
				  }
				  else if (value < ((UInt64)10000 				  {
				    value >>= 10;
				    c = L'K';
				  }
				  else if (value < ((UInt64)10000 				  {
				    value >>= 20;
				    c = L'M';
				  }
				  else
				  {
				    value >>= 30;
				    c = L'G';
				  }
				  ConvertUInt64ToString(value, s);
				  int p = MyStringLen(s);
				  s[p++] = L' ';
				  s[p++] = c;
				  s[p++] = c2;
				  s[p++] = L'\0';
				  return s;
				}
				
				UString ConvertSizeToString(UInt64 value)
				{
				  wchar_t s[32];
				  ConvertUInt64ToString(value, s);
				  int i = MyStringLen(s);
				  int pos = sizeof(s) / sizeof(s[0]);
				  s[--pos] = L'\0';
				  while (i > 3)
				  {
				    s[--pos] = s[--i];
				    s[--pos] = s[--i];
				    s[--pos] = s[--i];
				    s[--pos] = L' ';
				  }
				  while (i > 0)
				    s[--pos] = s[--i];
				  return s + pos;
				}
				
				LRESULT CPanel::SetItemText(LVITEMW &item)
				{
				  if (_dontShowMode)
				    return 0;
				
				  UINT32 realIndex = GetRealIndex(item);
				  /*
				  if ((item.mask & LVIF_IMAGE) != 0)
				  {
				    bool defined  = false;
				    CComPtr folderGetSystemIconIndex;
				    _folder.QueryInterface(&folderGetSystemIconIndex);
				    if (folderGetSystemIconIndex)
				    {
				      folderGetSystemIconIndex->GetSystemIconIndex(index, &item.iImage);
				      defined = (item.iImage > 0);
				    }
				    if (!defined)
				    {
				      NCOM::CPropVariant prop;
				      _folder->GetProperty(index, kpidAttrib, &prop);
				      UINT32 attrib = 0;
				      if (prop.vt == VT_UI4)
				        attrib = prop.ulVal;
				      else if (IsItemFolder(index))
				        attrib |= FILE_ATTRIBUTE_DIRECTORY;
				      if (_currentFolderPrefix.IsEmpty())
				        throw 1;
				      else
				        item.iImage = _extToIconMap.GetIconIndex(attrib, GetSystemString(GetItemName(index)));
				    }
				    // item.iImage = 1;
				  }
				  */
				
				  if ((item.mask & LVIF_TEXT) == 0)
				    return 0;
				
				  if (realIndex == kParentIndex)
				    return 0;
				  UString s;
				  UINT32 subItemIndex = item.iSubItem;
				  PROPID propID = _visibleProperties[subItemIndex].ID;
				  /*
				  {
				    NCOM::CPropVariant property;
				    if(propID == kpidType)
				      string = GetFileType(index);
				    else
				    {
				      HRESULT result = m_ArchiveFolder->GetProperty(index, propID, &property);
				      if (result != S_OK)
				      {
				        // PrintMessage("GetPropertyValue error");
				        return 0;
				      }
				      string = ConvertPropertyToString(property, propID, false);
				    }
				  }
				  */
				  // const NFind::CFileInfo &aFileInfo = m_Files[index];
				
				  NCOM::CPropVariant prop;
				  /*
				  bool needRead = true;
				  if (propID == kpidSize)
				  {
				    CComPtr getItemFullSize;
				    if (_folder.QueryInterface(&getItemFullSize) == S_OK)
				    {
				      if (getItemFullSize->GetItemFullSize(index, &prop) == S_OK)
				        needRead = false;
				    }
				  }
				  if (needRead)
				  */
				
				  if (_folder->GetProperty(realIndex, propID, &prop) != S_OK)
				      throw 2723407;
				
				  if ((propID == kpidSize || propID == kpidPackSize || propID == kpidClusterSize ||
				      propID == kpidNumSubDirs || propID == kpidNumSubFiles) &&
				      (prop.vt == VT_UI8 || prop.vt == VT_UI4))
				    s = ConvertSizeToString(ConvertPropVariantToUInt64(prop));
				  else if ((propID == kpidTotalSize || propID == kpidFreeSpace) &&
				      (prop.vt == VT_UI8 || prop.vt == VT_UI4))
				    s = ConvertSizeToStringShort(ConvertPropVariantToUInt64(prop));
				  else
				  {
				    s = ConvertPropertyToString(prop, propID, false);
				    s.Replace(wchar_t(0xA), L' ');
				    s.Replace(wchar_t(0xD), L' ');
				  }
				  int size = item.cchTextMax;
				  if(size > 0)
				  {
				    if(s.Length() + 1 > size)
				      s = s.Left(size - 1);
				    MyStringCopy(item.pszText, (const wchar_t *)s);
				  }
				  return 0;
				}
				
				extern DWORD g_ComCtl32Version;
				
				void CPanel::OnItemChanged(NMLISTVIEW *item)
				{
				  int index = (int)item->lParam;
				  if (index == kParentIndex)
				    return;
				  bool oldSelected = (item->uOldState & LVIS_SELECTED) != 0;
				  bool newSelected = (item->uNewState & LVIS_SELECTED) != 0;
				  // Don't change this code. It works only with such check
				  if(oldSelected != newSelected)
				    _selectedStatusVector[index] = newSelected;
				}
				
				bool CPanel::OnNotifyList(LPNMHDR header, LRESULT &result)
				{
				  // bool alt = (::GetKeyState(VK_MENU) & 0x8000) != 0;
				  // bool ctrl = (::GetKeyState(VK_CONTROL) & 0x8000) != 0;
				  // bool shift = (::GetKeyState(VK_SHIFT) & 0x8000) != 0;
				  switch(header->code)
				  {
				    case LVN_ITEMCHANGED:
				    {
				      if (_enableItemChangeNotify)
				      {
				        if (!_mySelectMode)
				          OnItemChanged((LPNMLISTVIEW)header);
				        RefreshStatusBar();
				      }
				      return false;
				    }
				    /*
				
				    case LVN_ODSTATECHANGED:
				      {
				      break;
				      }
				    */
				
				    case LVN_GETDISPINFOW:
				    {
				      LV_DISPINFOW *dispInfo = (LV_DISPINFOW *)header;
				
				      //is the sub-item information being requested?
				
				      if((dispInfo->item.mask & LVIF_TEXT) != 0 ||
				        (dispInfo->item.mask & LVIF_IMAGE) != 0)
				        SetItemText(dispInfo->item);
				      return false;
				    }
				    case LVN_KEYDOWN:
				    {
				      bool boolResult = OnKeyDown(LPNMLVKEYDOWN(header), result);
				      RefreshStatusBar();
				      return boolResult;
				    }
				
				    case LVN_COLUMNCLICK:
				      OnColumnClick(LPNMLISTVIEW(header));
				      return false;
				    /*
				    case LVN_ITEMACTIVATE:
				      RefreshStatusBar();
				      if (!alt && !ctrl && !shift)
				        OpenSelectedItems(true);
				      return false;
				    */
				
				    case NM_DBLCLK:
				      RefreshStatusBar();
				      OpenSelectedItems(true);
				      return false;
				    case NM_RETURN:
				    {
				      bool alt = (::GetKeyState(VK_MENU) & 0x8000) != 0;
				      bool ctrl = (::GetKeyState(VK_CONTROL) & 0x8000) != 0;
				      // bool leftCtrl = (::GetKeyState(VK_LCONTROL) & 0x8000) != 0;
				      // bool RightCtrl = (::GetKeyState(VK_RCONTROL) & 0x8000) != 0;
				      bool shift = (::GetKeyState(VK_SHIFT) & 0x8000) != 0;
				      if (!shift && alt && !ctrl)
				      {
				        Properties();
				        return false;
				      }
				      OpenSelectedItems(true);
				      return false;
				    }
				    case NM_RCLICK:
				      RefreshStatusBar();
				      break;
				
				    /*
				      return OnRightClick((LPNMITEMACTIVATE)header, result);
				    */
				      /*
				      case NM_CLICK:
				      SendRefreshStatusBarMessage();
				      return 0;
				      
				        // TODO : Handler default action...
				        return 0;
				        case LVN_ITEMCHANGED:
				        {
				        NMLISTVIEW *pNMLV = (NMLISTVIEW *) lpnmh;
				        SelChange(pNMLV);
				        return TRUE;
				        }
				        case NM_SETFOCUS:
				        return onSetFocus(NULL);
				        case NM_KILLFOCUS:
				        return onKillFocus(NULL);
				      */
				    case NM_CLICK:
				    {
				      // we need SetFocusToList, if we drag-select items from other panel.
				      SetFocusToList();
				      RefreshStatusBar();
				      if(_mySelectMode)
				        if(g_ComCtl32Version >= MAKELONG(71, 4))
				          OnLeftClick((LPNMITEMACTIVATE)header);
				      return false;
				    }
				    case LVN_BEGINLABELEDITW:
				      result = OnBeginLabelEdit((LV_DISPINFOW *)header);
				      return true;
				    case LVN_ENDLABELEDITW:
				      result = OnEndLabelEdit((LV_DISPINFOW *)header);
				      return true;
				
				    case NM_CUSTOMDRAW:
				    {
				      if (_mySelectMode)
				        return OnCustomDraw((LPNMLVCUSTOMDRAW)header, result);
				      break;
				    }
				    case LVN_BEGINDRAG:
				    {
				      OnDrag((LPNMLISTVIEW)header);
				      RefreshStatusBar();
				      break;
				    }
				    // case LVN_BEGINRDRAG:
				  }
				  return false;
				}
				
				bool CPanel::OnCustomDraw(LPNMLVCUSTOMDRAW lplvcd, LRESULT &result)
				{
				  switch(lplvcd->nmcd.dwDrawStage)
				  {
				  case CDDS_PREPAINT :
				    result = CDRF_NOTIFYITEMDRAW;
				    return true;
				    
				  case CDDS_ITEMPREPAINT:
				    /*
				    SelectObject(lplvcd->nmcd.hdc,
				    GetFontForItem(lplvcd->nmcd.dwItemSpec,
				    lplvcd->nmcd.lItemlParam) );
				    lplvcd->clrText = GetColorForItem(lplvcd->nmcd.dwItemSpec,
				    lplvcd->nmcd.lItemlParam);
				    lplvcd->clrTextBk = GetBkColorForItem(lplvcd->nmcd.dwItemSpec,
				    lplvcd->nmcd.lItemlParam);
				    */
				    int realIndex = (int)lplvcd->nmcd.lItemlParam;
				    bool selected = false;
				    if (realIndex != kParentIndex)
				      selected = _selectedStatusVector[realIndex];
				    if (selected)
				      lplvcd->clrTextBk = RGB(255, 192, 192);
				    // lplvcd->clrText = RGB(255, 0, 128);
				    else
				      lplvcd->clrTextBk = _listView.GetBkColor();
				    // lplvcd->clrText = RGB(0, 0, 0);
				    // result = CDRF_NEWFONT;
				    result = CDRF_NOTIFYITEMDRAW;
				    return true;
				    
				    // return false;
				    // return true;
				    /*
				    case CDDS_SUBITEM | CDDS_ITEMPREPAINT:
				    if (lplvcd->iSubItem == 0)
				    {
				    // lplvcd->clrText = RGB(255, 0, 0);
				    lplvcd->clrTextBk = RGB(192, 192, 192);
				    }
				    else
				    {
				    lplvcd->clrText = RGB(0, 0, 0);
				    lplvcd->clrTextBk = RGB(255, 255, 255);
				    }
				    return true;
				    */
				
				        /* At this point, you can change the background colors for the item
				        and any subitems and return CDRF_NEWFONT. If the list-view control
				        is in report mode, you can simply return CDRF_NOTIFYSUBITEMREDRAW
				        to customize the item's subitems individually */
				  }
				  return false;
				}
				
				void CPanel::OnRefreshStatusBar()
				{
				  CRecordVector indices;
				  GetOperatedItemIndices(indices);
				
				  _statusBar.SetText(0, MyFormatNew(IDS_N_SELECTED_ITEMS, 0x02000301, NumberToString(indices.Size())));
				
				  UString selectSizeString;
				
				  if (indices.Size() > 0)
				  {
				    UInt64 totalSize = 0;
				    for (int i = 0; i < indices.Size(); i++)
				      totalSize += GetItemSize(indices[i]);
				    selectSizeString = ConvertSizeToString(totalSize);
				  }
				  _statusBar.SetText(1, selectSizeString);
				
				  int focusedItem = _listView.GetFocusedItem();
				  UString sizeString;
				  UString dateString;
				  if (focusedItem >= 0 && _listView.GetSelectedCount() > 0)
				  {
				    int realIndex = GetRealItemIndex(focusedItem);
				    if (realIndex != kParentIndex)
				    {
				      sizeString = ConvertSizeToString(GetItemSize(realIndex));
				      NCOM::CPropVariant prop;
				      if (_folder->GetProperty(realIndex, kpidMTime, &prop) == S_OK)
				        dateString = ConvertPropertyToString(prop, kpidMTime, false);
				    }
				  }
				  _statusBar.SetText(2, sizeString);
				  _statusBar.SetText(3, dateString);
				  // _statusBar.SetText(4, nameString);
				  // _statusBar2.SetText(1, MyFormatNew(L"{0} bytes", NumberToStringW(totalSize)));
				}
							

相关资源