// SystemPage.cpp #include "StdAfx.h" #include "SystemPageRes.h" #include "SystemPage.h" #include "Common/StringConvert.h" #include "Common/MyCom.h" #include "Windows/Defs.h" #include "Windows/Control/ListView.h" #include "Windows/FileFind.h" #include "IFolder.h" #include "HelpUtils.h" #include "LangUtils.h" #include "PluginLoader.h" #include "ProgramLocation.h" #include "StringUtils.h" #include "PropertyNameRes.h" #include "../Agent/Agent.h" using namespace NRegistryAssociations; const int kRefreshpluginsListMessage = WM_USER + 1; const int kUpdateDatabase = kRefreshpluginsListMessage + 1; static CIDLangPair kIDLangPairs[] = { { IDC_SYSTEM_STATIC_ASSOCIATE, 0x03010302}, { IDC_SYSTEM_SELECT_ALL, 0x03000330} }; static LPCWSTR kSystemTopic = L"FM/options.htm#system"; bool CSystemPage::OnInit() { _initMode = true; LangSetDlgItemsText(HWND(*this), kIDLangPairs, sizeof(kIDLangPairs) / sizeof(kIDLangPairs[0])); _listViewExt.Attach(GetItem(IDC_SYSTEM_LIST_ASSOCIATE)); _listViewPlugins.Attach(GetItem(IDC_SYSTEM_LIST_PLUGINS)); /* CheckButton(IDC_SYSTEM_INTEGRATE_TO_CONTEXT_MENU, NRegistryAssociations::CheckContextMenuHandler()); */ UINT32 newFlags = LVS_EX_CHECKBOXES | LVS_EX_FULLROWSELECT; _listViewExt.SetExtendedListViewStyle(newFlags, newFlags); _listViewPlugins.SetExtendedListViewStyle(newFlags, newFlags); _listViewExt.InsertColumn(0, LangString(IDS_PROP_EXTENSION, 0x02000205), 70); const UString s = LangString(IDS_PLUGIN, 0x03010310); _listViewExt.InsertColumn(1, s, 70); _listViewPlugins.InsertColumn(0, s, 70); _extDatabase.Read(); for (int i = 0; i < _extDatabase.ExtBigItems.Size(); i++) { CExtInfoBig &extInfo = _extDatabase.ExtBigItems[i]; int itemIndex = _listViewExt.InsertItem(i, (LPCWSTR)extInfo.Ext); UString iconPath; int iconIndex; extInfo.Associated = NRegistryAssociations::CheckShellExtensionInfo(GetSystemString(extInfo.Ext), iconPath, iconIndex); if (extInfo.Associated && !NWindows::NFile::NFind::DoesFileExist(iconPath)) extInfo.Associated = false; _listViewExt.SetCheckState(itemIndex, extInfo.Associated); SetMainPluginText(itemIndex, i); } // _listViewExt.SortItems(); if(_listViewExt.GetItemCount() > 0) { UINT state = LVIS_SELECTED | LVIS_FOCUSED; _listViewExt.SetItemState(0, state, state); } RefreshPluginsList(-1); _initMode = false; return CPropertyPage::OnInit(); } void CSystemPage::SetMainPluginText(int itemIndex, int indexInDatabase) { _listViewExt.SetSubItem(itemIndex, 1, _extDatabase.GetMainPluginNameForExtItem(indexInDatabase)); } static UString GetProgramCommand() { UString path = L"\""; UString folder; if (GetProgramFolderPath(folder)) path += folder; path += L"7zFM.exe\" \"%1\""; return path; } static UString GetIconPath(const UString &filePath, const CLSID &clsID, const UString &extension, Int32 &iconIndex) { CPluginLibrary library; CMyComPtr folderManager; CMyComPtr folder; if (filePath.IsEmpty()) folderManager = new CArchiveFolderManager; else if (library.LoadAndCreateManager(filePath, clsID, &folderManager) != S_OK) return UString(); CMyComBSTR extBSTR; if (folderManager->GetExtensions(&extBSTR) != S_OK) return UString(); const UString ext2 = (const wchar_t *)extBSTR; UStringVector exts; SplitString(ext2, exts); for (int i = 0; i < exts.Size(); i++) { const UString &plugExt = exts[i]; if (extension.CompareNoCase((const wchar_t *)plugExt) == 0) { CMyComBSTR iconPathTemp; if (folderManager->GetIconPath(plugExt, &iconPathTemp, &iconIndex) != S_OK) break; if (iconPathTemp != 0) return (const wchar_t *)iconPathTemp; } } return UString(); } LONG CSystemPage::OnApply() { UpdateDatabase(); _extDatabase.Save(); UString command = GetProgramCommand(); for (int i = 0; i < _extDatabase.ExtBigItems.Size(); i++) { const CExtInfoBig &extInfo = _extDatabase.ExtBigItems[i]; if (extInfo.Associated) { UString title = extInfo.Ext + UString(L" Archive"); UString command = GetProgramCommand(); UString iconPath; Int32 iconIndex = -1; if (!extInfo.PluginsPairs.IsEmpty()) { const CPluginInfo &plugin = _extDatabase.Plugins[extInfo.PluginsPairs[0].Index]; iconPath = GetIconPath(plugin.FilePath, plugin.ClassID, extInfo.Ext, iconIndex); } NRegistryAssociations::AddShellExtensionInfo(GetSystemString(extInfo.Ext), title, command, iconPath, iconIndex, NULL, 0); } else NRegistryAssociations::DeleteShellExtensionInfo(GetSystemString(extInfo.Ext)); } /* if (IsButtonCheckedBool(IDC_SYSTEM_INTEGRATE_TO_CONTEXT_MENU)) NRegistryAssociations::AddContextMenuHandler(); else NRegistryAssociations::DeleteContextMenuHandler(); */ SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST, NULL, NULL); return PSNRET_NOERROR; } void CSystemPage::OnNotifyHelp() { ShowHelpWindow(NULL, kSystemTopic); } void CSystemPage::SelectAll() { int count = _listViewExt.GetItemCount(); for (int i = 0; i < count; i++) _listViewExt.SetCheckState(i, true); UpdateDatabase(); } bool CSystemPage::OnButtonClicked(int buttonID, HWND buttonHWND) { switch(buttonID) { case IDC_SYSTEM_SELECT_ALL: { SelectAll(); Changed(); return true; } } return CPropertyPage::OnButtonClicked(buttonID, buttonHWND); } bool CSystemPage::OnNotify(UINT controlID, LPNMHDR lParam) { if (lParam->hwndFrom == HWND(_listViewExt)) { switch(lParam->code) { case (LVN_ITEMCHANGED): return OnItemChanged((const NMLISTVIEW *)lParam); case NM_RCLICK: case NM_DBLCLK: case LVN_KEYDOWN: case NM_CLICK: case LVN_BEGINRDRAG: PostMessage(kRefreshpluginsListMessage, 0); PostMessage(kUpdateDatabase, 0); break; } } else if (lParam->hwndFrom == HWND(_listViewPlugins)) { switch(lParam->code) { case NM_RCLICK: case NM_DBLCLK: // case LVN_KEYDOWN: case NM_CLICK: case LVN_BEGINRDRAG: PostMessage(kUpdateDatabase, 0); break; case (LVN_ITEMCHANGED): { OnItemChanged((const NMLISTVIEW *)lParam); PostMessage(kUpdateDatabase, 0); break; } case LVN_KEYDOWN: { OnPluginsKeyDown((LPNMLVKEYDOWN)lParam); PostMessage(kUpdateDatabase, 0); break; } } } return CPropertyPage::OnNotify(controlID, lParam); } bool CSystemPage::OnPluginsKeyDown(LPNMLVKEYDOWN keyDownInfo) { bool alt = (::GetKeyState(VK_MENU) & 0x8000) != 0; // bool ctrl = (::GetKeyState(VK_CONTROL) & 0x8000) != 0; switch(keyDownInfo->wVKey) { case VK_UP: { if (alt) MovePlugin(true); return true; } case VK_DOWN: { if (alt) MovePlugin(false); return true; } } return false; } void CSystemPage::MovePlugin(bool upDirection) { int selectedPlugin = _listViewPlugins.GetSelectionMark(); if (selectedPlugin < 0) return; int newIndex = selectedPlugin + (upDirection ? -1: 1); if (newIndex < 0 || newIndex >= _listViewPlugins.GetItemCount()) return; int selectedExtIndex = GetSelectedExtIndex(); if (selectedExtIndex < 0) return; CExtInfoBig &extInfo = _extDatabase.ExtBigItems[selectedExtIndex]; CPluginEnabledPair pluginPairTemp = extInfo.PluginsPairs[newIndex]; extInfo.PluginsPairs[newIndex] = extInfo.PluginsPairs[selectedPlugin]; extInfo.PluginsPairs[selectedPlugin] = pluginPairTemp; SetMainPluginText(_listViewExt.GetSelectionMark(), selectedExtIndex); RefreshPluginsList(newIndex); Changed(); } bool CSystemPage::OnItemChanged(const NMLISTVIEW *info) { if (_initMode) return true; if ((info->uChanged & LVIF_STATE) != 0) { UINT oldState = info->uOldState & LVIS_STATEIMAGEMASK; UINT newState = info->uNewState & LVIS_STATEIMAGEMASK; if (oldState != newState) Changed(); } // PostMessage(kRefreshpluginsListMessage, 0); // RefreshPluginsList(); return true; } bool CSystemPage::OnMessage(UINT message, WPARAM wParam, LPARAM lParam) { switch(message) { case kRefreshpluginsListMessage: RefreshPluginsList(-1); return true; case kUpdateDatabase: UpdateDatabase(); return true; } return CPropertyPage::OnMessage(message, wParam, lParam); } void CSystemPage::UpdateDatabase() { int i; for (i = 0; i < _listViewExt.GetItemCount(); i++) { LPARAM param; if (!_listViewExt.GetItemParam(i, param)) return; CExtInfoBig &extInfo = _extDatabase.ExtBigItems[(int)param]; extInfo.Associated = _listViewExt.GetCheckState(i); } int selectedExtIndex = GetSelectedExtIndex(); if (selectedExtIndex < 0) return; CExtInfoBig &extInfo = _extDatabase.ExtBigItems[selectedExtIndex]; for (i = 0; i < _listViewPlugins.GetItemCount(); i++) { extInfo.PluginsPairs[i].Enabled = _listViewPlugins.GetCheckState(i); } } int CSystemPage::GetSelectedExtIndex() { int selectedIndex = _listViewExt.GetSelectionMark(); if (selectedIndex < 0) return -1; LPARAM param; if (!_listViewExt.GetItemParam(selectedIndex, param)) return -1; return (int)param; } void CSystemPage::RefreshPluginsList(int selectIndex) { _listViewPlugins.DeleteAllItems(); int selectedExtIndex = GetSelectedExtIndex(); if (selectedExtIndex < 0) return; const CExtInfoBig &extInfo = _extDatabase.ExtBigItems[selectedExtIndex]; _initMode = true; for (int i = 0; i < extInfo.PluginsPairs.Size(); i++) { CPluginEnabledPair pluginPair = extInfo.PluginsPairs[i]; int itemIndex = _listViewPlugins.InsertItem(i, _extDatabase.Plugins[pluginPair.Index].Name); _listViewPlugins.SetCheckState(itemIndex, pluginPair.Enabled); } if(_listViewPlugins.GetItemCount() > 0) { if (selectIndex < 0) selectIndex = 0; UINT state = LVIS_SELECTED | LVIS_FOCUSED; _listViewPlugins.SetItemState(selectIndex, state, state); } _initMode = false; } /* static BYTE kZipShellNewData[] = { 0x50-1, 0x4B, 5, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0 }; static BYTE kRarShellNewData[] = { 0x52-1, 0x61, 0x72, 0x21, 0x1A, 7, 0, 0xCF, 0x90, 0x73, 0, 0, 0x0D, 0, 0, 0, 0, 0, 0, 0}; class CSignatureMaker { public: CSignatureMaker() { kZipShellNewData[0]++; kRarShellNewData[0]++; }; }; static CSignatureMaker g_SignatureMaker; */