|
|
//+-------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1996 - 2000.
//
// File: view.cxx
//
// Contents:
//
// History: 15 Aug 1996 DLee Created
//
//--------------------------------------------------------------------------
#include "pch.cxx"
#pragma hdrstop
const int cpMargin = 2; const int cpInflate = 4; const int cpPaneMargin = 3; const int cpPaneSpacing = 5; const int cpPaneBottomSpacing = 0;
const DBID colAttrib = { PSGUID_STORAGE, DBKIND_GUID_PROPID, (LPWSTR) (ULONG_PTR) PID_STG_ATTRIBUTES }; const DBID colFileIndex = { PSGUID_STORAGE, DBKIND_GUID_PROPID, (LPWSTR) (ULONG_PTR) PID_STG_FILEINDEX };
CSearchView::CSearchView( HWND hwndSearch, CSearchControl & control, CColumnList & columns ) : _hwndSearch( hwndSearch ), _hwndQuery( 0 ), _hwndQueryTitle( 0 ), _hwndList( 0 ), _hwndHeader( 0 ), _hbrushWindow( 0 ), _hbrushHighlight( 0 ), _fHavePlacedTitles( FALSE ), _hfontShell( 0 ), _cLines( 0 ), _control( control ), _columns( columns ), _fMucked( FALSE ), _iColAttrib( 0xffffffff ), _iColFileIndex( 0xffffffff ) { MakeFont(); _cpFontHeight = ::GetLineHeight( hwndSearch, _hfontShell ); _iLineHeightList = ::GetLineHeight( hwndSearch, App.AppFont() ); SysColorChange (); } //CSearchView
CSearchView::~CSearchView() { if (0 != _hfontShell) DeleteObject(_hfontShell);
if (0 != _hbrushWindow) { DeleteObject(_hbrushWindow); DeleteObject(_hbrushHighlight); } } //~CSearchView
unsigned CSearchView::ColumnWidth( unsigned x ) { if ( 0 == x ) return _aWidths[ 0 ] + cpInflate + _cpAvgWidth/2 + cpMargin; else return _aWidths[ x ] + _cpAvgWidth; } //ColumnWidth
void CSearchView::SetColumnWidth( unsigned x, unsigned cpWidth ) { unsigned w;
if ( 0 == x ) w = cpWidth - cpInflate - _cpAvgWidth/2 - cpMargin; else w = cpWidth - _cpAvgWidth;
if ( _aWidths[ x ] > w ) _fMucked = TRUE;
_aWidths[ x ] = w; } //SetColumnWidth
unsigned CSearchView::SetDefColumnWidth( unsigned iCol ) { DBID *pdbid; unsigned cc; DBTYPE pt;
IColumnMapper & colMap = _control.GetColumnMapper();
SCODE sc = colMap.GetPropInfoFromName( _columns.GetColumn( iCol ), &pdbid, &pt, &cc ); if ( FAILED( sc ) ) THROW( CException( sc ) );
_aPropTypes[ iCol ] = pt;
if ( ( VT_FILETIME == pt ) || ( DBTYPE_DATE == pt ) ) _aWidths[ iCol ] = _cpDateWidth + _cpTimeWidth; else if ( VT_CLSID == pt ) _aWidths[ iCol ] = _cpGuidWidth; else if ( VT_BOOL == pt ) _aWidths[ iCol ] = _cpBoolWidth; else if ( !memcmp( pdbid, &colAttrib, sizeof DBID ) ) { _aWidths[ iCol ] = _cpAttribWidth; _iColAttrib = iCol; } else if ( !memcmp( pdbid, &colFileIndex, sizeof DBID ) ) { _aWidths[ iCol ] = _cpFileIndexWidth; _iColFileIndex = iCol; } else _aWidths[ iCol ] = cc * _cpAvgWidth;
// did the attrib column get redefined?
if ( _iColAttrib == iCol && memcmp( pdbid, &colAttrib, sizeof DBID ) ) _iColAttrib = 0xffffffff;
// did the fileindex column get redefined?
if ( _iColFileIndex == iCol && memcmp( pdbid, &colFileIndex, sizeof DBID ) ) _iColFileIndex = 0xffffffff;
return ColumnWidth( iCol ); } //SetDefColumnWidth
void CSearchView::ColumnsChanged() { _ComputeFieldWidths();
for ( unsigned iCol = 0; iCol < _columns.NumberOfColumns(); iCol++ ) SetDefColumnWidth( iCol ); } //ColumnsChanged
void CSearchView::MakeFont() { LOGFONT lf; memset( &lf, 0, sizeof LOGFONT );
lf.lfHeight = -11; lf.lfWeight = FW_NORMAL; lf.lfCharSet = ANSI_CHARSET; lf.lfOutPrecision = OUT_DEFAULT_PRECIS; lf.lfClipPrecision = CLIP_DEFAULT_PRECIS; lf.lfQuality = PROOF_QUALITY; lf.lfPitchAndFamily = FF_SWISS | VARIABLE_PITCH; wcscpy( lf.lfFaceName, L"MS SHELL DLG" ); _hfontShell = CreateFontIndirect( &lf ); } //MakeFont
void CSearchView::SysColorChange() { if (0 != _hbrushWindow) { DeleteObject(_hbrushWindow); DeleteObject(_hbrushHighlight); }
_colorHighlight = GetSysColor(COLOR_HIGHLIGHT); _colorHighlightText = GetSysColor(COLOR_HIGHLIGHTTEXT); _colorWindow = GetSysColor(COLOR_WINDOW); _colorWindowText = GetSysColor(COLOR_WINDOWTEXT);
_hbrushHighlight = CreateSolidBrush( _colorHighlight ); _hbrushWindow = CreateSolidBrush( _colorWindow ); } //SysColorChange
void CSearchView::InitPanes ( HWND hwndQueryTitle, HWND hwndQuery, HWND hwndList, HWND hwndHeader ) { _hwndQueryTitle = hwndQueryTitle; _hwndQuery = hwndQuery; _hwndList = hwndList; _hwndHeader = hwndHeader;
SendMessage( _hwndQueryTitle, WM_SETFONT, (WPARAM) _hfontShell, 1 ); SendMessage( _hwndHeader, WM_SETFONT, (WPARAM) _hfontShell, 1 ); SendMessage( _hwndQuery, WM_SETFONT, (WPARAM) App.AppFont(), 1 ); SendMessage( _hwndList, WM_SETFONT, (WPARAM) App.AppFont(), 1 ); } //InitPanes
void CSearchView::PrimeItem( LPDRAWITEMSTRUCT & lpdis, RECT & rc ) { CopyRect( &rc, &lpdis->rcItem ); InflateRect( (LPRECT) &rc, 1, 0 );
HBRUSH hbr;
if ( lpdis->itemState & ODS_SELECTED ) { SetBkColor( lpdis->hDC, _colorHighlight ); SetTextColor( lpdis->hDC, _colorHighlightText ); hbr = _hbrushHighlight; } else { SetBkColor( lpdis->hDC, _colorWindow ); SetTextColor( lpdis->hDC, _colorWindowText ); hbr = _hbrushWindow; }
FillRect( lpdis->hDC, &rc, hbr );
InflateRect( &rc, -cpInflate, 0 ); } //PrimeItem
inline void _drawText( HDC hdc, RECT & rc, unsigned cpWidth, WCHAR * pwc, int cwc, BOOL fClip ) { RECT rctext = rc; rctext.right = rc.left + cpWidth;
DrawText( hdc, pwc, cwc, &rctext, DT_VCENTER | DT_NOPREFIX | DT_RIGHT | DT_SINGLELINE | ( fClip ? 0 : DT_NOCLIP ) ); } //_drawText
template<class T> void _drawVectorItems( T * pVal, ULONG cVals, WCHAR * pwcFmt, HDC hdc, RECT & rc, unsigned width ) { WCHAR awcBuf[ cwcBufSize ]; unsigned ccUnused = cwcBufSize - 10; WCHAR *pwcEnd = awcBuf;
*pwcEnd++ = L'{';
for( unsigned iVal = 0; iVal < cVals && ccUnused > 0; iVal++ ) { int ccPrinted = _snwprintf( pwcEnd, ccUnused, pwcFmt, iVal == 0 ? L' ': L',', *pVal++ );
if ( ccPrinted == -1 ) break;
ccUnused -= ccPrinted; pwcEnd += ccPrinted; }
if ( iVal != cVals ) { *pwcEnd++ = L'.'; *pwcEnd++ = L'.'; *pwcEnd++ = L'.'; }
*pwcEnd++ = L' '; *pwcEnd++ = L'}'; *pwcEnd = L'\0';
_drawText( hdc, rc, width, awcBuf, -1, TRUE ); } //_drawVectorItems
void Append( CDynArrayInPlace<WCHAR> & xBuf, WCHAR const * pwc, unsigned cwc ) { for ( unsigned i = 0; i < cwc; i++ ) xBuf[ xBuf.Count() ] = pwc[ i ]; } //Append
void Append( CDynArrayInPlace<WCHAR> & xBuf, WCHAR const * pwc ) { while ( 0 != *pwc ) xBuf[ xBuf.Count() ] = *pwc++; } //Append
void RenderSafeArray( WCHAR * pwc, unsigned cwcMax, VARTYPE vt, LPSAFEARRAY pa );
void Render( CDynArrayInPlace<WCHAR> & xOut, VARTYPE vt, void * pv ) { srchDebugOut(( DEB_ITRACE, "vt %#x, pv %#x\n", vt, pv )); __int64 i = 0;
XArray<WCHAR> xBuf( cwcBufSize ); WCHAR *awcBuf = xBuf.GetPointer(); XArray<WCHAR> xTmp( cwcBufSize ); WCHAR *awcTmp = xTmp.GetPointer(); static WCHAR wszfmtU[] = L"%I64u"; WCHAR *pwszfmt = L"%I64d"; LCID lcid = App.GetLocale();
if ( VT_ARRAY & vt ) { SAFEARRAY *psa = *(SAFEARRAY **) pv; *awcBuf = 0; RenderSafeArray( awcBuf, cwcBufSize, vt - VT_ARRAY, psa ); Append( xOut, awcBuf ); return; }
switch ( vt ) { case VT_UI1: i = (unsigned __int64) *(BYTE *)pv; goto do_ui64;
case VT_I1: i = *(CHAR *)pv; goto do_i64;
case VT_UI2: i = (unsigned __int64) *(USHORT *)pv; goto do_ui64;
case VT_I2: i = (unsigned __int64) *(SHORT *)pv; goto do_i64;
case VT_UI4: case VT_UINT: i = (unsigned __int64) *(ULONG *)pv; goto do_ui64;
case VT_I4: case VT_ERROR: case VT_INT: i = (unsigned __int64) *(LONG *)pv; goto do_i64;
case VT_UI8: RtlCopyMemory( &i, pv, sizeof i ); do_ui64: pwszfmt = wszfmtU; goto do_i64;
case VT_I8: RtlCopyMemory( &i, pv, sizeof i );
do_i64: { swprintf( awcTmp, pwszfmt, i ); int cwc = GetNumberFormat( lcid, 0, awcTmp, & App.NumberFormat(), awcBuf, cwcBufSize ); Append( xOut, awcBuf, cwc - 1); break; } case VT_R4: { float f; RtlCopyMemory( &f, pv, sizeof f ); swprintf( awcTmp, L"%f", f ); int cwc = GetNumberFormat( lcid, 0, awcTmp, & App.NumberFormatFloat(), awcBuf, cwcBufSize ); Append( xOut, awcBuf, cwc - 1 ); break; } case VT_R8: { double d; RtlCopyMemory( &d, pv, sizeof d ); swprintf( awcTmp, L"%lf", d ); int cwc = GetNumberFormat( lcid, 0, awcTmp, & App.NumberFormatFloat(), awcBuf, cwcBufSize ); Append( xOut, awcBuf, cwc - 1 ); break; } case VT_DECIMAL: { double dbl; VarR8FromDec( (DECIMAL *) pv, &dbl ); swprintf( awcTmp, L"%lf", dbl ); int cwc = GetNumberFormat( lcid, 0, awcTmp, & App.NumberFormatFloat(), awcBuf, cwcBufSize ); Append( xOut, awcBuf, cwc - 1 ); break; } case VT_CY: { double dbl; VarR8FromCy( * (CY *) pv, &dbl ); swprintf( awcTmp, L"%lf", dbl ); int cwc = GetNumberFormat( lcid, 0, awcTmp, & App.NumberFormatFloat(), awcBuf, cwcBufSize ); Append( xOut, awcBuf, cwc - 1 ); break; } case VT_BOOL: { Append( xOut, *(VARIANT_BOOL *)pv ? App.GetTrue() : App.GetFalse() ); break; } case VT_BSTR: { BSTR bstr = *(BSTR *) pv; Append( xOut, bstr ); break; } case VT_VARIANT: { PROPVARIANT * pVar = (PROPVARIANT *) pv; Render( xOut, pVar->vt, & pVar->lVal ); break; } case VT_DATE: { DATE date; RtlCopyMemory( &date, pv, sizeof date ); awcBuf[0] = 0;
// no timezone is expressed or implied in variant dates.
SYSTEMTIME SysTime; RtlZeroMemory( &SysTime, sizeof SysTime ); VariantTimeToSystemTime( date, &SysTime );
// date
int cwc = GetDateFormat( lcid, DATE_SHORTDATE, &SysTime, 0, awcBuf, cwcBufSize ); if ( 0 != cwc ) Append( xOut, awcBuf, cwc - 1 );
Append( xOut, L" " );
// time
cwc = GetTimeFormat( lcid, 0, &SysTime, 0, awcBuf, cwcBufSize ); if ( 0 != cwc ) Append( xOut, awcBuf, cwc - 1 ); break; }
case VT_EMPTY: case VT_NULL: { break; } default : { swprintf( awcTmp, L"(vt 0x%x)", (int) vt ); Append( xOut, awcTmp ); break; } } } //Render
void RenderSafeArray( WCHAR * pwc, unsigned cwcMax, VARTYPE vt, LPSAFEARRAY pa ) { *pwc = 0; cwcMax -= 10; // leave room for formatting
// Get the dimensions of the array
CDynArrayInPlace<WCHAR> xOut; UINT cDim = SafeArrayGetDim( pa ); if ( 0 == cDim ) return;
XArray<LONG> xDim( cDim ); XArray<LONG> xLo( cDim ); XArray<LONG> xUp( cDim );
for ( UINT iDim = 0; iDim < cDim; iDim++ ) { HRESULT hr = SafeArrayGetLBound( pa, iDim + 1, &xLo[iDim] ); if ( FAILED( hr ) ) return;
xDim[ iDim ] = xLo[ iDim ];
hr = SafeArrayGetUBound( pa, iDim + 1, &xUp[iDim] ); if ( FAILED( hr ) ) return;
srchDebugOut(( DEB_ITRACE, "dim %d, lo %d, up %d\n", iDim, xLo[iDim], xUp[iDim] ));
xOut[ xOut.Count() ] = L'{'; }
// slog through the array
UINT iLastDim = cDim - 1; BOOL fDone = FALSE;
while ( !fDone && ( xOut.Count() < cwcMax ) ) { // inter-element formatting
if ( xDim[ iLastDim ] != xLo[ iLastDim ] ) xOut[ xOut.Count() ] = L',';
// Get the element and render it
void *pv; HRESULT hr = SafeArrayPtrOfIndex( pa, xDim.GetPointer(), &pv ); Win4Assert( SUCCEEDED( hr ) ); Render( xOut, vt, pv );
// Move to the next element and carry if necessary
ULONG cOpen = 0;
for ( LONG iDim = iLastDim; iDim >= 0; iDim-- ) { if ( xDim[ iDim ] < xUp[ iDim ] ) { xDim[ iDim ] = 1 + xDim[ iDim ]; break; }
xOut[ xOut.Count() ] = L'}';
if ( 0 == iDim ) fDone = TRUE; else { cOpen++; xDim[ iDim ] = xLo[ iDim ]; } }
for ( ULONG i = 0; !fDone && i < cOpen; i++ ) xOut[ xOut.Count() ] = L'{'; }
unsigned cwc = __min( cwcMax, xOut.Count() ); RtlCopyMemory( pwc, xOut.GetPointer(), cwc * sizeof WCHAR );
// If it wouldn't all fit, show ...
if ( !fDone ) { pwc[ cwc++ ] = '.'; pwc[ cwc++ ] = '.'; pwc[ cwc++ ] = '.'; }
pwc[ cwc ] = 0; } //RenderSafeArray
void CSearchView::PaintItem ( CSearchQuery * pSearch, HDC hdc, RECT & rc, DWORD iRow ) { static WCHAR wszfmtU[] = L"%u"; // unsigned scalar
static WCHAR wszfmtVU[] = L"%lc%u"; // vector of unsigned scalars
PROPVARIANT * aProps[ maxBoundCols ]; unsigned cColumns;
if ( ! pSearch->GetRow( iRow, cColumns, aProps ) ) return;
//
// These must be static for IceCap profiling to work. Declaring them on
// stack causes __alloca_probe (alias: _chkstk) to be called. This
// routine plays funny games with the stack that IceCap V3 doesn't understand.
//
static WCHAR awcBuf[cwcBufSize]; static WCHAR awcTmp[cwcBufSize];
LCID lcid = App.GetLocale(); rc.left += cpMargin; // leave a margin
for ( unsigned i = 0; i < cColumns; i++ ) { PROPVARIANT & v = * aProps[ i ]; unsigned width = _aWidths[ i ]; WCHAR *pwszfmt = L"%d"; // signed scalar
WCHAR *pwszfmtV = L"%lc%d"; // vector of signed scalars
BOOL fHighPartValid;
switch ( v.vt ) { case VT_UI1: v.ulVal = v.bVal; goto doulong;
case VT_I1: v.lVal = v.cVal; goto dolong;
case VT_UI2: v.ulVal = v.uiVal; goto doulong;
case VT_I2: v.lVal = v.iVal; goto dolong;
case VT_UI4: case VT_UINT: doulong: pwszfmt = wszfmtU; case VT_I4: case VT_INT: case VT_ERROR: dolong: { int cwc;
if ( i == _iColAttrib ) { cwc = 0; WCHAR *pwc = App.GetAttrib(); LONG l = v.lVal; if ( l & FILE_ATTRIBUTE_READONLY ) awcBuf[ cwc++ ] = pwc[ 0 ]; if ( l & FILE_ATTRIBUTE_HIDDEN ) awcBuf[ cwc++ ] = pwc[ 1 ]; if ( l & FILE_ATTRIBUTE_SYSTEM ) awcBuf[ cwc++ ] = pwc[ 2 ]; if ( l & FILE_ATTRIBUTE_DIRECTORY ) awcBuf[ cwc++ ] = pwc[ 3 ]; if ( l & FILE_ATTRIBUTE_ARCHIVE ) awcBuf[ cwc++ ] = pwc[ 4 ]; if ( l & FILE_ATTRIBUTE_ENCRYPTED ) awcBuf[ cwc++ ] = pwc[ 5 ]; if ( l & FILE_ATTRIBUTE_NORMAL ) awcBuf[ cwc++ ] = pwc[ 6 ]; if ( l & FILE_ATTRIBUTE_TEMPORARY ) awcBuf[ cwc++ ] = pwc[ 7 ]; if ( l & FILE_ATTRIBUTE_SPARSE_FILE ) awcBuf[ cwc++ ] = pwc[ 8 ]; if ( l & FILE_ATTRIBUTE_REPARSE_POINT ) awcBuf[ cwc++ ] = pwc[ 9 ]; if ( l & FILE_ATTRIBUTE_COMPRESSED ) awcBuf[ cwc++ ] = pwc[ 10 ]; if ( l & FILE_ATTRIBUTE_OFFLINE ) awcBuf[ cwc++ ] = pwc[ 11 ]; if ( l & FILE_ATTRIBUTE_NOT_CONTENT_INDEXED ) awcBuf[ cwc++ ] = pwc[ 12 ]; awcBuf[ cwc ] = 0; } else { if ( pwszfmt == wszfmtU ) _ultow( v.lVal, awcTmp, 10 ); else _ltow( v.lVal, awcTmp, 10 );
cwc = GetNumberFormat( lcid, 0, awcTmp, & App.NumberFormat(), awcBuf, cwcBufSize ); cwc--; }
_drawText( hdc, rc, width, awcBuf, cwc, _fMucked ); break; }
case VT_I8: { _i64tow( * (__int64 *) &v.hVal, awcTmp, 10 ); int cwc = GetNumberFormat( lcid, 0, awcTmp, & App.NumberFormat(), awcBuf, cwcBufSize ); cwc--; _drawText( hdc, rc, width, awcBuf, cwc, _fMucked ); break; }
case VT_UI8: { if ( i == _iColFileIndex ) { wcscpy( awcBuf, L"0x" );
if ( 0 != v.hVal.HighPart ) { wsprintf( awcTmp, L"%08x,", v.hVal.HighPart ); wcscat( awcBuf, awcTmp ); }
wsprintf( awcTmp, L"%08x", v.hVal.LowPart ); wcscat( awcBuf, awcTmp ); _drawText( hdc, rc, width, awcBuf, -1, _fMucked ); } else { _ui64tow( *(unsigned __int64 *) &v.hVal, awcTmp, 10 ); int cwc = GetNumberFormat( lcid, 0, awcTmp, & App.NumberFormat(), awcBuf, cwcBufSize ); cwc--; _drawText( hdc, rc, width, awcBuf, cwc, _fMucked ); } break; }
case VT_FILETIME : { awcBuf[0] = 0;
if ( 0 == v.filetime.dwLowDateTime && 0 == v.filetime.dwHighDateTime ) { _drawText( hdc, rc, width, L"0", -1, TRUE ); } else { // convert the file time to local time, then to system time
FILETIME LocalFTime; memset( &LocalFTime, 0, sizeof LocalFTime ); FileTimeToLocalFileTime( &(v.filetime), &LocalFTime ); SYSTEMTIME SysTime; memset( &SysTime, 0, sizeof SysTime ); FileTimeToSystemTime( &LocalFTime, &SysTime );
// date
int cwc = GetDateFormat( lcid, DATE_SHORTDATE, &SysTime, 0, awcBuf, cwcBufSize ); int dmin = __min( _cpDateWidth, (int) width ); if ( 0 != cwc ) _drawText( hdc, rc, dmin, awcBuf, cwc - 1, _fMucked );
// time
if ( (int) width > _cpDateWidth ) { cwc = GetTimeFormat( lcid, 0, &SysTime, 0, awcBuf, cwcBufSize ); int left = rc.left; rc.left += _cpDateWidth; int tmin = __min( _cpTimeWidth, (int) width - _cpDateWidth ); if ( 0 != cwc ) _drawText( hdc, rc, tmin, awcBuf, cwc - 1, _fMucked ); rc.left = left; } }
break; }
case VT_LPWSTR : case DBTYPE_WSTR | DBTYPE_BYREF : case VT_LPSTR : case DBTYPE_STR | DBTYPE_BYREF : case VT_BSTR : { if ( 0 != v.pwszVal ) { // don't clip if it's the last column
UINT f = ( i == ( cColumns - 1 ) ) ? DT_NOCLIP : 0; RECT rctext; CopyRect( &rctext, &rc ); rctext.right = rc.left + width;
if ( ( VT_LPSTR == v.vt ) || ( ( DBTYPE_STR | DBTYPE_BYREF ) == v.vt ) ) DrawTextA( hdc, v.pszVal, -1, &rctext, DT_VCENTER | DT_LEFT | DT_NOPREFIX | DT_SINGLELINE | f ); else DrawText( hdc, v.pwszVal, -1, &rctext, DT_VCENTER | DT_LEFT | DT_NOPREFIX | DT_SINGLELINE | f ); } break; }
case VT_R4: { swprintf( awcTmp, L"%f", v.fltVal ); int cwc = GetNumberFormat( lcid, 0, awcTmp, & App.NumberFormatFloat(), awcBuf, cwcBufSize ); cwc--; _drawText( hdc, rc, width, awcBuf, cwc, _fMucked ); break; }
case VT_DATE: { awcBuf[0] = 0;
SYSTEMTIME SysTime; RtlZeroMemory( &SysTime, sizeof SysTime ); VariantTimeToSystemTime( v.date, &SysTime );
// date
int cwc = GetDateFormat( lcid, DATE_SHORTDATE, &SysTime, 0, awcBuf, cwcBufSize ); int dmin = __min( _cpDateWidth, (int) width ); if ( 0 != cwc ) _drawText( hdc, rc, dmin, awcBuf, cwc - 1, _fMucked );
// time
if ( (int) width > _cpDateWidth ) { cwc = GetTimeFormat( lcid, 0, &SysTime, 0, awcBuf, cwcBufSize ); int left = rc.left; rc.left += _cpDateWidth; int tmin = __min( _cpTimeWidth, (int) width - _cpDateWidth ); if ( 0 != cwc ) _drawText( hdc, rc, tmin, awcBuf, cwc - 1, _fMucked ); rc.left = left; }
break; }
case VT_R8: { swprintf( awcTmp, L"%lf", v.dblVal ); int cwc = GetNumberFormat( lcid, 0, awcTmp, & App.NumberFormatFloat(), awcBuf, cwcBufSize ); cwc--; _drawText( hdc, rc, width, awcBuf, cwc, _fMucked ); break; }
case VT_DECIMAL: { double dbl; VarR8FromDec( &v.decVal, &dbl ); swprintf( awcBuf, L"%lf", dbl ); _drawText( hdc, rc, width, awcBuf, -1, TRUE ); break; }
case VT_CY: { double dbl; VarR8FromCy( v.cyVal, &dbl ); swprintf( awcTmp, L"$%lf", dbl ); _drawText( hdc, rc, width, awcTmp, -1, _fMucked ); break; }
case VT_BOOL: { _drawText( hdc, rc, width, v.boolVal ? App.GetTrue() : App.GetFalse(), -1, _fMucked ); break; }
case VT_CLSID: { GUID * puuid = v.puuid; if ( 0 != puuid ) swprintf( awcTmp, L"{%08lx-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}", puuid->Data1, puuid->Data2, puuid->Data3, puuid->Data4[0], puuid->Data4[1], puuid->Data4[2], puuid->Data4[3], puuid->Data4[4], puuid->Data4[5], puuid->Data4[6], puuid->Data4[7] ); else awcTmp[0] = 0;
_drawText( hdc, rc, width, awcTmp, -1, _fMucked ); break; }
case VT_BLOB: { swprintf( awcTmp, App.GetBlob(), v.blob.cbSize, v.blob.pBlobData );
_drawText( hdc, rc, width, awcTmp, -1, TRUE ); break; }
case VT_CF: { if ( 0 != v.pclipdata ) swprintf( awcTmp, L"vt_cf cb 0x%x, fmt 0x%x", v.pclipdata->cbSize, v.pclipdata->ulClipFmt ); else swprintf( awcTmp, L"vt_cf (null)" );
_drawText( hdc, rc, width, awcTmp, -1, TRUE ); break; }
case VT_VECTOR | VT_UI1: pwszfmtV = wszfmtVU; case VT_VECTOR | VT_I1: { _drawVectorItems( v.caub.pElems, v.caub.cElems, pwszfmtV, hdc, rc, width ); break; }
case VT_VECTOR | VT_BOOL: case VT_VECTOR | VT_UI2: pwszfmtV = wszfmtVU; case VT_VECTOR | VT_I2: { _drawVectorItems( v.cai.pElems, v.cai.cElems, pwszfmtV, hdc, rc, width ); break; }
case VT_VECTOR | VT_UI4: pwszfmtV = wszfmtVU; case VT_VECTOR | VT_I4: { _drawVectorItems( v.cal.pElems, v.cal.cElems, pwszfmtV, hdc, rc, width ); break; }
case VT_VECTOR | VT_LPSTR: case VT_VECTOR | VT_LPWSTR: case VT_VECTOR | VT_BSTR: { _drawVectorItems( v.calpwstr.pElems, v.calpwstr.cElems, ( ( VT_VECTOR | VT_LPSTR ) == v.vt ) ? L"%wc%S" : L"%wc%s", hdc, rc, width ); break; }
case VT_VECTOR | VT_R4: { _drawVectorItems( v.caflt.pElems, v.caflt.cElems, L"%wc%f", hdc, rc, width ); break; }
case VT_VECTOR | VT_R8: { _drawVectorItems( v.cadbl.pElems, v.cadbl.cElems, L"%wc%lf", hdc, rc, width ); break; }
case VT_VECTOR | VT_I8: case VT_VECTOR | VT_UI8: { _drawVectorItems( v.cah.pElems, v.cah.cElems, ( v.vt == ( VT_VECTOR | VT_I8 ) ) ? L"%wc%I64d" : L"%wc%I64u", hdc, rc, width ); break; }
//case VT_VECTOR | VT_DATE:
//case VT_VECTOR | VT_FILETIME:
//case VT_VECTOR | VT_CF:
//case VT_VECTOR | VT_CY:
//case VT_VECTOR | VT_VARIANT:
case VT_NULL : case VT_EMPTY : { //_drawText( hdc, rc, width, L"-", -1, TRUE );
break; }
default : { if ( VT_ARRAY & v.vt ) { RenderSafeArray( awcBuf, sizeof awcBuf / sizeof WCHAR, v.vt - VT_ARRAY, v.parray ); _drawText( hdc, rc, width, awcBuf, -1, TRUE ); break; }
swprintf( awcTmp, L"(vt 0x%x)", (int) v.vt ); _drawText( hdc, rc, width, awcTmp, -1, TRUE ); break; } }
rc.left += ( width + _cpAvgWidth ); } } //PaintItem
void CSearchView::Size( int cx, int cy ) { HDWP hDefer = BeginDeferWindowPos( 4 );
if ( 0 == hDefer ) return;
int iFontDY = _cpFontHeight; int dyQuery = _iLineHeightList + _cpFontHeight / 2; int iListHeight = cy - ( 2 * cpPaneSpacing ) - dyQuery;
int iX = cpPaneMargin; int iDX = cx - cpPaneMargin * 2; int iY = cpPaneSpacing; int iDY = iFontDY; int iTitleDX = iFontDY * 3;
if (!_fHavePlacedTitles) hDefer = DeferWindowPos( hDefer, _hwndQueryTitle, 0, iX, iY + iFontDY / 4, iTitleDX, iDY, SWP_NOZORDER );
hDefer = DeferWindowPos( hDefer, _hwndQuery, 0, iX + iTitleDX, iY, iDX - iTitleDX, dyQuery, SWP_NOZORDER );
if (iListHeight > 0) { HD_LAYOUT hdl; RECT rc = { 0, 0, cx, cy }; hdl.prc = &rc; WINDOWPOS wp; hdl.pwpos = ℘ Header_Layout( _hwndHeader, &hdl );
iY += ( dyQuery + cpPaneSpacing );
hDefer = DeferWindowPos( hDefer, _hwndHeader, 0, iX, iY, iDX, wp.cy, SWP_NOZORDER );
int iListY = iY + wp.cy;
iListY--; // too many black lines...
iListHeight = cy - iListY - cpPaneBottomSpacing;
// fit integral number of lines in listview
int cyBorder2x = 2 * GetSystemMetrics( SM_CYBORDER ); _cLines = ( iListHeight - cyBorder2x ) / GetLineHeight();
hDefer = DeferWindowPos( hDefer, _hwndList, 0, iX, iListY, iDX, _cLines * GetLineHeight() + cyBorder2x, SWP_NOZORDER ); }
EndDeferWindowPos( hDefer );
_fHavePlacedTitles = TRUE; } //Size
void CSearchView::FontChanged( HFONT hfontNew ) { HDC hdc = GetDC (_hwndList);
if (hdc) { HFONT hfOld = (HFONT) SelectObject( hdc, hfontNew ); TEXTMETRIC tm; GetTextMetrics (hdc, &tm); _iLineHeightList = (tm.tmHeight + 2 * tm.tmExternalLeading); SelectObject( hdc, hfOld );
RECT rc; GetWindowRect(_hwndList,(LPRECT) &rc); _cLines = (rc.bottom - rc.top) / GetLineHeight();
ReleaseDC( _hwndList, hdc ); } } //FontChanged
void CSearchView::ResizeQueryCB() { RECT rect;
ShowWindow( _hwndQuery, SW_HIDE );
if ( GetClientRect( _hwndQuery, &rect ) ) { SetWindowPos( _hwndQuery, 0, 0, 0, rect.right, 5 * ( _cpFontHeight * 3 ) / 2, SWP_NOZORDER | SWP_NOMOVE | SWP_NOREDRAW | SWP_DEFERERASE | SWP_NOACTIVATE ); } ShowWindow( _hwndQuery, SW_SHOWNOACTIVATE ); }
inline int CSearchView::_MeasureString( HDC hdc, WCHAR * pwcMeasure, RECT & rc, int cwc) { RECT rcMeasure; CopyRect( &rcMeasure, &rc );
DrawText( hdc, pwcMeasure, cwc, &rcMeasure, DT_CALCRECT | DT_SINGLELINE | DT_BOTTOM | DT_LEFT ); return rcMeasure.right - rcMeasure.left; } //_MeasureString
void CSearchView::_ComputeFieldWidths() { HDC hdc = GetDC( _hwndList );
if ( 0 == hdc ) return;
HFONT hfOld = (HFONT) SelectObject( hdc, (HGDIOBJ) App.AppFont() );
TEXTMETRIC tm; GetTextMetrics( hdc, &tm ); _cpAvgWidth = tm.tmAveCharWidth;
RECT rc = { 0, 0, 2000, 2000 };
SYSTEMTIME st; RtlZeroMemory( &st, sizeof st ); st.wMonth = 12; st.wDay = 28; st.wDayOfWeek = 3; st.wYear = 1994;
LCID lcid = App.GetLocale(); WCHAR awc[ cwcBufSize ]; int cwc = GetDateFormat( lcid, DATE_SHORTDATE, &st, 0, awc, cwcBufSize ); _cpDateWidth = _MeasureString( hdc, awc, rc, cwc - 1 );
st.wHour = 22; st.wMinute = 59; st.wSecond = 59; st.wMilliseconds = 10;
cwc = GetTimeFormat( lcid, 0, &st, 0, awc, cwcBufSize ); _cpTimeWidth = _MeasureString( hdc, awc, rc, cwc - 1 ); _cpTimeWidth += _cpAvgWidth; // room between time and date...
_cpGuidWidth = _MeasureString( hdc, L"{8dee0300-16c2-101b-b121-08002b2ecda9}", rc);
_cpBoolWidth = _MeasureString( hdc, App.GetFalse(), rc);
// guess that only half of the attributes will be on at once
_cpAttribWidth = 4 + _MeasureString( hdc, App.GetAttrib(), rc ) / 2;
_cpFileIndexWidth = _MeasureString( hdc, L"0x88888888,88888888", rc );
SelectObject( hdc, hfOld ); ReleaseDC( _hwndList, hdc ); } //_ComputeFieldWidths
|