📄 fingerdlg.cpp
字号:
else
// It's an example case, so doesn't have a real threads handle
dwStatus = !STILL_ACTIVE;
if (dwStatus == STILL_ACTIVE)
{
// Perform thread termination,
// it automatically deletes threads object
pFingerThread->Terminate();
}
else
{
// Delete threads object, since it persists on heap
// if we don't call Terminate()
delete pFingerThread;
}
// Delete threads item
m_cInput.DeleteString(n);
}
void CFingerDlg::ShowResult()
{
int n = m_iCurrentItem;
// Save user input
UpdateData();
// Show selected item progress
if( n )
{
// View specific thread
// Get associated threads object
CFingerThread *pFingerThread = static_cast<CFingerThread*>(m_cInput.GetItemDataPtr( n ));
// Show threads progress
m_sOutput = pFingerThread->Result();
}
else
// View all threads
m_sOutput = m_sResult;
// Refresh back
UpdateData(FALSE);
}
// Called from any spawned thread
//
void CFingerDlg::ProcessThread(void* pThread, const CString& sMsg, bool bState)
{
// Enter critical section
m_CritSection.Lock();
// Update summary
m_sResult.Insert(0,sMsg);
// Update view if need
if( m_iCurrentItem == 0 ||
m_cInput.GetItemDataPtr( m_iCurrentItem ) == pThread )
PostMessage( WM_THREAD_EVENT, 1 );
// Leave critical section
m_CritSection.Unlock();
}
// Called from any spawned thread
//
void CFingerDlg::ProcessThreadExit()
{
PostMessage( WM_THREAD_EVENT );
}
LRESULT CFingerDlg::OnThreadEvent(WPARAM wParam, LPARAM lParam)
{
if( wParam ) ShowResult(); // Update output
else UpdateTitleDec(); // One thread terminated
return 0;
}
void CFingerDlg::OnSelchangeCombo()
{
// Get selection
int n = m_cInput.GetCurSel(); if( n == CB_ERR ) return;
m_iCurrentItem = n;
ShowResult();
}
// Button handlers
//
void CFingerDlg::OnAbout()
{
CAboutDlg dlgAbout;
dlgAbout.DoModal();
}
void CFingerDlg::OnOptions()
{
// Get cursor position
POINT pt;
::GetCursorPos(&pt);
// Track menu
CMenu &menu = *m_cMenu.GetSubMenu(0);
menu.TrackPopupMenu( TPM_LEFTALIGN |TPM_RIGHTBUTTON, pt.x, pt.y, this);
}
// Menu handlers
//
void CFingerDlg::OnOptionsViewSummary()
{
// Flip state
m_bViewSummary = !m_bViewSummary;
// Check/uncheck menu
CMenu &menu = *m_cMenu.GetSubMenu(0);
menu.CheckMenuItem( 0, MF_BYPOSITION |(m_bViewSummary ? MF_CHECKED : MF_UNCHECKED));
// Test critical sections
#if 0
static bool b = true;
if( b )
{
// Suspend results output
m_CritSection.Lock();
}
else
{
// Resume results output
m_CritSection.Unlock();
}
b != b;
#endif
}
void CFingerDlg::OnOptionsCleanSummary()
{
// Enter critical section
m_CritSection.Lock();
// Clean summary
m_sResult.Empty();
m_sOutput.Empty();
UpdateData(FALSE);
// Leave critical section
m_CritSection.Unlock();
}
void CFingerDlg::OnOptionsRefreshCurrent()
{
// Get user input
CString sInput;
m_cInput.GetWindowText(sInput);
if( sInput.IsEmpty()) return;
// Find that string
int n = m_cInput.FindStringExact(1, sInput);
// Nothing found
if( n == CB_ERR )
{
if( AfxMessageBox( CString("There are no such query: '") +
sInput + "'. Submit?", MB_YESNO) == IDYES )
Finger(sInput);
return;
}
// If summary
if( n == 0 ) // Show summary
{
m_iCurrentItem = 0; ShowResult();
return;
}
// Corresponding item's been found
RemoveQuery(n);
// Restart thread
Finger(sInput);
}
void CFingerDlg::OnOptionsDeleteCurrent()
{
// Get user input
CString sInput;
m_cInput.GetWindowText(sInput);
if( sInput.IsEmpty()) return;
// Find that string
int n = m_cInput.FindStringExact(1, sInput);
// Nothing found
if( n == CB_ERR )
{
AfxMessageBox( CString("There are no such query: '") + sInput + "'." );
return;
}
// If summary
if( n == 0 )
{
AfxMessageBox("Summary can't be deleted.");
return;
}
// Corresponding item's been found
RemoveQuery(n);
// Set selection to summary
m_cInput.SetCurSel(0);
m_iCurrentItem = 0;
ShowResult();
}
void CFingerDlg::OnOptionsDeleteAll()
{
if( AfxMessageBox( "Really cancel all queries?", MB_YESNO) == IDNO ) return;
// It's important to go down, to escape mess
for( int i = m_cInput.GetCount()-1; i > 0; i-- ) RemoveQuery(i);
// Set selection to summary
m_cInput.SetCurSel(0);
m_iCurrentItem = 0;
ShowResult();
}
void CFingerDlg::OnOptionsRefreshAll()
{
for( int i = 1; i < m_cInput.GetCount(); i++ )
{
// Get query string
CString tmp;
m_cInput.GetLBText( i, tmp );
// Remove query
RemoveQuery(i);
// Submit it again
Finger(tmp);
}
// Set selection to summary
m_cInput.SetCurSel(0);
m_iCurrentItem = 0;
ShowResult();
}
void CFingerDlg::OnOptionsAbout()
{
OnAbout();
}
// Update title procedures
//
void CFingerDlg::UpdateTitleInc()
{
// Increase threads count
m_iActiveThreads++;
// Update title
CString str;
str.Format("Finger - %d active queries", m_iActiveThreads );
SetWindowText(str);
}
void CFingerDlg::UpdateTitleDec()
{
// Decrease threads count
m_iActiveThreads--;
CString str;
// Update title
if( m_iActiveThreads )
str.Format("Finger - %d active queries", m_iActiveThreads );
else
str = "Finger - waiting for a query";
SetWindowText(str);
}
// Initialize static members
//
const CString CFingerDlg::ms_sExamples[] =
{
"@mit.edu",
"alexv@mit.edu"
};
// Verify if a request is from an examples list
// if so, execute it and invalidate as example,
// so it becomes an ordinary request
bool CFingerDlg::IsExample(const CString &sInput)
{
static bool abExState[2] = { true, true };
if( abExState[0] && sInput == ms_sExamples[0] )
{
abExState[0] = false; // Not an example after we've tried it
return true;
}
if( abExState[1] && sInput == ms_sExamples[1] )
{
abExState[1] = false; // Not an example after we've tried it
return true;
}
return false;
}
// Help handlers
//
void CFingerDlg::OnHelp()
{
const char *asLocations[] = { "finger.hlp", "hlp\\finger.hlp", "..\\hlp\\finger.hlp" };
// Check possible locations of hlp file
for( int i = 0; i < 3; i++ )
if( ::GetFileAttributes( asLocations[i] ) != -1 ) break;
// If failed to find file, invoke help anyway
if( i >= 3 ) i = 0;
// Invoke help
::WinHelp( m_hWnd, asLocations[i], HELP_INDEX, 0 );
}
void CFingerDlg::OnOptionsHelp()
{
OnHelp();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -