📄 disklistctrl.cpp
字号:
{
if (m_nMouseInCode>=100)
GetOwner()->SendMessage(WM_DISKLIST_NOTIFY, NULL,
(LPARAM)m_arrayFolder.GetAt(m_nMouseInCode-100));
else
GetOwner()->SendMessage(WM_DISKLIST_NOTIFY, NULL,
(LPARAM)m_arrayDrive.GetAt(m_nMouseInCode));
}
/*
CRect rcClient, rcItem;
GetClientRect(&rcClient);
if (n>=0)
GetItemRect(rcClient, rcItem, n, -1);
else
GetItemRect(rcClient, rcItem, -1, -n);
CString str;
str.Format("Item %d : %d,%d, %d, %d", m_nMouseInCode, rcItem.left, rcItem.top, rcItem.right, rcItem.bottom);
MessageBox(str);*/
}else
{
int nOld = m_nMouseInCode;
m_bMouseDown = FALSE;
m_nMouseInCode = 1000;
m_nMouseDownCode = 1000;
RedrawItem(nOld);
}
}
}else
{
m_bMouseDown = FALSE;
m_nMouseDownCode = 1000;
RedrawItem(m_nMouseInCode);
}
CWnd::OnLButtonUp(nFlags, point);
}
int CDiskListCtrl::HitTestEx(CPoint pt)
{
int nCount = m_arrayDrive.GetSize();
CRect rcClient, rcItem;
GetClientRect(&rcClient);
int nHeight;
if (nCount>0)
{
GetItemRect(rcClient, rcItem, 0, -1);
nHeight = rcItem.Height();
rcItem.bottom += nHeight*(nCount-1);
if (rcItem.PtInRect(pt))
return (pt.y - rcItem.top) / nHeight;
}
//Check Folders
nCount = m_arrayFolder.GetSize();
if (nCount>0)
{
GetItemRect(rcClient, rcItem, 100, -1);
nHeight = rcItem.Height();
rcItem.bottom += nHeight*(nCount-1);
if (rcItem.PtInRect(pt))
return ((pt.y - rcItem.top) / nHeight)+100;
}
/*
for (int i=0; i<nCount; i++)
{
GetItemRect(rcClient, rcItem, i+100, -1);
if (rcItem.PtInRect(pt))
return i+100;
}
*/
// Check Title bar
for (int i=1; i<7; i++)
{
GetItemRect(rcClient, rcItem, -1, i);
if (rcItem.PtInRect(pt))
return -i;
}
return 1000;
/* // nType -1 = titlebar
// nType -2 = All Drivebuttons
// nType -3 = total info button
// nType -4 = All folderbuttons
// nType -5 = Border rect
// nType 0- = for button number
CRect rcC(rcClient);
rcC.DeflateRect(1,1,1,1);
rc = rcC;
int nDriveSize = GetDriveSize();
int nHeight = GetItemHeight(rcClient);
int nTitleHeight = GetItemHeight(rcClient, TRUE);
switch (nType)
{
case -1:
rc.top = 0;
rc.bottom = nTitleHeight;
rc.left -= 1;
rc.right += 1;
break;
case -2:
rc.top = nTitleHeight + 1; // Plus border
rc.bottom = rc.top + nHeight*nDriveSize;
break;
case -3:
rc.top = nTitleHeight + 1 + nHeight*nDriveSize; // Plus border
rc.bottom = rc.top + nHeight;
rc.left -= 1;
rc.right += 1;
break;
case -4:
rc.top = nTitleHeight + 1 + nHeight*(nDriveSize+(nDriveSize!=0)); // Plus border
rc.bottom = rc.top + nHeight*GetFolderSize();
break;
case -5:
rc.top = nTitleHeight;
rc.bottom = rcC.bottom+1;
rc.left -= 1;
rc.right += 1;
break;
default:
if (nType>=100) // Folders
rc.top = nTitleHeight + 1 + nHeight*((nType-100)+(nDriveSize!=0)+nDriveSize);
else
rc.top = nTitleHeight + 1 + nHeight*nType;
rc.bottom = rc.top + nHeight;
}
if (nPos == -1)
return;
// nPos -1 = Max Width
// nPos 0-n = for every column
// nPos in percent
// 4 20 11 15 15,6 15,6 18,8
// 0 <= nCode <= 6
// Drive item rects
if (nType<100)
{
double dWidth[7] = {0.04, 0.242, 0.11, 0.156, 0.14, 0.156, 0.156};
double dOff = 0;
int nTotal = rcC.Width();
for (int i=0; i<nPos; i++)
dOff += nTotal*dWidth[i];
rc.left += (int)dOff;
if (nPos == 6) // Last
rc.right = rcC.right;
else
rc.right = rc.left + (int)(nTotal*dWidth[nPos]);
}else // Folder rects
{
double dWidth[6] = {0.04, 0.47, 0.13, 0.13, 0.13, 0.10};
double dOff = 0;
int nTotal = rcC.Width();
for (int i=0; i<nPos; i++)
dOff += nTotal*dWidth[i];
rc.left += (int)dOff;
if (nPos == 5) // Last
rc.right = rcC.right;
else
rc.right = rc.left + (int)(nTotal*dWidth[nPos]);
}*/
}
void CDiskListCtrl::RedrawItem(int i)
{
if (!(i<1000))
return;
CRect rcClient, rcItem;
GetClientRect(&rcClient);
if (i>=0)
{
GetItemRect(rcClient, rcItem, i, -1);
//rcItem.bottom +=2;
InvalidateRect(rcItem, FALSE);
return;
}
// Check Title bar
GetItemRect(rcClient, rcItem, -1, -i);
InvalidateRect(rcItem, FALSE);
}
void CDiskListCtrl::OnTimer(UINT nIDEvent)
{
if (m_nMouseInCode < 1000)
{
CPoint pt;
if (!GetCursorPos(&pt))
return;
ScreenToClient(&pt);
CRect rcClient;
GetClientRect(&rcClient);
if (!rcClient.PtInRect(pt))
{
KillTimer(5);
int nOld = m_nMouseInCode;
m_nMouseInCode = 1000;
//m_bMouseDown = FALSE;
//m_nMouseDownCode = 1000;
RedrawItem(nOld);
}
}
CWnd::OnTimer(nIDEvent);
}
void CDiskListCtrl::SortItems(int n)
{
int nSize = m_arrayDrive.GetSize();
if (nSize>0)
{
if (m_nSortCode == n)
m_nSortCode = -n;
else
m_nSortCode = n;
qsort((void*)(m_arrayDrive.GetData()),
((size_t)nSize),
sizeof(m_arrayDrive.GetAt(0)),
CompareItemSize);
InvalidateRect(NULL, FALSE);
}
}
int CDiskListCtrl::CompareItemSize(const void* f1, const void* f2)
{
CItemInfo* pItem1 = *(CItemInfo**)f1;
CItemInfo* pItem2 = *(CItemInfo**)f2;
if (!pItem2->m_bAvailable && abs(m_nSortCode)!=1)
return -1;
else if (!pItem1->m_bAvailable && abs(m_nSortCode)!=1)
return 1;
switch (m_nSortCode)
{
case 1:
return (long)pItem1->m_strDriveName.CompareNoCase(pItem2->m_strDriveName);
case 2:
return (long)pItem1->m_strPartitionType.CompareNoCase(pItem2->m_strPartitionType);
case 3: // Total
return (int)(pItem1->m_ldTotalSpace/1048576 - pItem2->m_ldTotalSpace/1048576);
case 4: //Usage
return (long)((pItem1->GetUsage() - pItem2->GetUsage())*100);
case 5: // Used
return (long)((pItem1->m_ldTotalSpace - pItem1->m_ldFreeSpace - pItem2->m_ldTotalSpace
+ pItem2->m_ldFreeSpace)/1048576);
case 6: // Free
return (long)((pItem1->m_ldFreeSpace - pItem2->m_ldFreeSpace)/1048576);
case -1:
return (long)pItem2->m_strDriveName.CompareNoCase(pItem1->m_strDriveName);
case -2:
return (long)pItem2->m_strPartitionType.CompareNoCase(pItem1->m_strPartitionType);
case -3: // Total
return (long)(pItem2->m_ldTotalSpace/1048576 - pItem1->m_ldTotalSpace/1048576);
case -4: //Usage
return (long)((pItem2->GetUsage() - pItem1->GetUsage())*100);
case -5: // Used
return (long)((pItem2->m_ldTotalSpace - pItem2->m_ldFreeSpace - pItem1->m_ldTotalSpace
+ pItem1->m_ldFreeSpace)/1048576);
case -6: // Free
return (long)((pItem2->m_ldFreeSpace - pItem1->m_ldFreeSpace)/1048576);
}
return 0;
}
int CDiskListCtrl::GetSize()
{
return m_arrayDrive.GetSize() + m_arrayFolder.GetSize();
}
double CDiskListCtrl::CItemInfo::GetUsage()
{
return (m_ldTotalSpace==0)?0:((m_ldTotalSpace-m_ldFreeSpace)/m_ldTotalSpace);
}
void CDiskListCtrl::CItemInfo::UpdateFolder(int nItemCode)
{
if (m_pThread)
return;
m_nFileCount = 0;
m_nFolderCount = 0;
m_ldTotalSpace = 0; // Numbers of files in folder mode
// Create a process to update folder info
THREADPARAMS* pThreadParams = new THREADPARAMS;
strcpy(pThreadParams->charPath, m_strDriveName);
pThreadParams->nItemCode = nItemCode;
pThreadParams->pnThreadCode = &m_nThreadCode;
pThreadParams->pnFileCount = &m_nFileCount;
pThreadParams->pnFolderCount = &m_nFolderCount;
pThreadParams->pldTotalSpace = &m_ldTotalSpace;
pThreadParams->lParam = (LPARAM)m_pCtrl;
m_pThread = AfxBeginThread(ThreadFunc, pThreadParams, THREAD_PRIORITY_BELOW_NORMAL);
//....
}
UINT CDiskListCtrl::CItemInfo::ThreadFunc(LPVOID pParam)
{
THREADPARAMS* pThreadParams = (THREADPARAMS*)pParam;
/*
CString strPath = pThreadParams->strPath;
int nItemCode = pThreadParams->nItemCode;
int* pnThreadCode = pThreadParams->pnThreadCode;
int* pnFileCount = pThreadParams->pnFileCount;
int* pnFolderCount = pThreadParams->pnFolderCount;
long double* pldTotalSpace = pThreadParams->pldTotalSpace;
CDiskListCtrl* pCtrl = (CDiskListCtrl*)pThreadParams->lParam;
*/
((CDiskListCtrl*)pThreadParams->lParam)->OnStartUpdate(pThreadParams->nItemCode);
UpdateDir(pThreadParams);
((CDiskListCtrl*)pThreadParams->lParam)->PostMessage(WM_DISKLIST_UPDATE, NULL,
LPARAM(pThreadParams->nItemCode));
((CDiskListCtrl*)pThreadParams->lParam)->OnFinishedUpdate(pThreadParams->nItemCode);
delete pThreadParams;
return 0;
}
void CDiskListCtrl::CItemInfo::UpdateDir(THREADPARAMS* pThreadParams)
{
HANDLE hFind;
WIN32_FIND_DATA fd;
char charCmp[MAX_PATH], charPath[MAX_PATH];
strcpy(charPath, pThreadParams->charPath);
strcpy(charCmp, charPath);
strcat(charCmp, "*.*");
if ((hFind = ::FindFirstFile ((LPCTSTR) charCmp, &fd)) ==
INVALID_HANDLE_VALUE)
{
return;
}
do {
if (*(pThreadParams->pnThreadCode) == -1)
break;
if (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
{
strcpy(charCmp, (LPCTSTR) &fd.cFileName);
if ((strcmp(charCmp, ".")!=0) && (strcmp(charCmp, "..")!=0))
{
(*(pThreadParams->pnFolderCount)) ++;
strcat(pThreadParams->charPath, charCmp);
strcat(pThreadParams->charPath, "\\");
UpdateDir(pThreadParams);
strcpy(pThreadParams->charPath, charPath);
}
}else
{
(*(pThreadParams->pnFileCount)) ++;
(*(pThreadParams->pldTotalSpace)) += fd.nFileSizeLow;
}
if (*(pThreadParams->pnThreadCode) == -1)
break;
if (((*(pThreadParams->pnFileCount))+(*(pThreadParams->pnFileCount))) % 299 == 0)
{
((CDiskListCtrl*)pThreadParams->lParam)->PostMessage(WM_DISKLIST_UPDATE, NULL,
LPARAM(pThreadParams->nItemCode));
//((CDiskListCtrl*)pThreadParams->lParam)->RedrawItem(pThreadParams->nItemCode);
Sleep(1);
}else
Sleep(0);
} while (::FindNextFile (hFind, &fd));
::FindClose (hFind);
}
void CDiskListCtrl::OnStopAll()
{
int nCount = m_arrayFolder.GetSize();
for (int i = 0; i < nCount; i++)
m_arrayFolder.GetAt(i)->StopThread();
}
void CDiskListCtrl::OnPause()
{
}
void CDiskListCtrl::OnFinishedUpdate(int n)
{
CItemInfo* pItem = m_arrayFolder.GetAt(n-100);
pItem ->m_nThreadCode = 1;
pItem ->m_pThread = NULL;
m_nNrThread --;
RedrawItem(n);
}
void CDiskListCtrl::OnStartUpdate(int n)
{
m_nNrThread ++;
}
void CDiskListCtrl::CItemInfo::StopThread()
{
if (m_pThread)
{
m_nThreadCode = -1;
HANDLE hThread = m_pThread->m_hThread;
::WaitForSingleObject(hThread, INFINITE);
m_pThread = NULL;
m_nFileCount = -1;
}
}
inline BOOL CDiskListCtrl::CItemInfo::GetFinished()
{
return m_nFileCount!=-1;
}
void CDiskListCtrl::UpdateAbortedFolders()
{
int nCount = m_arrayFolder.GetSize();
CItemInfo* pItem;
for (int i = 0; i < nCount; i++)
{
pItem = m_arrayFolder.GetAt(i);
if (!pItem->GetFinished())
pItem->UpdateFolder(i+100);
}
}
void CDiskListCtrl::OnItemUpdate(WPARAM wParam, LPARAM lParam)
{
RedrawItem((int)lParam);
}
void CDiskListCtrl::EmptyFolderArray()
{
int nCount = m_arrayFolder.GetSize();
for (int i = 0; i < nCount; i++)
delete m_arrayFolder.GetAt(i);
m_arrayFolder.RemoveAll();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -