|
|
//
// Copyright 2001 - Microsoft Corporation
//
//
// Created By:
// Geoff Pease (GPease) 23-JAN-2001
//
// Maintained By:
// Geoff Pease (GPease) 23-JAN-2001
//
#include "pch.h"
#include "DocProp.h"
#include "DefProp.h"
#include "PropertyCacheItem.h"
#include "PropertyCache.h"
#include "SimpleDlg.h"
#include "shutils.h"
#include "WMUser.h"
#include "PropVar.h"
#pragma hdrstop
DEFINE_THISCLASS( "CSimpleDlg" )
//
// Globals
//
#define SUMMARYPROP(s) { &FMTID_SummaryInformation, PIDSI_##s, IDC_##s }
#define DOCSUMMARYPROP(s) { &FMTID_DocSummaryInformation, PIDDSI_##s, IDC_##s }
const struct { const FMTID *pFmtId; PROPID propid; UINT idc; // could add VARTYPE if we did anything other than strings
} g_rgBasicProps[] = { SUMMARYPROP(TITLE) , SUMMARYPROP(SUBJECT) , SUMMARYPROP(AUTHOR) , SUMMARYPROP(KEYWORDS) , SUMMARYPROP(COMMENTS) , DOCSUMMARYPROP(CATEGORY) };
// ************************************************************************
//
// Constructor / Destructor
//
// ************************************************************************
//
//
//
HRESULT CSimpleDlg::CreateInstance( CSimpleDlg ** pSimDlgOut , HWND hwndParentIn , BOOL fMultipleIn ) { TraceFunc( "" );
HRESULT hr;
Assert( NULL != pSimDlgOut );
CSimpleDlg * pthis = new CSimpleDlg; if ( NULL != pthis ) { hr = THR( pthis->Init( hwndParentIn, fMultipleIn ) ); if ( SUCCEEDED( hr ) ) { *pSimDlgOut = pthis; (*pSimDlgOut)->AddRef( ); }
pthis->Release( ); } else { hr = E_OUTOFMEMORY; }
HRETURN( hr );
}
//
//
//
CSimpleDlg::CSimpleDlg( void ) : _cRef( 1 ) { TraceFunc( "" );
Assert( 1 == _cRef ); Assert( NULL == _hwndParent ); Assert( NULL == _hdlg ); Assert( FALSE == _fMultipleSources ); Assert( FALSE == _fNoProperties );
InterlockedIncrement( &g_cObjects );
TraceFuncExit(); }
//
//
//
HRESULT CSimpleDlg::Init( HWND hwndParentIn , BOOL fMultipleIn ) { TraceFunc( "" );
HRESULT hr = S_OK;
_hwndParent = hwndParentIn; _fMultipleSources = fMultipleIn;
// IUnknown stuff
Assert( _cRef == 1 ); //
// Create the dialog
//
_hdlg = CreateDialogParam( g_hInstance , MAKEINTRESOURCE(IDD_SIMPLEVIEW) , _hwndParent , DlgProc , (LPARAM) this ); if ( NULL == _hdlg ) goto ErrorGLE; Cleanup: HRETURN( hr );
ErrorGLE: { DWORD dwErr = TW32( GetLastError( ) ); hr = HRESULT_FROM_WIN32( dwErr ); } goto Cleanup; }
//
//
//
CSimpleDlg::~CSimpleDlg( ) { TraceFunc( "" );
if ( NULL != _hdlg ) { DestroyWindow( _hdlg ); }
InterlockedDecrement( &g_cObjects );
TraceFuncExit(); }
// ************************************************************************
//
// IUnknown
//
// ************************************************************************
//
//
//
STDMETHODIMP CSimpleDlg::QueryInterface( REFIID riid, LPVOID *ppv ) { TraceQIFunc( riid, ppv );
HRESULT hr = E_NOINTERFACE;
if ( IsEqualIID( riid, __uuidof(IUnknown) ) ) { *ppv = static_cast< IUnknown * >( this ); hr = S_OK; } #if 0
else if ( IsEqualIID( riid, __uuidof(IShellExtInit) ) ) { *ppv = TraceInterface( __THISCLASS__, IShellExtInit, this, 0 ); hr = S_OK; } #endif
if ( SUCCEEDED( hr ) ) { ((IUnknown*) *ppv)->AddRef( ); }
QIRETURN( hr, riid ); }
//
//
//
STDMETHODIMP_(ULONG) CSimpleDlg::AddRef( void ) { TraceFunc( "[IUnknown]" );
_cRef ++; // apartment
RETURN( _cRef ); }
//
//
//
STDMETHODIMP_(ULONG) CSimpleDlg::Release( void ) { TraceFunc( "[IUnknown]" );
_cRef --; // apartment
if ( 0 != _cRef ) RETURN( _cRef );
delete this;
RETURN( 0 ); }
// ***************************************************************************
//
// Dialog Proc and Property Sheet Callback
//
// ***************************************************************************
//
//
//
INT_PTR CALLBACK CSimpleDlg::DlgProc( HWND hDlgIn , UINT uMsgIn , WPARAM wParam , LPARAM lParam ) { // Don't do TraceFunc because every mouse movement will cause this function to be called.
WndMsg( hDlgIn, uMsgIn, wParam, lParam );
LRESULT lr = FALSE;
CSimpleDlg * pPage = (CSimpleDlg *) GetWindowLongPtr( hDlgIn, DWLP_USER );
if ( uMsgIn == WM_INITDIALOG ) { SetWindowLongPtr( hDlgIn, DWLP_USER, lParam ); pPage = (CSimpleDlg *) lParam ; pPage->_hdlg = hDlgIn; }
if ( pPage != NULL ) { Assert( hDlgIn == pPage->_hdlg );
switch( uMsgIn ) { case WM_INITDIALOG: lr = pPage->OnInitDialog( ); break;
case WM_COMMAND: lr = pPage->OnCommand( HIWORD(wParam), LOWORD(wParam), lParam ); break;
case WM_NOTIFY: lr = pPage->OnNotify( (int) wParam, (LPNMHDR) lParam ); break;
case WM_DESTROY: SetWindowLongPtr( hDlgIn, DWLP_USER, NULL ); lr = pPage->OnDestroy( ); break;
case WM_HELP: lr = pPage->OnHelp( (LPHELPINFO) lParam ); break;
case WM_CONTEXTMENU: lr = pPage->OnContextMenu( (HWND) wParam, LOWORD(lParam), HIWORD(lParam) ); break; } }
return lr; }
// ***************************************************************************
//
// Private methods
//
// ***************************************************************************
//
// WM_INITDIALOG handler
//
LRESULT CSimpleDlg::OnInitDialog( void ) { TraceFunc( "" );
LRESULT lr = TRUE; // set focus
Assert( NULL != _hdlg ); // this should have been initialized in the DlgProc.
RETURN( lr ); }
//
// WM_COMMAND handler
//
LRESULT CSimpleDlg::OnCommand( WORD wCodeIn , WORD wCtlIn , LPARAM lParam ) { TraceFunc( "" );
LRESULT lr = FALSE;
switch( wCtlIn ) { case IDC_ADVANCED: if ( BN_CLICKED == wCodeIn ) { THR( (HRESULT) SendMessage( _hwndParent, WMU_TOGGLE, 0, 0 ) ); } break;
case IDC_TITLE: case IDC_SUBJECT: case IDC_AUTHOR: case IDC_CATEGORY: case IDC_KEYWORDS: case IDC_COMMENTS: if ( EN_CHANGE == wCodeIn ) { PropSheet_Changed( GetParent( _hwndParent ), _hwndParent ); } else if ( EN_KILLFOCUS == wCodeIn ) { STHR( PersistControlInProperty( wCtlIn ) ); } break; }
RETURN( lr ); }
//
// WM_NOTIFY handler
//
LRESULT CSimpleDlg::OnNotify( int iCtlIdIn , LPNMHDR pnmhIn ) { TraceFunc( "" );
LRESULT lr = FALSE; #if 0
switch( pnmhIn->code ) { default: break; } #endif
RETURN( lr ); }
//
// WM_DESTROY handler
//
LRESULT CSimpleDlg::OnDestroy( void ) { TraceFunc( "" );
LRESULT lr = FALSE;
RETURN( lr ); }
//
// Description:
// Stores the "basic" properties into the prop variant.
//
// Return Values:
// S_OK
// Success!
//
// other HRESULTs.
//
HRESULT CSimpleDlg::PersistProperties( void ) { TraceFunc( "" );
HRESULT hr; ULONG idx;
//
// Loop the the properties updating the dialog as we go.
//
for ( idx = 0; idx < ARRAYSIZE(g_rgBasicProps); idx ++ ) { hr = STHR( PersistControlInProperty( g_rgBasicProps[ idx ].idc ) ); if ( FAILED( hr ) ) goto Cleanup; }
hr = S_OK;
Cleanup: HRETURN( hr ); }
//
// Description:
// Stores the current value of a control into the property cache.
//
// Return Values:
// S_OK
// Success!
//
// S_FALSE
// Nothing to save.
//
// E_FAIL
// Property could not be persisted.
//
// E_OUTOFMEMORY
// OutOfMemory
//
// other HRESULTs.
//
HRESULT CSimpleDlg::PersistControlInProperty( UINT uCtlIdIn ) { TraceFunc( "" );
HRESULT hr; int iLen; int iRet; HWND hwndCtl; UINT uCodePage; VARTYPE vt;
CPropertyCacheItem * pItem; PROPVARIANT * ppropvar;
LPWSTR pszBuf = NULL;
hwndCtl = GetDlgItem( _hdlg, uCtlIdIn ); if ( NULL == hwndCtl ) goto ErrorPersistingValue;
pItem = (CPropertyCacheItem *) GetWindowLongPtr( hwndCtl, GWLP_USERDATA ); if ( NULL == pItem ) { hr = S_FALSE; goto Cleanup; }
hr = THR( pItem->GetCodePage( &uCodePage ) ); if ( FAILED( hr ) ) goto Cleanup;
hr = THR( pItem->GetPropertyValue( &ppropvar ) ); if ( FAILED( hr ) ) goto Cleanup;
switch ( ppropvar->vt ) { case VT_EMPTY: case VT_NULL: { PropVariantInit( ppropvar );
hr = THR( pItem->GetDefaultVarType( &vt ) ); if ( FAILED( hr ) ) goto Cleanup; } break;
default: vt = ppropvar->vt; break; }
iLen = GetWindowTextLength( hwndCtl ); if ( iLen == 0 ) { //
// If nothing to get, then just clear the value and mark it dirty.
//
hr = THR( PropVariantClear( ppropvar ) ); if ( FAILED( hr ) ) goto Cleanup;
hr = THR( pItem->MarkDirty( ) ); goto Cleanup; }
pszBuf = (LPWSTR) SysAllocStringLen( NULL, iLen ); if ( NULL == pszBuf ) goto OutOfMemory;
iRet = GetWindowText( hwndCtl, pszBuf, iLen + 1 ); Assert( iRet == iLen );
hr = THR( PropVariantFromString( pszBuf, uCodePage, 0, vt, ppropvar ) ); if ( FAILED( hr ) ) goto Cleanup;
hr = THR( pItem->MarkDirty( ) ); if ( FAILED( hr ) ) goto Cleanup;
Cleanup: if ( NULL != pszBuf ) { SysFreeString( pszBuf ); }
HRETURN( hr );
OutOfMemory: hr = E_OUTOFMEMORY; goto Cleanup;
ErrorPersistingValue: hr = THR( E_FAIL ); goto Cleanup; }
//
// WM_HELP handler
//
LRESULT CSimpleDlg::OnHelp( LPHELPINFO pHelpInfoIn ) { TraceFunc( "" );
LRESULT lr = FALSE; THR( DoHelp( (HWND) pHelpInfoIn->hItemHandle, pHelpInfoIn->MousePos.x, pHelpInfoIn->MousePos.y, HELP_WM_HELP ) );
RETURN( lr ); }
//
// WM_CONTEXTMENU handler
//
LRESULT CSimpleDlg::OnContextMenu( HWND hwndIn , int iXIn , int iYIn ) { TraceFunc( "" );
LRESULT lr = FALSE;
THR( DoHelp( hwndIn, iXIn, iYIn, HELP_CONTEXTMENU ) );
RETURN( lr ); }
//
// Description:
// Handles locating the item within the list view and construct
// a fake IDC to IDH to display the correct help text for the
// item.
//
// Return Values:
// S_OK
// Success.
//
HRESULT CSimpleDlg::DoHelp( HWND hwndIn , int iXIn , int iYIn , UINT uCommandIn ) { TraceFunc( "" );
ULONG idx;
HRESULT hr = S_OK;
for ( idx = 0; idx < ARRAYSIZE(g_rgBasicProps); idx ++ ) { HWND hwndCtl = GetDlgItem( _hdlg, g_rgBasicProps[ idx ].idc ); AssertMsg( NULL != hwndCtl, "Missing control or table is out of date!" );
if ( hwndCtl == hwndIn ) { CPropertyCacheItem * pItem;
pItem = (CPropertyCacheItem *) GetWindowLongPtr( hwndCtl, GWLP_USERDATA ); if ( NULL != pItem ) { LPCWSTR pszHelpFile; // don't free
UINT uHelpId;
DWORD mapIDStoIDH[ ] = { 0, 0, 0, 0 };
hr = THR( pItem->GetPropertyHelpInfo( &pszHelpFile, &uHelpId ) ); if ( FAILED( hr ) ) goto Cleanup;
mapIDStoIDH[ 0 ] = g_rgBasicProps[ idx ].idc; mapIDStoIDH[ 1 ] = uHelpId;
TBOOL( WinHelp( hwndIn, pszHelpFile, uCommandIn, (DWORD_PTR)(LPSTR) mapIDStoIDH ) ); } } }
Cleanup: HRETURN( hr ); }
// ***************************************************************************
//
// Public methods
//
// ***************************************************************************
//
// Description:
// Hides the dialog.
//
// Return Value:
// S_OK
// Success!
//
HRESULT CSimpleDlg::Hide( void ) { TraceFunc( "" );
HRESULT hr;
ShowWindow( _hdlg, SW_HIDE ); hr = S_OK;
HRETURN( hr ); }
//
// Description:
// Shows the dialog.
//
// Return Values:
// S_OK
// Success!
//
// S_FALSE
// Success, but there isn't anything useful to display to the user.
// One might flip to the Advanced dialog if possible (and the user
// didn't ask to go to the Simple dialog).
//
HRESULT CSimpleDlg::Show( void ) { TraceFunc( "" );
HRESULT hr = S_OK;
ShowWindow( _hdlg, SW_SHOW ); SetFocus( _hdlg );
if ( _fNoProperties ) { hr = S_FALSE; }
HRETURN( hr ); }
//
// Description:
// Populates the properties of the dialog.
//
// Return Values:
// S_OK
// Success!
//
// E_INVALIDARG
// ppcIn is NULL.
//
// other HRESULTs.
//
HRESULT CSimpleDlg::PopulateProperties( CPropertyCache * ppcIn , DWORD dwDocTypeIn , BOOL fMultipleIn ) { TraceFunc( "" );
HRESULT hr; ULONG idx; LPCWSTR pcszValue;
CPropertyCacheItem * pItem;
static const WCHAR s_cszNULL[] = L"";
//
// Check parameters
//
if ( NULL == ppcIn ) goto InvalidArg;
//
// Loop the the properties updating the dialog as we go.
//
_fNoProperties = TRUE;
for ( idx = 0; idx < ARRAYSIZE(g_rgBasicProps); idx ++ ) { HWND hwndCtl = GetDlgItem( _hdlg, g_rgBasicProps[ idx ].idc ); AssertMsg( NULL != hwndCtl, "Missing control or table is out of date!" );
//
// Search the property cache for the entry.
//
hr = STHR( ppcIn->FindItemEntry( g_rgBasicProps[ idx ].pFmtId , g_rgBasicProps[ idx ].propid , &pItem ) ); if ( S_OK == hr ) { int iImage;
Assert ( NULL != pItem ); // paranoid
//
// Retrieve the string value.
//
hr = THR( pItem->GetPropertyStringValue( &pcszValue ) ); if ( S_OK != hr ) goto ControlFailure;
if ( NULL == pcszValue ) { pcszValue = s_cszNULL; }
//
// Update the control.
//
SetWindowText( hwndCtl, pcszValue );
SetWindowLongPtr( hwndCtl, GWLP_USERDATA, (LPARAM) pItem );
_fNoProperties = FALSE;
//
// If the property is read-only, change the edit control to match.
//
hr = THR( pItem->GetImageIndex( &iImage ) ); if ( S_OK != hr ) goto ControlFailure;
if ( PTI_PROP_READONLY == iImage ) { EnableWindow( hwndCtl, FALSE ); }
//
// If the control has mutliple values, mark it read-only. They can edit
// it in the "Advanced" view and this would be an advanced operation.
//
if ( _fMultipleSources ) { EnableWindow( hwndCtl, FALSE ); } } else { ControlFailure: //
// No equivalent property was found or there is an error in the
// property set. Clear and disable the control.
//
SetWindowText( hwndCtl, s_cszNULL ); EnableWindow( hwndCtl, FALSE ); } }
hr = S_OK;
Cleanup: HRETURN( hr );
InvalidArg: hr = THR( E_INVALIDARG ); goto Cleanup; }
|