1747 lines
41 KiB
C++
1747 lines
41 KiB
C++
|
//////////////////////////////////////////////////////////////////////////////
|
||
|
//
|
||
|
// Copyright (c) 2000-2001 Microsoft Corporation
|
||
|
//
|
||
|
// Module Name:
|
||
|
// DetailsDlg.cpp
|
||
|
//
|
||
|
// Maintained By:
|
||
|
// David Potter (DavidP) 27-MAR-2001
|
||
|
//
|
||
|
//////////////////////////////////////////////////////////////////////////////
|
||
|
|
||
|
#include "Pch.h"
|
||
|
#include "TaskTreeView.h"
|
||
|
#include "DetailsDlg.h"
|
||
|
#include "WizardUtils.h"
|
||
|
|
||
|
DEFINE_THISCLASS("DetailsDlg");
|
||
|
|
||
|
//////////////////////////////////////////////////////////////////////////////
|
||
|
// Static Function Prototypes
|
||
|
//////////////////////////////////////////////////////////////////////////////
|
||
|
|
||
|
static
|
||
|
BOOL
|
||
|
ButtonFaceColorIsDark( void );
|
||
|
|
||
|
static
|
||
|
void
|
||
|
SetButtonImage(
|
||
|
HWND hwndBtnIn
|
||
|
, ULONG idIconIn
|
||
|
);
|
||
|
|
||
|
static
|
||
|
void
|
||
|
FreeButtonImage(
|
||
|
HWND hwndBtnIn
|
||
|
);
|
||
|
|
||
|
static
|
||
|
HRESULT
|
||
|
HrAppendStringToClipboardString(
|
||
|
BSTR * pbstrClipboard
|
||
|
, UINT idsLabelIn
|
||
|
, LPCWSTR pszDataIn
|
||
|
, bool fNewlineBeforeTextIn
|
||
|
);
|
||
|
|
||
|
//////////////////////////////////////////////////////////////////////////////
|
||
|
//++
|
||
|
//
|
||
|
// CDetailsDlg::S_HrDisplayModalDialog
|
||
|
//
|
||
|
// Description:
|
||
|
// Display the dialog box.
|
||
|
//
|
||
|
// Arguments:
|
||
|
// hwndParentIn - Parent window for the dialog box.
|
||
|
// pttvIn - Task tree view control.
|
||
|
// htiSelectedIn - Handle to the selected item.
|
||
|
//
|
||
|
// Return Values:
|
||
|
// S_OK - Operation completed successfully.
|
||
|
//
|
||
|
// Remarks:
|
||
|
//
|
||
|
//--
|
||
|
//////////////////////////////////////////////////////////////////////////////
|
||
|
HRESULT
|
||
|
CDetailsDlg::S_HrDisplayModalDialog(
|
||
|
HWND hwndParentIn
|
||
|
, CTaskTreeView * pttvIn
|
||
|
, HTREEITEM htiSelectedIn
|
||
|
)
|
||
|
{
|
||
|
TraceFunc( "" );
|
||
|
|
||
|
Assert( pttvIn != NULL );
|
||
|
Assert( htiSelectedIn != NULL );
|
||
|
|
||
|
HRESULT hr = S_OK;
|
||
|
CDetailsDlg dlg( pttvIn, htiSelectedIn );
|
||
|
|
||
|
DialogBoxParam(
|
||
|
g_hInstance
|
||
|
, MAKEINTRESOURCE( IDD_DETAILS )
|
||
|
, hwndParentIn
|
||
|
, CDetailsDlg::S_DlgProc
|
||
|
, (LPARAM) &dlg
|
||
|
);
|
||
|
|
||
|
HRETURN( hr );
|
||
|
|
||
|
} //*** CDetailsDlg::S_HrDisplayModalDialog()
|
||
|
|
||
|
//////////////////////////////////////////////////////////////////////////////
|
||
|
//++
|
||
|
//
|
||
|
// CDetailsDlg::CDetailsDlg
|
||
|
//
|
||
|
// Description:
|
||
|
// Constructor.
|
||
|
//
|
||
|
// Arguments:
|
||
|
// pttvIn - Tree view to traverse.
|
||
|
// htiSelectedIn - Handle to the selected item in the tree control.
|
||
|
//
|
||
|
// Return Values:
|
||
|
// None.
|
||
|
//
|
||
|
//--
|
||
|
//////////////////////////////////////////////////////////////////////////////
|
||
|
CDetailsDlg::CDetailsDlg(
|
||
|
CTaskTreeView * pttvIn
|
||
|
, HTREEITEM htiSelectedIn
|
||
|
)
|
||
|
{
|
||
|
TraceFunc( "" );
|
||
|
|
||
|
Assert( pttvIn != NULL );
|
||
|
Assert( htiSelectedIn != NULL );
|
||
|
|
||
|
// m_hwnd
|
||
|
m_hiconWarn = NULL;
|
||
|
m_hiconError = NULL;
|
||
|
m_pttv = pttvIn;
|
||
|
m_htiSelected = htiSelectedIn;
|
||
|
|
||
|
m_fControlDown = FALSE;
|
||
|
m_fAltDown = FALSE;
|
||
|
|
||
|
TraceFuncExit();
|
||
|
|
||
|
} //*** CDetailsDlg::CDetailsDlg()
|
||
|
|
||
|
//////////////////////////////////////////////////////////////////////////////
|
||
|
//++
|
||
|
//
|
||
|
// CDetailsDlg::~CDetailsDlg
|
||
|
//
|
||
|
// Description:
|
||
|
// Destructor.
|
||
|
//
|
||
|
// Arguments:
|
||
|
// None.
|
||
|
//
|
||
|
// Return Values:
|
||
|
// None.
|
||
|
//
|
||
|
//--
|
||
|
//////////////////////////////////////////////////////////////////////////////
|
||
|
CDetailsDlg::~CDetailsDlg( void )
|
||
|
{
|
||
|
TraceFunc( "" );
|
||
|
|
||
|
if ( m_hiconWarn != NULL )
|
||
|
{
|
||
|
DeleteObject( m_hiconWarn );
|
||
|
}
|
||
|
|
||
|
if ( m_hiconError != NULL )
|
||
|
{
|
||
|
DeleteObject( m_hiconError );
|
||
|
}
|
||
|
|
||
|
TraceFuncExit();
|
||
|
|
||
|
} //*** CDetailsDlg::~CDetailsDlg()
|
||
|
|
||
|
//////////////////////////////////////////////////////////////////////////////
|
||
|
//++
|
||
|
//
|
||
|
// CDetailsDlg::S_DlgProc
|
||
|
//
|
||
|
// Description:
|
||
|
// Dialog proc for the Details dialog box.
|
||
|
//
|
||
|
// Arguments:
|
||
|
// hwndDlgIn - Dialog box window handle.
|
||
|
// nMsgIn - Message ID.
|
||
|
// wParam - Message-specific parameter.
|
||
|
// lParam - Message-specific parameter.
|
||
|
//
|
||
|
// Return Values:
|
||
|
// TRUE - Message was processed by this procedure.
|
||
|
// FALSE - Message was NOT processed by this procedure.
|
||
|
//
|
||
|
// Remarks:
|
||
|
// It is expected that this dialog box is invoked by a call to
|
||
|
// DialogBoxParam() with the lParam argument set to the address of the
|
||
|
// instance of this class.
|
||
|
//
|
||
|
//--
|
||
|
//////////////////////////////////////////////////////////////////////////////
|
||
|
INT_PTR
|
||
|
CALLBACK
|
||
|
CDetailsDlg::S_DlgProc(
|
||
|
HWND hwndDlgIn
|
||
|
, UINT nMsgIn
|
||
|
, WPARAM wParam
|
||
|
, LPARAM lParam
|
||
|
)
|
||
|
{
|
||
|
// Don't do TraceFunc because every mouse movement
|
||
|
// will cause this function to be called.
|
||
|
|
||
|
WndMsg( hwndDlgIn, nMsgIn, wParam, lParam );
|
||
|
|
||
|
LRESULT lr = FALSE;
|
||
|
HACCEL haccel = NULL;
|
||
|
CDetailsDlg * pdlg;
|
||
|
|
||
|
//
|
||
|
// Get a pointer to the class.
|
||
|
//
|
||
|
|
||
|
if ( nMsgIn == WM_INITDIALOG )
|
||
|
{
|
||
|
SetWindowLongPtr( hwndDlgIn, GWLP_USERDATA, lParam );
|
||
|
pdlg = reinterpret_cast< CDetailsDlg * >( lParam );
|
||
|
pdlg->m_hwnd = hwndDlgIn;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
pdlg = reinterpret_cast< CDetailsDlg * >( GetWindowLongPtr( hwndDlgIn, GWLP_USERDATA ) );
|
||
|
}
|
||
|
|
||
|
if ( pdlg != NULL )
|
||
|
{
|
||
|
Assert( hwndDlgIn == pdlg->m_hwnd );
|
||
|
|
||
|
switch( nMsgIn )
|
||
|
{
|
||
|
case WM_INITDIALOG:
|
||
|
lr = pdlg->OnInitDialog();
|
||
|
break;
|
||
|
|
||
|
case WM_DESTROY:
|
||
|
pdlg->OnDestroy();
|
||
|
break;
|
||
|
|
||
|
case WM_SYSCOLORCHANGE:
|
||
|
pdlg->OnSysColorChange();
|
||
|
break;
|
||
|
|
||
|
case WM_NOTIFY:
|
||
|
lr = pdlg->OnNotify( wParam, reinterpret_cast< LPNMHDR >( lParam ) );
|
||
|
break;
|
||
|
|
||
|
case WM_COMMAND:
|
||
|
lr = pdlg->OnCommand( HIWORD( wParam ), LOWORD( wParam ), reinterpret_cast< HWND >( lParam ) );
|
||
|
break;
|
||
|
|
||
|
case WM_KEYDOWN:
|
||
|
lr = pdlg->OnKeyDown( lParam );
|
||
|
break;
|
||
|
|
||
|
case WM_KEYUP:
|
||
|
lr = pdlg->OnKeyUp( lParam );
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
lr = FALSE;
|
||
|
} // switch: nMsgIn
|
||
|
} // if: page is specified
|
||
|
|
||
|
return lr;
|
||
|
|
||
|
} //*** CDetailsDlg::S_DlgProc()
|
||
|
|
||
|
//////////////////////////////////////////////////////////////////////////////
|
||
|
//++
|
||
|
//
|
||
|
// CDetailsDlg::OnInitDialog
|
||
|
//
|
||
|
// Description:
|
||
|
// Handler for the WM_INITDIALOG message.
|
||
|
//
|
||
|
// Arguments:
|
||
|
// None.
|
||
|
//
|
||
|
// Return Values:
|
||
|
// TRUE Focus has been set.
|
||
|
// FALSE Focus has not been set.
|
||
|
//--
|
||
|
//////////////////////////////////////////////////////////////////////////////
|
||
|
LRESULT
|
||
|
CDetailsDlg::OnInitDialog( void )
|
||
|
{
|
||
|
TraceFunc( "" );
|
||
|
|
||
|
LRESULT lr = TRUE; // did set focus
|
||
|
HWND hwnd;
|
||
|
|
||
|
//
|
||
|
// Tell the rich edit controls we want to receive notifications of clicks
|
||
|
// on text that has the link (hyperlink, aka URL) format. Also, set the
|
||
|
// background color of the rich edit to match the background color of
|
||
|
// the dialog.
|
||
|
//
|
||
|
|
||
|
hwnd = GetDlgItem( m_hwnd, IDC_DETAILS_RE_DESCRIPTION );
|
||
|
|
||
|
SendMessage( hwnd, EM_SETEVENTMASK, 0, ENM_LINK );
|
||
|
SendMessage( hwnd, EM_SETBKGNDCOLOR, 0, GetSysColor( COLOR_BTNFACE ) );
|
||
|
SendMessage( hwnd, EM_AUTOURLDETECT, TRUE, 0 );
|
||
|
|
||
|
hwnd = GetDlgItem( m_hwnd, IDC_DETAILS_RE_STATUS );
|
||
|
|
||
|
SendMessage( hwnd, EM_SETEVENTMASK, 0, ENM_LINK );
|
||
|
SendMessage( hwnd, EM_SETBKGNDCOLOR, 0, GetSysColor( COLOR_BTNFACE ) );
|
||
|
SendMessage( hwnd, EM_AUTOURLDETECT, TRUE, 0 );
|
||
|
|
||
|
hwnd = GetDlgItem( m_hwnd, IDC_DETAILS_RE_REFERENCE );
|
||
|
|
||
|
SendMessage( hwnd, EM_SETEVENTMASK, 0, ENM_LINK );
|
||
|
SendMessage( hwnd, EM_SETBKGNDCOLOR, 0, GetSysColor( COLOR_BTNFACE ) );
|
||
|
SendMessage( hwnd, EM_AUTOURLDETECT, TRUE, 0 );
|
||
|
|
||
|
//
|
||
|
// Set the icons for the icon pushbuttons
|
||
|
//
|
||
|
|
||
|
OnSysColorChange();
|
||
|
SetButtonImage( GetDlgItem( m_hwnd, IDC_DETAILS_PB_COPY ), IDI_COPY );
|
||
|
|
||
|
//
|
||
|
// Load the status icons.
|
||
|
//
|
||
|
|
||
|
m_hiconWarn = (HICON) LoadImage(
|
||
|
g_hInstance
|
||
|
, MAKEINTRESOURCE( IDI_WARN )
|
||
|
, IMAGE_ICON
|
||
|
, 16
|
||
|
, 16
|
||
|
, LR_SHARED
|
||
|
);
|
||
|
Assert( m_hiconWarn != NULL );
|
||
|
m_hiconError = (HICON) LoadImage(
|
||
|
g_hInstance
|
||
|
, MAKEINTRESOURCE( IDI_FAIL )
|
||
|
, IMAGE_ICON
|
||
|
, 16
|
||
|
, 16
|
||
|
, LR_SHARED
|
||
|
);
|
||
|
Assert( m_hiconError != NULL );
|
||
|
|
||
|
//
|
||
|
// Display the selected item.
|
||
|
//
|
||
|
|
||
|
THR( HrDisplayItem( m_htiSelected ) );
|
||
|
|
||
|
//
|
||
|
// Update the buttons based on what is selected.
|
||
|
//
|
||
|
|
||
|
UpdateButtons();
|
||
|
|
||
|
//
|
||
|
// Set focus to the OK button.
|
||
|
//
|
||
|
|
||
|
SetFocus( GetDlgItem( m_hwnd, IDOK ) );
|
||
|
|
||
|
RETURN( lr );
|
||
|
|
||
|
} //*** CDetailsDlg::OnInitDialog()
|
||
|
|
||
|
//////////////////////////////////////////////////////////////////////////////
|
||
|
//++
|
||
|
//
|
||
|
// CDetailsDlg::OnDestroy
|
||
|
//
|
||
|
// Description:
|
||
|
// Handler for the WM_DESTROY message.
|
||
|
//
|
||
|
// Arguments:
|
||
|
// None.
|
||
|
//
|
||
|
// Return Values:
|
||
|
// None.
|
||
|
//
|
||
|
//--
|
||
|
//////////////////////////////////////////////////////////////////////////////
|
||
|
void
|
||
|
CDetailsDlg::OnDestroy( void )
|
||
|
{
|
||
|
TraceFunc( "" );
|
||
|
|
||
|
//
|
||
|
// Destroy the images loaded for the icon pushbuttons
|
||
|
//
|
||
|
|
||
|
FreeButtonImage( GetDlgItem( m_hwnd, IDC_DETAILS_PB_PREV ) );
|
||
|
FreeButtonImage( GetDlgItem( m_hwnd, IDC_DETAILS_PB_NEXT ) );
|
||
|
FreeButtonImage( GetDlgItem( m_hwnd, IDC_DETAILS_PB_COPY ) );
|
||
|
|
||
|
} //*** CDetailsDlg::OnDestroy()
|
||
|
|
||
|
//////////////////////////////////////////////////////////////////////////////
|
||
|
//++
|
||
|
//
|
||
|
// CDetailsDlg::OnSysColorChange
|
||
|
//
|
||
|
// Description:
|
||
|
// Handler for the WM_SYSCOLORCHANGE message.
|
||
|
//
|
||
|
// Arguments:
|
||
|
// None.
|
||
|
//
|
||
|
// Return Values:
|
||
|
// None.
|
||
|
//
|
||
|
//--
|
||
|
//////////////////////////////////////////////////////////////////////////////
|
||
|
void
|
||
|
CDetailsDlg::OnSysColorChange( void )
|
||
|
{
|
||
|
TraceFunc( "" );
|
||
|
|
||
|
if ( ButtonFaceColorIsDark() )
|
||
|
{
|
||
|
SetButtonImage( GetDlgItem( m_hwnd, IDC_DETAILS_PB_PREV ), IDI_PREVIOUS_HC );
|
||
|
SetButtonImage( GetDlgItem( m_hwnd, IDC_DETAILS_PB_NEXT ), IDI_NEXT_HC );
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
SetButtonImage( GetDlgItem( m_hwnd, IDC_DETAILS_PB_PREV ), IDI_PREVIOUS );
|
||
|
SetButtonImage( GetDlgItem( m_hwnd, IDC_DETAILS_PB_NEXT ), IDI_NEXT );
|
||
|
}
|
||
|
|
||
|
SendDlgItemMessage(
|
||
|
m_hwnd
|
||
|
, IDC_DETAILS_RE_DESCRIPTION
|
||
|
, EM_SETBKGNDCOLOR
|
||
|
, 0
|
||
|
, GetSysColor( COLOR_BTNFACE )
|
||
|
);
|
||
|
|
||
|
TraceFuncExit();
|
||
|
|
||
|
} //*** CDetailsDlg::OnSysColorChange()
|
||
|
|
||
|
//////////////////////////////////////////////////////////////////////////////
|
||
|
//++
|
||
|
//
|
||
|
// CDetailsDlg::OnKeyDown
|
||
|
//
|
||
|
// Description:
|
||
|
// Handler for the WM_KEYDOWN message.
|
||
|
//
|
||
|
// Arguments:
|
||
|
// lParamIn - Parameter containing information about the key.
|
||
|
//
|
||
|
// Return Values:
|
||
|
// TRUE - Message was processed.
|
||
|
// FALSE - Message was not processed.
|
||
|
//
|
||
|
//--
|
||
|
//////////////////////////////////////////////////////////////////////////////
|
||
|
LRESULT
|
||
|
CDetailsDlg::OnKeyDown(
|
||
|
LPARAM lParamIn
|
||
|
)
|
||
|
{
|
||
|
TraceFunc( "" );
|
||
|
|
||
|
LRESULT lr = FALSE;
|
||
|
|
||
|
union
|
||
|
{
|
||
|
LPARAM lParam;
|
||
|
struct
|
||
|
{
|
||
|
BYTE cRepeat;
|
||
|
BYTE nScanCode;
|
||
|
unsigned fExtendedKey : 1;
|
||
|
unsigned reserved : 4;
|
||
|
unsigned fIsAltKeyDown : 1; // always 0 for WM_KEYDOWN
|
||
|
unsigned fKeyDownBefore : 1;
|
||
|
unsigned fKeyReleased : 1; // always 0 for WM_KEYDOWN
|
||
|
};
|
||
|
} uFlags;
|
||
|
|
||
|
uFlags.lParam = lParamIn;
|
||
|
|
||
|
switch ( uFlags.nScanCode )
|
||
|
{
|
||
|
case VK_CONTROL:
|
||
|
m_fControlDown = TRUE;
|
||
|
lr = TRUE;
|
||
|
break;
|
||
|
|
||
|
case VK_MENU: // ALT
|
||
|
m_fAltDown = TRUE;
|
||
|
lr = TRUE;
|
||
|
break;
|
||
|
|
||
|
case 'c':
|
||
|
case 'C':
|
||
|
if ( m_fControlDown )
|
||
|
{
|
||
|
OnCommandBnClickedCopy();
|
||
|
lr = TRUE;
|
||
|
}
|
||
|
break;
|
||
|
} // switch: scan code
|
||
|
|
||
|
RETURN( lr );
|
||
|
|
||
|
} //*** CDetailsDlg::OnKeyDown()
|
||
|
|
||
|
//////////////////////////////////////////////////////////////////////////////
|
||
|
//++
|
||
|
//
|
||
|
// CDetailsDlg::OnKeyUp
|
||
|
//
|
||
|
// Description:
|
||
|
// Handler for the WM_KEYUP message.
|
||
|
//
|
||
|
// Arguments:
|
||
|
// lParamIn - Parameter containing information about the key.
|
||
|
//
|
||
|
// Return Values:
|
||
|
// TRUE - Message was processed.
|
||
|
// FALSE - Message was not processed.
|
||
|
//
|
||
|
//--
|
||
|
//////////////////////////////////////////////////////////////////////////////
|
||
|
LRESULT
|
||
|
CDetailsDlg::OnKeyUp(
|
||
|
LPARAM lParamIn
|
||
|
)
|
||
|
{
|
||
|
TraceFunc( "" );
|
||
|
|
||
|
LRESULT lr = FALSE;
|
||
|
|
||
|
union
|
||
|
{
|
||
|
LPARAM lParam;
|
||
|
struct
|
||
|
{
|
||
|
BYTE cRepeat;
|
||
|
BYTE nScanCode;
|
||
|
unsigned fExtendedKey : 1;
|
||
|
unsigned reserved : 4;
|
||
|
unsigned fIsAltKeyDown : 1; // always 0 for WM_KEYDOWN
|
||
|
unsigned fKeyDownBefore : 1;
|
||
|
unsigned fKeyReleased : 1; // always 0 for WM_KEYDOWN
|
||
|
};
|
||
|
} uFlags;
|
||
|
|
||
|
uFlags.lParam = lParamIn;
|
||
|
|
||
|
switch ( uFlags.nScanCode )
|
||
|
{
|
||
|
case VK_CONTROL:
|
||
|
m_fControlDown = FALSE;
|
||
|
lr = TRUE;
|
||
|
break;
|
||
|
|
||
|
case VK_MENU: // ALT
|
||
|
m_fAltDown = FALSE;
|
||
|
lr = TRUE;
|
||
|
break;
|
||
|
} // switch: scan code
|
||
|
|
||
|
RETURN( lr );
|
||
|
|
||
|
} //*** CDetailsDlg::OnKeyUp()
|
||
|
|
||
|
//////////////////////////////////////////////////////////////////////////////
|
||
|
//++
|
||
|
//
|
||
|
// CDetailsDlg::OnCommand
|
||
|
//
|
||
|
// Description:
|
||
|
// Handler for the WM_COMMAND message.
|
||
|
//
|
||
|
// Arguments:
|
||
|
// idNotificationIn - Notification code.
|
||
|
// idControlIn - Control ID.
|
||
|
// hwndSenderIn - Handle for the window that sent the message.
|
||
|
//
|
||
|
// Return Values:
|
||
|
// TRUE - Message has been handled.
|
||
|
// FALSE - Message has not been handled yet.
|
||
|
//
|
||
|
//--
|
||
|
//////////////////////////////////////////////////////////////////////////////
|
||
|
LRESULT
|
||
|
CDetailsDlg::OnCommand(
|
||
|
UINT idNotificationIn
|
||
|
, UINT idControlIn
|
||
|
, HWND hwndSenderIn
|
||
|
)
|
||
|
{
|
||
|
TraceFunc( "" );
|
||
|
|
||
|
LRESULT lr = FALSE;
|
||
|
|
||
|
switch ( idControlIn )
|
||
|
{
|
||
|
case IDC_DETAILS_PB_PREV:
|
||
|
if ( idNotificationIn == BN_CLICKED )
|
||
|
{
|
||
|
lr = OnCommandBnClickedPrev();
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case IDC_DETAILS_PB_NEXT:
|
||
|
if ( idNotificationIn == BN_CLICKED )
|
||
|
{
|
||
|
lr = OnCommandBnClickedNext();
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case IDC_DETAILS_PB_COPY:
|
||
|
if ( idNotificationIn == BN_CLICKED )
|
||
|
{
|
||
|
lr = OnCommandBnClickedCopy();
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case IDCANCEL:
|
||
|
EndDialog( m_hwnd, IDCANCEL );
|
||
|
break;
|
||
|
|
||
|
} // switch: idControlIn
|
||
|
|
||
|
RETURN( lr );
|
||
|
|
||
|
} //*** CDetailsDlg::OnCommand()
|
||
|
|
||
|
//////////////////////////////////////////////////////////////////////////////
|
||
|
//++
|
||
|
//
|
||
|
// CDetailsDlg::OnCommandBnClickedPrev
|
||
|
//
|
||
|
// Description:
|
||
|
// Handler for the BN_CLICKED notification on the Prev button.
|
||
|
//
|
||
|
// Arguments:
|
||
|
// None.
|
||
|
//
|
||
|
// Return Values:
|
||
|
// TRUE - Message has been handled.
|
||
|
// FALSE - Message has not been handled yet.
|
||
|
//
|
||
|
//--
|
||
|
//////////////////////////////////////////////////////////////////////////////
|
||
|
LRESULT
|
||
|
CDetailsDlg::OnCommandBnClickedPrev( void )
|
||
|
{
|
||
|
TraceFunc( "" );
|
||
|
|
||
|
LRESULT lr = FALSE;
|
||
|
HRESULT hr;
|
||
|
HTREEITEM htiPrev;
|
||
|
|
||
|
//
|
||
|
// Find the previous item.
|
||
|
//
|
||
|
|
||
|
hr = STHR( m_pttv->HrFindPrevItem( &htiPrev ) );
|
||
|
if ( FAILED( hr ) )
|
||
|
{
|
||
|
goto Cleanup;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Select that item.
|
||
|
//
|
||
|
|
||
|
hr = THR( m_pttv->HrSelectItem( htiPrev ) );
|
||
|
if ( FAILED( hr ) )
|
||
|
{
|
||
|
goto Cleanup;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Display the newly selected item.
|
||
|
//
|
||
|
|
||
|
if ( htiPrev != NULL )
|
||
|
{
|
||
|
hr = THR( HrDisplayItem( htiPrev ) );
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Update the buttons based on our new position.
|
||
|
//
|
||
|
|
||
|
UpdateButtons();
|
||
|
|
||
|
lr = TRUE;
|
||
|
|
||
|
Cleanup:
|
||
|
RETURN( lr );
|
||
|
|
||
|
} //*** CDetailsDlg::OnCommandBnClickedPrev()
|
||
|
|
||
|
//////////////////////////////////////////////////////////////////////////////
|
||
|
//++
|
||
|
//
|
||
|
// CDetailsDlg::OnCommandBnClickedNext
|
||
|
//
|
||
|
// Description:
|
||
|
// Handler for the BN_CLICKED notification on the Next button.
|
||
|
//
|
||
|
// Arguments:
|
||
|
// None.
|
||
|
//
|
||
|
// Return Values:
|
||
|
// TRUE - Message has been handled.
|
||
|
// FALSE - Message has not been handled yet.
|
||
|
//
|
||
|
//--
|
||
|
//////////////////////////////////////////////////////////////////////////////
|
||
|
LRESULT
|
||
|
CDetailsDlg::OnCommandBnClickedNext( void )
|
||
|
{
|
||
|
TraceFunc( "" );
|
||
|
|
||
|
LRESULT lr = FALSE;
|
||
|
HRESULT hr;
|
||
|
HTREEITEM htiNext;
|
||
|
|
||
|
//
|
||
|
// Find the next item.
|
||
|
//
|
||
|
|
||
|
hr = STHR( m_pttv->HrFindNextItem( &htiNext ) );
|
||
|
if ( FAILED( hr ) )
|
||
|
{
|
||
|
goto Cleanup;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Select that item.
|
||
|
//
|
||
|
|
||
|
hr = THR( m_pttv->HrSelectItem( htiNext ) );
|
||
|
if ( FAILED( hr ) )
|
||
|
{
|
||
|
goto Cleanup;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Display the newly selected item.
|
||
|
//
|
||
|
|
||
|
if ( htiNext != NULL )
|
||
|
{
|
||
|
hr = THR( HrDisplayItem( htiNext ) );
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Update the buttons based on our new position.
|
||
|
//
|
||
|
|
||
|
UpdateButtons();
|
||
|
|
||
|
lr = TRUE;
|
||
|
|
||
|
Cleanup:
|
||
|
RETURN( lr );
|
||
|
|
||
|
} //*** CDetailsDlg::OnCommandBnClickedNext()
|
||
|
|
||
|
//////////////////////////////////////////////////////////////////////////////
|
||
|
//++
|
||
|
//
|
||
|
// CDetailsDlg::OnCommandBnClickedCopy
|
||
|
//
|
||
|
// Description:
|
||
|
// Handler for the BN_CLICKED notification on the Copy button.
|
||
|
//
|
||
|
// Arguments:
|
||
|
// None.
|
||
|
//
|
||
|
// Return Values:
|
||
|
// TRUE - Message has been handled.
|
||
|
// FALSE - Message has not been handled yet.
|
||
|
//
|
||
|
//--
|
||
|
//////////////////////////////////////////////////////////////////////////////
|
||
|
LRESULT
|
||
|
CDetailsDlg::OnCommandBnClickedCopy( void )
|
||
|
{
|
||
|
TraceFunc( "" );
|
||
|
|
||
|
LRESULT lr = FALSE;
|
||
|
HRESULT hr;
|
||
|
DWORD sc;
|
||
|
BSTR bstrClipboard = NULL;
|
||
|
HGLOBAL hgbl = NULL;
|
||
|
LPWSTR pszGlobal = NULL;
|
||
|
BOOL fOpenedClipboard;
|
||
|
|
||
|
//
|
||
|
// Open the clipboard.
|
||
|
//
|
||
|
|
||
|
fOpenedClipboard = OpenClipboard( m_hwnd );
|
||
|
|
||
|
if ( ! fOpenedClipboard )
|
||
|
{
|
||
|
sc = TW32( GetLastError() );
|
||
|
hr = HRESULT_FROM_WIN32( sc );
|
||
|
TraceFlow2( "Can't open clipboard (error = %#08x), currently owned by %#x", sc, GetClipboardOwner() );
|
||
|
goto Cleanup;
|
||
|
}
|
||
|
|
||
|
if ( ! EmptyClipboard() )
|
||
|
{
|
||
|
sc = TW32( GetLastError() );
|
||
|
hr = HRESULT_FROM_WIN32( sc );
|
||
|
goto Cleanup;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Construct the text to put on the clipboard.
|
||
|
//
|
||
|
|
||
|
hr = THR( HrAppendControlStringToClipboardString(
|
||
|
&bstrClipboard
|
||
|
, IDS_DETAILS_CLP_DATE
|
||
|
, IDC_DETAILS_E_DATE
|
||
|
, false // fNewlineBeforeTextIn
|
||
|
) );
|
||
|
if ( FAILED( hr ) )
|
||
|
{
|
||
|
goto Cleanup;
|
||
|
}
|
||
|
|
||
|
hr = THR( HrAppendControlStringToClipboardString(
|
||
|
&bstrClipboard
|
||
|
, IDS_DETAILS_CLP_TIME
|
||
|
, IDC_DETAILS_E_TIME
|
||
|
, false // fNewlineBeforeTextIn
|
||
|
) );
|
||
|
if ( FAILED( hr ) )
|
||
|
{
|
||
|
goto Cleanup;
|
||
|
}
|
||
|
|
||
|
hr = THR( HrAppendControlStringToClipboardString(
|
||
|
&bstrClipboard
|
||
|
, IDS_DETAILS_CLP_COMPUTER
|
||
|
, IDC_DETAILS_E_COMPUTER
|
||
|
, false // fNewlineBeforeTextIn
|
||
|
) );
|
||
|
if ( FAILED( hr ) )
|
||
|
{
|
||
|
goto Cleanup;
|
||
|
}
|
||
|
|
||
|
hr = THR( HrAppendControlStringToClipboardString(
|
||
|
&bstrClipboard
|
||
|
, IDS_DETAILS_CLP_MAJOR
|
||
|
, IDC_DETAILS_E_MAJOR_ID
|
||
|
, false // fNewlineBeforeTextIn
|
||
|
) );
|
||
|
if ( FAILED( hr ) )
|
||
|
{
|
||
|
goto Cleanup;
|
||
|
}
|
||
|
|
||
|
hr = THR( HrAppendControlStringToClipboardString(
|
||
|
&bstrClipboard
|
||
|
, IDS_DETAILS_CLP_MINOR
|
||
|
, IDC_DETAILS_E_MINOR_ID
|
||
|
, false // fNewlineBeforeTextIn
|
||
|
) );
|
||
|
if ( FAILED( hr ) )
|
||
|
{
|
||
|
goto Cleanup;
|
||
|
}
|
||
|
|
||
|
hr = THR( HrAppendControlStringToClipboardString(
|
||
|
&bstrClipboard
|
||
|
, IDS_DETAILS_CLP_DESC
|
||
|
, IDC_DETAILS_RE_DESCRIPTION
|
||
|
, true // fNewlineBeforeTextIn
|
||
|
) );
|
||
|
if ( FAILED( hr ) )
|
||
|
{
|
||
|
goto Cleanup;
|
||
|
}
|
||
|
|
||
|
hr = THR( HrAppendControlStringToClipboardString(
|
||
|
&bstrClipboard
|
||
|
, IDS_DETAILS_CLP_STATUS
|
||
|
, IDC_DETAILS_E_STATUS
|
||
|
, false // fNewlineBeforeTextIn
|
||
|
) );
|
||
|
if ( FAILED( hr ) )
|
||
|
{
|
||
|
goto Cleanup;
|
||
|
}
|
||
|
|
||
|
hr = THR( HrAppendControlStringToClipboardString(
|
||
|
&bstrClipboard
|
||
|
, 0
|
||
|
, IDC_DETAILS_RE_STATUS
|
||
|
, false // fNewlineBeforeTextIn
|
||
|
) );
|
||
|
if ( FAILED( hr ) )
|
||
|
{
|
||
|
goto Cleanup;
|
||
|
}
|
||
|
|
||
|
hr = THR( HrAppendControlStringToClipboardString(
|
||
|
&bstrClipboard
|
||
|
, IDS_DETAILS_CLP_INFO
|
||
|
, IDC_DETAILS_RE_REFERENCE
|
||
|
, true // fNewlineBeforeTextIn
|
||
|
) );
|
||
|
if ( FAILED( hr ) )
|
||
|
{
|
||
|
goto Cleanup;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Set the string onto the clipboard.
|
||
|
//
|
||
|
|
||
|
{
|
||
|
//
|
||
|
// Allocate a global buffer for the string, since
|
||
|
// clipboard needs this as HGLOBAL.
|
||
|
//
|
||
|
|
||
|
hgbl = GlobalAlloc(
|
||
|
GMEM_MOVEABLE | GMEM_DDESHARE
|
||
|
, ( wcslen( bstrClipboard ) + 1) * sizeof( *bstrClipboard )
|
||
|
);
|
||
|
if ( hgbl == NULL )
|
||
|
{
|
||
|
hr = E_OUTOFMEMORY;
|
||
|
goto Cleanup;
|
||
|
}
|
||
|
|
||
|
pszGlobal = (LPWSTR) GlobalLock( hgbl );
|
||
|
if ( pszGlobal == NULL )
|
||
|
{
|
||
|
sc = TW32( GetLastError() );
|
||
|
hr = HRESULT_FROM_WIN32( sc );
|
||
|
goto Cleanup;
|
||
|
}
|
||
|
|
||
|
wcscpy( pszGlobal, bstrClipboard );
|
||
|
|
||
|
//
|
||
|
// Put it on the clipboard.
|
||
|
//
|
||
|
|
||
|
if ( SetClipboardData( CF_UNICODETEXT, hgbl ) )
|
||
|
{
|
||
|
// System owns it now.
|
||
|
pszGlobal = NULL;
|
||
|
hgbl = NULL;
|
||
|
}
|
||
|
} // Set the string onto the clipboard
|
||
|
|
||
|
Cleanup:
|
||
|
TraceSysFreeString( bstrClipboard );
|
||
|
|
||
|
if ( pszGlobal != NULL )
|
||
|
{
|
||
|
GlobalUnlock( hgbl );
|
||
|
}
|
||
|
GlobalFree( hgbl );
|
||
|
|
||
|
if ( fOpenedClipboard )
|
||
|
{
|
||
|
CloseClipboard();
|
||
|
}
|
||
|
|
||
|
RETURN( lr );
|
||
|
|
||
|
} //*** CDetailsDlg::OnCommandBnClickedCopy()
|
||
|
|
||
|
//////////////////////////////////////////////////////////////////////////////
|
||
|
//++
|
||
|
//
|
||
|
// CDetailsDlg::HrAppendControlStringToClipboardString
|
||
|
//
|
||
|
// Description:
|
||
|
// Append a string from a control on the dialog box to the clipboard string.
|
||
|
//
|
||
|
// Arguments:
|
||
|
// pbstrClipboardInout - Clipboard string.
|
||
|
// idsLabelIn - ID for the label string resource.
|
||
|
// idcDataIn - ID for the control to read the text from.
|
||
|
// fNewlineBeforeTextIn- TRUE if a newline should be added before the data.
|
||
|
//
|
||
|
// Return Values:
|
||
|
// S_OK - Operation completed successfully.
|
||
|
//
|
||
|
//--
|
||
|
//////////////////////////////////////////////////////////////////////////////
|
||
|
HRESULT
|
||
|
CDetailsDlg::HrAppendControlStringToClipboardString(
|
||
|
BSTR * pbstrClipboard
|
||
|
, UINT idsLabelIn
|
||
|
, UINT idcDataIn
|
||
|
, bool fNewlineBeforeTextIn
|
||
|
)
|
||
|
{
|
||
|
TraceFunc( "" );
|
||
|
|
||
|
HRESULT hr = S_OK;
|
||
|
LPWSTR pszData = NULL;
|
||
|
HWND hwndControl = GetDlgItem( m_hwnd, idcDataIn );
|
||
|
int cch;
|
||
|
|
||
|
//
|
||
|
// Get the string from the control.
|
||
|
//
|
||
|
|
||
|
cch = GetWindowTextLength( hwndControl );
|
||
|
|
||
|
pszData = new WCHAR[ cch + 1 ];
|
||
|
if ( pszData == NULL )
|
||
|
{
|
||
|
hr = E_OUTOFMEMORY;
|
||
|
goto Cleanup;
|
||
|
}
|
||
|
|
||
|
GetWindowText( hwndControl, pszData, cch + 1 );
|
||
|
|
||
|
//
|
||
|
// Append the string to the clipboard string.
|
||
|
//
|
||
|
|
||
|
hr = THR( HrAppendStringToClipboardString( pbstrClipboard, idsLabelIn, pszData, fNewlineBeforeTextIn ) );
|
||
|
if ( FAILED( hr ) )
|
||
|
{
|
||
|
goto Cleanup;
|
||
|
}
|
||
|
|
||
|
Cleanup:
|
||
|
delete [] pszData;
|
||
|
|
||
|
HRETURN( hr );
|
||
|
|
||
|
} //*** HrAppendControlStringToClipboardString()
|
||
|
|
||
|
//////////////////////////////////////////////////////////////////////////////
|
||
|
//++
|
||
|
//
|
||
|
// HrAppendStringToClipboardString
|
||
|
//
|
||
|
// Description:
|
||
|
// Append a label and data string to the clipboard string.
|
||
|
//
|
||
|
// Arguments:
|
||
|
// pbstrClipboardInout - Clipboard string.
|
||
|
// idsLabelIn - ID for the label string resource.
|
||
|
// pszDataIn - Data string.
|
||
|
// fNewlineBeforeTextIn- TRUE if a newline should be added before the data.
|
||
|
//
|
||
|
// Return Values:
|
||
|
// S_OK - Operation completed successfully.
|
||
|
//
|
||
|
//--
|
||
|
//////////////////////////////////////////////////////////////////////////////
|
||
|
HRESULT
|
||
|
HrAppendStringToClipboardString(
|
||
|
BSTR * pbstrClipboard
|
||
|
, UINT idsLabelIn
|
||
|
, LPCWSTR pszDataIn
|
||
|
, bool fNewlineBeforeTextIn
|
||
|
)
|
||
|
{
|
||
|
TraceFunc( "" );
|
||
|
|
||
|
HRESULT hr = S_OK;
|
||
|
BSTR bstrLabel = NULL;
|
||
|
BSTR bstr = NULL;
|
||
|
LPCWSTR pszLabel;
|
||
|
LPCWSTR pszFmt;
|
||
|
|
||
|
static const WCHAR s_szBlank[] = L"";
|
||
|
static const WCHAR s_szNoNewlineFmt[] = L"%1!ws!%2!ws!\n";
|
||
|
static const WCHAR s_szNewlineFmt[] = L"%1!ws!\n%2!ws!\n";
|
||
|
|
||
|
//
|
||
|
// Load the label string.
|
||
|
//
|
||
|
|
||
|
if ( idsLabelIn == 0 )
|
||
|
{
|
||
|
pszLabel = s_szBlank;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
hr = THR( HrLoadStringIntoBSTR( g_hInstance, idsLabelIn, &bstrLabel ) );
|
||
|
if ( FAILED( hr ) )
|
||
|
{
|
||
|
goto Cleanup;
|
||
|
}
|
||
|
pszLabel = bstrLabel;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Get the right format string.
|
||
|
//
|
||
|
|
||
|
if ( fNewlineBeforeTextIn )
|
||
|
{
|
||
|
pszFmt = s_szNewlineFmt;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
pszFmt = s_szNoNewlineFmt;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Get the string from the dialog.
|
||
|
//
|
||
|
//
|
||
|
// Format the new label + string.
|
||
|
//
|
||
|
|
||
|
hr = THR( HrFormatStringIntoBSTR( pszFmt, &bstr, pszLabel, pszDataIn ) );
|
||
|
if ( FAILED( hr ) )
|
||
|
{
|
||
|
goto Cleanup;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Concatenate the resulting string onto the end of the clipboard string.
|
||
|
//
|
||
|
|
||
|
hr = THR( HrConcatenateBSTRs( pbstrClipboard, bstr ) );
|
||
|
if ( FAILED( hr ) )
|
||
|
{
|
||
|
goto Cleanup;
|
||
|
}
|
||
|
|
||
|
Cleanup:
|
||
|
TraceSysFreeString( bstrLabel );
|
||
|
TraceSysFreeString( bstr );
|
||
|
|
||
|
HRETURN( hr );
|
||
|
|
||
|
} //*** HrAppendStringToClipboardString()
|
||
|
|
||
|
//////////////////////////////////////////////////////////////////////////////
|
||
|
//++
|
||
|
//
|
||
|
// CDetailsDlg::OnNotify
|
||
|
//
|
||
|
// Description:
|
||
|
// Handle the WM_NOTIFY message.
|
||
|
//
|
||
|
// Arguments:
|
||
|
// idCtrlIn - Control ID.
|
||
|
// pnmhdrIn - Notification structure.
|
||
|
//
|
||
|
// Return Values:
|
||
|
// TRUE - Message has been handled.
|
||
|
// FALSE - Message has not been handled yet.
|
||
|
//
|
||
|
//--
|
||
|
//////////////////////////////////////////////////////////////////////////////
|
||
|
LRESULT
|
||
|
CDetailsDlg::OnNotify(
|
||
|
WPARAM idCtrlIn
|
||
|
, LPNMHDR pnmhdrIn
|
||
|
)
|
||
|
{
|
||
|
TraceFunc( "" );
|
||
|
|
||
|
LRESULT lr = FALSE;
|
||
|
|
||
|
switch( pnmhdrIn->code )
|
||
|
{
|
||
|
case EN_LINK:
|
||
|
lr = OnNotifyEnLink( idCtrlIn, pnmhdrIn );
|
||
|
break;
|
||
|
} // switch: notify code
|
||
|
|
||
|
RETURN( lr );
|
||
|
|
||
|
} //*** CDetailsDlg::OnNotify()
|
||
|
|
||
|
//////////////////////////////////////////////////////////////////////////////
|
||
|
//++
|
||
|
//
|
||
|
// CDetailsDlg::OnNotifyEnLink
|
||
|
//
|
||
|
// Description:
|
||
|
// Handle the WM_NOTIFY message.
|
||
|
//
|
||
|
// Arguments:
|
||
|
// idCtrlIn - Control ID.
|
||
|
// pnmhdrIn - Notification structure.
|
||
|
//
|
||
|
// Return Values:
|
||
|
// TRUE - Message has been handled.
|
||
|
// FALSE - Message has not been handled yet.
|
||
|
//
|
||
|
//--
|
||
|
//////////////////////////////////////////////////////////////////////////////
|
||
|
LRESULT
|
||
|
CDetailsDlg::OnNotifyEnLink(
|
||
|
WPARAM idCtrlIn
|
||
|
, LPNMHDR pnmhdrIn
|
||
|
)
|
||
|
{
|
||
|
TraceFunc( "" );
|
||
|
|
||
|
LRESULT lr = FALSE;
|
||
|
ENLINK * penl = (ENLINK *) pnmhdrIn;
|
||
|
|
||
|
switch( idCtrlIn )
|
||
|
{
|
||
|
case IDC_DETAILS_RE_DESCRIPTION:
|
||
|
case IDC_DETAILS_RE_STATUS:
|
||
|
case IDC_DETAILS_RE_REFERENCE:
|
||
|
if ( penl->msg == WM_LBUTTONDOWN )
|
||
|
{
|
||
|
//
|
||
|
// Rich edit notification user has left clicked on link
|
||
|
//
|
||
|
|
||
|
m_chrgEnLinkClick = penl->chrg;
|
||
|
} // if: left button down
|
||
|
else if ( penl->msg == WM_LBUTTONUP )
|
||
|
{
|
||
|
if ( ( penl->chrg.cpMax == m_chrgEnLinkClick.cpMax )
|
||
|
&& ( penl->chrg.cpMin == m_chrgEnLinkClick.cpMin )
|
||
|
)
|
||
|
{
|
||
|
ZeroMemory( &m_chrgEnLinkClick, sizeof m_chrgEnLinkClick );
|
||
|
HandleLinkClick( penl, idCtrlIn );
|
||
|
}
|
||
|
} // else if: left button up
|
||
|
break;
|
||
|
} // switch: notify code
|
||
|
|
||
|
RETURN( lr );
|
||
|
|
||
|
} //*** CDetailsDlg::OnNotifyEnLink()
|
||
|
|
||
|
//////////////////////////////////////////////////////////////////////////////
|
||
|
//++
|
||
|
//
|
||
|
// CDetailsDlg::HandleLinkClick
|
||
|
//
|
||
|
// Description:
|
||
|
// Handle notification that the user has clicked on text in a richedit
|
||
|
// control that is marked with the hyperlink attribute.
|
||
|
//
|
||
|
// Arguments:
|
||
|
// penlIn - Contains information about link clicked.
|
||
|
// idCtrlIn - Control in which user clicked.
|
||
|
//
|
||
|
// Return Values:
|
||
|
// None.
|
||
|
//
|
||
|
//--
|
||
|
//////////////////////////////////////////////////////////////////////////////
|
||
|
void
|
||
|
CDetailsDlg::HandleLinkClick(
|
||
|
ENLINK * penlIn
|
||
|
, WPARAM idCtrlIn
|
||
|
)
|
||
|
{
|
||
|
TraceFunc( "" );
|
||
|
|
||
|
Assert( penlIn->chrg.cpMax > penlIn->chrg.cpMin );
|
||
|
|
||
|
PWSTR pszLink = NULL;
|
||
|
ULONG cch;
|
||
|
TEXTRANGE tr;
|
||
|
DWORD sc;
|
||
|
|
||
|
//
|
||
|
// Get the text of the link.
|
||
|
//
|
||
|
|
||
|
cch = penlIn->chrg.cpMax - penlIn->chrg.cpMin + 1;
|
||
|
|
||
|
pszLink = new WCHAR[ cch ];
|
||
|
if ( pszLink == NULL )
|
||
|
{
|
||
|
goto Cleanup;
|
||
|
}
|
||
|
|
||
|
pszLink[ 0 ] = '\0';
|
||
|
|
||
|
ZeroMemory( &tr, sizeof( tr ) );
|
||
|
tr.chrg = penlIn->chrg;
|
||
|
tr.lpstrText = pszLink;
|
||
|
|
||
|
cch = (ULONG) SendDlgItemMessage(
|
||
|
m_hwnd
|
||
|
, (int) idCtrlIn
|
||
|
, EM_GETTEXTRANGE
|
||
|
, 0
|
||
|
, (LPARAM) &tr
|
||
|
);
|
||
|
Assert( cch > 0 );
|
||
|
|
||
|
//
|
||
|
// Pass the URL straight through to ShellExecute.
|
||
|
//
|
||
|
// Note that ShellExecute returns an HINSTANCE for historical reasons,
|
||
|
// but actually only returns integers. Any value greater than 32
|
||
|
// indicates success.
|
||
|
//
|
||
|
|
||
|
TraceFlow1( "Calling ShellExecute on %hs", pszLink );
|
||
|
sc = HandleToULong( ShellExecute( NULL, NULL, pszLink, NULL, NULL, SW_NORMAL ) );
|
||
|
if ( sc <= 32 )
|
||
|
{
|
||
|
TW32( sc );
|
||
|
THR( HrMessageBoxWithStatus(
|
||
|
m_hwnd
|
||
|
, IDS_ERR_INVOKING_LINK_TITLE
|
||
|
, IDS_ERR_INVOKING_LINK_TEXT
|
||
|
, sc
|
||
|
, 0 // idsSubStatusIn
|
||
|
, ( MB_OK
|
||
|
| MB_ICONEXCLAMATION )
|
||
|
, NULL // pidReturnOut
|
||
|
, pszLink
|
||
|
) );
|
||
|
} // if: error from ShellExecute
|
||
|
|
||
|
Cleanup:
|
||
|
delete [] pszLink;
|
||
|
|
||
|
} //*** CDetailsDlg::HandleLinkClick()
|
||
|
|
||
|
//////////////////////////////////////////////////////////////////////////////
|
||
|
//++
|
||
|
//
|
||
|
// CDetailsDlg::UpdateButtons
|
||
|
//
|
||
|
// Description:
|
||
|
// Update the buttons based on whether there is a previous or next
|
||
|
// item or not.
|
||
|
//
|
||
|
// Arguments:
|
||
|
// None.
|
||
|
//
|
||
|
// Return Values:
|
||
|
// None.
|
||
|
//
|
||
|
//--
|
||
|
//////////////////////////////////////////////////////////////////////////////
|
||
|
void
|
||
|
CDetailsDlg::UpdateButtons( void )
|
||
|
{
|
||
|
TraceFunc( "" );
|
||
|
|
||
|
Assert( m_pttv != NULL );
|
||
|
|
||
|
HTREEITEM hti = NULL;
|
||
|
HRESULT hr;
|
||
|
BOOL fEnablePrev;
|
||
|
BOOL fEnableNext;
|
||
|
|
||
|
STHR( m_pttv->HrFindPrevItem( &hti ) );
|
||
|
// ignore error
|
||
|
fEnablePrev = ( hti != NULL );
|
||
|
|
||
|
STHR( m_pttv->HrFindNextItem( &hti ) );
|
||
|
// ignore error
|
||
|
fEnableNext = ( hti != NULL );
|
||
|
|
||
|
EnableWindow( GetDlgItem( m_hwnd, IDC_DETAILS_PB_PREV ), fEnablePrev );
|
||
|
EnableWindow( GetDlgItem( m_hwnd, IDC_DETAILS_PB_NEXT ), fEnableNext );
|
||
|
|
||
|
} //*** CDetailsDlg::UpdateButtons()
|
||
|
|
||
|
//////////////////////////////////////////////////////////////////////////////
|
||
|
//++
|
||
|
//
|
||
|
// CDetailsDlg::HrDisplayItem
|
||
|
//
|
||
|
// Description:
|
||
|
// Display an item in the details dialog.
|
||
|
//
|
||
|
// Arguments:
|
||
|
// htiIn - Handle to the item to display.
|
||
|
//
|
||
|
// Return Values:
|
||
|
// S_OK - Operation completed successfully.
|
||
|
// S_FALSE - Item not displayed.
|
||
|
//
|
||
|
// Remarks:
|
||
|
//
|
||
|
//--
|
||
|
//////////////////////////////////////////////////////////////////////////////
|
||
|
HRESULT
|
||
|
CDetailsDlg::HrDisplayItem(
|
||
|
HTREEITEM htiIn
|
||
|
)
|
||
|
{
|
||
|
TraceFunc( "" );
|
||
|
|
||
|
Assert( htiIn != NULL );
|
||
|
|
||
|
HRESULT hr = S_FALSE;
|
||
|
DWORD sc = ERROR_SUCCESS;
|
||
|
BOOL fRet;
|
||
|
BOOL fDisplayIcon;
|
||
|
STreeItemLParamData * ptipd;
|
||
|
BSTR bstr = NULL;
|
||
|
BSTR bstrAdditionalInfo = NULL;
|
||
|
WCHAR wszText[ 64 ];
|
||
|
FILETIME filetime;
|
||
|
SYSTEMTIME systemtime;
|
||
|
int cch;
|
||
|
HICON hicon;
|
||
|
|
||
|
//
|
||
|
// Get information about the selected item to see if it has details.
|
||
|
//
|
||
|
|
||
|
fRet = m_pttv->FGetItem( htiIn, &ptipd );
|
||
|
if ( ! fRet )
|
||
|
{
|
||
|
goto Cleanup;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Set the date and time information from the structure into
|
||
|
// the dialog box.
|
||
|
//
|
||
|
|
||
|
if ( ( ptipd->ftTime.dwHighDateTime == 0 )
|
||
|
&& ( ptipd->ftTime.dwLowDateTime == 0 )
|
||
|
)
|
||
|
{
|
||
|
SetDlgItemText( m_hwnd, IDC_DETAILS_E_DATE, L"" );
|
||
|
SetDlgItemText( m_hwnd, IDC_DETAILS_E_TIME, L"" );
|
||
|
} // if: no date time specified
|
||
|
else
|
||
|
{
|
||
|
//
|
||
|
// Convert the date time to local time, then to something we can
|
||
|
// use to display it.
|
||
|
//
|
||
|
|
||
|
if ( ! FileTimeToLocalFileTime( &ptipd->ftTime, &filetime ) )
|
||
|
{
|
||
|
sc = TW32( GetLastError() );
|
||
|
}
|
||
|
else if ( ! FileTimeToSystemTime( &filetime, &systemtime ) )
|
||
|
{
|
||
|
sc = TW32( GetLastError() );
|
||
|
}
|
||
|
if ( sc == ERROR_SUCCESS )
|
||
|
{
|
||
|
//
|
||
|
// Get the date string and display it.
|
||
|
//
|
||
|
|
||
|
cch = GetDateFormat(
|
||
|
LOCALE_USER_DEFAULT
|
||
|
, DATE_SHORTDATE
|
||
|
, &systemtime
|
||
|
, NULL // lpFormat
|
||
|
, wszText
|
||
|
, ARRAYSIZE( wszText )
|
||
|
);
|
||
|
if ( cch == 0 )
|
||
|
{
|
||
|
sc = TW32( GetLastError() );
|
||
|
}
|
||
|
SetDlgItemText( m_hwnd, IDC_DETAILS_E_DATE, wszText );
|
||
|
|
||
|
//
|
||
|
// Get the time string and display it.
|
||
|
//
|
||
|
|
||
|
cch = GetTimeFormat(
|
||
|
LOCALE_USER_DEFAULT
|
||
|
, 0
|
||
|
, &systemtime
|
||
|
, NULL // lpFormat
|
||
|
, wszText
|
||
|
, ARRAYSIZE( wszText )
|
||
|
);
|
||
|
if ( cch == 0 )
|
||
|
{
|
||
|
sc = TW32( GetLastError() );
|
||
|
}
|
||
|
SetDlgItemText( m_hwnd, IDC_DETAILS_E_TIME, wszText );
|
||
|
} // if: time converted successfully
|
||
|
else
|
||
|
{
|
||
|
SetDlgItemText( m_hwnd, IDC_DETAILS_E_DATE, L"" );
|
||
|
SetDlgItemText( m_hwnd, IDC_DETAILS_E_TIME, L"" );
|
||
|
}
|
||
|
} // else: date time specified
|
||
|
|
||
|
//
|
||
|
// Set the task IDs.
|
||
|
//
|
||
|
|
||
|
THR( HrFormatGuidIntoBSTR( &ptipd->clsidMajorTaskId, &bstr ) );
|
||
|
if ( SUCCEEDED( hr ) )
|
||
|
{
|
||
|
SetDlgItemText( m_hwnd, IDC_DETAILS_E_MAJOR_ID, bstr );
|
||
|
}
|
||
|
|
||
|
hr = THR( HrFormatGuidIntoBSTR( &ptipd->clsidMinorTaskId, &bstr ) );
|
||
|
if ( SUCCEEDED( hr ) )
|
||
|
{
|
||
|
SetDlgItemText( m_hwnd, IDC_DETAILS_E_MINOR_ID, bstr );
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Set the text information.
|
||
|
//
|
||
|
|
||
|
// Node name.
|
||
|
if ( ptipd->bstrNodeName == NULL )
|
||
|
{
|
||
|
SetDlgItemText( m_hwnd, IDC_DETAILS_E_COMPUTER, L"" );
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
SetDlgItemText( m_hwnd, IDC_DETAILS_E_COMPUTER, ptipd->bstrNodeName );
|
||
|
}
|
||
|
|
||
|
// Description.
|
||
|
if ( ptipd->bstrDescription == NULL )
|
||
|
{
|
||
|
SetDlgItemText( m_hwnd, IDC_DETAILS_RE_DESCRIPTION, L"" );
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
SetDlgItemText( m_hwnd, IDC_DETAILS_RE_DESCRIPTION, ptipd->bstrDescription );
|
||
|
}
|
||
|
|
||
|
// Reference.
|
||
|
hr = THR( HrLoadStringIntoBSTR( g_hInstance, IDS_DEFAULT_DETAILS_REFERENCE, &bstrAdditionalInfo ) );
|
||
|
if ( SUCCEEDED( hr ) )
|
||
|
{
|
||
|
if ( ( ptipd->bstrReference == NULL )
|
||
|
|| ( *ptipd->bstrReference == L'\0' )
|
||
|
)
|
||
|
{
|
||
|
bstr = bstrAdditionalInfo;
|
||
|
bstrAdditionalInfo = NULL;
|
||
|
} // if: no reference specified
|
||
|
else
|
||
|
{
|
||
|
hr = THR( HrFormatStringIntoBSTR( L"%s\n\n%s", &bstr, ptipd->bstrReference, bstrAdditionalInfo ) );
|
||
|
} // else: reference specified
|
||
|
}
|
||
|
|
||
|
SetDlgItemText( m_hwnd, IDC_DETAILS_RE_REFERENCE, bstr );
|
||
|
|
||
|
//
|
||
|
// Set the status information.
|
||
|
//
|
||
|
|
||
|
_snwprintf( wszText, ARRAYSIZE( wszText ), L"0x%08x", ptipd->hr );
|
||
|
SetDlgItemText( m_hwnd, IDC_DETAILS_E_STATUS, wszText );
|
||
|
|
||
|
hr = ptipd->hr;
|
||
|
if ( hr == S_FALSE )
|
||
|
{
|
||
|
hr = THR( HrFormatStringIntoBSTR( L"S_FALSE", &bstr ) );
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// If not S_OK, this is a warning, so set the high bit before
|
||
|
// translating to text, since the text string will not be found
|
||
|
// without doing this.
|
||
|
if ( hr != S_OK )
|
||
|
{
|
||
|
hr |= 0x80000000;
|
||
|
}
|
||
|
hr = THR( HrFormatErrorIntoBSTR( hr, &bstr ) );
|
||
|
} // else: hr not S_FALSE
|
||
|
if ( SUCCEEDED( hr ) )
|
||
|
{
|
||
|
SetDlgItemText( m_hwnd, IDC_DETAILS_RE_STATUS, bstr );
|
||
|
if ( ptipd->hr == S_OK )
|
||
|
{
|
||
|
fDisplayIcon = FALSE;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
fDisplayIcon = TRUE;
|
||
|
if ( FAILED( ptipd->hr ) )
|
||
|
{
|
||
|
hicon = m_hiconError;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
hicon = m_hiconWarn;
|
||
|
}
|
||
|
SendDlgItemMessage( m_hwnd, IDC_DETAILS_I_STATUS, STM_SETIMAGE, IMAGE_ICON, (LPARAM) hicon );
|
||
|
} // else: status not informational
|
||
|
}
|
||
|
ShowWindow( GetDlgItem( m_hwnd, IDC_DETAILS_I_STATUS ), fDisplayIcon ? SW_SHOW : SW_HIDE );
|
||
|
|
||
|
hr = S_OK;
|
||
|
|
||
|
Cleanup:
|
||
|
TraceSysFreeString( bstr );
|
||
|
TraceSysFreeString( bstrAdditionalInfo );
|
||
|
|
||
|
HRETURN( hr );
|
||
|
|
||
|
} //*** CDetailsDlg::HrDisplayItem()
|
||
|
|
||
|
|
||
|
//****************************************************************************
|
||
|
//
|
||
|
// Private Functions
|
||
|
//
|
||
|
//****************************************************************************
|
||
|
|
||
|
|
||
|
//////////////////////////////////////////////////////////////////////////////
|
||
|
//++
|
||
|
//
|
||
|
// ButtonFaceColorIsDark
|
||
|
//
|
||
|
// Description:
|
||
|
// Return TRUE if the button face color is dark (implying that
|
||
|
// the light colored button icons should be used).
|
||
|
//
|
||
|
// Arguments:
|
||
|
// None.
|
||
|
//
|
||
|
// Return Values:
|
||
|
// TRUE - Button face color is dark.
|
||
|
// FALSE - Button face color is light.
|
||
|
//
|
||
|
//--
|
||
|
//////////////////////////////////////////////////////////////////////////////
|
||
|
BOOL
|
||
|
ButtonFaceColorIsDark( void )
|
||
|
{
|
||
|
TraceFunc( "" );
|
||
|
|
||
|
COLORREF rgbBtnFace = GetSysColor( COLOR_BTNFACE );
|
||
|
|
||
|
ULONG ulColors = GetRValue( rgbBtnFace ) +
|
||
|
GetGValue( rgbBtnFace ) +
|
||
|
GetBValue( rgbBtnFace );
|
||
|
|
||
|
RETURN( ulColors < 300 ); // arbitrary threshold
|
||
|
|
||
|
} //*** ButtonFaceColorIsDark()
|
||
|
|
||
|
//////////////////////////////////////////////////////////////////////////////
|
||
|
//++
|
||
|
//
|
||
|
// SetButtonImage
|
||
|
//
|
||
|
// Description:
|
||
|
// Set an image on a button.
|
||
|
//
|
||
|
// Arguments:
|
||
|
// hwndBtnIn - Handle to the button window.
|
||
|
// idIconIn - ID for the icon resource.
|
||
|
//
|
||
|
// Return Values:
|
||
|
// None.
|
||
|
//
|
||
|
//--
|
||
|
//////////////////////////////////////////////////////////////////////////////
|
||
|
void
|
||
|
SetButtonImage(
|
||
|
HWND hwndBtnIn
|
||
|
, ULONG idIconIn
|
||
|
)
|
||
|
{
|
||
|
TraceFunc( "" );
|
||
|
|
||
|
HICON hIcon = (HICON) LoadImage( g_hInstance,
|
||
|
MAKEINTRESOURCE( idIconIn ),
|
||
|
IMAGE_ICON,
|
||
|
16,
|
||
|
16,
|
||
|
LR_DEFAULTCOLOR
|
||
|
);
|
||
|
if ( hIcon != NULL )
|
||
|
{
|
||
|
HICON hIconPrev = (HICON) SendMessage( hwndBtnIn,
|
||
|
BM_SETIMAGE,
|
||
|
(WPARAM) IMAGE_ICON,
|
||
|
(LPARAM) hIcon
|
||
|
);
|
||
|
|
||
|
if ( hIconPrev )
|
||
|
{
|
||
|
DestroyIcon( hIconPrev );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
TraceFuncExit();
|
||
|
|
||
|
} //*** SetButtonImage()
|
||
|
|
||
|
//////////////////////////////////////////////////////////////////////////////
|
||
|
//++
|
||
|
//
|
||
|
// FreeButtonImage
|
||
|
//
|
||
|
// Description:
|
||
|
// Free an image used by button.
|
||
|
//
|
||
|
// Arguments:
|
||
|
// hwndBtnIn - Handle to the button window.
|
||
|
//
|
||
|
// Return Values:
|
||
|
// None.
|
||
|
//
|
||
|
//--
|
||
|
//////////////////////////////////////////////////////////////////////////////
|
||
|
void
|
||
|
FreeButtonImage(
|
||
|
HWND hwndBtnIn
|
||
|
)
|
||
|
{
|
||
|
HANDLE hIcon = (HANDLE) SendMessage( hwndBtnIn, BM_GETIMAGE, IMAGE_ICON, 0 );
|
||
|
|
||
|
if ( hIcon != NULL )
|
||
|
{
|
||
|
SendMessage( hwndBtnIn, BM_SETIMAGE, IMAGE_ICON, 0 );
|
||
|
DestroyIcon( (HICON) hIcon );
|
||
|
}
|
||
|
|
||
|
} //*** FreeButtonImage()
|