Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

969 lines
25 KiB

// StatsDlg.cpp : Implementation of CStatusDlg
#include "stdafx.h"
#include "WizChain.h"
#include "StatsDlg.h"
// This is the thread that displays the status dialog
DWORD WINAPI DialogThreadProc( LPVOID lpv )
{
HRESULT hr;
CStatusDlg * pSD = (CStatusDlg *)lpv;
// Increment the ref count so that the object does not disappear when the user releases it
hr = pSD->AddRef();
if( SUCCEEDED(hr) && pSD )
{
pSD->DoModal(NULL);
}
// Decrement the ref count
pSD->Release();
return 0;
}
STDMETHODIMP CStatusDlg::AddComponent( BSTR bstrComponent, long * plIndex )
{
HRESULT hr = S_OK;
// If the dialog is already displayed
// we are not accepting new components
if( m_hThread )
return E_UNEXPECTED;
// Validate the arguments
if( NULL == bstrComponent || NULL == plIndex )
return E_INVALIDARG;
// Get a new index
long lNewIndex = m_mapComponents.size();
if( m_mapComponents.find(lNewIndex) == m_mapComponents.end() )
{
// Add the new component
BSTR bstrNewComponent = SysAllocString(bstrComponent);
if( bstrNewComponent )
{
m_mapComponents.insert(COMPONENTMAP::value_type(lNewIndex, bstrNewComponent));
}
else
{
hr = E_OUTOFMEMORY;
}
}
else
{
hr = E_UNEXPECTED; // This cannot happen!
}
if( SUCCEEDED(hr) )
{
*plIndex = lNewIndex;
}
return hr;
}
STDMETHODIMP CStatusDlg::Initialize( BSTR bstrWindowTitle, BSTR bstrWindowText, VARIANT varFlags )
{
HRESULT hr = S_OK;
// If the dialog is already displayed
// do not allow to reinitialize
if( m_hThread ) return E_UNEXPECTED;
if( !bstrWindowTitle || !bstrWindowText ) return E_INVALIDARG;
if( VT_I2 != V_VT(&varFlags) && VT_I4 != V_VT(&varFlags) ) return E_INVALIDARG;
if( VT_I2 == V_VT(&varFlags) )
{
m_lFlags = (long) varFlags.iVal;
}
else
{
m_lFlags = varFlags.lVal;
}
if( SUCCEEDED(hr) )
{
// Initialize the common control library
INITCOMMONCONTROLSEX initCommonControlsEx;
initCommonControlsEx.dwSize = sizeof(initCommonControlsEx);
initCommonControlsEx.dwICC = ICC_PROGRESS_CLASS | ICC_LISTVIEW_CLASSES;
if( !::InitCommonControlsEx(&initCommonControlsEx) )
{
hr = HRESULT_FROM_WIN32(GetLastError());
}
}
if( SUCCEEDED(hr) )
{
if( bstrWindowTitle )
{
m_strWindowTitle = bstrWindowTitle; // Status Dialog Title
}
if( bstrWindowText )
{
m_strWindowText = bstrWindowText; // Status Dialog Text
}
}
return hr;
}
STDMETHODIMP CStatusDlg::SetStatus(long lIndex, SD_STATUS lStatus)
{
HRESULT hr = S_OK;
BOOL bToggleActive = FALSE;
COMPONENTMAP::iterator compIterator;
// Validate the arguments
if( (SD_STATUS_NONE > lStatus) || (SD_STATUS_RUNNING < lStatus) )
{
return E_INVALIDARG;
}
compIterator = m_mapComponents.find(lIndex);
if( compIterator == m_mapComponents.end() )
{
return E_INVALIDARG; // Cannot find the component
}
if( IsWindow() )
{
if( m_pProgressList )
{
CProgressItem * pPI;
compIterator = m_mapComponents.begin();
// Make sure that no component has status "running"
while( compIterator != m_mapComponents.end() )
{
pPI = m_pProgressList->GetProgressItem(compIterator->first);
if( pPI && pPI->m_bActive )
{
m_pProgressList->ToggleActive(compIterator->first);
}
compIterator++;
}
if( SD_STATUS_RUNNING == lStatus )
{
m_pProgressList->ToggleActive(lIndex); // New status is "running"
}
else
{
// Update the state of the component on the Listview
m_pProgressList->SetItemState(lIndex, (ItemState) lStatus);
// If the component's done, update the total progress
if( (lStatus == SD_STATUS_SUCCEEDED) || (lStatus == SD_STATUS_FAILED) )
{
// TO DO: No need to do this, just send a message to the dialog to do that
PBRANGE range;
SendDlgItemMessage(IDC_PROGRESS1, PBM_GETRANGE, FALSE, (LPARAM) &range);
SendDlgItemMessage(IDC_PROGRESS1, PBM_SETPOS, range.iHigh, 0);
InterlockedExchangeAdd(&m_lTotalProgress, range.iHigh);
}
}
}
else
{
hr = E_UNEXPECTED;
}
if( SUCCEEDED(hr) )
{
SetupButtons( );
}
}
else
{
hr = E_UNEXPECTED;
}
return hr;
}
void CStatusDlg::SetupButtons( )
{
HWND hWnd = NULL;
HWND hWndOK = NULL;
HWND hWndCancel = NULL;
CString csText;
BOOL bFailed = FALSE;
BSTR bstrText = NULL;
USES_CONVERSION;
hWndOK = GetDlgItem(IDOK);
hWndCancel = GetDlgItem(IDCANCEL);
if( IsWindow() && hWndOK && hWndCancel )
{
if( AreAllComponentsDone(bFailed) )
{
// Enable OK button
::EnableWindow(hWndOK, TRUE);
// Disable Cancel button
::EnableWindow(hWndCancel, FALSE);
// Default button is the Close button
::SendMessage(m_hWnd, WM_NEXTDLGCTL, (WPARAM) hWndOK, 1);
//
// When all components are done we will hide the progress bars to give the user
// a visual clue to realize that the wizard is done. I know, that sounds stupid.
//
hWnd = GetDlgItem(IDC_STATIC2); // Component progress text
if (NULL != hWnd)
{
::ShowWindow(hWnd, SW_HIDE);
}
hWnd = GetDlgItem(IDC_PROGRESS1); // Component progress text
if (NULL != hWnd)
{
::ShowWindow(hWnd, SW_HIDE);
}
hWnd = GetDlgItem(IDC_STATIC3); // Overall progress text
if (NULL != hWnd)
{
::ShowWindow(hWnd, SW_HIDE);
}
hWnd = GetDlgItem(IDC_PROGRESS2); // Overall progress
if (NULL != hWnd)
{
::ShowWindow(hWnd, SW_HIDE);
}
if (FALSE == bFailed)
{
if (csText.LoadString(IDS_STATUS_SUCCESS))
{
bstrText = T2BSTR(csText);
if (NULL != bstrText)
{
SetStatusText(bstrText);
}
}
}
else
{
if (csText.LoadString(IDS_STATUS_FAIL))
{
bstrText = T2BSTR(csText);
if (NULL != bstrText)
{
SetStatusText(bstrText);
}
}
}
if (NULL != bstrText)
{
::SysFreeString(bstrText);
}
}
else
{
// Disable OK button
::EnableWindow( hWndOK, FALSE );
if( m_lFlags & SD_BUTTON_CANCEL )
{
::EnableWindow( hWndCancel, TRUE );
}
}
}
}
STDMETHODIMP CStatusDlg::Display( BOOL bShow )
{
HRESULT hr = S_OK;
if( bShow )
{
if( m_hThread != NULL )
{
if( !IsWindowVisible() ) // We are already on
{
ShowWindow(SW_SHOW);
}
}
else
{
// Create a new thread which will DoModal the status dialog
m_hThread = CreateThread( NULL, 0, DialogThreadProc, (void *) this, 0, NULL );
if( NULL == m_hThread )
{
hr = HRESULT_FROM_WIN32(GetLastError());
}
else if( m_hDisplayedEvent ) // Wait till the dialog is displayed
{
if( WAIT_OBJECT_0 != WaitForSingleObject(m_hDisplayedEvent, INFINITE) )
{
hr = E_UNEXPECTED;
}
}
}
}
else
{
// Will close the dialog
if( m_hThread != NULL )
{
EndDialog(IDCANCEL);
WaitForSingleObject(m_hThread, INFINITE);
}
}
return hr;
}
// The wizard writer should call this function to wait on user response
// If the user has already responded: clicked OK or Cancel
// then this method will return immediately
STDMETHODIMP CStatusDlg::WaitForUser( )
{
if( m_hThread )
{
WaitForSingleObject(m_hThread, INFINITE);
}
return S_OK;
}
STDMETHODIMP CStatusDlg::get_Cancelled( BOOL *pVal )
{
if( NULL == pVal )
{
return E_INVALIDARG;
}
if( m_lFlags & SD_BUTTON_CANCEL )
{
if( m_iCancelled == 0 )
{
*pVal = FALSE;
}
else
{
*pVal = TRUE;
}
}
else
{
*pVal = FALSE;
}
return S_OK;
}
STDMETHODIMP CStatusDlg::get_ComponentProgress( IStatusProgress** pVal )
{
HRESULT hr = S_OK;
if( NULL == pVal )
{
return E_INVALIDARG;
}
if( m_lFlags & SD_PROGRESS_COMPONENT )
{
// Create component progress object
if( m_pComponentProgress == NULL )
{
hr = CComObject<CStatusProgress>::CreateInstance(&m_pComponentProgress);
if( SUCCEEDED(hr) )
{
hr = m_pComponentProgress->AddRef();
}
if( SUCCEEDED(hr) && IsWindow() )
{
// Initialize the component progress with the progress bar handle
hr = m_pComponentProgress->Initialize(this, GetDlgItem(IDC_PROGRESS1), FALSE);
}
}
if( SUCCEEDED(hr) )
{
hr = (m_pComponentProgress->QueryInterface(IID_IStatusProgress, (void **) pVal));
}
}
return hr;
}
LRESULT CStatusDlg::OnInitDialog( UINT uint, WPARAM wparam, LPARAM lparam, BOOL& bbool )
{
HWND hWndText = GetDlgItem(IDC_STATIC1);
HWND hWndLV = GetDlgItem(IDC_LIST2);
HWND hWndCompText = GetDlgItem(IDC_STATIC2);
HWND hWndCompProgress = GetDlgItem(IDC_PROGRESS1);
HWND hWndOverallText = GetDlgItem(IDC_STATIC3);
HWND hWndOverallProgress = GetDlgItem(IDC_PROGRESS2);
HWND hWndOK = GetDlgItem(IDOK);
HWND hWndCancel = GetDlgItem(IDCANCEL);
LOGFONT logFont;
HIMAGELIST hILSmall;
HBITMAP hBitmap;
HDC hDC;
TEXTMETRIC tm;
RECT rect;
CWindow wnd;
int iResizeLV = 0;
int iResize = 0;
// Attach to the Listview
wnd.Attach(hWndLV);
wnd.GetWindowRect(&rect);
hDC = GetDC();
GetTextMetrics(hDC, &tm);
ReleaseDC(hDC);
// Check if size of the list view is OK enough to hold all the components
iResizeLV = rect.bottom - rect.top - ((tm.tmHeight + 2) * (m_mapComponents.size() + 1));
// Depending on the options selected, decide whether the stus dialog will shrink or expand
if( (m_lFlags & SD_PROGRESS_COMPONENT) && !(m_lFlags & SD_PROGRESS_OVERALL) )
{
iResize = GetWindowLength(hWndOverallText, hWndOverallProgress);
}
else if( !(m_lFlags & SD_PROGRESS_COMPONENT) && (m_lFlags & SD_PROGRESS_OVERALL) )
{
iResize = GetWindowLength(hWndCompText, hWndCompProgress);
}
else if( !(m_lFlags & SD_PROGRESS_COMPONENT) && !(m_lFlags & SD_PROGRESS_OVERALL) )
{
iResize = GetWindowLength(hWndCompText, hWndOverallProgress);
}
// Hide component progress if necessary
if( !(m_lFlags & SD_PROGRESS_COMPONENT) )
{
::ShowWindow(hWndCompText, SW_HIDE);
::ShowWindow(hWndCompProgress, SW_HIDE);
}
// Hide overall progress if necessary
if( !(m_lFlags & SD_PROGRESS_OVERALL) )
{
::ShowWindow(hWndOverallText, SW_HIDE);
::ShowWindow(hWndOverallProgress, SW_HIDE);
}
if ((!(m_lFlags & SD_PROGRESS_OVERALL)) || (!(m_lFlags & SD_PROGRESS_COMPONENT)))
{
// We need to get rid of the space between the progress bars
iResize -= GetWindowLength(hWndCompText, hWndOverallProgress) - GetWindowLength(hWndOverallText, hWndOverallProgress) - GetWindowLength(hWndCompText, hWndOverallProgress) + 4;
}
// Well, we may need to make LV bigger, but the dialog length could stay the same
// if the user does not want component and/or overall progress
if( iResizeLV < 0 ) // Will need to make the LV bigger
{
iResize += iResizeLV;
}
else
{
iResizeLV = 0; // We will not touch the LV
}
if( iResizeLV != 0 || iResize != 0 ) // We will need to do some moving and resizing
{
VerticalResizeWindow(m_hWnd, iResize);
VerticalMoveWindow(hWndOK, iResize);
VerticalMoveWindow(hWndCancel, iResize);
// Location of progress bars completely depend on the resizing of the LV
VerticalMoveWindow(hWndOverallText, iResizeLV);
VerticalMoveWindow(hWndOverallProgress, iResizeLV);
VerticalMoveWindow(hWndCompText, iResizeLV);
VerticalMoveWindow(hWndCompProgress, iResizeLV);
// Last, but not the least, resize the LV
VerticalResizeWindow(hWndLV, iResizeLV);
}
if( !(m_lFlags & SD_BUTTON_CANCEL) ) // We will only have an OK button
{
LONG_PTR dwStyle = ::GetWindowLongPtr( m_hWnd, GWL_STYLE );
if( 0 != dwStyle )
{
// Get rid of the System Menu (Close X) as well
dwStyle &= ~WS_SYSMENU;
::SetWindowLongPtr( m_hWnd, GWL_STYLE, dwStyle );
}
ReplaceWindow(hWndCancel, hWndOK);
}
// if we only have overall progress, we need to move it up
// so that it replaces the component progress
if( (m_lFlags & SD_PROGRESS_OVERALL) && !(m_lFlags & SD_PROGRESS_COMPONENT) )
{
ReplaceWindow(hWndCompText, hWndOverallText);
ReplaceWindow(hWndCompProgress, hWndOverallProgress);
}
// Set some style for the LV
::SendMessage(hWndLV, LVM_SETEXTENDEDLISTVIEWSTYLE, 0, LVS_EX_SUBITEMIMAGES);
::SendMessage(hWndLV, LVM_SETBKCOLOR, 0, (LPARAM) CLR_NONE);
::SendMessage(hWndLV, LVM_SETTEXTBKCOLOR, 0, (LPARAM) CLR_NONE);
LVCOLUMN col;
ZeroMemory (&col, sizeof(col));
col.mask = LVCF_WIDTH;
col.cx = 500;
SendMessage( hWndLV, LVM_INSERTCOLUMN, 0, (LPARAM)&col );
// Thanks to Jeffzi
m_pProgressList->Attach( hWndLV );
COMPONENTMAP::iterator compIterator;
compIterator = m_mapComponents.begin();
while( compIterator != m_mapComponents.end() )
{
// Add each component to the LV
m_pProgressList->AddItem(compIterator->second);
m_pProgressList->SetItemState(compIterator->first, IS_NONE, FALSE );
compIterator++;
}
if( m_pComponentProgress )
{
// Initialize the component progress with the progress bar handle
m_pComponentProgress->Initialize( this, hWndCompProgress, FALSE );
}
if (m_pOverallProgress)
{
// Initialize the overall progress with the progress bar handle
m_pOverallProgress->Initialize( this, hWndOverallProgress, TRUE );
}
// Here comes the dialog title and text
SetWindowText(m_strWindowTitle.c_str());
::SetWindowText(hWndText, m_strWindowText.c_str());
SetupButtons();
// Center the window, no Jeff this works just right if you have 2 monitors
CenterWindow();
if( m_hDisplayedEvent )
{
SetEvent(m_hDisplayedEvent);
}
return TRUE;
}
BOOL CStatusDlg::VerticalMoveWindow( HWND hWnd, int iResize )
{
BOOL bRet;
CWindow wnd;
RECT rect;
wnd.Attach( hWnd ); // Returns void
if(wnd.GetWindowRect(&rect) )
{
rect.top -= iResize;
rect.bottom -= iResize;
// GetWindowRect fills in RECT relative to the desktop
// We need to make it relative to the dialog
// as MoveWindow works that way
if( ScreenToClient(&rect) )
{
bRet = wnd.MoveWindow(&rect);
}
else
{
bRet = FALSE;
}
}
else
{
bRet = FALSE;
}
return bRet;
}
BOOL CStatusDlg::ReplaceWindow( HWND hWndOld, HWND hWndNew )
{
BOOL bRet;
CWindow wnd;
RECT rect;
wnd.Attach(hWndOld);
// Get the coordinates of the old Window
if( wnd.GetWindowRect(&rect) )
{
// Hide it, we are trying to replace it
wnd.ShowWindow(SW_HIDE);
// Attach to the new one
wnd.Attach(hWndNew);
// Map the coordinates and move the window on top of the old one
if( ScreenToClient(&rect) )
{
bRet = wnd.MoveWindow(&rect);
}
else
{
bRet = FALSE;
}
}
else
{
bRet = FALSE;
}
return bRet;
}
BOOL CStatusDlg::VerticalResizeWindow( HWND hWnd, int iResize )
{
CWindow wnd;
RECT rect;
BOOL bRet = FALSE;
if( iResize )
{
// Attach to the window
wnd.Attach(hWnd);
// Get the coordinates
if( wnd.GetWindowRect(&rect) )
{
rect.bottom -= iResize; // Increase the bottom
if( ScreenToClient(&rect) )
{
bRet = wnd.MoveWindow(&rect); // Resize
}
else
{
bRet= FALSE;
}
}
else
{
bRet = FALSE;
}
}
return bRet;
}
int CStatusDlg::GetWindowLength( HWND hWndTop, HWND hWndBottom )
{
CWindow wnd;
RECT rect;
int iTop;
wnd.Attach(hWndTop);
if( wnd.GetWindowRect(&rect) )
{
iTop = rect.top;
wnd.Attach(hWndBottom);
if( wnd.GetWindowRect(&rect) )
{
return rect.bottom - iTop;
}
}
return 0;
}
STDMETHODIMP CStatusDlg::get_OverallProgress( IStatusProgress** pVal )
{
HRESULT hr = S_OK;
if( NULL == pVal )
{
return E_INVALIDARG;
}
if( m_lFlags & SD_PROGRESS_OVERALL )
{
// Create component progress object
if( m_pOverallProgress == NULL )
{
hr = CComObject<CStatusProgress>::CreateInstance(&m_pOverallProgress);
if( SUCCEEDED(hr) )
{
hr = m_pOverallProgress->AddRef();
}
if( SUCCEEDED(hr) && IsWindow() )
{
// Initialize the overall progress with the progress bar handle
hr = m_pOverallProgress->Initialize(this, GetDlgItem(IDC_PROGRESS2), TRUE);
}
}
hr = m_pOverallProgress->QueryInterface(IID_IStatusProgress, (void **) pVal);
}
return hr;
}
BOOL CStatusDlg::AreAllComponentsDone( BOOL& bFailedComponent )
{
BOOL bComponentToRun = FALSE;
COMPONENTMAP::iterator compIterator = m_mapComponents.begin();
if( m_pProgressList )
{
// Look for a component that's not done
while( m_pProgressList && !bComponentToRun && compIterator != m_mapComponents.end() )
{
CProgressItem * pPI = m_pProgressList->GetProgressItem(compIterator->first);
if( NULL != pPI )
{
// Is the component done?
if( IS_NONE == pPI->m_eState )
{
bComponentToRun = TRUE;
}
else if( IS_FAILED == pPI->m_eState )
{
bFailedComponent = TRUE;
}
}
else
{
_ASSERT( pPI );
}
compIterator++;
}
}
return !bComponentToRun;
}
LRESULT CStatusDlg::OnCloseCmd( WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*/, BOOL& /*bHandled*/ )
{
EndDialog(wID);
return 0;
}
LRESULT CStatusDlg::OnCancelCmd( WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*/, BOOL& /*bHandled*/ )
{
HWND hWnd = NULL;
if( 0 == m_iCancelled )
{
InterlockedIncrement((LONG *) &m_iCancelled);
}
// Disable the Cancel button
hWnd = GetDlgItem(IDCANCEL);
if( hWnd && ::IsWindow(hWnd) )
{
::EnableWindow( hWnd, FALSE );
}
// EndDialog(wID);
// Leaving it to the component to close the dialog
return 0;
}
LRESULT CStatusDlg::OnDrawItem( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled )
{
if( wParam == IDC_LIST2 )
{
if( m_pProgressList )
{
m_pProgressList->OnDrawItem( lParam );
}
}
return 0;
}
LRESULT CStatusDlg::OnMeasureItem( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled )
{
if( wParam == IDC_LIST2)
{
if( m_pProgressList )
{
m_pProgressList->OnMeasureItem( lParam );
}
}
return 0;
}
LRESULT CStatusDlg::OnClose( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled )
{
if( m_lFlags & SD_BUTTON_CANCEL ) // Cancel button?
{
if( ::IsWindowEnabled( GetDlgItem(IDCANCEL) ) ) // Is it enabled?
{
if( 0 == m_iCancelled )
{
InterlockedIncrement( (LONG*)&m_iCancelled );
}
EndDialog(0);
}
else if( ::IsWindowEnabled( GetDlgItem(IDOK) ) )
{
// it could be OK button sending WM_CLOSE or the user
// As long as OK button is enabled we need to close the dialog
EndDialog(1);
}
}
else if( ::IsWindowEnabled( GetDlgItem(IDOK) ) )
{
EndDialog( 1 );
}
return 0;
}
LRESULT CStatusDlg::OnTimerProgress( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled )
{
HRESULT hr;
long lPosition;
if( wParam && (m_lTimer == wParam) ) // Make sure that this is for our timer
{
lPosition = SendDlgItemMessage(IDC_PROGRESS1, PBM_GETPOS, 0, 0);
if( lPosition < m_lMaxSteps ) // Do we still have room for progress?
{
SendDlgItemMessage(IDC_PROGRESS1, PBM_STEPIT, 0, 0); // Step 1
SendMessage(WM_UPDATEOVERALLPROGRESS, 0, 0); // Update the overall progress
}
else
{
// There's no room to progress, we've reached the max
// Let's kill the timer
SendMessage(WM_KILLTIMER, 0);
}
}
return 0;
}
LRESULT CStatusDlg::OnUpdateOverallProgress( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled )
{
long lPosition = 0;
if( m_lFlags & SD_PROGRESS_COMPONENT ) // Make sure that there's a component progress
{
lPosition = SendDlgItemMessage(IDC_PROGRESS1, PBM_GETPOS, 0, 0);
// Update the overall progress
SendDlgItemMessage(IDC_PROGRESS2, PBM_SETPOS, m_lTotalProgress + lPosition, 0);
}
return 0;
}
LRESULT CStatusDlg::OnStartTimer( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled )
{
if( !m_lTimer ) // There might be a timer already
{
m_lTimer = SetTimer(SD_TIMER_ID, wParam * 500); // Create a timer
m_lMaxSteps = (long) lParam; // Max. not to exceed for the progress bar
}
return 0;
}
LRESULT CStatusDlg::OnKillTimer( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled )
{
if( m_lTimer ) // Is there a timer?
{
KillTimer( m_lTimer ); // Kill it
m_lTimer = 0;
m_lMaxSteps = 0;
}
return 0;
}
STDMETHODIMP CStatusDlg::SetStatusText(BSTR bstrText)
{
if( !bstrText ) return E_POINTER;
HRESULT hr = S_OK;
HWND hWnd = GetDlgItem(IDC_STATIC1);
if( hWnd && ::IsWindow(hWnd) )
{
if( 0 == ::SetWindowText(hWnd, OLE2T(bstrText)) )
{
hr = HRESULT_FROM_WIN32(GetLastError());
}
}
else
{
hr = E_FAIL;
}
return hr;
}
STDMETHODIMP CStatusDlg::DisplayError(BSTR bstrError, BSTR bstrTitle, DWORD dwFlags, long * pRet)
{
if( !bstrError || !bstrTitle || !pRet ) return E_POINTER;
HRESULT hr = S_OK;
*pRet = MessageBox( bstrError, bstrTitle, dwFlags );
if( 0 == *pRet )
{
hr = HRESULT_FROM_WIN32(GetLastError());
}
return hr;
}