📄 searchlistctrl.cpp
字号:
cur_rec.left = iNextLeft;
}
else
{
cur_rec.right += cx;
DrawSourceChild(dc, iColumn, &cur_rec, content);
cur_rec.left += cx;
}
}
}
}
//draw rectangle around selected item(s)
if (content->GetListParent()==NULL && (lpDrawItemStruct->itemAction | ODA_SELECT) && (lpDrawItemStruct->itemState & ODS_SELECTED))
{
RECT outline_rec = lpDrawItemStruct->rcItem;
outline_rec.top--;
outline_rec.bottom++;
dc->FrameRect(&outline_rec, &CBrush(GetBkColor()));
outline_rec.top++;
outline_rec.bottom--;
outline_rec.left++;
outline_rec.right--;
if (notFirst && GetItemState(lpDrawItemStruct->itemID - 1, LVIS_SELECTED))
{
const CSearchFile* prev = (CSearchFile*)GetItemData(lpDrawItemStruct->itemID - 1);
if (prev->GetListParent()==NULL)
outline_rec.top--;
}
if (notLast && GetItemState(lpDrawItemStruct->itemID + 1, LVIS_SELECTED))
{
const CSearchFile* next = (CSearchFile*)GetItemData(lpDrawItemStruct->itemID + 1);
if (next->GetListParent()==NULL)
outline_rec.bottom++;
}
if (bCtrlFocused)
dc->FrameRect(&outline_rec, &CBrush(m_crFocusLine));
else
dc->FrameRect(&outline_rec, &CBrush(m_crNoFocusLine));
}
//draw focus rectangle around non-highlightable items when they have the focus
else if (GetFocus() == this && (lpDrawItemStruct->itemState & ODS_FOCUS) == ODS_FOCUS)
{
RECT focus_rec;
focus_rec.top = lpDrawItemStruct->rcItem.top;
focus_rec.bottom = lpDrawItemStruct->rcItem.bottom;
focus_rec.left = lpDrawItemStruct->rcItem.left + 1;
focus_rec.right = lpDrawItemStruct->rcItem.right - 1;
dc->FrameRect(&focus_rec, &CBrush(m_crNoFocusLine));
}
//draw tree last so it draws over selected and focus (looks better)
if(tree_start < tree_end)
{
//set new bounds
RECT tree_rect;
tree_rect.top = lpDrawItemStruct->rcItem.top;
tree_rect.bottom = lpDrawItemStruct->rcItem.bottom;
tree_rect.left = tree_start;
tree_rect.right = tree_end;
dc->SetBoundsRect(&tree_rect, DCB_DISABLE);
//gather some information
BOOL hasNext = notLast && ((const CSearchFile*)GetItemData(lpDrawItemStruct->itemID + 1))->GetListParent()!=NULL;
BOOL isOpenRoot = hasNext && content->GetListParent() == NULL;
BOOL isChild = content->GetListParent()!= NULL;
//might as well calculate these now
int treeCenter = tree_start + 4;
int middle = (cur_rec.top + cur_rec.bottom + 1) / 2;
//set up a new pen for drawing the tree
CPen pn, *oldpn;
pn.CreatePen(PS_SOLID, 1, RGB(128,128,128)/*m_crWindowText*/);
oldpn = dc->SelectObject(&pn);
if(isChild)
{
//draw the line to the status bar
dc->MoveTo(tree_end+10, middle);
dc->LineTo(tree_start + 4, middle);
//draw the line to the child node
if(hasNext)
{
dc->MoveTo(treeCenter, middle);
dc->LineTo(treeCenter, cur_rec.bottom + 1);
}
}
else if (isOpenRoot || (content->GetListParent() == NULL && content->GetListChildCount() > 1))
{
//draw box
RECT circle_rec;
circle_rec.top = middle - 5;
circle_rec.bottom = middle + 4;
circle_rec.left = treeCenter - 4;
circle_rec.right = treeCenter + 5;
dc->FrameRect(&circle_rec, &CBrush(RGB(128,128,128)/*m_crWindowText*/));
CPen penBlack;
penBlack.CreatePen(PS_SOLID, 1, m_crWindowText);
CPen* pOldPen2;
pOldPen2 = dc->SelectObject(&penBlack);
dc->MoveTo(treeCenter-2,middle - 1);
dc->LineTo(treeCenter+3,middle - 1);
if (!content->GetListIsExpanded())
{
dc->MoveTo(treeCenter,middle-3);
dc->LineTo(treeCenter,middle+2);
}
dc->SelectObject(pOldPen2);
//draw the line to the child node
if (hasNext)
{
dc->MoveTo(treeCenter, middle + 4);
dc->LineTo(treeCenter, cur_rec.bottom + 1);
}
}
//draw the line back up to parent node
if (notFirst && isChild)
{
dc->MoveTo(treeCenter, middle);
dc->LineTo(treeCenter, cur_rec.top - 1);
}
//put the old pen back
dc->SelectObject(oldpn);
pn.DeleteObject();
}
//put the original objects back
if (m_crWindowTextBk == CLR_NONE)
dc.SetBkMode(iOldBkMode);
dc->SelectObject(pOldFont);
dc->SetTextColor(crOldTextColor);
}
static COLORREF GetSearchItemColor(/*const*/ CSearchFile* src)
{
// default to black color (may be "corrected" below)
uint32 red = 0;
uint32 green = 0;
uint32 blue = 0;
const CKnownFile* pFile = theApp.downloadqueue->GetFileByID(src->GetFileHash());
if (pFile)
{
if (pFile->IsPartFile())
src->SetKnownType(CSearchFile::Downloading);
else
src->SetKnownType(CSearchFile::Shared);
red = 255;
}
else if (theApp.sharedfiles->GetFileByID(src->GetFileHash()))
{
src->SetKnownType(CSearchFile::Shared);
red = 255;
}
else if (theApp.knownfiles->FindKnownFileByID(src->GetFileHash()))
{
src->SetKnownType(CSearchFile::Downloaded);
green = 128;
}
else
{
// shade of blue = availability of the file
blue = src->GetSourceCount() == 0 ? 0 : ((src->GetSourceCount() - 1) * 20);
if (blue > 255)
blue = 255;
else if (blue == 0)
{
// avoid the worst case (drawing black text on black background) for users
// which are using extreme color schemes by eventually switching to default
// windows text color
COLORREF crText = ::GetSysColor(COLOR_WINDOWTEXT);
red = GetRValue(crText);
green = GetGValue(crText);
blue = GetBValue(crText);
}
}
return RGB(red, green, blue);
}
void CSearchListCtrl::DrawSourceChild(CDC *dc, int nColumn, LPRECT lpRect, /*const*/ CSearchFile* src)
{
if (!src)
return;
if (lpRect->left < lpRect->right)
{
CString buffer;
COLORREF crOldTextColor = dc->SetTextColor(GetSearchItemColor(src));
switch (nColumn)
{
case 0: // file name
lpRect->left += 30;
dc->DrawText(src->GetFileName(), src->GetFileName().GetLength(), lpRect, DLC_DT_TEXT);
lpRect->left -= 30;
break;
case 1: // file size
break;
case 2: // number of same filenames
buffer.Format(_T("%u"), src->GetListChildCount());
dc->DrawText(buffer,buffer.GetLength(), lpRect, DLC_DT_TEXT | DT_RIGHT);
break;
case 3:
break;
case 4: // file type
break;
case 5: // file hash
break;
case 6:
buffer = src->GetStrTagValue(FT_MEDIA_ARTIST);
dc->DrawText(buffer, buffer.GetLength(), lpRect, DLC_DT_TEXT);
break;
case 7:
buffer = src->GetStrTagValue(FT_MEDIA_ALBUM);
dc->DrawText(buffer, buffer.GetLength(), lpRect, DLC_DT_TEXT);
break;
case 8:
buffer = src->GetStrTagValue(FT_MEDIA_TITLE);
dc->DrawText(buffer, buffer.GetLength(), lpRect, DLC_DT_TEXT);
break;
case 9:{
uint32 nMediaLength = src->GetIntTagValue(FT_MEDIA_LENGTH);
if (nMediaLength){
SecToTimeLength(nMediaLength, buffer);
dc->DrawText(buffer, buffer.GetLength(), lpRect, DLC_DT_TEXT | DT_RIGHT);
}
break;
}
case 10:{
uint32 nBitrate = src->GetIntTagValue(FT_MEDIA_BITRATE);
if (nBitrate){
buffer.Format(_T("%u kBit/s"), nBitrate);
dc->DrawText(buffer, buffer.GetLength(), lpRect, DLC_DT_TEXT | DT_RIGHT);
}
break;
}
case 11:
buffer = src->GetStrTagValue(FT_MEDIA_CODEC);
dc->DrawText(buffer, buffer.GetLength(), lpRect, DLC_DT_TEXT);
break;
case 12: // dir
if (src->GetDirectory()){
buffer = src->GetDirectory();
dc->DrawText(buffer, buffer.GetLength(), lpRect, DLC_DT_TEXT);
}
break;
case 13:
if (src->m_eKnown == CSearchFile::Shared)
buffer = GetResString(IDS_SHARED);
else if (src->m_eKnown == CSearchFile::Downloading)
buffer = GetResString(IDS_DOWNLOADING);
else if (src->m_eKnown == CSearchFile::Downloaded)
buffer = GetResString(IDS_DOWNLOADED);
else
buffer.Empty();
dc->DrawText(buffer, buffer.GetLength(), lpRect, DLC_DT_TEXT);
break;
}
dc->SetTextColor(crOldTextColor);
}
}
void CSearchListCtrl::DrawSourceParent(CDC *dc, int nColumn, LPRECT lpRect, /*const*/ CSearchFile* src)
{
if (!src)
return;
if (lpRect->left < lpRect->right)
{
CString buffer;
COLORREF crOldTextColor = dc->SetTextColor(GetSearchItemColor(src));
switch (nColumn)
{
case 0: // file name
lpRect->left += 22;
dc->DrawText(src->GetFileName(), src->GetFileName().GetLength(), lpRect, DLC_DT_TEXT);
lpRect->left -= 22;
break;
case 1: // file size
buffer = CastItoXBytes(src->GetFileSize(), false, false);
dc->DrawText(buffer, buffer.GetLength(), lpRect, DLC_DT_TEXT | DT_RIGHT);
break;
case 2:{ // avail
uint32 nSources = src->GetSourceCount();
int iClients = src->GetClientsCount();
if ( thePrefs.IsExtControlsEnabled() && iClients > 0)
buffer.Format(_T("%u (%u)"), nSources, iClients);
else
buffer.Format(_T("%u"), nSources);
dc->DrawText(buffer, buffer.GetLength(), lpRect, DLC_DT_TEXT | DT_RIGHT);
break;
}
case 3:{ // complete sources
if (!src->IsKademlia()){
uint32 nSources = src->GetSourceCount();
uint32 uCompleteSources;
if ( (uCompleteSources = src->GetIntTagValue(FT_COMPLETE_SOURCES)) > 0 && nSources > 0){
buffer.Format(_T("%u%%"), (uCompleteSources*100)/nSources);
dc->DrawText(buffer, buffer.GetLength(), lpRect, DLC_DT_TEXT | DT_RIGHT);
}
else{
buffer = _T("0%");
COLORREF crColorBuffer = dc->SetTextColor(RGB(255,0,0));
dc->DrawText(buffer, buffer.GetLength(), lpRect, DLC_DT_TEXT | DT_RIGHT);
dc->SetTextColor(crColorBuffer);
}
}
else
dc->DrawText(_T("?"), 1, lpRect, DLC_DT_TEXT | DT_RIGHT);
break;
}
case 4: // file type
dc->DrawText(src->GetFileTypeDisplayStr(), src->GetFileTypeDisplayStr().GetLength(), lpRect, DLC_DT_TEXT);
break;
case 5: // file hash
buffer = md4str(src->GetFileHash());
dc->DrawText(buffer, buffer.GetLength(), lpRect, DLC_DT_TEXT);
break;
case 6:
buffer = src->GetStrTagValue(FT_MEDIA_ARTIST);
dc->DrawText(buffer, buffer.GetLength(), lpRect, DLC_DT_TEXT);
break;
case 7:
buffer = src->GetStrTagValue(FT_MEDIA_ALBUM);
dc->DrawText(buffer, buffer.GetLength(), lpRect, DLC_DT_TEXT);
break;
case 8:
buffer = src->GetStrTagValue(FT_MEDIA_TITLE);
dc->DrawText(buffer, buffer.GetLength(), lpRect, DLC_DT_TEXT);
break;
case 9:{
uint32 nMediaLength = src->GetIntTagValue(FT_MEDIA_LENGTH);
if (nMediaLength){
SecToTimeLength(nMediaLength, buffer);
dc->DrawText(buffer, buffer.GetLength(), lpRect, DLC_DT_TEXT | DT_RIGHT);
}
break;
}
case 10:{
uint32 nBitrate = src->GetIntTagValue(FT_MEDIA_BITRATE);
if (nBitrate){
buffer.Format(_T("%u kBit/s"), nBitrate);
dc->DrawText(buffer, buffer.GetLength(), lpRect, DLC_DT_TEXT | DT_RIGHT);
}
break;
}
case 11:
buffer = src->GetStrTagValue(FT_MEDIA_CODEC);
dc->DrawText(buffer, buffer.GetLength(), lpRect, DLC_DT_TEXT);
break;
case 12: // dir
if (src->GetDirectory()){
buffer = src->GetDirectory();
dc->DrawText(buffer, buffer.GetLength(), lpRect, DLC_DT_TEXT);
}
break;
case 13:
if (src->m_eKnown == CSearchFile::Shared)
buffer = GetResString(IDS_SHARED);
else if (src->m_eKnown == CSearchFile::Downloading)
buffer = GetResString(IDS_DOWNLOADING);
else if (src->m_eKnown == CSearchFile::Downloaded)
buffer = GetResString(IDS_DOWNLOADED);
else
buffer.Empty();
dc->DrawText(buffer, buffer.GetLength(), lpRect, DLC_DT_TEXT);
break;
}
dc->SetTextColor(crOldTextColor);
}
}
void CSearchListCtrl::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
{
if (nChar == 'C' && (GetKeyState(VK_CONTROL) & 0x8000))
{
// Ctrl+C: Copy listview items to clipboard
SendMessage(WM_COMMAND, MP_GETED2KLINK);
return;
}
CMuleListCtrl::OnKeyDown(nChar, nRepCnt, nFlags);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -