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

📄 mulelistctrl.cpp

📁 另外一款开放源码的高质量p2p源码软件
💻 CPP
📖 第 1 页 / 共 3 页
字号:
//this file is part of eMule
//Copyright (C)2002 Merkur ( merkur-@users.sourceforge.net / http://www.emule-project.net )
//
//This program is free software; you can redistribute it and/or
//modify it under the terms of the GNU General Public License
//as published by the Free Software Foundation; either
//version 2 of the License, or (at your option) any later version.
//
//This program is distributed in the hope that it will be useful,
//but WITHOUT ANY WARRANTY; without even the implied warranty of
//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//GNU General Public License for more details.
//
//You should have received a copy of the GNU General Public License
//along with this program; if not, write to the Free Software
//Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#include "stdafx.h"
#include "emule.h"
#include "MemDC.h"
#include "MuleListCtrl.h"
#include "Ini2.h"
#include "SharedFilesCtrl.h"
#include "SearchListCtrl.h"
#include "KadContactListCtrl.h"
#include "KadSearchListCtrl.h"
#include "DownloadListCtrl.h"
#include "UploadListCtrl.h"
#include "QueueListCtrl.h"
#include "ClientListCtrl.h"
#include "FriendListCtrl.h"
#include "ServerListCtrl.h"
#include "MenuCmds.h"
#include "OtherFunctions.h"
#include "ListViewSearchDlg.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif


#define MLC_BLEND(A, B, X) ((A + B * (X-1) + ((X+1)/2)) / X)

#define MLC_RGBBLEND(A, B, X) (                   \
	RGB(MLC_BLEND(GetRValue(A), GetRValue(B), X), \
	MLC_BLEND(GetGValue(A), GetGValue(B), X),     \
	MLC_BLEND(GetBValue(A), GetBValue(B), X))     \
)

#define MLC_DT_TEXT (DT_SINGLELINE | DT_NOPREFIX | DT_VCENTER | DT_END_ELLIPSIS)

#define MLC_IDC_MENU	4875
#define MLC_IDC_UPDATE	(MLC_IDC_MENU - 1)

//a value that's not a multiple of 4 and uncommon
#define MLC_MAGIC 0xFEEBDEEF

//used for very slow assertions
//#define MLC_ASSERT(f)	ASSERT(f)
#define MLC_ASSERT(f)	((void)0)

#ifndef HDM_SETBITMAPMARGIN
#define HDM_SETBITMAPMARGIN	(HDM_FIRST + 20)
#define HDM_GETBITMAPMARGIN	(HDM_FIRST + 21)
#endif

//////////////////////////////////
// CMuleListCtrl

IMPLEMENT_DYNAMIC(CMuleListCtrl, CListCtrl)
CMuleListCtrl::CMuleListCtrl(PFNLVCOMPARE pfnCompare, DWORD dwParamSort) {
	m_SortProc = pfnCompare;
	m_dwParamSort = dwParamSort;

	m_bCustomDraw = false;
	m_iCurrentSortItem = -1;
	m_iColumnsTracked = 0;
	m_aColumns = NULL;
	m_iRedrawCount = 0;

	//just in case
    m_crWindow = 0;
    m_crWindowText = 0;
	m_crWindowTextBk = m_crWindow;
    m_crHighlight = 0;
	m_crGlow=0;
    m_crFocusLine = 0;
    m_crNoHighlight = 0;
    m_crNoFocusLine = 0;
	m_bGeneralPurposeFind = false;
    m_bFindMatchCase = false;
    m_iFindDirection = 1;
    m_iFindColumn = 0;
}

CMuleListCtrl::~CMuleListCtrl() {
	if(m_aColumns != NULL)
		delete[] m_aColumns;
}

int CMuleListCtrl::SortProc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort) {
	return 0;
}

void CMuleListCtrl::SetName(LPCTSTR lpszName) {
	m_Name = lpszName;
}

void CMuleListCtrl::PreSubclassWindow() {
	SetColors();
	CListCtrl::PreSubclassWindow();
	ModifyStyle(LVS_SINGLESEL|LVS_LIST|LVS_ICON|LVS_SMALLICON,LVS_REPORT|LVS_SINGLESEL|LVS_REPORT);
	SetExtendedStyle(LVS_EX_HEADERDRAGDROP);
}

int CMuleListCtrl::IndexToOrder(CHeaderCtrl* pHeader, int iIndex) {
	int iCount = pHeader->GetItemCount();
	int *piArray = new int[iCount];
	Header_GetOrderArray( pHeader->m_hWnd, iCount, piArray);
	for(int i=0; i < iCount; i++ ) {
		if(piArray[i] == iIndex) {
			delete[] piArray;
			return i;
		}
	}
	delete[] piArray;
	return -1;
}

void CMuleListCtrl::HideColumn(int iColumn) {
	CHeaderCtrl* pHeaderCtrl = GetHeaderCtrl();
	int iCount = pHeaderCtrl->GetItemCount();
	if(iColumn < 1 || iColumn >= iCount || m_aColumns[iColumn].bHidden)
		return;

	//stop it from redrawing
	SetRedraw(FALSE);

	//shrink width to 0
	HDITEM item;
	item.mask = HDI_WIDTH;
	pHeaderCtrl->GetItem(iColumn, &item);
	m_aColumns[iColumn].iWidth = item.cxy;
	item.cxy = 0;
	pHeaderCtrl->SetItem(iColumn, &item);

	//move to front of list
	INT *piArray = new INT[m_iColumnsTracked];
	pHeaderCtrl->GetOrderArray(piArray, m_iColumnsTracked);

	int iFrom = m_aColumns[iColumn].iLocation;
	for(int i = 0; i < m_iColumnsTracked; i++)
		if(m_aColumns[i].iLocation > m_aColumns[iColumn].iLocation && m_aColumns[i].bHidden)
			iFrom++;

	for(int i = iFrom; i > 0; i--)
		piArray[i] = piArray[i - 1];
	piArray[0] = iColumn;
	pHeaderCtrl->SetOrderArray(m_iColumnsTracked, piArray);
	delete[] piArray;

	//update entry
	m_aColumns[iColumn].bHidden = true;

	//redraw
	SetRedraw(TRUE);
	Invalidate(FALSE);
}

void CMuleListCtrl::ShowColumn(int iColumn) {
	CHeaderCtrl* pHeaderCtrl = GetHeaderCtrl();
	int iCount = pHeaderCtrl->GetItemCount();
	if(iColumn < 1 || iColumn >= iCount || !m_aColumns[iColumn].bHidden)
		return;

	//stop it from redrawing
	SetRedraw(FALSE);

	//restore position in list
	INT *piArray = new INT[m_iColumnsTracked];
	pHeaderCtrl->GetOrderArray(piArray, m_iColumnsTracked);
	int iCurrent = IndexToOrder(pHeaderCtrl, iColumn);

	for(; iCurrent < IndexToOrder(pHeaderCtrl, 0) && iCurrent < m_iColumnsTracked - 1; iCurrent++ )
		piArray[iCurrent] = piArray[iCurrent + 1];
	for(; m_aColumns[iColumn].iLocation > m_aColumns[pHeaderCtrl->OrderToIndex(iCurrent + 1)].iLocation &&
	      iCurrent < m_iColumnsTracked - 1; iCurrent++)
		piArray[iCurrent] = piArray[iCurrent + 1];
	piArray[iCurrent] = iColumn;
	pHeaderCtrl->SetOrderArray(m_iColumnsTracked, piArray);
	delete[] piArray;

	//and THEN restore original width
	HDITEM item;
	item.mask = HDI_WIDTH;
	item.cxy = m_aColumns[iColumn].iWidth;
	pHeaderCtrl->SetItem(iColumn, &item);

	//update entry
	m_aColumns[iColumn].bHidden = false;

	//redraw
	SetRedraw(TRUE);
	Invalidate(FALSE);
}

void CMuleListCtrl::SaveSettings(CPreferences::Table tID) {
	INT *piArray = new INT[m_iColumnsTracked];

	for(int i = 0; i < m_iColumnsTracked; i++) {
		thePrefs.SetColumnWidth(tID, i, GetColumnWidth(i));
		thePrefs.SetColumnHidden(tID, i, IsColumnHidden(i));
		piArray[i] = m_aColumns[i].iLocation;
	}

	thePrefs.SetColumnOrder(tID, piArray);
	delete[] piArray;
}

void CMuleListCtrl::SaveSettings(CIni* ini, LPCTSTR pszLVName)
{
	int* piColWidths = new int[m_iColumnsTracked];
	int* piColHidden = new int[m_iColumnsTracked];
	INT *piColOrders = new INT[m_iColumnsTracked];

	for(int i = 0; i < m_iColumnsTracked; i++)
	{
		piColWidths[i] = GetColumnWidth(i);
		piColHidden[i] = IsColumnHidden(i);
		piColOrders[i] = m_aColumns[i].iLocation;
	}

	ini->SerGet(false, piColWidths, m_iColumnsTracked, CString(pszLVName) + _T("ColumnWidths"));
	ini->SerGet(false, piColHidden, m_iColumnsTracked, CString(pszLVName) + _T("ColumnHidden"));
	ini->SerGet(false, piColOrders, m_iColumnsTracked, CString(pszLVName) + _T("ColumnOrders"));

	delete[] piColOrders;
	delete[] piColWidths;
	delete[] piColHidden;
}

void CMuleListCtrl::LoadSettings(CPreferences::Table tID) {
	CHeaderCtrl* pHeaderCtrl = GetHeaderCtrl();

	INT *piArray = new INT[m_iColumnsTracked];
	for(int i = 0; i < m_iColumnsTracked; i++)
		piArray[i] = i;

	for(int i = 0; i < m_iColumnsTracked; i++) {
		int iWidth = thePrefs.GetColumnWidth(tID, i);
		if(iWidth >= 2) // don't allow column widths of 0 and 1 -- just because it looks very confusing in GUI
			SetColumnWidth(i, iWidth);
		if(i == 0) {
			piArray[0] = 0;
		} else {
			int iOrder = thePrefs.GetColumnOrder(tID, i);
			if(iOrder > 0 && iOrder < m_iColumnsTracked && iOrder != i)
				piArray[iOrder] = i;
		}
	}

	pHeaderCtrl->SetOrderArray(m_iColumnsTracked, piArray);
	pHeaderCtrl->GetOrderArray(piArray, m_iColumnsTracked);
	for(int i = 0; i < m_iColumnsTracked; i++)
		m_aColumns[piArray[i]].iLocation = i;

	delete[] piArray;

	for(int i = 1; i < m_iColumnsTracked; i++) {
		if(thePrefs.GetColumnHidden(tID, i))
			HideColumn(i);
	}
}

void CMuleListCtrl::LoadSettings(CIni* ini, LPCTSTR pszLVName)
{
	CHeaderCtrl* pHeaderCtrl = GetHeaderCtrl();

	int* piColWidths = new int[m_iColumnsTracked];
	int* piColHidden = new int[m_iColumnsTracked];
	int* piColOrders = new int[m_iColumnsTracked];
	ini->SerGet(true, piColWidths, m_iColumnsTracked, CString(pszLVName) + _T("ColumnWidths"));
	ini->SerGet(true, piColHidden, m_iColumnsTracked, CString(pszLVName) + _T("ColumnHidden"));
	ini->SerGet(true, piColOrders, m_iColumnsTracked, CString(pszLVName) + _T("ColumnOrders"));

	INT *piArray = new INT[m_iColumnsTracked];
	for (int i = 0; i < m_iColumnsTracked; i++)
		piArray[i] = i;

	for (int i = 0; i < m_iColumnsTracked; i++)
	{
		int iWidth = piColWidths[i];
		if (iWidth >= 2) // don't allow column widths of 0 and 1 -- just because it looks very confusing in GUI
			SetColumnWidth(i, iWidth);
		if (i == 0) {
			piArray[0] = 0;
		}
		else {
			int iOrder = piColOrders[i];
			if (iOrder > 0 && iOrder < m_iColumnsTracked && iOrder != i)
				piArray[iOrder] = i;
		}
	}

	pHeaderCtrl->SetOrderArray(m_iColumnsTracked, piArray);
	pHeaderCtrl->GetOrderArray(piArray, m_iColumnsTracked);
	for(int i = 0; i < m_iColumnsTracked; i++)
		m_aColumns[piArray[i]].iLocation = i;

	delete[] piArray;

	for(int i = 1; i < m_iColumnsTracked; i++) {
		if (piColHidden[i])
			HideColumn(i);
	}

	delete[] piColOrders;
	delete[] piColWidths;
	delete[] piColHidden;
}

