|
|
//=============================================================================*
// COPYRIGHT� 2001 Microsoft Corporation and Executive Software International, Inc.
//=============================================================================*
// File: DfrgCtl.cpp
//=============================================================================*
//#define ESI_MULTI_ALLOWED
#include "stdafx.h"
#define GLOBAL_DATAHOME
#ifndef SNAPIN
#ifndef NOWINDOWSH
#include <windows.h>
#endif
#endif
#include <commctrl.h>
#include <htmlhelp.h>
#include "adminprivs.h"
extern "C" { #include "SysStruc.h"
}
#include "DfrgCmn.h"
#include "DfrgEngn.h"
#include "DiskDisp.h"
#include "DfrgUI.h"
#include "DfrgCtl.h"
#include "DataIo.h"
#include "DataIoCl.h"
#include "ListView.h"
#include "ErrMacro.h"
#include "ErrMsg.h"
#include "Graphix.h"
#include "DfrgRes.h"
#include "EsButton.h"
#include "DlgRpt.h"
#include "DfrgRes.h"
#include "GetDfrgRes.h"
#include "IntFuncs.h"
#include "VolList.h"
#include "VolCom.h"
#include "MIMessage.h"
#include "adminprivs.h"
#include <algorithm>
#include "secattr.h"
#define NUM_ACCELERATORS 5
#ifndef SM_REMOTESESSION
#define SM_REMOTESESSION 0x1000
#endif
#define MULTI_INSTANCE_TIMER 1000
#define PING_TIMER 3000
static const MI_TIMER_ID = 1; static const LISTVIEW_TIMER_ID = 2; static const PING_TIMER_ID = 3;
BOOL CALLBACK TabEnumChildren( HWND hwnd, LPARAM lParam );
//-------------------------------------------------------------------*
// function: CDfrgCtl::
//
// returns: None
// note:
//-------------------------------------------------------------------*
CDfrgCtl::CDfrgCtl() : m_VolumeList( this ), m_ListView ( this ) { ATLTRACE( _T( "Creating defrag control.\n" ) );
m_bStart = TRUE; m_bNeedMultiInstanceMessage = TRUE; m_bNeedIllegalVolumeMessage = FALSE; m_dwInstanceRegister = 0; m_hIsOkToRunSemaphore = NULL;
// Determine if we're the first instance of the control running.
m_IsOkToRun = IsOnlyInstance();
if ( m_IsOkToRun ) { //
// Register the dataio with the system.
//
m_dwInstanceRegister = InitializeDataIo( CLSID_DfrgCtlDataIo, REGCLS_MULTIPLEUSE ); }
m_LegendHeight = 34; m_FontHeight = 0; // calculated later
m_LegendTextSpacer = 0; // calculated later
m_LegendTopSpace = 10; m_EtchedLineOffset = 5; #ifdef ESI_PROGRESS_BAR
m_ProgressBarOffset = 7; // offset top and bottom in legend window
m_ProgressBarLength = 121; #endif
m_Margin = 14; m_GraphicWellHeight = 40; m_LegendGraphicSpacer = 5; m_LegendTextWidth = 0; // calculated later
m_BitmapVOffset = 0; // calculated later
m_ButtonTopBottomSpacer = 14; m_ButtonHeight = 26; m_ButtonWidth = 84; m_ButtonSpacer = 6; m_GraphicWellSpacer = 40; m_hFont = NULL;
m_bHaveButtons = FALSE; m_pAnalyzeButton = (ESButton *) NULL; m_pDefragButton = (ESButton *) NULL; m_pPauseButton = (ESButton *) NULL; m_pStopButton = (ESButton *) NULL; m_pReportButton = (ESButton *) NULL; m_pLegend = (CBmp *) NULL;
ZeroMemory(&rcLegendBG, sizeof(RECT)); ZeroMemory(&rcReportButton, sizeof(RECT));
// Initialize the legend.
INT_PTR iBmp[20];
if(SIMPLE_DISPLAY){ iBmp[0] = (INT_PTR)MAKEINTRESOURCE(IDB_FRAGMENTED_FILES); iBmp[1] = (INT_PTR)MAKEINTRESOURCE(IDB_CONTIGUOUS_FILES); iBmp[2] = (INT_PTR)MAKEINTRESOURCE(IDB_SYSTEM_FILES); iBmp[3] = (INT_PTR)MAKEINTRESOURCE(IDB_FREE_SPACE); m_pLegend = new CBmp(GetDfrgResHandle(), iBmp, 4); EV_ASSERT(m_pLegend); // load the strings into all the text strings
m_LegendData[0].text.LoadString(IDS_FRAGMENTED_FILES, GetDfrgResHandle()); m_LegendData[1].text.LoadString(IDS_CONTIGUOUS_FILES, GetDfrgResHandle()); m_LegendData[2].text.LoadString(IDS_SYSTEM_FILES, GetDfrgResHandle()); m_LegendData[3].text.LoadString(IDS_FREE_SPACE, GetDfrgResHandle()); } else{ iBmp[0] = (INT_PTR)MAKEINTRESOURCE(IDB_SYSTEM_FILES); iBmp[1] = (INT_PTR)MAKEINTRESOURCE(IDB_RESERVED_SPACE); iBmp[2] = (INT_PTR)MAKEINTRESOURCE(IDB_PAGE_FILE); iBmp[3] = (INT_PTR)MAKEINTRESOURCE(IDB_DIRECTORY_FILES); iBmp[4] = (INT_PTR)MAKEINTRESOURCE(IDB_FRAGMENTED_FILES); iBmp[5] = (INT_PTR)MAKEINTRESOURCE(IDB_CONTIGUOUS_FILES); iBmp[6] = (INT_PTR)MAKEINTRESOURCE(IDB_FREE_SPACE); m_pLegend = new CBmp(GetDfrgResHandle(), iBmp, 7); EV_ASSERT(m_pLegend); m_LegendData[0].text.LoadString(IDS_SYSTEM_FILES, GetDfrgResHandle()); m_LegendData[1].text.LoadString(IDS_RESERVED_SPACE, GetDfrgResHandle()); m_LegendData[2].text.LoadString(IDS_PAGE_FILE, GetDfrgResHandle()); m_LegendData[3].text.LoadString(IDS_DIRECTORY_FILES, GetDfrgResHandle()); m_LegendData[3].text.LoadString(IDS_FRAGMENTED_FILES, GetDfrgResHandle()); m_LegendData[3].text.LoadString(IDS_CONTIGUOUS_FILES, GetDfrgResHandle()); m_LegendData[3].text.LoadString(IDS_FREE_SPACE, GetDfrgResHandle()); } }
//-------------------------------------------------------------------*
// function: CDfrgCtl::~CDfrgCtl
//
// returns: None
// note:
//-------------------------------------------------------------------*
CDfrgCtl::~CDfrgCtl() { CVolume *pVolume = m_VolumeList.GetCurrentVolume(); if (pVolume) { pVolume->StoppedByUser(TRUE); }
DestroyButtons();
if(m_pLegend){ delete m_pLegend; }
::DeleteObject(m_hFont);
//
// Remove our instance handler.
//
if ( m_dwInstanceRegister ) CoRevokeClassObject( m_dwInstanceRegister );
if(m_hIsOkToRunSemaphore) { if (m_IsOkToRun) { // this would increment the count, and make the semaphore seem like
// is was available (signaled). Only do this if this is the running instance
ReleaseSemaphore(m_hIsOkToRunSemaphore, 1, NULL); } CloseHandle(m_hIsOkToRunSemaphore); }
return; }
//-------------------------------------------------------------------*
// function: CDfrgCtl::OnClose
//
// returns: None
// note:
//-------------------------------------------------------------------*
HRESULT CDfrgCtl::OnClose(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& lResult){ return S_OK; }
//-------------------------------------------------------------------*
// function: CDfrgCtl::InterfaceSupportsErrorInfo
//
// returns: None
// note:
//-------------------------------------------------------------------*
STDMETHODIMP CDfrgCtl::InterfaceSupportsErrorInfo(REFIID riid) { static const IID* arr[] = { &IID_IDfrgCtl,};
for (int i=0;i<sizeof(arr)/sizeof(arr[0]);i++) { if (InlineIsEqualGUID(*arr[i],riid)) return S_OK; } return S_FALSE; }
//-------------------------------------------------------------------*
// function: CDfrgCtl::OnNotify
//
// returns: None
// note:
//-------------------------------------------------------------------*
HRESULT CDfrgCtl::OnNotify(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& lResult) { m_ListView.NotifyListView(lParam);
return S_OK; }
//-------------------------------------------------------------------*
// function: CDfrgCtl::OnCommand
//
// returns: None
// note:
//-------------------------------------------------------------------*
HRESULT CDfrgCtl::OnCommand(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& lResult) { switch (LOWORD(wParam)) {
case ID_ANALYZE: put_Command(ID_ANALYZE); break;
case ID_DEFRAG: put_Command(ID_DEFRAG); break;
case ID_PAUSE: put_Command(ID_PAUSE); break;
case ID_STOP: put_Command(ID_STOP); break;
case ID_REFRESH: put_Command(ID_REFRESH); break;
case ID_HELP_CONTENTS: put_Command(ID_HELP_CONTENTS); break;
case ID_REPORT: { // is the engine IDLE?
CVolume *pVolume = m_VolumeList.GetCurrentVolume(); if (pVolume){ if(pVolume->EngineState() == ENGINE_STATE_IDLE){ RaiseReportDialog(pVolume); ::SetFocus(m_pReportButton->GetWindowHandle()); } } } break; } return S_OK; }
//-------------------------------------------------------------------*
// function: CDfrgCtl::OnSize
//
// returns: None
// note:
//-------------------------------------------------------------------*
HRESULT CDfrgCtl::OnSize(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& lResult) { TCHAR msg[200]; _stprintf(msg, TEXT("CDfrgCtl::OnSize() lParam LO=%d, HI=%d"), LOWORD(lParam), HIWORD(lParam)); Message(msg, -1, NULL);
//Zero is passed in the first time this function is called. This puts incorrect data into
//the rectangles below for a fraction of a second. Probably harmless, but better safe than sorry.
if(!lParam) { ZeroMemory(&m_rcCtlRect, sizeof(RECT)); return S_OK; }
m_rcCtlRect.top = 0; m_rcCtlRect.left = 0; m_rcCtlRect.right = LOWORD(lParam); m_rcCtlRect.bottom = HIWORD(lParam);
SizeWindow();
return S_OK; }
//-------------------------------------------------------------------*
// function: CDfrgCtl::SizeWindow
//
// returns: None
// note:
//-------------------------------------------------------------------*
HRESULT CDfrgCtl::SizeWindow() { TCHAR msg[200]; _stprintf(msg, TEXT("CDfrgCtl::SizeWindow() m_bStart=%d"), m_bStart); Message(msg, -1, NULL);
if( m_bStart) {
NONCLIENTMETRICS ncm; ncm.cbSize = sizeof(ncm);
::SystemParametersInfo (SPI_GETNONCLIENTMETRICS, sizeof (ncm), &ncm, 0); ncm.lfMenuFont.lfWeight = FW_NORMAL; m_hFont = ::CreateFontIndirect(&ncm.lfMenuFont); m_FontHeight = -ncm.lfMenuFont.lfHeight;
EH_ASSERT(m_hFont);
VString windowText(IDS_DK_TITLE, GetDfrgResHandle()); SetWindowText(windowText.GetBuffer());
CreateButtons();
// Initialize list view and graphix windows.
m_ListView.InitializeListView(&m_VolumeList, m_hWndCD, _Module.GetModuleInstance());
// Display the drives available in the listview.
m_ListView.GetDrivesToListView();
// get the first drive hilited (check command line)
m_ListView.SelectInitialListViewDrive(&m_bNeedIllegalVolumeMessage);
// Hide or show the listview
m_ListView.EnableWindow(m_IsOkToRun);
// get the buttons enabled/disables properly
SetButtonState();
//Set the multi-instance timer.
SetTimer(MI_TIMER_ID, MULTI_INSTANCE_TIMER, NULL);
//Set the list view timer.
SetTimer(LISTVIEW_TIMER_ID, m_VolumeList.GetRefreshInterval(), NULL);
//Set the ping timer.
SetTimer(PING_TIMER_ID, PING_TIMER, NULL);
m_bStart = FALSE; }
// size the legend and progress bar
SizeLegend();
// Size the buttons
SizeButtons();
m_pAnalyzeButton->ShowButton(SW_SHOW); m_pDefragButton->ShowButton(SW_SHOW); m_pReportButton->ShowButton(SW_SHOW); m_pPauseButton->ShowButton(SW_SHOW); m_pStopButton->ShowButton(SW_SHOW); ::SetFocus(m_pAnalyzeButton->GetWindowHandle()); // Now size the graphics window.
SizeGraphicsWindow();
// size the list view (he gets the screen that is left over)
rcListView.bottom = rcGraphicsBG.top; rcListView.top = 0; rcListView.left = 0; rcListView.right = m_rcCtlRect.right;
// Now size the listview
m_ListView.SizeListView( rcListView.left, rcListView.top, rcListView.right - rcListView.left, // width
rcListView.bottom - rcListView.top); // height
Invalidate(FALSE);
return S_OK; }
//-------------------------------------------------------------------*
// function: CDfrgCtl::OnEraseBkgnd
//
// returns: None
// note:
//-------------------------------------------------------------------*
HRESULT CDfrgCtl::OnEraseBkgnd(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& lResult) { return S_OK; }
//-------------------------------------------------------------------*
// function: CDfrgCtl::RefreshListViewRow
//
// returns: None
// note:
//-------------------------------------------------------------------*
HRESULT CDfrgCtl::RefreshListViewRow(CVolume *pVolume) { // refresh this row of the list view
m_ListView.Update(pVolume); return S_OK; }
//-------------------------------------------------------------------*
// function: CDfrgCtl::OnPaint
//
// returns: None
// note:
//-------------------------------------------------------------------*
HRESULT CDfrgCtl::OnPaint(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& lResult) { PAINTSTRUCT paintStruct; HDC OutputDC = BeginPaint(&paintStruct);
// Paint the various windows.
if (OutputDC){ DrawLegend(OutputDC); #ifdef ESI_PROGRESS_BAR
DrawProgressBar(OutputDC); #endif
PaintGraphicsWindow(OutputDC); DrawButtons(OutputDC); }
EndPaint(&paintStruct);
// display the multi-instance screen if needed
if (!m_IsOkToRun && m_bNeedMultiInstanceMessage){ m_bNeedMultiInstanceMessage = FALSE;
if (CheckForAdminPrivs() == FALSE) { SetLastError(ESI_VOLLIST_ERR_NON_ADMIN); VString title(IDS_DK_TITLE, GetDfrgResHandle()); VString msg(IDS_NEED_ADMIN_PRIVS, GetDfrgResHandle()); MessageBox(msg.GetBuffer(), title.GetBuffer(), MB_OK|MB_ICONWARNING); } else if (!RaiseMIDialog(m_hWndCD)) { ATLTRACE( _T( "MI Dialog failed\n" ) ); } }
// display the illegal volume dialog if needed
if (m_bNeedIllegalVolumeMessage) {
// don't need to do it again
m_bNeedIllegalVolumeMessage = FALSE;
// warn user he can't defrag illegal volume
VString title(IDS_DK_TITLE, GetDfrgResHandle()); VString msg(IDS_VOLUME_TYPE_NOT_SUPPORTED, GetDfrgResHandle()); MessageBox(msg.GetBuffer(), title.GetBuffer(), MB_OK | MB_ICONWARNING); }
return S_OK; }
//-------------------------------------------------------------------*
// function: CDfrgCtl::OnTimer
//
// returns: None
// note:
//-------------------------------------------------------------------*
HRESULT CDfrgCtl::OnTimer(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& lResult) { switch (wParam) { // This timer checks the multi-instance semaphore
case MI_TIMER_ID:
// if we are in a Terminal Server session, don't change anything
// if (GetSystemMetrics(SM_REMOTESESSION)){
// return S_OK;
//}
//
// Refresh whether or not we're the only instance.
//
if ( m_IsOkToRun == FALSE ) { m_IsOkToRun = IsOnlyInstance(); if ( m_IsOkToRun == TRUE ) { m_dwInstanceRegister = InitializeDataIo( CLSID_DfrgCtlDataIo, REGCLS_MULTIPLEUSE );
SetButtonState();
// Hide or show the listview
m_ListView.EnableWindow(m_IsOkToRun);
// Send OKToRun property change to advises.
SendOKToRun( TRUE );
Invalidate(TRUE); } }
KillTimer(MI_TIMER_ID);
SetTimer(MI_TIMER_ID, MULTI_INSTANCE_TIMER, NULL); break;
// This timer refreshes the list view
case LISTVIEW_TIMER_ID:
KillTimer(LISTVIEW_TIMER_ID);
m_ListView.GetDrivesToListView();
SetTimer(LISTVIEW_TIMER_ID, m_VolumeList.GetRefreshInterval(), NULL); break;
// This timer pings the engine
case PING_TIMER_ID: { KillTimer(PING_TIMER_ID);
CVolume *pVolume; for (UINT ii = 0; ii < m_VolumeList.GetVolumeCount(); ii++) { pVolume = (CVolume *) m_VolumeList.GetVolumeAt(ii); if (pVolume) { pVolume->PingEngine(); } }
SetTimer(PING_TIMER_ID, PING_TIMER, NULL); break; }
default: EE_ASSERT(FALSE); break; }
return S_OK; }
//-------------------------------------------------------------------*
// function: CDfrgCtl::get_EngineState
//
// returns: None
// note:
//-------------------------------------------------------------------*
STDMETHODIMP CDfrgCtl::get_EngineState(short * pVal) { // sets pVal to current engine state
CVolume *pVolume = m_VolumeList.GetCurrentVolume(); if (pVolume) { *pVal = (short) pVolume->EngineState(); } else { *pVal = 0; } return S_OK; }
//-------------------------------------------------------------------*
// function: CDfrgCtl::get_IsEngineRunning
//
// returns: None
// note:
//-------------------------------------------------------------------*
STDMETHODIMP CDfrgCtl::get_IsEngineRunning(BOOL *pVal) { // TRUE or FALSE whether current engine is running
CVolume *pVolume = m_VolumeList.GetCurrentVolume(); if (pVolume) { *pVal = (pVolume->EngineState() == ENGINE_STATE_RUNNING); } else { *pVal = FALSE; } return S_OK; }
//-------------------------------------------------------------------*
// function: CDfrgCtl::get_IsOkToRun
//
// returns: None
// note:
//-------------------------------------------------------------------*
STDMETHODIMP CDfrgCtl::get_IsOkToRun(BOOL *pVal) { *pVal = m_IsOkToRun;
return S_OK; }
//-------------------------------------------------------------------*
// function: CDfrgCtl::get_IsEnginePaused
//
// returns: None
// note:
//-------------------------------------------------------------------*
STDMETHODIMP CDfrgCtl::get_IsEnginePaused(BOOL *pVal) { // TRUE or FALSE whether current engine is paused
CVolume *pVolume = m_VolumeList.GetCurrentVolume(); if (pVolume) { *pVal = pVolume->Paused(); } else { *pVal = FALSE; } return S_OK; }
//-------------------------------------------------------------------*
// function: CDfrgCtl::get_IsDefragInProcess
//
// returns: None
// note:
//-------------------------------------------------------------------*
STDMETHODIMP CDfrgCtl::get_IsDefragInProcess(BOOL *pVal) { // TRUE or FALSE whether any engine is running
*pVal = m_VolumeList.DefragInProcess(); return S_OK; }
//-------------------------------------------------------------------*
// function: CDfrgCtl::get_IsVolListLocked
//
// returns: None
// note:
//-------------------------------------------------------------------*
STDMETHODIMP CDfrgCtl::get_IsVolListLocked(BOOL *pVal) { // TRUE or FALSE if current volume is locked
*pVal = m_VolumeList.Locked(); return S_OK; }
//-------------------------------------------------------------------*
// function: CDfrgCtl::get_ReportStatus
//
// returns: None
// note:
//-------------------------------------------------------------------*
STDMETHODIMP CDfrgCtl::get_ReportStatus(BOOL * pVal) { CVolume *pVolume = m_VolumeList.GetCurrentVolume(); if (pVolume) { *pVal = pVolume->IsReportOKToDisplay(); } else { *pVal = FALSE; }
return S_OK; }
//-------------------------------------------------------------------*
// function: CDfrgCtl::get_Command
//
// returns: None
// note:
//-------------------------------------------------------------------*
STDMETHODIMP CDfrgCtl::get_Command(short * pVal) { // not used so far
return S_OK; }
//-------------------------------------------------------------------*
// function: CDfrgCtl::put_Command
//
// returns: None
// note:
//-------------------------------------------------------------------*
STDMETHODIMP CDfrgCtl::put_Command(short newVal) { // get a pointer to the current volume
CVolume *pVolume = m_VolumeList.GetCurrentVolume(); if (pVolume == (CVolume *) NULL) { return S_OK; }
switch (newVal){ case ID_REFRESH: // Display the drives available in the listview.
m_ListView.GetDrivesToListView(); Invalidate(TRUE); break;
case ID_REPORT: pVolume->ShowReport(); ::SetFocus(m_pReportButton->GetWindowHandle()); break;
case ID_HELP_CONTENTS: HtmlHelp( m_hWndCD, TEXT("defrag.chm::/defrag_overview.htm"), HH_DISPLAY_TOPIC, //HH_TP_HELP_CONTEXTMENU,
NULL); //(DWORD)(LPVOID)myarray);
break;
case ID_STOP: m_ListView.SetFocus(); // list box gets focus
pVolume->StopEngine(); break;
case ID_ABORT: pVolume->AbortEngine(); break;
case ID_PAUSE: pVolume->PauseEngine(); break;
case ID_CONTINUE: if (!pVolume->ContinueEngine()){ if (GetLastError() == ESI_VOLLIST_ERR_MUST_RESTART){ VString msg(IDS_MUST_RESTART, GetDfrgResHandle()); VString title(IDS_DK_TITLE, GetDfrgResHandle()); MessageBox(msg.GetBuffer(), title.GetBuffer(), MB_OK|MB_ICONWARNING); } } break;
case ID_ANALYZE: m_ListView.SetFocus(); // list box gets focus
m_VolumeList.Locked(TRUE); pVolume->Analyze(); m_VolumeList.Locked(FALSE); break;
case ID_DEFRAG: m_ListView.SetFocus(); // list box gets focus
m_VolumeList.Locked(TRUE); pVolume->Defragment(); m_VolumeList.Locked(FALSE); break;
default: return S_OK;
}
SetButtonState();
return S_OK; }
//-------------------------------------------------------------------*
// function: CDfrgCtl::CreateButtons
//
// returns: None
// note:
//-------------------------------------------------------------------*
HRESULT CDfrgCtl::CreateButtons(void) { m_pAnalyzeButton = new ESButton(m_hWndCD, ID_ANALYZE, _Module.GetModuleInstance()); m_pDefragButton = new ESButton(m_hWndCD, ID_DEFRAG, _Module.GetModuleInstance()); m_pPauseButton = new ESButton(m_hWndCD, ID_PAUSE, _Module.GetModuleInstance()); m_pStopButton = new ESButton(m_hWndCD, ID_STOP, _Module.GetModuleInstance()); m_pReportButton = new ESButton(m_hWndCD, ID_REPORT, _Module.GetModuleInstance());
// if any buttons fail, abort the whole thing and mark have buttons false
if (m_pAnalyzeButton == NULL || m_pDefragButton == NULL || m_pPauseButton == NULL || m_pStopButton == NULL || m_pReportButton == NULL) {
Message(TEXT("CDfrgCtl::CreateButtons failed to alloc memory"), -1, NULL); m_bHaveButtons = FALSE; DestroyButtons(); return E_OUTOFMEMORY; }
// if all ok, set up buttons
m_bHaveButtons = TRUE;
m_pAnalyzeButton->SetFont(m_hFont); m_pAnalyzeButton->LoadString(GetDfrgResHandle(), IDS_BTN_ANALYZE);
m_pDefragButton->SetFont(m_hFont); m_pDefragButton->LoadString(GetDfrgResHandle(), IDS_BTN_DEFRAGMENT);
m_pPauseButton->SetFont(m_hFont); m_pPauseButton->LoadString(GetDfrgResHandle(), IDS_BTN_PAUSE);
m_pStopButton->SetFont(m_hFont); m_pStopButton->LoadString(GetDfrgResHandle(), IDS_BTN_STOP);
m_pReportButton->SetFont(m_hFont); m_pReportButton->LoadString(GetDfrgResHandle(), IDS_BTN_REPORT);
SetButtonState();
return S_OK; }
//-------------------------------------------------------------------*
// function: CDfrgCtl::DestroyButtons
//
// returns: None
// note:
//-------------------------------------------------------------------*
HRESULT CDfrgCtl::DestroyButtons(void) { if (m_pAnalyzeButton) { delete m_pAnalyzeButton; } if (m_pDefragButton) { delete m_pDefragButton; } if (m_pPauseButton) { delete m_pPauseButton; } if (m_pStopButton) { delete m_pStopButton; } if (m_pReportButton) { delete m_pReportButton; }
return S_OK; }
//-------------------------------------------------------------------*
// function: CDfrgCtl::PaintClusterMap
//
// returns: None
// note:
//-------------------------------------------------------------------*
BOOL CDfrgCtl::PaintClusterMap( IN BOOL bPartialRedraw, HDC WorkDC ) { CVolume *pVolume = m_VolumeList.GetCurrentVolume(); if (pVolume == (CVolume *) NULL) { return FALSE; }
/////////////////////////////////////////////////////////////////
// Status text written in the graphics wells
/////////////////////////////////////////////////////////////////
// make the text white in all color schemes
// SetTextColor(WorkDC, GetSysColor(COLOR_HIGHLIGHTTEXT));
// SetBkMode(WorkDC, TRANSPARENT);
UINT defaultId; if (pVolume->NoGraphicsMemory() || pVolume->m_AnalyzeDisplay.NoGraphicsMemory() || pVolume->m_DefragDisplay.NoGraphicsMemory()) { defaultId = IDS_NO_GRAPHICS_MEMORY; } else { defaultId = IDS_LABEL_RESIZING; }
// get the label that appears in the graphics wells
VString defragLabel; VString analyzeLabel; VString statusLabel; VString compactingLabel(IDS_COMPACTING_FILES, GetDfrgResHandle()); VString movingLabel(IDS_MOVING_FILES, GetDfrgResHandle());
analyzeLabel.Empty(); defragLabel.Empty(); statusLabel.Empty();
switch (pVolume->DefragState()){ case DEFRAG_STATE_ANALYZING: case DEFRAG_STATE_REANALYZING: analyzeLabel = pVolume->DisplayLabel(); analyzeLabel.AddChar(L' '); analyzeLabel += pVolume->sDefragState(); statusLabel = analyzeLabel; //acs bug #101862//
statusLabel += _T(" "); statusLabel += pVolume->cPercentDone(); statusLabel += _T("%"); if (pVolume->PausedBySnapshot()) { pVolume->m_AnalyzeDisplay.SetReadyToDraw(FALSE); } break;
case DEFRAG_STATE_ENGINE_DEAD: analyzeLabel = pVolume->DisplayLabel(); analyzeLabel.AddChar(L' '); analyzeLabel += pVolume->sDefragState(); statusLabel = analyzeLabel; break;
case DEFRAG_STATE_DEFRAGMENTING: analyzeLabel.LoadString(defaultId, GetDfrgResHandle()); defragLabel = pVolume->DisplayLabel(); defragLabel.AddChar(L' '); defragLabel += pVolume->sDefragState(); statusLabel += defragLabel; //acs bug #101862//
UINT mmpass; mmpass = pVolume->Pass();
if (pVolume->PausedBySnapshot()) { pVolume->m_DefragDisplay.SetReadyToDraw(FALSE); } else {
if(mmpass == 2 || mmpass == 4 || mmpass == 6) { statusLabel += _T(" "); statusLabel += pVolume->cPercentDone(); statusLabel += _T("%"); statusLabel += compactingLabel; } else { statusLabel += _T(" "); statusLabel += pVolume->cPercentDone(); statusLabel += _T("%"); statusLabel += movingLabel; statusLabel += pVolume->m_fileName; } } break;
case DEFRAG_STATE_BOOT_OPTIMIZING: analyzeLabel.LoadString(defaultId, GetDfrgResHandle()); defragLabel = pVolume->DisplayLabel(); defragLabel.AddChar(L' '); defragLabel += pVolume->sDefragState(); statusLabel += defragLabel;
if (pVolume->PausedBySnapshot()) { pVolume->m_DefragDisplay.SetReadyToDraw(FALSE); } else { statusLabel += _T(" "); statusLabel += pVolume->cPercentDone(); statusLabel += _T("%"); statusLabel += compactingLabel; } break;
case DEFRAG_STATE_ANALYZED: analyzeLabel.LoadString(defaultId, GetDfrgResHandle()); statusLabel = pVolume->DisplayLabel(); statusLabel.AddChar(L' '); statusLabel += pVolume->sDefragState(); break;
case DEFRAG_STATE_DEFRAGMENTED: analyzeLabel.LoadString(defaultId, GetDfrgResHandle()); defragLabel.LoadString(defaultId, GetDfrgResHandle()); statusLabel = pVolume->DisplayLabel(); statusLabel.AddChar(L' '); statusLabel += pVolume->sDefragState(); break; }
// override the others if the user pressed "Stop"
if (pVolume->StoppedByUser()){ analyzeLabel.Empty(); defragLabel.Empty(); statusLabel.Empty(); }
pVolume->m_AnalyzeDisplay.SetLabel(analyzeLabel.GetBuffer()); pVolume->m_DefragDisplay.SetLabel(defragLabel.GetBuffer());
// write the text into the graphic wells
// ::DrawText(WorkDC, analyzeLabel, analyzeLabel.GetLength(), &rcAnalyzeDisp, DT_CENTER);
// ::DrawText(WorkDC, defragLabel, defragLabel.GetLength(), &rcDefragDisp, DT_CENTER);
#ifndef ESI_PROGRESS_BAR
// add the progress bar percent to the status text
// Format: "left status well text"|"%percentdone"|"right status well text"
// we are not currently using the right well, but we could if we ever
// get an accurate progress bar percentage...
statusLabel += _T("|%"); statusLabel += pVolume->cPercentDone(); #endif
// send the status text to the lower-left status box
SendStatusChange(statusLabel.GetBuffer());
//Do the draw.
pVolume->m_AnalyzeDisplay.DrawLinesInHDC(WorkDC);
//Do the draw.
pVolume->m_DefragDisplay.DrawLinesInHDC(WorkDC);
return TRUE; }
//-------------------------------------------------------------------*
// function: CDfrgCtl::InvalidateProgressBar
//
// returns: None
// note:
//-------------------------------------------------------------------*
#ifdef ESI_PROGRESS_BAR
void CDfrgCtl::InvalidateProgressBar(void) { if (!InvalidateRect(&rcProgressBarBG, FALSE)){ Message(L"CDfrgCtl::InvalidateProgressBar()", GetLastError(), NULL); } } #endif
//-------------------------------------------------------------------*
// function: CDfrgCtl::InvalidateGraphicsWindow
//
// returns: None
// note:
//-------------------------------------------------------------------*
void CDfrgCtl::InvalidateGraphicsWindow(void) { if(::IsWindow(m_hWnd)) { if (!InvalidateRect(&rcGraphicsBG, FALSE)) { Message(L"CDfrgCtl::InvalidateGraphicsWindow()", GetLastError(), NULL); } } }
//-------------------------------------------------------------------*
// function: CDfrgCtl::PaintGraphicsWindow
//
// returns: None
// note:
//-------------------------------------------------------------------*
BOOL CDfrgCtl::PaintGraphicsWindow(HDC OutputDC) { // total background in local coordinates
RECT tmpGraphicsBGLocal = {0}; tmpGraphicsBGLocal.bottom = rcGraphicsBG.bottom - rcGraphicsBG.top; tmpGraphicsBGLocal.right = rcGraphicsBG.right - rcGraphicsBG.left;
HANDLE hBitmap = ::CreateCompatibleBitmap( OutputDC, rcGraphicsBG.right - rcGraphicsBG.left, rcGraphicsBG.bottom - rcGraphicsBG.top);
if (hBitmap == NULL) return 0;
// Now we need a memory DC to copy old bitmap to new one.
HDC WorkDC = ::CreateCompatibleDC(OutputDC); EF_ASSERT(WorkDC);
HANDLE hOld = ::SelectObject(WorkDC, hBitmap);
// Paint the background of the legend
HBRUSH hBrush = ::CreateSolidBrush(GetSysColor(COLOR_BTNFACE)); EF_ASSERT(hBrush);
::FillRect(WorkDC, &tmpGraphicsBGLocal, hBrush); ::DeleteObject(hBrush);
// edge below the list view is at the very top of this window
::DrawEdge(WorkDC, &tmpGraphicsBGLocal, EDGE_SUNKEN, BF_TOP);
/////////////////////////////////////////////////////////////////
// Draw the graphics wells
/////////////////////////////////////////////////////////////////
// Fill the dark gray analyze and defrag graphics area
// hBrush = ::CreateSolidBrush(GetSysColor(COLOR_3DSHADOW));
// EF_ASSERT(hBrush);
// ::FillRect(WorkDC, &rcAnalyzeDisp, hBrush);
// ::FillRect(WorkDC, &rcDefragDisp, hBrush);
// ::DeleteObject(hBrush);
// Draw the sunken box borders around the analyze and defragment graphics displays
// ::DrawBorderEx(WorkDC, rcAnalyzeBorder, SUNKEN_BOX);
// ::DrawBorderEx(WorkDC, rcDefragBorder, SUNKEN_BOX);
// Draw the text above the analyze and defrag displays
::SetBkColor(WorkDC, GetSysColor(COLOR_BTNFACE)); ::SetBkMode(WorkDC, OPAQUE); if (m_IsOkToRun){ ::SetTextColor(WorkDC, GetSysColor(COLOR_BTNTEXT)); } else { ::SetTextColor(WorkDC, GetSysColor(COLOR_GRAYTEXT)); }
::SelectObject(WorkDC, m_hFont);
// write the graphic wells' labels
VString textMsg; textMsg.LoadString(IDS_LABEL_ANALYSIS_DISPLAY, GetDfrgResHandle()); UINT oldTxtAlignMode = ::SetTextAlign(WorkDC, TA_BOTTOM|TA_LEFT); ::TextOut( WorkDC, rcAnalyzeDisp.left-0, rcAnalyzeDisp.top-6, textMsg.GetBuffer(), textMsg.GetLength());
textMsg.LoadString(IDS_LABEL_DEFRAG_DISPLAY, GetDfrgResHandle()); ::TextOut( WorkDC, rcDefragDisp.left-1, rcDefragDisp.top-6, textMsg.GetBuffer(), textMsg.GetLength());
::SetTextAlign(WorkDC, oldTxtAlignMode);
PaintClusterMap(FALSE, WorkDC);
::BitBlt(OutputDC, // screen DC
rcGraphicsBG.left, rcGraphicsBG.top, rcGraphicsBG.right-rcGraphicsBG.left, rcGraphicsBG.bottom-rcGraphicsBG.top, WorkDC, 0, 0, SRCCOPY);
// Cleanup the bitmap stuff.
::SelectObject(WorkDC, hOld); ::DeleteObject(hBitmap); ::DeleteDC(WorkDC);
return TRUE; }
//-------------------------------------------------------------------*
// function: CDfrgCtl::DrawButtons
//
// returns: None
// note:
//-------------------------------------------------------------------*
BOOL CDfrgCtl::DrawButtons(HDC OutputDC) { // total background in local coordinates
RECT tmpButtonBGLocal = {0}; tmpButtonBGLocal.bottom = rcButtonBG.bottom - rcButtonBG.top; tmpButtonBGLocal.right = rcButtonBG.right - rcButtonBG.left;
HANDLE hBitmap = ::CreateCompatibleBitmap( OutputDC, rcButtonBG.right - rcButtonBG.left, rcButtonBG.bottom - rcButtonBG.top);
if (hBitmap == NULL) return 0;
// Now we need a memory DC to copy old bitmap to new one.
HDC WorkDC = ::CreateCompatibleDC(OutputDC); EF_ASSERT(WorkDC);
HANDLE hOld = ::SelectObject(WorkDC, hBitmap);
// Paint the background of the buttons
HBRUSH hBrush = ::CreateSolidBrush(GetSysColor(COLOR_BTNFACE)); EF_ASSERT(hBrush); ::FillRect(WorkDC, &tmpButtonBGLocal, hBrush); ::DeleteObject(hBrush);
::BitBlt(OutputDC, // screen DC
rcButtonBG.left, rcButtonBG.top, rcButtonBG.right-rcButtonBG.left, rcButtonBG.bottom-rcButtonBG.top, WorkDC, 0, 0, SRCCOPY);
// Cleanup the bitmap stuff.
::SelectObject(WorkDC, hOld); ::DeleteObject(hBitmap); ::DeleteDC(WorkDC);
return TRUE; }
//-------------------------------------------------------------------*
// function: CDfrgCtl::SizeLegend
//
// returns: None
// note:
//-------------------------------------------------------------------*
void CDfrgCtl::SizeLegend() { int x = 0, y = 0, i;
// get the x and y size of the legend bitmap
// use the size of number 0 as representative of all bitmaps
// if they someday vary in size, put this call back into the loop
m_pLegend->GetBmpSize(0, &x, &y);
if (m_LegendTextWidth == 0) { // calculate the width of the legend with all the
// entries on one line
HDC OutputDC = GetDC(); EV_ASSERT(OutputDC); HDC WorkDC = ::CreateCompatibleDC(OutputDC); EV_ASSERT(WorkDC); ::SelectObject(WorkDC, m_hFont);
// use the width of X to determine the spacer between legend entries
m_LegendTextSpacer = 3 * GetStringWidth(_T("X"), WorkDC);
m_LegendTextWidth = m_Margin; UINT iStringWidth; for (i=0; i < (SIMPLE_DISPLAY?4:7); i++) { // calc the width of the legend string
iStringWidth = GetStringWidth(m_LegendData[i].text.GetBuffer(), WorkDC);
// save the string width
m_LegendData[i].length = x + iStringWidth + m_LegendTextSpacer;
// calculate the overall length
m_LegendTextWidth += m_LegendData[i].length; // add the space and the bitmap
} // calculate the spacer between the top of the bitmaps and the legend rectangle
m_BitmapVOffset = (m_LegendHeight - y) / 2; // subtract off the last spacers
m_LegendTextWidth -= x + m_LegendTextSpacer;
::DeleteDC(WorkDC); EH_ASSERT(ReleaseDC(OutputDC)); // member function
}
// this is the longest that the text can be and still have the progress
// bar on the same line, based on the current window width
#ifdef ESI_PROGRESS_BAR
int legendTextMaxWidth = m_rcCtlRect.right - 2*m_Margin - 2*m_EtchedLineOffset - m_ProgressBarLength; #else
int legendTextMaxWidth = m_rcCtlRect.right - 2*m_Margin - 2*m_EtchedLineOffset; #endif
#ifdef ESI_PROGRESS_BAR
// check if we need to move the progress bar down
if (m_LegendTextWidth < legendTextMaxWidth){ // if true, all on 1 line
m_IsProgressBarMoved = FALSE;
// progress bar background (absolute coords)
rcProgressBarBG.right = m_rcCtlRect.right; rcProgressBarBG.left = m_rcCtlRect.right - m_Margin - m_ProgressBarLength - m_EtchedLineOffset; rcProgressBarBG.bottom = m_rcCtlRect.bottom; rcProgressBarBG.top = m_rcCtlRect.bottom - 2*m_EtchedLineOffset - m_LegendHeight;
// legend background (absolute coords)
rcLegendBG.left = m_rcCtlRect.left; rcLegendBG.top = m_rcCtlRect.bottom - 2*m_EtchedLineOffset - m_LegendHeight; rcLegendBG.right = m_rcCtlRect.right - m_Margin - m_ProgressBarLength - m_EtchedLineOffset; rcLegendBG.bottom = m_rcCtlRect.bottom;
// calculate the rectangle positions for the legend bitmaps
int currentLineLength = 0; for (i=0; i<(SIMPLE_DISPLAY?4:7); i++) { m_LegendData[i].rcBmp.top = 0; m_LegendData[i].rcBmp.bottom = m_LegendData[i].rcBmp.top + y; m_LegendData[i].rcBmp.left = currentLineLength; m_LegendData[i].rcBmp.right = m_LegendData[i].rcBmp.left + x; currentLineLength += m_LegendData[i].length; } } else { // need to move progress bar down below text
m_IsProgressBarMoved = TRUE;
// progress bar background (absolute coords)
rcProgressBarBG.right = m_rcCtlRect.right; rcProgressBarBG.left = m_rcCtlRect.left; rcProgressBarBG.bottom = m_rcCtlRect.bottom; rcProgressBarBG.top = m_rcCtlRect.bottom - 2*m_EtchedLineOffset - m_LegendHeight; #endif
int yOffset = 0; // use a Bitmap coordinate system first, stack from the top
int screenWidth = m_rcCtlRect.right - m_rcCtlRect.left - 2 * m_Margin;
// start the first legend entry off at the upper left
m_LegendData[0].rcBmp.top = 0; m_LegendData[0].rcBmp.left = 0; int currentLineLength = m_LegendData[0].length;
// loop thru the rest of the entries (note the loop starts at 1!)
// and determine if they will fit on the current line, or if
// we need to start another line
for (i=1; i<(SIMPLE_DISPLAY?4:7); i++) { if (currentLineLength + m_LegendData[i].length > screenWidth){ // need to go to the next line
yOffset += m_FontHeight + m_LegendGraphicSpacer; // add height of bitmap and a spacer
m_LegendData[i].rcBmp.top = yOffset; m_LegendData[i].rcBmp.left = 0; // current length of current line is reset
currentLineLength = m_LegendData[i].length; } else { // it will fit on this line
m_LegendData[i].rcBmp.top = yOffset; m_LegendData[i].rcBmp.left = currentLineLength; currentLineLength += m_LegendData[i].length; } }
#ifdef ESI_PROGRESS_BAR
rcLegendBG.left = m_rcCtlRect.left; rcLegendBG.right = m_rcCtlRect.right; rcLegendBG.top = m_rcCtlRect.bottom - (m_LegendHeight + 4*m_EtchedLineOffset + y + 2*m_BitmapVOffset + yOffset); rcLegendBG.bottom = m_rcCtlRect.bottom - (m_LegendHeight + 2*m_EtchedLineOffset); } #else
// legend background (absolute coords)
rcLegendBG.left = m_rcCtlRect.left; rcLegendBG.right = m_rcCtlRect.right; rcLegendBG.bottom = m_rcCtlRect.bottom; rcLegendBG.top = m_rcCtlRect.bottom - (2*m_EtchedLineOffset + y + 2*m_BitmapVOffset + yOffset); #endif
}
//-------------------------------------------------------------------*
// function: CDfrgCtl::DrawSingleInstanceScreen
//
// returns: None
// note:
//-------------------------------------------------------------------*
BOOL CDfrgCtl::DrawSingleInstanceScreen(HDC OutputDC) {
HANDLE hBitmap = ::CreateCompatibleBitmap( OutputDC, m_rcCtlRect.right - m_rcCtlRect.left, m_rcCtlRect.bottom - m_rcCtlRect.top);
if (hBitmap == NULL) return FALSE;
// Now we need a memory DC to copy old bitmap to new one.
HDC WorkDC = ::CreateCompatibleDC(OutputDC); EF_ASSERT(WorkDC);
HANDLE hOld = ::SelectObject(WorkDC, hBitmap);
// Paint the background of the legend
HBRUSH hBrush = ::CreateSolidBrush(GetSysColor(COLOR_BTNFACE)); EF_ASSERT(hBrush); ::FillRect(WorkDC, &m_rcCtlRect, hBrush); ::DeleteObject(hBrush);
::BitBlt(OutputDC, // screen DC
0, 0, m_rcCtlRect.right-m_rcCtlRect.left, m_rcCtlRect.bottom-m_rcCtlRect.top, WorkDC, 0, 0, SRCCOPY);
HBITMAP hCriticalIcon = (HBITMAP)::LoadImage( GetDfrgResHandle(), MAKEINTRESOURCE(IDB_CRITICALICON_GREY), IMAGE_BITMAP, 0, 0, LR_LOADTRANSPARENT|LR_LOADMAP3DCOLORS);
::SelectObject(WorkDC, hCriticalIcon);
::BitBlt(OutputDC, // screen DC
10, 10, m_rcCtlRect.right-m_rcCtlRect.left, m_rcCtlRect.bottom-m_rcCtlRect.top, WorkDC, 0, 0, SRCCOPY);
// Cleanup the bitmap stuff.
::SelectObject(WorkDC, hOld); ::DeleteObject(hCriticalIcon); ::DeleteObject(hBitmap); ::DeleteDC(WorkDC);
return TRUE; }
//-------------------------------------------------------------------*
// function: CDfrgCtl::DrawLegend
//
// returns: None
// note:
//-------------------------------------------------------------------*
BOOL CDfrgCtl::DrawLegend(HDC OutputDC) { int x = 0, y = 0;
m_pLegend->GetBmpSize(0, &x, &y);
// total legend background in local coordinates
RECT tmpLegendBGLocal = {0}; tmpLegendBGLocal.bottom = rcLegendBG.bottom - rcLegendBG.top; tmpLegendBGLocal.right = rcLegendBG.right - rcLegendBG.left;
HANDLE hBitmap = ::CreateCompatibleBitmap( OutputDC, rcLegendBG.right - rcLegendBG.left, rcLegendBG.bottom - rcLegendBG.top);
if (hBitmap == NULL) return FALSE;
// Now we need a memory DC to copy old bitmap to new one.
HDC WorkDC = ::CreateCompatibleDC(OutputDC); EF_ASSERT(WorkDC);
HANDLE hOld = ::SelectObject(WorkDC, hBitmap);
// Paint the background of the legend
HBRUSH hBrush = ::CreateSolidBrush(GetSysColor(COLOR_BTNFACE)); EF_ASSERT(hBrush); ::FillRect(WorkDC, &tmpLegendBGLocal, hBrush); ::DeleteObject(hBrush);
// select the font
::SetBkColor(WorkDC, GetSysColor(COLOR_BTNFACE)); ::SetBkMode(WorkDC, OPAQUE); if (m_IsOkToRun){ ::SetTextColor(WorkDC, GetSysColor(COLOR_BTNTEXT)); } else { ::SetTextColor(WorkDC, GetSysColor(COLOR_GRAYTEXT)); } ::SelectObject(WorkDC, m_hFont);
// use for debugging
//::DrawEdge(WorkDC, &tmpLegendBGLocal, EDGE_RAISED, BF_RECT);
RECT rcBmp; RECT rcLegend = tmpLegendBGLocal; rcLegend.left += m_Margin; rcLegend.top += m_EtchedLineOffset; rcLegend.bottom -= m_EtchedLineOffset;
// Draw the legend at the bottom
for (int i=0; i<(SIMPLE_DISPLAY?4:7); i++) {
// rcBmp gets the bitmap position in absolute coordinates
rcBmp.top = rcLegend.top + m_BitmapVOffset + m_LegendData[i].rcBmp.top; rcBmp.left = rcLegend.left + m_LegendData[i].rcBmp.left; rcBmp.bottom = rcBmp.top + y; rcBmp.right = rcBmp.left + x;
// draw bitmap in upper-left corner of rectangle
m_pLegend->DrawBmpInHDCTruncate(WorkDC, i, &rcBmp);
// draw the text 5 units to the right of the bitmap
::TextOut( WorkDC, rcBmp.left + x + m_LegendGraphicSpacer, rcBmp.top-0, m_LegendData[i].text.GetBuffer(), m_LegendData[i].text.GetLength()); }
// etched line on top of legend
RECT rcHorizontalDivider = tmpLegendBGLocal; rcHorizontalDivider.left += m_Margin; rcHorizontalDivider.right += 1; // small adjustment
// is the progress bar is on the bottom, adjust the line in from the margin
#ifdef ESI_PROGRESS_BAR
if (m_IsProgressBarMoved){ rcHorizontalDivider.right -= m_Margin; } #else
rcHorizontalDivider.right -= m_Margin; #endif
// rectangle used as the horizontal divider line (top, and bottom if necessary)
::DrawEdge(WorkDC, &rcHorizontalDivider, EDGE_ETCHED, BF_TOP);
::BitBlt(OutputDC, // screen DC
rcLegendBG.left, rcLegendBG.top, rcLegendBG.right-rcLegendBG.left, rcLegendBG.bottom-rcLegendBG.top, WorkDC, 0, 0, SRCCOPY);
// Cleanup the bitmap stuff.
::SelectObject(WorkDC, hOld); ::DeleteObject(hBitmap); ::DeleteDC(WorkDC);
return TRUE; }
//-------------------------------------------------------------------*
// function: CDfrgCtl::DrawProgressBar
//
// returns: None
// note:
//-------------------------------------------------------------------*
#ifdef ESI_PROGRESS_BAR
BOOL CDfrgCtl::DrawProgressBar(HDC OutputDC) { UINT percentDone = 0; CVolume *pVolume = m_VolumeList.GetCurrentVolume(); if (pVolume){ percentDone = pVolume->PercentDone(); }
// total progress background in local coordinates
RECT tmpProgressBarBGLocal = {0}; tmpProgressBarBGLocal.bottom = rcProgressBarBG.bottom - rcProgressBarBG.top; tmpProgressBarBGLocal.right = rcProgressBarBG.right - rcProgressBarBG.left;
HANDLE hBitmap = ::CreateCompatibleBitmap( OutputDC, rcProgressBarBG.right - rcProgressBarBG.left, rcProgressBarBG.bottom - rcProgressBarBG.top);
if (hBitmap == NULL) return FALSE;
// Now we need a memory DC to copy old bitmap to new one.
HDC WorkDC = ::CreateCompatibleDC(OutputDC); EF_ASSERT(WorkDC);
HANDLE hOld = ::SelectObject(WorkDC, hBitmap);
// Paint the background of the legend
HBRUSH hBrush = ::CreateSolidBrush(GetSysColor(COLOR_BTNFACE)); EF_ASSERT(hBrush); ::FillRect(WorkDC, &tmpProgressBarBGLocal, hBrush); ::DeleteObject(hBrush);
// use for debugging
//DrawEdge(WorkDC, &tmpProgressBarBGLocal, EDGE_RAISED, BF_RECT);
// find the actual outline of the progress bar
rcProgressBar.left = m_Margin; rcProgressBar.top = m_EtchedLineOffset + m_ProgressBarOffset; rcProgressBar.right = m_EtchedLineOffset + m_ProgressBarLength; rcProgressBar.bottom = m_EtchedLineOffset + m_LegendHeight - m_ProgressBarOffset;
// etched line on top of legend
RECT rcHorizontalDivider = tmpProgressBarBGLocal; rcHorizontalDivider.right -= m_Margin;
if (m_IsProgressBarMoved){ rcHorizontalDivider.left += m_Margin; // rectangle used as the horizontal divider line (top, and bottom if necessary)
::DrawEdge(WorkDC, &rcHorizontalDivider, EDGE_ETCHED, BF_TOP); } else{ ::DrawEdge(WorkDC, &rcHorizontalDivider, EDGE_ETCHED, BF_TOP);
// etched line to the left (if needed)
RECT rcVerticalDivider = tmpProgressBarBGLocal; rcVerticalDivider.top = m_EtchedLineOffset + m_ProgressBarOffset; rcVerticalDivider.bottom -= m_EtchedLineOffset + m_ProgressBarOffset; // Draw the etched line to the left of the progress bar
::DrawEdge(WorkDC, &rcVerticalDivider, EDGE_ETCHED, BF_LEFT); }
ProgressBar(WorkDC, &rcProgressBar, m_hFont, 4, // width
2, // space
percentDone);
::BitBlt(OutputDC, // screen DC
rcProgressBarBG.left, rcProgressBarBG.top, rcProgressBarBG.right-rcProgressBarBG.left, rcProgressBarBG.bottom-rcProgressBarBG.top, WorkDC, 0, 0, SRCCOPY);
// Cleanup the bitmap stuff.
::SelectObject(WorkDC, hOld); ::DeleteObject(hBitmap); ::DeleteDC(WorkDC);
return TRUE; } #endif
//-------------------------------------------------------------------*
// function: CDfrgCtl::SizeButtons
//
// returns: None
// note:
//-------------------------------------------------------------------*
void CDfrgCtl::SizeButtons(void) { /////////////////////////////////////////
// The button coordinates are absolute!!!
/////////////////////////////////////////
// the area around the buttons needed to grey out the background
rcButtonBG.left = m_rcCtlRect.left; rcButtonBG.top = rcLegendBG.top - m_ButtonTopBottomSpacer - m_ButtonHeight; rcButtonBG.bottom = rcLegendBG.top; rcButtonBG.right = m_rcCtlRect.right;
HDC OutputDC = GetDC(); EV_ASSERT(OutputDC); HDC WorkDC = ::CreateCompatibleDC(OutputDC); EV_ASSERT(WorkDC); ::SelectObject(WorkDC, m_hFont);
TCHAR buttonText[200]; UINT adjustedButtonWidth; const bigButtonSpacer = 20;
UINT adjustedButtonHeight = __max((UINT)(1.5 * m_FontHeight), m_ButtonHeight);
// Calculate the Analyze button position and size.
::LoadString(GetDfrgResHandle(), IDS_BTN_ANALYZE, buttonText, 200); adjustedButtonWidth = __max(bigButtonSpacer + GetStringWidth(buttonText, WorkDC), m_ButtonWidth);
rcAnalyzeButton.left = m_Margin; rcAnalyzeButton.bottom = rcLegendBG.top - m_ButtonTopBottomSpacer; rcAnalyzeButton.top = rcAnalyzeButton.bottom - adjustedButtonHeight; rcAnalyzeButton.right = rcAnalyzeButton.left + adjustedButtonWidth;
// start off with all buttons the same as the analyze button
rcDefragButton = rcPauseButton = rcCancelButton = rcReportButton = rcAnalyzeButton;
// Calculate the Defrag button position and size.
::LoadString(GetDfrgResHandle(), IDS_BTN_DEFRAGMENT, buttonText, 200); adjustedButtonWidth = __max(bigButtonSpacer + GetStringWidth(buttonText, WorkDC), m_ButtonWidth); rcDefragButton.left = rcAnalyzeButton.right + m_ButtonSpacer; rcDefragButton.right = rcDefragButton.left + adjustedButtonWidth;
// Calculate the Pause button position and size.
::LoadString(GetDfrgResHandle(), IDS_BTN_PAUSE, buttonText, 200); adjustedButtonWidth = __max(bigButtonSpacer + GetStringWidth(buttonText, WorkDC), m_ButtonWidth); // check to see if the resume text is longer
::LoadString(GetDfrgResHandle(), IDS_BTN_RESUME, buttonText, 200); adjustedButtonWidth = __max(bigButtonSpacer + GetStringWidth(buttonText, WorkDC), adjustedButtonWidth); rcPauseButton.left = rcDefragButton.right + m_ButtonSpacer; rcPauseButton.right = rcPauseButton.left + adjustedButtonWidth;
// Calculate the Cancel button position and size.
::LoadString(GetDfrgResHandle(), IDS_BTN_STOP, buttonText, 200); adjustedButtonWidth = __max(bigButtonSpacer + GetStringWidth(buttonText, WorkDC), m_ButtonWidth); rcCancelButton.left = rcPauseButton.right + m_ButtonSpacer; rcCancelButton.right = rcCancelButton.left + adjustedButtonWidth;
// Calculate the See Report button position and size.
::LoadString(GetDfrgResHandle(), IDS_BTN_REPORT, buttonText, 200); adjustedButtonWidth = __max(bigButtonSpacer + GetStringWidth(buttonText, WorkDC), m_ButtonWidth); rcReportButton.left = rcCancelButton.right + m_ButtonSpacer; rcReportButton.right = rcReportButton.left + adjustedButtonWidth;
// Set the rectangles of the buttons
if (m_bHaveButtons) { m_pAnalyzeButton->PositionButton(&rcAnalyzeButton); m_pDefragButton->PositionButton(&rcDefragButton); m_pPauseButton->PositionButton(&rcPauseButton); m_pStopButton->PositionButton(&rcCancelButton); m_pReportButton->PositionButton(&rcReportButton); }
::DeleteDC(WorkDC); EH_ASSERT(ReleaseDC(OutputDC)); }
//-------------------------------------------------------------------*
// function: CDfrgCtl::SizeGraphicsWindow
//
// returns: None
// note:
//-------------------------------------------------------------------*
BOOL CDfrgCtl::SizeGraphicsWindow(void) { rcGraphicsBG.left = m_rcCtlRect.left; rcGraphicsBG.right = m_rcCtlRect.right; rcGraphicsBG.bottom = rcLegendBG.top - m_ButtonTopBottomSpacer - m_ButtonHeight; rcGraphicsBG.top = rcGraphicsBG.bottom - m_ButtonTopBottomSpacer - 2*m_GraphicWellHeight - 2*m_GraphicWellSpacer;
// analyze graphics well
rcAnalyzeDisp.left = m_Margin+1; rcAnalyzeDisp.top = m_GraphicWellSpacer; rcAnalyzeDisp.bottom = rcAnalyzeDisp.top + m_GraphicWellHeight; rcAnalyzeDisp.right = __max(rcGraphicsBG.right - m_Margin, rcReportButton.right); // defrag graphics well
rcDefragDisp = rcAnalyzeDisp; rcDefragDisp.top = rcAnalyzeDisp.bottom + m_GraphicWellSpacer; rcDefragDisp.bottom = rcDefragDisp.top + m_GraphicWellHeight;
// Calculate the analyze display border.
rcAnalyzeBorder.top = rcAnalyzeDisp.top - 1; rcAnalyzeBorder.left = rcAnalyzeDisp.left - 1; rcAnalyzeBorder.right = rcAnalyzeDisp.right; rcAnalyzeBorder.bottom = rcAnalyzeDisp.bottom;
// Calculate the defrag display border.
rcDefragBorder.top = rcDefragDisp.top - 1; rcDefragBorder.left = rcDefragDisp.left - 1; rcDefragBorder.right = rcDefragDisp.right; rcDefragBorder.bottom = rcDefragDisp.bottom;
//Set output dimensions on the analyze display rectangle.
CVolume *pVolume = m_VolumeList.GetCurrentVolume(); if (pVolume == (CVolume *) NULL){ return FALSE; }
//Set the dimensions.
pVolume->m_AnalyzeDisplay.SetOutputArea(rcAnalyzeBorder);
//Set the dimensions.
pVolume->m_DefragDisplay.SetOutputArea(rcDefragBorder);
//tell the engines what the line count is
SET_DISP_DATA DispData = {0}; DispData.AnalyzeLineCount = pVolume->m_AnalyzeDisplay.GetLineCount(); DispData.DefragLineCount = pVolume->m_DefragDisplay.GetLineCount(); DispData.bSendGraphicsUpdate = TRUE; // send graphics back immediately
DataIoClientSetData(ID_SETDISPDIMENSIONS, (PTCHAR)&DispData, sizeof(SET_DISP_DATA), pVolume->m_pdataDefragEngine);
return TRUE; }
//-------------------------------------------------------------------*
// function: CDfrgCtl::SetButtonState
//
// returns: None
// note:
//-------------------------------------------------------------------*
void CDfrgCtl::SetButtonState(void) { // sanity check to make sure the buttons are created
if (!m_bHaveButtons) { return; }
CVolume *pVolume = m_VolumeList.GetCurrentVolume(); if (pVolume == (CVolume *) NULL){ return; }
// set the pause/resume text correctly
m_pPauseButton->LoadString(GetDfrgResHandle(), pVolume->Paused() ? IDS_BTN_RESUME : IDS_BTN_PAUSE);
if (m_VolumeList.Locked() || !m_IsOkToRun){ m_pAnalyzeButton->EnableButton(FALSE); m_pDefragButton->EnableButton(FALSE); m_pReportButton->EnableButton(FALSE); m_pPauseButton->EnableButton(FALSE); m_pStopButton->EnableButton(FALSE); return; }
if (pVolume->EngineState() == ENGINE_STATE_RUNNING){ // the selected vol is being analyzed/defragged
m_pAnalyzeButton->EnableButton(FALSE); m_pDefragButton->EnableButton(FALSE); m_pPauseButton->EnableButton(TRUE); m_pStopButton->EnableButton(TRUE); m_pReportButton->EnableButton(FALSE); } else { m_pAnalyzeButton->EnableButton(TRUE); m_pDefragButton->EnableButton(TRUE); m_pPauseButton->EnableButton(FALSE); m_pStopButton->EnableButton(FALSE); m_pReportButton->EnableButton(pVolume->IsReportOKToDisplay()); } }
//-------------------------------------------------------------------*
// function: CDfrgCtl::GetStringWidth
//
// returns: None
// note:
//-------------------------------------------------------------------*
UINT CDfrgCtl::GetStringWidth(PTCHAR stringBuf, HDC WorkDC) { if (!stringBuf){ return 0; }
UINT iStringWidth = 0; int iCharWidth = 0; //initialize for bugf 445627
for (UINT i=0; i<wcslen(stringBuf); i++){ ::GetCharWidth32( WorkDC, stringBuf[i], stringBuf[i], &iCharWidth); iStringWidth += iCharWidth; }
return iStringWidth; }
//-------------------------------------------------------------------*
// function: CDfrgCtl::IsOnlyInstance
//
// returns: None
// note:
//-------------------------------------------------------------------*
BOOL CDfrgCtl::IsOnlyInstance() { BOOL fFirst = FALSE; IDataObject* pData = NULL;
SECURITY_ATTRIBUTES saSecurityAttributes; SECURITY_DESCRIPTOR sdSecurityDescriptor;
if (CheckForAdminPrivs() == FALSE) { return FALSE; } ZeroMemory(&sdSecurityDescriptor, sizeof(SECURITY_DESCRIPTOR));
saSecurityAttributes.nLength = sizeof (saSecurityAttributes); saSecurityAttributes.lpSecurityDescriptor = &sdSecurityDescriptor; saSecurityAttributes.bInheritHandle = FALSE;
if (!ConstructSecurityAttributes(&saSecurityAttributes, esatSemaphore, FALSE)) { return FALSE; }
#ifdef ESI_MULTI_ALLOWED
return( TRUE ); #endif
if (CheckForAdminPrivs() == FALSE) { return FALSE; } if (m_hIsOkToRunSemaphore == NULL){ m_hIsOkToRunSemaphore = CreateSemaphore(&saSecurityAttributes, 1, 1, IS_OK_TO_RUN_SEMAPHORE_NAME); }
CleanupSecurityAttributes(&saSecurityAttributes); ZeroMemory(&sdSecurityDescriptor, sizeof(SECURITY_DESCRIPTOR));
if (m_hIsOkToRunSemaphore){ // is the semaphore signaled?
DWORD retValue = WaitForSingleObject(m_hIsOkToRunSemaphore, 10);
// if so, this process is the only one, and the semaphore count is decremented to 0
if (retValue == WAIT_OBJECT_0){ return TRUE; } }
return FALSE; }
//-------------------------------------------------------------------*
// function: CDfrgCtl::SendStatusChange
//
// returns: None
// note: Loops through all of the connection points and sends
// the status change message.
//-------------------------------------------------------------------*
void CDfrgCtl::SendStatusChange( LPCTSTR pszStatus ) { BSTR bszStatus; if (pszStatus){ bszStatus = SysAllocString( pszStatus ); } else { bszStatus = SysAllocString(_T("")); }
Lock(); IUnknown** pp = m_vec.begin(); while (pp < m_vec.end()) { if (*pp != NULL) { IDfrgEvents* pEvents = reinterpret_cast<IDfrgEvents*>( *pp ); pEvents->StatusChanged( bszStatus ); } pp++; } Unlock();
SysFreeString( bszStatus ); }
//-------------------------------------------------------------------*
// function: CDfrgCtl::SendOKToRun
//
// returns: None
// note: Loops through all of the connection points and sends
// the new OKToRun property.
//-------------------------------------------------------------------*
void CDfrgCtl::SendOKToRun( BOOL bOK ) { Lock(); IUnknown** pp = m_vec.begin(); while (pp < m_vec.end()) { if (*pp != NULL) { IDfrgEvents* pEvents = reinterpret_cast<IDfrgEvents*>( *pp ); pEvents->IsOKToRun( bOK ); } pp++; } Unlock(); }
//-------------------------------------------------------------------*
// function: CDfrgCtl::TranslateAccelerator
//
// returns: None
// note:
//-------------------------------------------------------------------*
STDMETHODIMP CDfrgCtl::TranslateAccelerator(LPMSG pMsg) { HRESULT hr = S_FALSE; // we didn't handle keypress
switch( pMsg->message ) { case WM_KEYDOWN: { switch ( pMsg->wParam ) { case VK_TAB: { //
// Check for the shift key.
//
Message(TEXT("CDfrgCtl got a tab key press"), -1, NULL);
if ( GetAsyncKeyState( VK_SHIFT ) & 0x8000 ) hr = PreviousTab(); else hr = NextTab(); } break;
case VK_SPACE: Message(TEXT("CDfrgCtl got a spacebar key press"), -1, NULL); break;
case VK_RETURN: Message(TEXT("CDfrgCtl got an enter key press"), -1, NULL); hr = HandleEnterKeyPress(); break;
case VK_F5: m_ListView.GetDrivesToListView(); hr = S_OK; // we handled keypress
break; } } break; default: break; }
return( hr ); }
//-------------------------------------------------------------------*
// function: CDfrgCtl::PreviousTab
//
// returns: None
// note: Handle moving to the previous tab.
//-------------------------------------------------------------------*
HRESULT CDfrgCtl::PreviousTab() { HRESULT hr; HWND hWndNext = NULL; CTabEnumerator TabEnum(m_hWndCD, FALSE);
hWndNext = TabEnum.GetNextTabWindow(); if(hWndNext == NULL) //out of memory bug 445628
{ return(S_FALSE); }
::SetFocus(hWndNext);
if (hWndNext == m_ListView.m_hwndListView) hr = S_FALSE; // we didn't handle keypress
else hr = S_OK; // we handled keypress
return(hr); }
//-------------------------------------------------------------------*
// function: CDfrgCtl::NextTab
//
// returns: None
// note: Handle moving to the next tab.
//-------------------------------------------------------------------*
HRESULT CDfrgCtl::NextTab() { HRESULT hr; HWND hWndNext = NULL; CTabEnumerator TabEnum(m_hWndCD, TRUE);
hWndNext = TabEnum.GetNextTabWindow(); if(hWndNext == NULL) //out of memory bug 445628
{ return(S_FALSE); }
::SetFocus(hWndNext);
if (hWndNext == m_ListView.m_hwndListView) hr = S_FALSE; // we didn't handle keypress
else hr = S_OK; // we handled keypress
return(hr); }
//-------------------------------------------------------------------*
// function: CDfrgCtl::GetNextTabWindow
//
// returns: None
// note:
//-------------------------------------------------------------------*
HWND CTabEnumerator::GetNextTabWindow() { HWND hWndNext = NULL; //
// Get the window with the current focus.
//
HWND hWndCurrent = GetFocus(); _ASSERTE( hWndCurrent ); //
// Enumerate our child windows. This should generate
// a list of child windows.
//
EnumChildWindows( m_hWndParent, TabEnumChildren, (LONG_PTR) this );
//
// Find the existing position of the focus window.
//
HWND* pFind = find( m_Children.begin(), m_Children.end(), hWndCurrent ); //
// Determine if we need to wrap around to the beginning.
//
if (m_fForward) { if (pFind == m_Children.end() - 1) pFind = m_Children.begin(); else pFind++; } else { if (pFind == m_Children.begin()) pFind = m_Children.end() - 1; else pFind--; }
hWndNext = *pFind;
return(hWndNext); }
//-------------------------------------------------------------------*
// function: TabEnumChildren
//
// returns: None
// note:
//-------------------------------------------------------------------*
BOOL CALLBACK TabEnumChildren( HWND hwnd, LPARAM lParam ) { reinterpret_cast<CTabEnumerator*>( lParam )->AddChild( hwnd ); return( TRUE ); }
//-------------------------------------------------------------------*
// function: OnContextMenu
//
// returns: None
// note:
//-------------------------------------------------------------------*
HRESULT CDfrgCtl::OnContextMenu(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& lResult) { //return( m_ListView.OnContextMenu( (HWND) wParam, LOWORD( lParam ), HIWORD( lParam ) ) );
HRESULT hr = E_NOTIMPL;
CVolume *pVolume = m_VolumeList.GetCurrentVolume();
if (pVolume == (CVolume *) NULL){ return hr; }
if ( m_ListView.m_hwndListView == (HWND) wParam ) { HMENU hMenu;
hMenu = ::CreatePopupMenu(); if ( hMenu != NULL ) { // determine button availability
BOOL AnalDfrgOk = FALSE; BOOL StopPauseOk = FALSE; BOOL ReportOk = FALSE;
if (m_VolumeList.Locked() || !m_IsOkToRun) { // UI disabled
AnalDfrgOk = FALSE; StopPauseOk = FALSE; ReportOk = FALSE; } else if (pVolume->EngineState() == ENGINE_STATE_RUNNING) { // the selected vol is being analyzed/defragged
AnalDfrgOk = FALSE; StopPauseOk = TRUE; ReportOk = FALSE; } else { AnalDfrgOk = TRUE; StopPauseOk = FALSE; ReportOk = pVolume->IsReportOKToDisplay(); }
TCHAR menuText[200]; UINT uFlags;
//
// Populate context menu.
//
// analyze
::LoadString(GetDfrgResHandle(), IDS_ANALYZE, menuText, sizeof(menuText) / sizeof(TCHAR)); uFlags = MF_STRING | (AnalDfrgOk ? MF_ENABLED : MF_GRAYED); ::AppendMenu(hMenu, uFlags, ID_ANALYZE, menuText);
// defrag
::LoadString(GetDfrgResHandle(), IDS_DEFRAGMENT, menuText, sizeof(menuText) / sizeof(TCHAR)); uFlags = MF_STRING | (AnalDfrgOk ? MF_ENABLED : MF_GRAYED); ::AppendMenu(hMenu, uFlags, ID_DEFRAG, menuText);
if (pVolume->Paused()){ // resume
::LoadString(GetDfrgResHandle(), IDS_RESUME, menuText, sizeof(menuText) / sizeof(TCHAR)); uFlags = MF_STRING | (StopPauseOk ? MF_ENABLED : MF_GRAYED); ::AppendMenu(hMenu, uFlags, ID_PAUSE, menuText); } else { // pause
::LoadString(GetDfrgResHandle(), IDS_PAUSE, menuText, sizeof(menuText) / sizeof(TCHAR)); uFlags = MF_STRING | (StopPauseOk ? MF_ENABLED : MF_GRAYED); ::AppendMenu(hMenu, uFlags, ID_PAUSE, menuText); }
// stop
::LoadString(GetDfrgResHandle(), IDS_STOP, menuText, sizeof(menuText) / sizeof(TCHAR)); uFlags = MF_STRING | (StopPauseOk ? MF_ENABLED : MF_GRAYED); ::AppendMenu(hMenu, uFlags, ID_STOP, menuText);
// see report
::LoadString(GetDfrgResHandle(), IDS_REPORT, menuText, sizeof(menuText) / sizeof(TCHAR)); uFlags = MF_STRING | (ReportOk ? MF_ENABLED : MF_GRAYED); ::AppendMenu(hMenu, uFlags, ID_REPORT, menuText);
// separator
::AppendMenu(hMenu, MF_SEPARATOR, NULL, NULL);
// refresh
::LoadString(GetDfrgResHandle(), IDS_REFRESH, menuText, sizeof(menuText) / sizeof(TCHAR)); ::AppendMenu(hMenu, MF_STRING | MF_ENABLED, ID_REFRESH, menuText);
// separator
::AppendMenu(hMenu, MF_SEPARATOR, NULL, NULL);
// help
::LoadString(GetDfrgResHandle(), IDS_HELP, menuText, sizeof(menuText) / sizeof(TCHAR)); ::AppendMenu(hMenu, MF_STRING | MF_ENABLED, ID_HELP_CONTENTS, menuText);
//
// Display pop-up.
//
// get mouse coordinates
short xPos = LOWORD(lParam); short yPos = HIWORD(lParam);
// get window screen location
RECT rect; BOOL ok = ::GetWindowRect(m_ListView.m_hwndListView, &rect); // if we got the window location and the mouse coords are negative,
// assume invoked from keyboard and locate menu in window
if (ok && (xPos < 0 || yPos < 0)) { xPos = rect.left + 10; yPos = rect.top + 10; }
// map menu
TrackPopupMenu(hMenu, TPM_LEFTALIGN | TPM_RIGHTBUTTON, xPos, yPos, 0, m_hWndCD, //GetParent( m_hwndListView ),
NULL );
::DestroyMenu(hMenu); hr = S_OK; } }
return( hr ); }
STDMETHODIMP CDfrgCtl::get_Enabled(BOOL *pVal) { if (m_IsOkToRun) Message(TEXT("CDfrgCtl::get_Enabled returning TRUE"), -1, NULL); else Message(TEXT("CDfrgCtl::get_Enabled returning FALSE"), -1, NULL);
*pVal = m_IsOkToRun;
return S_OK; }
STDMETHODIMP CDfrgCtl::put_Enabled(BOOL newVal) { if (newVal) Message(TEXT("CDfrgCtl::put_Enabled got TRUE"), -1, NULL); else Message(TEXT("CDfrgCtl::put_Enabled got FALSE"), -1, NULL);
return S_OK; }
//-------------------------------------------------------------------*
// function: OnSetFocus
//
// returns: None
// note:
//-------------------------------------------------------------------*
LRESULT CDfrgCtl::OnSetFocus(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) { Message(TEXT("CDfrgCtl::OnSetFocus"), -1, NULL);
CComQIPtr <IOleControlSite, &IID_IOleControlSite> spSite(m_spClientSite); if (m_bInPlaceActive && spSite) { spSite->OnFocus(TRUE); m_ListView.SetFocus(); // list box gets focus first
}
return 0; }
LRESULT CDfrgCtl::OnKillFocus(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) { Message(TEXT("CDfrgCtl::OnKillFocus"), -1, NULL);
CComQIPtr <IOleControlSite, &IID_IOleControlSite> spSite(m_spClientSite); if (m_bInPlaceActive && spSite) spSite->OnFocus(FALSE); return 0; }
//-------------------------------------------------------------------*
// function: HandleEnterKeyPress
//
// returns: S_OK: we handled keypress
// S_FALSE: we didn't handle keypress
// note:
//-------------------------------------------------------------------*
HRESULT CDfrgCtl::HandleEnterKeyPress() { HWND hWndCurrent = GetFocus(); // current focus window
HRESULT hr = S_FALSE;
if (hWndCurrent == m_pAnalyzeButton->GetWindowHandle()) { put_Command(ID_ANALYZE); hr = S_OK; } else if (hWndCurrent == m_pDefragButton->GetWindowHandle()) { put_Command(ID_DEFRAG); hr = S_OK; } else if (hWndCurrent == m_pPauseButton->GetWindowHandle()) { put_Command(ID_PAUSE); hr = S_OK; } else if (hWndCurrent == m_pStopButton->GetWindowHandle()) { put_Command(ID_STOP); hr = S_OK; } else if (hWndCurrent == m_pReportButton->GetWindowHandle()) { // is the engine IDLE?
CVolume *pVolume = m_VolumeList.GetCurrentVolume(); if (pVolume) { if(pVolume->EngineState() == ENGINE_STATE_IDLE) { RaiseReportDialog(pVolume); hr = S_OK; ::SetFocus(m_pReportButton->GetWindowHandle()); } } }
return hr; }
|