// 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), 40);
const UString s = LangString(IDS_PLUGIN, 0x03010310);
_listViewExt.InsertColumn(1, s, 40);
_listViewPlugins.InsertColumn(0, s, 40);
_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)
_listViewExt.SetItemState_FocusedSelected(0);
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<IFolderManager> folderManager;
CMyComPtr<IFolderFolder> 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();
*/
#ifndef UNDER_CE
SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST, NULL, NULL);
WasChanged = true;
#endif
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;
_listViewPlugins.SetItemState_FocusedSelected(selectIndex);
}
_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;
*/