void CMuleListCtrl::SetColors(LPCTSTR pszLvKey) {
	m_crWindow      = ::GetSysColor(COLOR_WINDOW);
	m_crWindowText  = ::GetSysColor(COLOR_WINDOWTEXT);
	m_crWindowTextBk = m_crWindow;

	COLORREF crHighlight = ::GetSysColor(COLOR_HIGHLIGHT);

	CString strBkImage;
	LPCTSTR pszSkinProfile = thePrefs.GetSkinProfile();
	if (pszSkinProfile != NULL && pszSkinProfile[0] != _T('\0'))
	{
		CString strKey;
		if (pszLvKey != NULL && pszLvKey[0] != _T('\0'))
			strKey = pszLvKey;
		else if (IsKindOf(RUNTIME_CLASS(CServerListCtrl)))
			strKey = _T("ServersLv");
		else if (IsKindOf(RUNTIME_CLASS(CSearchListCtrl)))
			strKey = _T("SearchResultsLv");
		else if (IsKindOf(RUNTIME_CLASS(CDownloadListCtrl)))
			strKey = _T("DownloadsLv");
		else if (IsKindOf(RUNTIME_CLASS(CUploadListCtrl)))
			strKey = _T("UploadsLv");
		else if (IsKindOf(RUNTIME_CLASS(CQueueListCtrl)))
			strKey = _T("QueuedLv");
		else if (IsKindOf(RUNTIME_CLASS(CClientListCtrl)))
			strKey = _T("ClientsLv");
		else if (IsKindOf(RUNTIME_CLASS(CFriendListCtrl)))
			strKey = _T("FriendsLv");
		else if (IsKindOf(RUNTIME_CLASS(CSharedFilesCtrl)))
			strKey = _T("SharedFilesLv");
		else if (IsKindOf(RUNTIME_CLASS(CKadContactListCtrl)))
			strKey = _T("KadContactsLv");
		else if (IsKindOf(RUNTIME_CLASS(CKadSearchListCtrl)))
			strKey = _T("KadActionsLv");
		else
			GetWindowText(strKey);

		if (strKey.IsEmpty())
			strKey = _T("DefLv");

		TCHAR szColor[MAX_PATH];
		GetPrivateProfileString(_T("Colors"), strKey + _T("Bk"), _T(""), szColor, ARRSIZE(szColor), pszSkinProfile);
		if (szColor[0] == _T('\0'))
			GetPrivateProfileString(_T("Colors"), _T("DefLvBk"), _T(""), szColor, ARRSIZE(szColor), pszSkinProfile);
		if (szColor[0] != _T('\0'))
		{
			UINT red, grn, blu;
			int iVals = _stscanf(szColor, _T("%i , %i , %i"), &red, &grn, &blu);
			if (iVals == 3)
			{
				m_crWindow = RGB(red, grn, blu);
				m_crWindowTextBk = m_crWindow;
			}
		}

		GetPrivateProfileString(_T("Colors"), strKey + _T("Fg"), _T(""), szColor, ARRSIZE(szColor), pszSkinProfile);
		if (szColor[0] == _T('\0'))
			GetPrivateProfileString(_T("Colors"), _T("DefLvFg"), _T(""), szColor, ARRSIZE(szColor), pszSkinProfile);
		if (szColor[0] != _T('\0'))
		{
			UINT red, grn, blu;
			int iVals = _stscanf(szColor, _T("%i , %i , %i"), &red, &grn, &blu);
			if (iVals == 3)
				m_crWindowText = RGB(red, grn, blu);
		}

		GetPrivateProfileString(_T("Colors"), strKey + _T("Hl"), _T(""), szColor, ARRSIZE(szColor), pszSkinProfile);
		if (szColor[0] == _T('\0'))
			GetPrivateProfileString(_T("Colors"), _T("DefLvHl"), _T(""), szColor, ARRSIZE(szColor), pszSkinProfile);
		if (szColor[0] != _T('\0'))
		{
			UINT red, grn, blu;
			int iVals = _stscanf(szColor, _T("%i , %i , %i"), &red, &grn, &blu);
			if (iVals == 3)
				crHighlight = RGB(red, grn, blu);
		}

		GetPrivateProfileString(_T("Colors"), strKey + _T("BkImg"), _T(""), szColor, ARRSIZE(szColor), pszSkinProfile);
		if (szColor[0] == _T('\0'))
			GetPrivateProfileString(_T("Colors"), _T("DefLvBkImg"), _T(""), szColor, ARRSIZE(szColor), pszSkinProfile);
		if (szColor[0] != _T('\0'))
			strBkImage = szColor;
	}
	SetBkColor(m_crWindow);
	SetTextBkColor(m_crWindowTextBk);
	SetTextColor(m_crWindowText);
	LVBKIMAGE lvimg = {0};
	lvimg.ulFlags = LVBKIF_SOURCE_NONE;
	SetBkImage(&lvimg);
	if (!strBkImage.IsEmpty())
	{
		// expand any optional available environment strings
		TCHAR szExpSkinRes[MAX_PATH];
		if (ExpandEnvironmentStrings(strBkImage, szExpSkinRes, ARRSIZE(szExpSkinRes)) != 0)
			strBkImage = szExpSkinRes;

		// create absolute path to icon resource file
		TCHAR szFullResPath[MAX_PATH];
		if (PathIsRelative(strBkImage))
		{
			TCHAR szSkinResFolder[MAX_PATH];
			_tcsncpy(szSkinResFolder, pszSkinProfile, ARRSIZE(szSkinResFolder));
			szSkinResFolder[ARRSIZE(szSkinResFolder)-1] = _T('\0');
			PathRemoveFileSpec(szSkinResFolder);
			_tmakepath(szFullResPath, NULL, szSkinResFolder, strBkImage, NULL);
		}
		else
		{
			_tcsncpy(szFullResPath, strBkImage, ARRSIZE(szFullResPath));
			szFullResPath[ARRSIZE(szFullResPath)-1] = _T('\0');
		}

		CString strUrl(_T("file://"));
		strUrl += szFullResPath;
		if (SetBkImage(const_cast<LPTSTR>((LPCTSTR)strUrl), FALSE, 0, 0))
		{
			m_crWindowTextBk = CLR_NONE;
			SetTextBkColor(m_crWindowTextBk);
		}
	}

	m_crFocusLine   = crHighlight;
	m_crNoHighlight = MLC_RGBBLEND(crHighlight, m_crWindow, 8);
	m_crNoFocusLine = MLC_RGBBLEND(crHighlight, m_crWindow, 2);
	m_crHighlight   = MLC_RGBBLEND(crHighlight, m_crWindow, 4);
	m_crGlow		= MLC_RGBBLEND(crHighlight, m_crWindow, 3);
}

void CMuleListCtrl::SetSortArrow(int iColumn, ArrowType atType) {
	HDITEM headerItem;
	headerItem.mask = HDI_FORMAT;
	CHeaderCtrl* pHeaderCtrl = GetHeaderCtrl();

	if(iColumn != m_iCurrentSortItem) {
		pHeaderCtrl->GetItem(m_iCurrentSortItem, &headerItem);
		headerItem.fmt &= ~(HDF_IMAGE | HDF_BITMAP_ON_RIGHT);
		pHeaderCtrl->SetItem(m_iCurrentSortItem, &headerItem);
		m_iCurrentSortItem = iColumn;
		m_imlHeaderCtrl.DeleteImageList();
	}

	//place new arrow unless we were given an invalid column
	if(iColumn >= 0 && pHeaderCtrl->GetItem(iColumn, &headerItem)) {

⌨️ 快捷键说明

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