/////////////////////////////////////////////////////////////////////////////////////////
// Project: SP Numeric Edit Control 1.2
//
// File: NumericEditBox.cpp
//
// Developer(s): Sergei Pavlovsky
// sergei_vp@hotmail.com
// Copyright (c) 2004-2005
//
// Description: Implementation of CoNumericEditBox class.
// CoNumericEditBox represents ActiveX control.
//
// Platforms: Win32, ATL
//
// This code may be used in compiled form in any way you desire. This file may be
// redistributed unmodified by any means PROVIDING it is not sold for profit without
// the authors written consent, and providing that this notice and the authors name
// is included. If the source code in this file is used in any commercial application
// then acknowledgement must be made to the author of this file (in whatever form
// you wish).
//
// This file is provided "as is" with no expressed or implied warranty. The author
// accepts no liability for any damage/loss of business that this product may cause.
/////////////////////////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "NumericEditBox.h"
#include "SpNumericEditModule.h"
#include <map>
#include <sstream>
/////////////////////////////////////////////////////////////////////////////////////////
// CoNumericEditBox::CFontPropertyNotifySink class implementation
/////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////
// Operations
void CoNumericEditBox::CFontPropertyNotifySink::Advise(IFont* piFont) // throw(ELogError)
{
ATLASSERT( piFont && !m_dwCookie );
try
{
HRESULT hr = AtlAdvise(piFont, static_cast<IPropertyNotifySink*>(this),
IID_IPropertyNotifySink, &m_dwCookie);
ATLASSERT( SUCCEEDED(hr) );
if ( FAILED(hr) )
throw EComLogError(hr);
}
catch( ELogError& e )
{
throw EAppLogError(ENEC_CONNECTFONTEVENTSINK, &e);
}
}
void CoNumericEditBox::CFontPropertyNotifySink::Unadvise(IFont* piFont) throw()
{
ATLASSERT( piFont && m_dwCookie );
#ifdef _DEBUG
HRESULT hr = AtlUnadvise(piFont, IID_IPropertyNotifySink, m_dwCookie);
ATLASSERT( SUCCEEDED(hr) );
#else // _DEBUG
AtlUnadvise(piFont, IID_IPropertyNotifySink, m_dwCookie);
#endif // _DEBUG
m_dwCookie = 0;
}
/////////////////////////////////////////////////////////////////////////////////////////
// IPropertyNotifySink implementation
STDMETHODIMP CoNumericEditBox::CFontPropertyNotifySink::OnRequestEdit(DISPID dispid)
{
if ( m_pOwner )
{
if ( m_pOwner->m_nFreezeEvents )
return S_FALSE;
return m_pOwner->FireOnRequestEdit(DISPID_FONT);
}
return S_OK;
}
STDMETHODIMP CoNumericEditBox::CFontPropertyNotifySink::OnChanged(DISPID dispid)
{
if ( m_pOwner )
{
m_pOwner->m_ctlEdit._OnFontChanging();
m_pOwner->m_bRequiresSave = TRUE;
if ( m_pOwner->m_nFreezeEvents == 0 )
m_pOwner->FireOnChanged(DISPID_FONT);
m_pOwner->m_ctlEdit._OnFontChanged();
m_pOwner->FireViewChange();
m_pOwner->SendOnDataChange(NULL);
}
return S_OK;
}
/////////////////////////////////////////////////////////////////////////////////////////
// CoNumericEditBox class implementation
/////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////
// Constants
LPCOLESTR CoNumericEditBox::ms_rgszParamNames[] =
{
L"ValueType",
L"FormatType",
L"DisplayMask",
L"EditingMask"
};
SIZE_T CoNumericEditBox::ms_cchMaxParamName = 11;
/////////////////////////////////////////////////////////////////////////////////////////
// Construction & destruction
#pragma warning(push)
#pragma warning(disable: 4355) // 'this' : used in base member initializer list
CoNumericEditBox::CoNumericEditBox() throw()
: m_ctlEdit(_T("Edit"), this, 1),
m_pcoFontNS(NULL),
m_pcoFormatter(NULL)
{
m_bWindowOnly = TRUE;
}
#pragma warning(pop)
CoNumericEditBox::~CoNumericEditBox() throw()
{
ATLASSERT( m_pcoFontNS == NULL );
ATLASSERT( m_pcoFormatter == NULL );
}
HRESULT CoNumericEditBox::FinalConstruct() throw()
{
ATLASSERT( !m_pcoFontNS );
// Set internal event sink to edit window.
m_ctlEdit.AdviseEventSink(this);
// Create Property Notify sink
HRESULT hr = CComObject<CFontPropertyNotifySink>::CreateInstance(&m_pcoFontNS);
ATLASSERT( SUCCEEDED(hr) );
if FAILED(hr)
return hr;
m_pcoFontNS->AddRef();
m_pcoFontNS->Initialize(this);
return S_OK;
}
void CoNumericEditBox::FinalRelease()throw()
{
ATLASSERT( m_pcoFontNS );
// Free Property Notify sink
if ( m_pcoFontNS->GetCookie() )
m_pcoFontNS->Unadvise(m_ctlEdit.GetRefOleFont());
m_pcoFontNS->Uninitialize();
m_pcoFontNS->Release();
m_pcoFontNS = NULL;
// Discard internal event sink of edit window.
m_ctlEdit.UnadviseEventSink();
}
/////////////////////////////////////////////////////////////////////////////////////////
// Helpers: Parsing of Params string
CoNumericEditBox::ParamsEnum CoNumericEditBox::ReadParamID(LPCOLESTR lpParams,
SIZE_T cchParams,
UINT_PTR unPos,
UINT_PTR* punNext)
// throw(ELogError);
{
typedef std::basic_string<OLECHAR> olestring;
ATLASSERT( !::IsBadReadPtr(lpParams, cchParams * sizeof(OLECHAR)) );
ATLASSERT( unPos < cchParams);
ATLASSERT( !::IsBadReadPtr(punNext, sizeof(UINT_PTR)) );
try
{
try
{
olestring sParamName;
sParamName.reserve(ms_cchMaxParamName);
*punNext = unPos;
for ( UINT_PTR i = unPos; i < cchParams; i++ )
{
const OLECHAR chCurrent = lpParams[i];
if ( chCurrent == L' ' ||
chCurrent == L'\x9' ||
chCurrent == L'=' )
break;
sParamName.push_back(chCurrent);
}
*punNext = i;
for ( UINT i = 0; i < sizeof(ms_rgszParamNames)/sizeof(LPCOLESTR); i++ )
{
LPCOLESTR lpcszCurrentParamName = ms_rgszParamNames[i];
if ( sParamName == lpcszCurrentParamName )
return static_cast<ParamsEnum>(i + 1);
}
/*
UINT_PTR cBuf;
// Load Error Source
cBuf = _AtlModule.LoadString(IDS_ELS_SPNUMERICEDITBOX, NULL, 0);
LPTSTR lpszSrc = LPTSTR(_alloca((cBuf + 1) * sizeof(TCHAR)));
_AtlModule.LoadString(IDS_ELS_SPNUMERICEDITBOX, lpszSrc, cBuf + 1);
lpszSrc[cBuf] = _T('\x0');
// Load Error Reason format
cBuf = _AtlModule.LoadString(IDS_ERCC_UNRECOGNIZEDPARAM, NULL, 0);
LPTSTR lpszFmt = LPTSTR(_alloca((cBuf + 1) * sizeof(TCHAR)));
_AtlModule.LoadString(IDS_ERCC_UNRECOGNIZEDPARAM, lpszFmt, cBuf + 1);
lpszFmt[cBuf] = _T('\x0');
// Format Error Message
cBuf += sParamName.length();
LPTSTR lpszMsg = LPTSTR(_alloca((cBuf + 1) * sizeof(TCHAR)));
_stprintf(lpszMsg, lpszFmt, sParamName.c_str());
SP::AccountError(SP::AE_LOG|SP::AE_SETMSG, lpszSrc, 0, lpszMsg);
*/
throw EAppLogError(ENEC_UNRECOGNIZEDPARAM);
}
catch( std::bad_alloc& e )
{
throw EStlLogError(e);
}
}
catch( ELogError& e )
{
throw EAppLogError(ENEC_READPARAMNAME, &e);
}
}
void CoNumericEditBox::WriteParamID(std::wostringstream& os, ParamsEnum enID)
// throw(ELogError)
{
ATLASSERT( enID <= sizeof(ms_rgszParamNames)/sizeof(LPCOLESTR) );
typedef std::basic_string<OLECHAR> olestring;
try
{
try
{
os << olestring(ms_rgszParamNames[enID - 1]);
}
catch( std::bad_alloc& e )
{
throw EStlLogError(e);
}
}
catch( ELogError& e )
{
throw EAppLogError(ENEC_WRITEPARAMNAME, &e);
}
}
void CoNumericEditBox::ReadParamValue(LPCOLESTR lpParams, SIZE_T cchParams,
UINT_PTR unPos, UINT_PTR * punNext,
BSTR* pbsValue) // throw(ELogError)
{
ATLASSERT( !::IsBadReadPtr(lpParams, cchParams * sizeof(OLECHAR)) );
ATLASSERT( unPos < cchParams);
ATLASSERT( !::IsBadReadPtr(punNext, sizeof(UINT_PTR)) );
ATLASSERT( !::IsBadReadPtr(pbsValue, sizeof(BSTR)) );
typedef std::basic_string<OLECHAR> olestring;
try
{
try
{
std::wostringstream os;
*punNext = unPos;
if ( unPos < cchParams && lpParams[unPos] == L'"' )
{
// Value is surrounded with double quotes.
for ( UINT_PTR i = unPos + 1; i < cchParams; i++ )
{
const OLECHAR chCurrent = lpParams[i];
if ( chCurrent == L'"' )
{
const UINT_PTR iNext = i + 1;
if ( iNext < cchParams && lpParams[iNext] == L'"' )
i++;
else
break;
}
os << chCurrent;
}
if ( lpParams[i] != L'"' || i == unPos )
throw EAppLogError(ENEC_NOCLOSINGQUOTE);
*punNext = i + 1;
}
else
{
// Value is not surrounded with double quotes.
for ( UINT_PTR i = unPos; i < cchParams; i++ )
{
const OLECHAR chCurrent = lpParams[i];
if ( chCurrent == L';' )
break;
if ( chCurrent == L'"' )
throw EAppLogError(ENEC_PARAMVALUEQUOTES);
os << chCurrent;
}
*punNext = i;
}
olestring sValue = os.str();
if ( !sValue.empty() )
{
*pbsValue = ::SysAllocStringLen(sValue.c_str(), UINT(sValue.length()));
ATLASSERT( *pbsValue );
if ( !(*pbsValue) )
throw EComLogError(E_OUTOFMEMORY);
}
else
{
*pbsValue = NULL;
}
}
catch( std::bad_alloc& e )
{
throw EStlLogError(e);
}
catch( CAtlException& e )
{
throw EAtlLogError(e);
}
}
catch( ELogError& e )
{
throw EAppLogError(ENEC_READPARAMVALUE, &e);
}
}
void CoNumericEditBox::WriteParamValue(std::wostringstream& os,
LPCOLESTR lpValue, SIZE_T cchValue,
bool bInsideQuotes) // throw(ELogError)
{
ATLASSERT( !::IsBadReadPtr(lpValue, cchValue * sizeof(WCHAR)) );
typedef std::basic_string<OLECHAR> olestring;
try
{
try
{
if ( bInsideQuotes )
{
os << L'\"';
for ( UINT_PTR i = 0; i < cchValue; i++ )
{
const OLECHAR chCurrent = lpValue[i];
if ( chCurrent == L'\"' )
os << L'\"';
os << chCurrent;
}
os << L'\"';
}
else
{
os << olestring(lpValue, lpValue + cchValue);
}
}
catch( std::bad_alloc& e )
{
throw EStlLogError(e);
}
}
catch( ELogError& e )
{
throw EAppLogError(ENEC_WRITEPARAMVALUE, &e);
}
}
/////////////////////////////////////////////////////////////////////////////////////////
// Operations: Parsing of Params string
void CoNumericEditBox::ParseFormatterParamString(BSTR bsParams,
ValueTypeConstants* penValueType,
FormatTypeConstants* penFormatType,
BSTR* pbsDisplayMask,
BSTR* pbsEditingMask)
// throw(ELogError)
{
ATLASSERT( !::IsBadWritePtr(penValueType, sizeof(ValueTypeConstants)) );
ATLASSERT( !::IsBadWritePtr(penFormatType, sizeof(FormatTypeConstants)) );
ATLASSERT( !::IsBadWritePtr(pbsDisplayMask, sizeof(BSTR)) );
ATLASSERT( !::IsBadWritePtr(pbsEditingMask, sizeof(BSTR)) );
enum ParseStatusEnum
{
PS_EXPECTPARAMNAME = 0,
PS_EXPECTASSIGNMENT = 1,
PS_EXPECTPARAMVALUE = 2,
PS_EXPECTPARAMEND = 3
};
typedef std::map<ParamsEnum, CComBSTR> CParamValuesMap;
try
{
try
{
*penValueType = ValueTypeConstants(0);
*penFormatType = FormatTypeConstants(0);
*pbsDisplayMask = NULL;
*pbsEditingMask = NULL;
if ( bsParams )
{
CParamValuesMap mapParams;
std::pair<CParamValuesMap::iterator, bool> pairInsRes;
ParamsEnum enCurrentParam = TN_NON;
CComBSTR cbsCurrentValue;
ParseStatusEnum enParseStatus = PS_EXPECTPARAMNAME;
UINT cchParams = ::SysStringLen(bsParams);
for ( UINT i = 0; i < cchParams; )
{
switch ( bsParams[i] )
{
case _T(' '):
case _T('\x9'):
i++; // Skip white spaces
break;
case _T('='):
if ( enParseStatus != PS_EXPECTASSIGNMENT )
throw EAppLogError(ENEC_UNEXPECTEDASSIGNMENTSIGN);
i++;
enParseStatus = PS_EXPECTPARAMVALUE;
break;
case _T(';'):
if ( enParseStatus != PS_EXPECTPARAMEND &&
enParseStatus != PS_EXPECTPARAMVALUE )
throw EAppLogError(ENEC_UNEXPECTEDSEMICOLONSIGN);
pairInsRes = mapParams.insert(
CParamValuesMap::value_type(enCurrentParam,
cbsCurrentValue));
if ( !pairInsRes.second )
throw EAppLogError(ENEC_DUPLICATEDPARAM);
enCurrentParam = TN_NON;
cbsCurrentValue = BSTR(NULL);
i++;
enParseStatus = PS_EXPECTPARAMNAME;
break;
default:
if ( enParseStatus == PS_EXPECTPARAMNAME )
{
// Define Param
UINT iNext;
enCurrentParam = ReadParamID(bsParams, cchParams,
i, &iNext);
enParseStatus = PS_EXPECTASSIGNMENT;
i = iNext;
}
else
{
ATLASSERT( enParseStatus == PS_EXPECTPARAMVALUE );
UINT iNext;
ReadParamValue(bsParams, cchParams, i, &iNext,
&cbsCurrentValue);
enParseStatus = PS_EXPECTPARAMEND;
i = iNext;
}
break;
}
}
// Add last parameter
if ( enCurrentParam != TN_NON )
{
pairInsRes = mapParams.insert(
CParamValuesMap::value_type(enCurrentParam,
cbsCurrentValue));
if ( !pairInsRes.second )
throw EAppLogError(ENEC_DUPLICATEDPARAM);
}
// Convert parameter values
CComPtr<ITypeLib> spiTLB;
CSpNumericEditModule::LoadTypeLib(&spiTLB);
for ( CParamValuesMap::iterator it = mapParams.begin();
it != mapParams.end(); it++ )
{
CComBSTR& cbsValue = (*it).second;
switch ( (*it).first )
{
case TN_VALUETYPE:
{
CComPtr<ITypeInfo> spiTI;
CSpNumericEditModule::GetValueTypesTypeInfo(spiTLB, &spiTI);
const LONG lValue =
CSpNumericEditModule::ConvertEnumValueName(
spiTI, cbsValue);
*penValueType = ValueTypeConstants(lValue);
}
break;
case TN_FORMATTYPE:
{
CComPtr<ITypeInfo> spiTI;
CSpNumericEditModule::GetFormatTypesTypeInfo(spiTLB, &spiTI);
const LONG lValue =
CSpNumericEditModule::ConvertEnumValueName(
spiTI, cbsValue);
*penFormatType = FormatTypeConstants(lValue);
}
break;
case TN_DISPLAYMASK:
*pbsDisplayMask = cbsValue.Detach();
break;
case TN_EDITINGMASK:
*pbsEditingMask = cbsValue.Detach();
break;
}
}
}
}
catch( CAtlException& e )
{
throw EAtlLogError(e);
}
catch( std::bad_alloc& e )
{
throw EStlLogError(e);
}
}
catch( EAppLogError& e )
{
throw EAppLogError(ENEC_PARSEFMTPARAMSSTRING, &e);
}
}
void CoNumericEditBox::BuildFormatterParamString(ValueTypeConstants enValueType,
FormatTypeConstants enFormatType,
LPCOLESTR lpszDisplayMask,
LPCOLESTR lpszEditingMask,
BSTR* pbsParams) // throw(ELogError)
{
ATLASSERT( !::IsBadWritePtr(pbsParams, sizeof(BSTR)) );
typedef std::basic_string<OLECHAR> olestring;
try
{
try
{
*pbsParams = NULL;
CComPtr<ITypeLib> spiTLB;
CSpNumericEditModule::LoadTypeLib(&spiTLB);
std::wostringstream oss;
bool bEmpty = true;
// Add ValueType parameter
if ( enValueType )
{
CComPtr<ITypeInfo> spiTI;
CSpNumericEditModule::GetValueTypesTypeInfo(spiTLB, &spiTI);
CComBSTR cbsValue;
CSpNumericEditModule::ConvertEnumValueName(spiTI, enValueType, &cbsValue);
WriteParamID(oss, TN_VALUETYPE);
oss << L'=';
WriteParamValue(oss, cbsValue, cbsValue.Length(), false);
oss << L';';
bEmpty = false;
}
// Add FormatType parameter
if ( enFormatType )
{
if ( !bEmpty )
oss << L' ';
CComPtr<ITypeInfo> spiTI;
CSpNumericEditModule::GetFormatTypesTypeInfo(spiTLB, &spiTI);
CComBSTR cbsValue;
CSpNumericEditModule::ConvertEnumValueName(spiTI, enFormatType, &cbsValue);
WriteParamID(oss, TN_FORMATTYPE);
oss << L'=';
WriteParamValue(oss, cbsValue, cbsValue.Length(), false);
oss << L';';
bEmpty = false;
}
// Add DisplayMask parameter
if ( lpszDisplayMask )
{
if ( !bEmpty )
oss << L' ';
WriteParamID(oss, TN_DISPLAYMASK);
oss << L'=';
WriteParamValue(oss, lpszDisplayMask, wcslen(lpszDisplayMask), true);
oss << L';';
bEmpty = false;
}
// Add EditingMask parameter
if ( lpszEditingMask )
{
if ( !bEmpty )
oss << L' ';
WriteParamID(oss, TN_EDITINGMASK);
oss << L'=';
WriteParamValue(oss, lpszEditingMask, wcslen(lpszEditingMask), true);
oss << L';';
}
// Allocate system string
if ( !bEmpty )
{
olestring strBuffer = oss.str();
*pbsParams = ::SysAllocStringLen(strBuffer.c_str(),
static_cast<UINT>(strBuffer.length()));
ATLASSERT( *pbsParams );
if ( !(*pbsParams) )
throw EComLogError(E_OUTOFMEMORY);
}
}
catch( CAtlException& e )
{
throw EAtlLogError(e);
}
catch( std::bad_alloc& e )
{
throw EStlLogError(e);
}
}
catch( ELogError& e )
{
throw EAppLogError(ENEC_GENERATEFMTPARAMSSTRING, &e);
}
}
/////////////////////////////////////////////////////////////////////////////////////////
// Operations: Formatter
void CoNumericEditBox::ProvideFormatter(IFormatter** ppiFormatter) // throw(ELogError)
{
ATLASSERT( !::IsBadWritePtr(ppiFormatter, sizeof(IFormatter*)) );
// Code below is not comletely safe to be used with multithreading.
Lock();
try
{
if ( !m_pcoFormatter )
{
HRESULT hr = CComObject<CoFormatter>::CreateInstance(&m_pcoFormatter);
ATLASSERT( SUCCEEDED(hr) );
if ( FAILED(hr) )
throw EComLogError(hr);
m_pcoFormatter->Initialize(this);
}
*ppiFormatter = m_pcoFormatter;
(*ppiFormatter)->AddRef();
}
catch( ELogError& e )
{
throw EAppLogError(ENEC_CREATEOBJFORMATTER, &e);
}
catch( ... )
{
ATLASSERT( 0 );
Unlock();
throw;
}
Unlock();
}
void CoNumericEditBox::DiscardFormatter()
{
ATLASSERT( m_pcoFormatter && m_pcoFormatter->IsInitialized() );
// Code below is not comletely safe to be used with multithreading.
Lock();
__try
{
m_pcoFormatter->Uninitialize();
m_pcoFormatter = NULL;
}
__finally
{
Unlock();
}
}
HRESULT CoNumericEditBox::_OnRequestEditFormatterParams() throw()
{
if ( m_nFreezeEvents == 0 )
return FireOnRequestEdit(DISPID_FORMATTERPARAMS);
return S_OK;
}
void CoNumericEditBox::_OnFormatterParamsChanged(BOOL bValueTypeChanged,
BOOL bUpdateCtrl) throw()
{
m_bRequiresSave = TRUE;
if ( m_nFreezeEvents == 0 )
FireOnChanged(DISPID_FORMATTERPARAMS);
if ( bUpdateCtrl )
m_ctlEdit._OnFormatterChanged(bValueTypeChanged);
FireViewChange();
SendOnDataChange(NULL);
}
/////////////////////////////////////////////////////////////////////////////////////////
// Implementation: Masked edit event handlers
void CoNumericEditBox::_OnModified()
{
Fire_OnModifyChanged();
}
BOOL CoNumericEditBox::_OnValueChanging(const void* lpcNewValue, BOOL bValid)
{
CComVariant cvtNewValue;
COleFormatterParams::ConvertValue(m_ctlEdit.GetFormatter().GetOleValueType(),
lpcNewValue, bValid, &cvtNewValue);
VARIANT_BOOL vbAccepted;
Fire_OnValueChanging(cvtNewValue, &vbAccepted);
return vbAccepted;
}
void CoNumericEditBox::_OnValueChanged()
{
Fire_OnValueChanged();
}
void CoNumericEditBox::_OnError(ELogError& e)
{
Fire_OnError();
}
/////////////////////////////////////////////////////////////////////////////////////////
// Helpers
void CoNumericEditBox::DrawBorder(HDC hDC, RECT* prc, BOOL bAdjustRect) throw()
{
struct DEParams
{
UINT fEdgeType;
UINT fEdgeFlags;
};
const DEParams aDEParams[] =
{
{ BDR_SUNKENOUTER, BF_MONO|BF_FLAT|BF_SOFT }, // acFlat
{ BDR_SUNKENINNER|BDR_SUNKENOUTER, 0 }, // ac3D
{ BDR_SUNKENINNER, BF_SOFT } // acSoft
};
ATLASSERT( m_ctlEdit.GetAppearance() < sizeof(aDEParams)/sizeof(DEParams) );
if ( m_ctlEdit.GetBorderVisible() )
{
const DEParams& deParams =
aDEParams[static_cast<SIZE_T>(m_ctlEdit.GetAppearance())];
const UINT fEdgeType = deParams.fEdgeType;
const UINT fEdgeFlags = (bAdjustRect)
? deParams.fEdgeFlags|BF_RECT|BF_ADJUST
: deParams.fEdgeFlags|BF_RECT;
::DrawEdge(hDC, prc, fEdgeType, fEdgeFlags);
}
}
void CoNumericEditBox::CalcMargins(HDC hDC, LONG* pdxLeft, LONG* pdxRight,
LONG* pdyTopBottom) throw()
{
ATLASSERT( !::IsBadWritePtr(pdxLeft, sizeof(LONG)) );
ATLASSERT( !::IsBadWritePtr(pdxRight, sizeof(LONG)) );
ATLASSERT( !::IsBadWritePtr(pdyTopBottom, sizeof(LONG)) );
TEXTMETRIC tm;
GetTextMetrics(hDC, &tm);
if ( tm.tmPitchAndFamily & TMPF_TRUETYPE )
{
ABC abc;
::GetCharABCWidths(hDC, _T('A'), _T('A'), &abc);
*pdxLeft = tm.tmAveCharWidth - abc.abcC;
*pdxRight = tm.tmAveCharWidth - abc.abcA;;
}
else
{
*pdxLeft = tm.tmAveCharWidth - tm.tmOverhang;
*pdxRight = tm.tmAveCharWidth - tm.tmOverhang;
}
if ( *pdxLeft < 0 )
*pdxLeft = 0;
if ( *pdxRight < 0 )
*pdxRight = 0;
*pdyTopBottom = (tm.tmInternalLeading + tm.tmExternalLeading) / 2;
}
/////////////////////////////////////////////////////////////////////////////////////////
// Operations: Persistence
void CoNumericEditBox::InitData() // throw(ELogError)
{
ATLASSERT( !m_ctlEdit.IsWindow() );
ATLASSERT( m_pcoFontNS && !m_pcoFontNS->GetCookie() );
try
{
// Appearance
short nAppearance;
HRESULT hr = GetAmbientAppearance(nAppearance);
if ( SUCCEEDED(hr) )
{
if ( nAppearance )
m_ctlEdit.SetAppearance(ac3D);
else
m_ctlEdit.SetAppearance(acFlat);
}
else
{
m_ctlEdit.SetAppearance(ac3D);
}
// Alignment
SHORT shAlignment;
hr = GetAmbientTextAlign(shAlignment);
if ( FAILED(hr) )
shAlignment = 0;
m_ctlEdit.SetAlignment(static_cast<AlignmentConstants>(shAlignment));
// Font
CComPtr<IFont> spiAmbientFont;
hr = GetAmbientFont(&spiAmbientFont);
if ( SUCCEEDED(hr) )
{
ATLASSERT( spiAmbientFont );
m_ctlEdit.SetOleFontCopy(spiAmbientFont);
}
else
{
HFONT hFont = reinterpret_cast<HFONT>(::GetStockObject(DEFAULT_GUI_FONT));
m_ctlEdit.SetFontHandle(hFont);
}
ATLASSERT( m_ctlEdit.GetRefOleFont() );
m_pcoFontNS->Advise(m_ctlEdit.GetRefOleFont());
// We should not use GetAmbientForeColor and GetAmbientBackColor to get
// fore and back colors for edit control.
m_ctlEdit.SetForeOleColor(0x80000000 | COLOR_WINDOWTEXT);
m_ctlEdit.SetBackOleColor(0x80000000 | COLOR_WINDOW);
m_ctlEdit.SetReadOnlyForeOleColor(0x80000000 | COLOR_BTNTEXT);
m_ctlEdit.SetReadOnlyBackOleColor(0x80000000 | COLOR_BTNFACE);
// RightToLeft
BOOL bRightToLeft = FALSE;
BOOL bRightAlignment = FALSE;
hr = GetAmbientRightToLeft(bRightToLeft);
if ( SUCCEEDED(hr) )
{
bRightAlignment = bRightToLeft;
}
// else
// {
// DWORD fLayout;
// if ( ::GetProcessDefaultLayout(&fLayout) )
// {
// bRightToLeft = fLayout & WS_EX_RTLREADING;
// bRightAlignment = fLayout & WS_EX_RIGHT;
// }
// }
m_ctlEdit.SetRightToLeft(bRightToLeft);
// Set default size
SIZEL size = { 150, 23 };
AtlPixelToHiMetric(&size, &m_sizeExtent);
// GetAmbientLocaleID
// GetAmbientCodePage
// GetAmbientCharSet
// GetAmbientTopToBottom
// GetAmbientUserMode(
// DISPID_AMBIENT_SHOWGRABHANDLES
// GetAmbientSupportsMnemonics
// GetAmbientPalette
// Configure formatter by default
m_ctlEdit.GetFormatter().Configure(COleFormatterParams(vtInt32, ftNumeric));
}
catch( ELogError& e )
{
throw EAppLogError(ENEC_INITCONTROLDATA, &e);
}
}
void CoNumericEditBox::GetDataSizeMax(ULARGE_INTEGER* pcbSize) // throw(ELogError)
{
ATLASSERT( !::IsBadWritePtr(pcbSize, sizeof(ULARGE_INTEGER)) );
try
{
pcbSize->HighPart = 0;
// Add size of the ATL version we write out.
pcbSize->LowPart = sizeof(DWORD);
// Add size of control extent.
pcbSize->LowPart += sizeof(SIZE);
// Add size of appearance.
pcbSize->LowPart += sizeof(AppearanceConstants);
// Add size of BorderVisible.
pcbSize->LowPart += sizeof(VARIANT_BOOL);
// AlignmentConstants
pcbSize->LowPart += sizeof(AlignmentConstants);
// Add size of ForeColor, BackColor, ReadOnlyForeColor, ReadOnlyBackColor.
pcbSize->LowPart += sizeof(OLE_COLOR) * 4;
// Add size of Font object
CComVariant cvtFont(m_ctlEdit.GetRefOleFont());
pcbSize->LowPart += cvtFont.GetSize();
// Add size of ReadOnly.
pcbSize->LowPart += sizeof(VARIANT_BOOL);
// Add size of RightToLeft.
pcbSize->LowPart += sizeof(VARIANT_BOOL);
// Add size of Modify
pcbSize->LowPart += sizeof(VARIANT_BOOL);
// Add size of Formatter parameters
CComPtr<IFormatter> spiFormatter;
ProvideFormatter(&spiFormatter);
ATLASSERT( m_pcoFormatter );
ULARGE_INTEGER cbSize;
m_pcoFormatter->GetDataSizeMax(&cbSize);
pcbSize->LowPart += cbSize.LowPart;
}
catch( ELogError& e )
{
throw EAppLogError(ENEC_CALCSIZECONTROLDATA, &e);
}
}
void CoNumericEditBox::LoadData(IStream* piStream) // throw(ELogError)
{
try
{
try
{
VARIANT_BOOL vbValue;
OLE_COLOR oleClr;
// Check version
DWORD dwVer;
HRESULT hr = piStream->Read(&dwVer, sizeof(DWORD), NULL);
ATLASSERT( SUCCEEDED(hr) );
if ( FAILED(hr) )
throw EComLogError(hr, piStream, IID_IStream);
if ( dwVer > _ATL_VER )
throw EAppLogError(ENEC_ATLVERSION);
// Read size of control extents.
hr = piStream->Read(&m_sizeExtent, sizeof(SIZE), NULL);
ATLASSERT( SUCCEEDED(hr) );
if ( FAILED(hr) )
throw EComLogError(hr, piStream, IID_IStream);
// Read Appearance.
AppearanceConstants enAppearance;
hr = piStream->Read(&enAppearance, sizeof(AppearanceConstants), NULL);
ATLASSERT( SUCCEEDED(hr) );
if ( FAILED(hr) )
throw EComLogError(hr, piStream, IID_IStream);
m_ctlEdit.SetAppearance(enAppearance);
// Read BorderVisible.
hr = piStream->Read(&vbValue, sizeof(VARIANT_BOOL), NULL);
ATLASSERT( SUCCEEDED(hr) );
if ( FAILED(hr) )
throw EComLogError(hr, piStream, IID_IStream);
m_ctlEdit.SetBorderVisible(vbValue == VARIANT_TRUE);
// Read AlignmentConstants
AlignmentConstants enAlignment;
hr = piStream->Read(&enAlignment, sizeof(AlignmentConstants), NULL);
ATLASSERT( SUCCEEDED(hr) );
if ( FAILED(hr) )
throw EComLogError(hr, piStream, IID_IStream);
m_ctlEdit.SetAlignment(enAlignment);
// Read ForeColor
hr = piStream->Read(&oleClr, sizeof(OLE_COLOR), NULL);
ATLASSERT( SUCCEEDED(hr) );
if ( FAILED(hr) )
throw EComLogError(hr, piStream, IID_IStream);
m_ctlEdit.SetForeOleColor(oleClr);
// Read BackColor
hr = piStream->Read(&oleClr, sizeof(OLE_COLOR), NULL);
ATLASSERT( SUCCEEDED(hr) );
if ( FAILED(hr) )
throw EComLogError(hr, piStream, IID_IStream);
m_ctlEdit.SetBackOleColor(oleClr);
// Read ReadOnlyForeColor
hr = piStream->Read(&oleClr, sizeof(OLE_COLOR), NULL);
ATLASSERT( SUCCEEDED(hr) );
if ( FAILED(hr) )
throw EComLogError(hr, piStream, IID_IStream);
m_ctlEdit.SetReadOnlyForeColor(oleClr);
// Read ReadOnlyBackColor
hr = piStream->Read(&oleClr, sizeof(OLE_COLOR), NULL);
ATLASSERT( SUCCEEDED(hr) );
if ( FAILED(hr) )
throw EComLogError(hr, piStream, IID_IStream);
m_ctlEdit.SetReadOnlyBackColor(oleClr);
// Read Font object
CComVariant cvtFont;
hr = cvtFont.ReadFromStream(piStream);
ATLASSERT( SUCCEEDED(hr) );
if ( FAILED(hr) )
throw EComLogError(hr);
hr = cvtFont.ChangeType(VT_UNKNOWN);
ATLASSERT( SUCCEEDED(hr) );
if ( FAILED(hr) )
throw EComLogError(hr);
CComPtr<IFont> spiFont;
if ( cvtFont.punkVal )
{
hr = cvtFont.punkVal->QueryInterface(IID_IFont, (void**)(&spiFont));
ATLASSERT( SUCCEEDED(hr) );
if ( FAILED(hr) )
throw EComLogError(hr, cvtFont.punkVal, IID_IUnknown);
}
m_ctlEdit.SetOleFont(spiFont);
// Read ReadOnly.
hr = piStream->Read(&vbValue, sizeof(VARIANT_BOOL), NULL);
ATLASSERT( SUCCEEDED(hr) );
if ( FAILED(hr) )
throw EComLogError(hr, piStream, IID_IStream);
m_ctlEdit.SetReadOnly(vbValue == VARIANT_TRUE);
// Read RightToLeft
hr = piStream->Read(&vbValue, sizeof(VARIANT_BOOL), NULL);
ATLASSERT( SUCCEEDED(hr) );
if ( FAILED(hr) )
throw EComLogError(hr, piStream, IID_IStream);
m_ctlEdit.SetRightToLeft(vbValue == VARIANT_TRUE);
// ErrorSymbol
CComBSTR cbsErrorSymbol;
hr = cbsErrorSymbol.ReadFromStream(piStream);
ATLASSERT( SUCCEEDED(hr) );
if ( FAILED(hr) )
throw EComLogError(hr);
m_ctlEdit.SetErrorOleSymbol(cbsErrorSymbol);
// Read Formatter parameters
CComPtr<IFormatter> spiFormatter;
ProvideFormatter(&spiFormatter);
ATLASSERT( m_pcoFormatter );
m_pcoFormatter->LoadData(piStream);
}
catch( CAtlException& e )
{
throw EAtlLogError(e);
}
}
catch( ELogError& e )
{
throw EAppLogError(ENEC_LOADCONTROLDATA, &e);
}
}
void CoNumericEditBox::SaveData(IStream* piStream) // throw(ELogError)
{
try
{
try
{
VARIANT_BOOL vbValue;
OLE_COLOR oleClr;
// Write ATL version.
const DWORD dw = _ATL_VER;
HRESULT hr = piStream->Write(&dw, sizeof(DWORD), NULL);
ATLASSERT( SUCCEEDED(hr) );
if ( FAILED(hr) )
throw EComLogError(hr, piStream, IID_IStream);
// Write control extent.
hr = piStream->Write(&m_sizeExtent, sizeof(SIZE), NULL);
ATLASSERT( SUCCEEDED(hr) );
if ( FAILED(hr) )
throw EComLogError(hr, piStream, IID_IStream);
// Write Appearance.
AppearanceConstants enAppearance = m_ctlEdit.GetAppearance();
hr = piStream->Write(&enAppearance, sizeof(AppearanceConstants), NULL);
ATLASSERT( SUCCEEDED(hr) );
if ( FAILED(hr) )
throw EComLogError(hr, piStream, IID_IStream);
// Write BorderVisible.
vbValue = m_ctlEdit.GetBorderVisible() ? VARIANT_TRUE : VARIANT_FALSE;
hr = piStream->Write(&vbValue, sizeof(VARIANT_BOOL), NULL);
ATLASSERT( SUCCEEDED(hr) );
if ( FAILED(hr) )
throw EComLogError(hr, piStream, IID_IStream);
// Write AlignmentConstants
AlignmentConstants enAlignment = m_ctlEdit.GetAlignment();
hr = piStream->Write(&enAlignment, sizeof(AlignmentConstants), NULL);
ATLASSERT( SUCCEEDED(hr) );
if ( FAILED(hr) )
throw EComLogError(hr, piStream, IID_IStream);
// Write ForeColor
oleClr = m_ctlEdit.GetForeOleColor();
hr = piStream->Write(&oleClr, sizeof(OLE_COLOR), NULL);
ATLASSERT( SUCCEEDED(hr) );
if ( FAILED(hr) )
throw EComLogError(hr, piStream, IID_IStream);
// Write BackColor
oleClr = m_ctlEdit.GetBackOleColor();
hr = piStream->Write(&oleClr, sizeof(OLE_COLOR), NULL);
ATLASSERT( SUCCEEDED(hr) );
if ( FAILED(hr) )
throw EComLogError(hr, piStream, IID_IStream);
// Write ReadOnlyForeColor
oleClr = m_ctlEdit.GetReadOnlyForeOleColor();
hr = piStream->Write(&oleClr, sizeof(OLE_COLOR), NULL);
ATLASSERT( SUCCEEDED(hr) );
if ( FAILED(hr) )
throw EComLogError(hr, piStream, IID_IStream);
// Write ReadOnlyBackColor
oleClr = m_ctlEdit.GetReadOnlyForeOleColor();
hr = piStream->Write(&oleClr, sizeof(OLE_COLOR), NULL);
ATLASSERT( SUCCEEDED(hr) );
if ( FAILED(hr) )
throw EComLogError(hr, piStream, IID_IStream);
// Write Font object
CComVariant cvtFont = m_ctlEdit.GetRefOleFont();
hr = cvtFont.WriteToStream(piStream);
ATLASSERT( SUCCEEDED(hr) );
if ( FAILED(hr) )
throw EComLogError(hr, piStream, IID_IStream);
// Write ReadOnly.
vbValue = m_ctlEdit.GetReadOnly() ? VARIANT_TRUE : VARIANT_FALSE;
hr = piStream->Write(&vbValue, sizeof(VARIANT_BOOL), NULL);
ATLASSERT( SUCCEEDED(hr) );
if ( FAILED(hr) )
throw EComLogError(hr, piStream, IID_IStream);
// Write RightToLeft.
vbValue = m_ctlEdit.GetRightToLeft() ? VARIANT_TRUE : VARIANT_FALSE;
hr = piStream->Write(&vbValue, sizeof(VARIANT_BOOL), NULL);
ATLASSERT( SUCCEEDED(hr) );
if ( FAILED(hr) )
throw EComLogError(hr, piStream, IID_IStream);
// ErrorSymbol
CComBSTR cbsErrorSymbol;
m_ctlEdit.GetErrorOleSymbol(&cbsErrorSymbol);
hr = cbsErrorSymbol.WriteToStream(piStream);
ATLASSERT( SUCCEEDED(hr) );
if ( FAILED(hr) )
throw EComLogError(hr, piStream, IID_IStream);
// Write Formatter parameters
CComPtr<IFormatter> spiFormatter;
ProvideFormatter(&spiFormatter);
ATLASSERT( m_pcoFormatter );
m_pcoFormatter->SaveData(piStream);
}
catch( CAtlException& e )
{
throw EAtlLogError(e);
}
}
catch( ELogError& e )
{
throw EAppLogError(ENEC_SAVECONTROLDATA, &e);
}
}
/////////////////////////////////////////////////////////////////////////////////////////
// Overrides
BOOL CoNumericEditBox::PreTranslateAccelerator(LPMSG pMsg, HRESULT& hRet) throw()
{
if( pMsg->message == WM_KEYDOWN )
{
switch( pMsg->wParam )
{
case VK_LEFT:
case VK_RIGHT:
case VK_UP:
case VK_DOWN:
case VK_HOME:
case VK_END:
case VK_NEXT:
case VK_PRIOR:
hRet = S_FALSE;
return TRUE;
}
}
//TODO: Add your additional accelerator handling code here
return FALSE;
}
HRESULT CoNumericEditBox::OnDraw(ATL_DRAWINFO& di) throw()
{
if ( m_ctlEdit.IsWindow() )
return S_OK;
try
{
RECT rc = *reinterpret_cast<const RECT*>(di.prcBounds);
// Draw border
DrawBorder(di.hdcDraw, &rc, TRUE);
// Define fore and back colors
COLORREF crFore;
COLORREF crBack;
if ( m_ctlEdit.GetReadOnly() )
{
crFore = m_ctlEdit.GetReadOnlyForeColor();
crBack = m_ctlEdit.GetReadOnlyBackColor();
}
else
{
crFore = m_ctlEdit.GetForeColor();
crBack = m_ctlEdit.GetBackColor();
}
// Draw background
HBRUSH hbrBack = CreateSolidBrush(crBack);
::FillRect(di.hdcDraw, &rc, hbrBack);
::DeleteObject(hbrBack);
// Draw text
HFONT hFont = m_ctlEdit.GetFontHandle();
HFONT hFontOld = (HFONT)::SelectObject(di.hdcDraw, hFont);
LONG dxLeft = 0;
LONG dxRight = 0;
LONG dyTopBottom = 0;
CalcMargins(di.hdcDraw, &dxLeft, &dxRight, &dyTopBottom);
LONG cxWidth = rc.right - rc.left;
if ( cxWidth < dxLeft + dxRight )
{
dxLeft = cxWidth / 2;
dxRight = cxWidth / 2;
}
::InflateRect(&rc, 0, -dyTopBottom);
const DWORD aDTOptions[] =
{
DT_EDITCONTROL|DT_NOPREFIX|DT_RIGHT,
DT_EDITCONTROL|DT_NOPREFIX|DT_LEFT,
DT_EDITCONTROL|DT_NOPREFIX|DT_CENTER,
DT_EDITCONTROL|DT_NOPREFIX|DT_RIGHT
};
ATLASSERT( m_ctlEdit.GetAlignment() < sizeof(aDTOptions)/sizeof(DWORD) );
DWORD fDTOptions = aDTOptions[static_cast<SIZE_T>(m_ctlEdit.GetAlignment())];
if ( m_ctlEdit.GetRightToLeft() )
{
fDTOptions |= DT_RTLREADING;
}
::SetTextColor(di.hdcDraw, crFore);
::SetBkColor(di.hdcDraw, crBack);
DRAWTEXTPARAMS dtp;
dtp.cbSize = sizeof(DRAWTEXTPARAMS);
dtp.iLeftMargin = dxLeft;
dtp.iRightMargin = dxRight;
dtp.iTabLength = 0;
dtp.uiLengthDrawn = 0;
::DrawTextEx(di.hdcDraw, _T("Sample edit box"), 15, &rc, fDTOptions, &dtp);
// Restore DC font
::SelectObject(di.hdcDraw, hFontOld);
m_ctlEdit.FreeFontHandle(hFont);
}
catch( ELogError& )
{
ATLASSERT( 0 );
return E_FAIL;
}
return S_OK;
}
/////////////////////////////////////////////////////////////////////////////////////////
// Message handling
LRESULT CoNumericEditBox::OnCtrlCreate(UINT uMsg, WPARAM wParam, LPARAM lParam,
BOOL& bHandled)
{
RECT rc;
GetWindowRect(&rc);
rc.right -= rc.left;
rc.bottom -= rc.top;
rc.top = rc.left = 0;
// Set window styles
DWORD dwStyle = GetWndStyle(0);
DWORD dwExStyle = GetWndExStyle(0);
m_ctlEdit.DefineWindowStyles(&dwStyle, &dwExStyle,
CNumericEditContainedWindow::MES_ALL);
m_ctlEdit.Create(m_hWnd, rc, NULL, dwStyle, dwExStyle);
// Update ReadOnly
m_ctlEdit._OnReadOnlyChanged();
// Update font
m_ctlEdit.UpdateFont();
return 0;
}
LRESULT CoNumericEditBox::OnCtrlSetFocus(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
LRESULT lRes = CComControl<CoNumericEditBox>::OnSetFocus(uMsg, wParam, lParam, bHandled);
if ( m_bInPlaceActive )
{
if( !IsChild(::GetFocus()) )
m_ctlEdit.SetFocus();
}
return lRes;
}
LRESULT CoNumericEditBox::OnCtrlColorEdit(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
ATLASSERT( m_ctlEdit.m_hWnd == (HWND)lParam );
HBRUSH hbrBkg = NULL;
m_ctlEdit.UpdateEditDC(reinterpret_cast<HDC>(wParam), &hbrBkg);
return reinterpret_cast<LRESULT>(hbrBkg);
}
LRESULT CoNumericEditBox::OnCtrlColorStatic(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
ATLASSERT( m_ctlEdit.m_hWnd == (HWND)lParam );
HBRUSH hbrBkg = NULL;
m_ctlEdit.UpdateStaticDC(reinterpret_cast<HDC>(wParam), &hbrBkg);
return reinterpret_cast<LRESULT>(hbrBkg);
}
LRESULT CoNumericEditBox::OnCtrlEditChange(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
{
if ( m_ctlEdit.IsEditing() )
{
bool bModifyWnd = m_ctlEdit.SendMessage(EM_GETMODIFY) != FALSE;
bool bModifyCtl = m_ctlEdit.IsModified() != FALSE;
if ( bModifyWnd != bModifyCtl )
{
m_ctlEdit.SetModify(bModifyWnd);
_OnModified();
}
}
return 0;
}
/////////////////////////////////////////////////////////////////////////////////////////
// Message handling (subclassing window procedure)
LRESULT CoNumericEditBox::OnSetFocus(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
bHandled = FALSE;
try
{
m_ctlEdit.BeginEdit();
}
catch( ELogError& e )
{
_OnError(e);
}
catch( ... )
{
ATLASSERT( 0 );
_OnError(EAppLogError(ENEC_UNEXPECTED));
}
return 0;
}
LRESULT CoNumericEditBox::OnKillFocus(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
bHandled = FALSE;
try
{
m_ctlEdit.EndEdit();
}
catch( ELogError& e )
{
_OnError(e);
}
catch( ... )
{
ATLASSERT( 0 );
_OnError(EAppLogError(ENEC_UNEXPECTED));
}
return 0;
}
/////////////////////////////////////////////////////////////////////////////////////////
// Implementation: ISupportErrorInfo
STDMETHODIMP CoNumericEditBox::InterfaceSupportsErrorInfo(REFIID riid)
{
static const IID* arr[] =
{
&IID_INumericEditBox,
&IID_IPersist,
&IID_IPersistStreamInit,
&IID_IPersistStorage
};
for (int i=0; i<sizeof(arr)/sizeof(arr[0]); i++)
{
if ( InlineIsEqualGUID(*arr[i], riid) )
return S_OK;
}
return S_FALSE;
}
/////////////////////////////////////////////////////////////////////////////////////////
// Implementation: IOleInPlaceObjectWindowless
STDMETHODIMP CoNumericEditBox::SetObjectRects(LPCRECT prcPos,LPCRECT prcClip)
{
IOleInPlaceObjectWindowlessImpl<CoNumericEditBox>::SetObjectRects(prcPos, prcClip);
int cx = prcPos->right - prcPos->left;
int cy = prcPos->bottom - prcPos->top;
::SetWindowPos(m_ctlEdit.m_hWnd, NULL, 0, 0, cx, cy, SWP_NOZORDER|SWP_NOACTIVATE);
return S_OK;
}
/////////////////////////////////////////////////////////////////////////////////////////
// Operations: Persistence
HRESULT CoNumericEditBox::_Persist_InitNew()
{
ATLASSERT( !m_ctlEdit.IsWindow() );
ATLASSERT( m_pcoFontNS && !m_pcoFontNS->GetCookie() );
try
{
InitData();
}
catch( ELogError& e )
{
return _AtlModule.ReportErrorWithCom(e, GetObjectCLSID(),
IID_IPersistStreamInit);
}
return S_OK;
}
HRESULT CoNumericEditBox::_PersistStream_GetSizeMax(ULARGE_INTEGER* pcbSize)
{
ATLASSERT( !::IsBadWritePtr(pcbSize, sizeof(ULARGE_INTEGER)) );
try
{
GetDataSizeMax(pcbSize);
}
catch( ELogError& e )
{
return _AtlModule.ReportErrorWithCom(e, GetObjectCLSID(),
IID_IPersistStreamInit);
}
return S_OK;
}
HRESULT CoNumericEditBox::_PersistStream_Load(LPSTREAM piStream)
{
ATLASSERT( piStream );
try
{
LoadData(piStream);
m_bRequiresSave = FALSE;
}
catch( ELogError& e )
{
return _AtlModule.ReportErrorWithCom(e, GetObjectCLSID(),
IID_IPersistStreamInit);
}
return S_OK;
}
HRESULT CoNumericEditBox::_PersistStream_Save(LPSTREAM piStream, BOOL fClearDirty)
{
ATLASSERT( piStream );
try
{
SaveData(piStream);
// if ( fClearDirty )
// m_bRequiresSave = FALSE;
}
catch( ELogError& e )
{
return _AtlModule.ReportErrorWithCom(e, GetObjectCLSID(),
IID_IPersistStreamInit);
}
return S_OK;
}
HRESULT CoNumericEditBox::_PersistStorage_InitNew(IStorage* piStorage)
{
ATLASSERT( !m_ctlEdit.IsWindow() );
ATLASSERT( m_pcoFontNS && !m_pcoFontNS->GetCookie() );
try
{
InitData();
}
catch( ELogError& e )
{
return _AtlModule.ReportErrorWithCom(e, GetObjectCLSID(),
IID_IPersistStreamInit);
}
return S_OK;
}
HRESULT CoNumericEditBox::_PersistStorage_Load(IStorage* piStorage)
{
ATLASSERT( piStorage );
try
{
LPCOLESTR lpcszContents = OLESTR("Contents");
const DWORD fOptions = STGM_DIRECT|STGM_SHARE_EXCLUSIVE;
CComPtr<IStream> spiStream;
HRESULT hr = piStorage->OpenStream(lpcszContents, NULL, fOptions, 0, &spiStream);
ATLASSERT( SUCCEEDED(hr) );
if FAILED(hr)
throw EComLogError(hr, piStorage, IID_IStorage);
LoadData(spiStream);
m_bRequiresSave = FALSE;
}
catch( ELogError& e )
{
return _AtlModule.ReportErrorWithCom(e, GetObjectCLSID(), IID_IPersistStorage);
}
return S_OK;
}
HRESULT CoNumericEditBox::_PersistStorage_Save(IStorage* piStorage, BOOL fSameAsLoad)
{
ATLASSERT( piStorage );
try
{
LPCOLESTR lpcszContents = OLESTR("Contents");
const DWORD fOptions = STGM_READWRITE|STGM_SHARE_EXCLUSIVE|STGM_CREATE;
CComPtr<IStream> spiStream;
HRESULT hr = piStorage->CreateStream(lpcszContents, fOptions, 0, 0, &spiStream);
ATLASSERT( SUCCEEDED(hr) );
if FAILED(hr)
throw EComLogError(hr, piStorage, IID_IStorage);
SaveData(spiStream);
// if ( fClearDirty )
// m_bRequiresSave = FALSE;
}
catch( ELogError& e )
{
return _AtlModule.ReportErrorWithCom(e, GetObjectCLSID(), IID_IPersistStorage);
}
return S_OK;
}
HRESULT CoNumericEditBox::_PersistStorage_SaveCompleted(IStorage* piStorage)
{
return S_OK;
}
HRESULT CoNumericEditBox::_PersistStorage_HandsOffStorage()
{
return S_OK;
}
/////////////////////////////////////////////////////////////////////////////////////////
// Implementation: INumericEditBox
// Appearance
STDMETHODIMP CoNumericEditBox::get_Appearance(AppearanceConstants* penAppearance)
{
ATLTRACE( ATL::atlTraceControls, 2, _T("CoNumericEditBox::get_Appearance\n") );
ATLASSERT( !::IsBadWritePtr(penAppearance, sizeof(AppearanceConstants)) );
if ( !penAppearance )
return E_POINTER;
*penAppearance = m_ctlEdit.GetAppearance();
return S_OK;
}
STDMETHODIMP CoNumericEditBox::put_Appearance(AppearanceConstants enAppearance)
{
ATLTRACE( ATL::atlTraceControls, 2, _T("CoNumericEditBox::put_Appearance\n") );
if ( m_nFreezeEvents == 0 && FireOnRequestEdit(DISPID_APPEARANCE) == S_FALSE )
return S_FALSE;
m_ctlEdit.SetAppearance(enAppearance);
m_bRequiresSave = TRUE;
if ( m_nFreezeEvents == 0 )
FireOnChanged(DISPID_APPEARANCE);
m_ctlEdit._OnAppearanceChanged();
FireViewChange();
SendOnDataChange(NULL);
return S_OK;
}
// BorderVisible
STDMETHODIMP CoNumericEditBox::get_BorderVisible(VARIANT_BOOL* pvbValue)
{
ATLTRACE( ATL::atlTraceControls, 2, _T("CoNumericEditBox::get_TabStop\n") );
ATLASSERT( !::IsBadWritePtr(pvbValue, sizeof(VARIANT_BOOL)) );
if ( !pvbValue )
return E_POINTER;
*pvbValue = m_ctlEdit.GetBorderVisible() ? ATL_VARIANT_TRUE : ATL_VARIANT_FALSE;
return S_OK;
}
STDMETHODIMP CoNumericEditBox::put_BorderVisible(VARIANT_BOOL vbValue)
{
ATLTRACE( ATL::atlTraceControls, 2, _T("CoNumericEditBox::put_TabStop\n") );
if ( m_nFreezeEvents == 0 && FireOnRequestEdit(DISPID_TABSTOP) == S_FALSE )
return S_FALSE;
m_ctlEdit.SetBorderVisible(vbValue);
m_bRequiresSave = TRUE;
if ( m_nFreezeEvents == 0 )
FireOnChanged(DISPID_TABSTOP);
m_ctlEdit._OnBorderVisibleChanged();
FireViewChange();
SendOnDataChange(NULL);
return S_OK;
}
// Alignment
STDMETHODIMP CoNumericEditBox::get_Alignment(AlignmentConstants* penValue)
{
ATLTRACE( ATL::atlTraceControls, 2, _T("CoNumericEditBox::get_Alignment\n") );
ATLASSERT( !::IsBadWritePtr(penValue, sizeof(AlignmentConstants)) );
if ( !penValue )
return E_POINTER;
*penValue = m_ctlEdit.GetAlignment();
return S_OK;
}
STDMETHODIMP CoNumericEditBox::put_Alignment(AlignmentConstants enValue)
{
ATLTRACE( ATL::atlTraceControls, 2, _T("CoNumericEditBox::put_Alignment\n") );
try
{
BOOL bUserMode;
HRESULT hr = GetAmbientUserMode(bUserMode);
if ( SUCCEEDED(hr) && bUserMode && IsWindow() )
throw EComLogError(ENEC_CANNOTCHANGEALIGNMENT);
if ( m_nFreezeEvents == 0 && FireOnRequestEdit(DISPID_ALIGNMENT) == S_FALSE )
return S_FALSE;
m_ctlEdit.SetAlignment(enValue);
m_bRequiresSave = TRUE;
if ( m_nFreezeEvents == 0 )
FireOnChanged(DISPID_ALIGNMENT);
m_ctlEdit._OnAlignmentChanged();
FireViewChange();
SendOnDataChange(NULL);
}
catch( ELogError& e )
{
return _AtlModule.ReportErrorWithCom(e, GetObjectCLSID(), IID_INumericEditBox);
}
return S_OK;
}
// ForeColor
STDMETHODIMP CoNumericEditBox::get_ForeColor(OLE_COLOR* poleColor)
{
ATLTRACE( ATL::atlTraceControls, 2, _T("CoNumericEditBox::get_ForeColor\n") );
if ( !poleColor )
return E_POINTER;
*poleColor = m_ctlEdit.GetForeOleColor();
return S_OK;
}
STDMETHODIMP CoNumericEditBox::put_ForeColor(OLE_COLOR oleColor)
{
ATLTRACE( ATL::atlTraceControls, 2, _T("CoNumericEditBox::put_ForeColor\n") );
if ( m_nFreezeEvents == 0 && FireOnRequestEdit(DISPID_FORECOLOR) == S_FALSE )
return S_FALSE;
m_ctlEdit.SetForeOleColor(oleColor);
m_bRequiresSave = TRUE;
if ( m_nFreezeEvents == 0 )
FireOnChanged(DISPID_FORECOLOR);
m_ctlEdit._OnForeColorChanged();
FireViewChange();
SendOnDataChange(NULL);
return S_OK;
}
// BackColor
STDMETHODIMP CoNumericEditBox::get_BackColor(OLE_COLOR* poleColor)
{
ATLTRACE( ATL::atlTraceControls, 2, _T("CoNumericEditBox::get_BackColor\n") );
if ( !poleColor )
return E_POINTER;
*poleColor = m_ctlEdit.GetBackOleColor();
return S_OK;
}
STDMETHODIMP CoNumericEditBox::put_BackColor(OLE_COLOR oleColor)
{
ATLTRACE( ATL::atlTraceControls, 2, _T("CoNumericEditBox::put_BackColor\n") );
if ( m_nFreezeEvents == 0 && FireOnRequestEdit(DISPID_BACKCOLOR) == S_FALSE )
return S_FALSE;
m_ctlEdit.SetBackOleColor(oleColor);
m_bRequiresSave = TRUE;
if ( m_nFreezeEvents == 0 )
FireOnChanged(DISPID_BACKCOLOR);
m_ctlEdit._OnBackColorChanged();
FireViewChange();
SendOnDataChange(NULL);
return S_OK;
}
// ReadOnlyForeColor
STDMETHODIMP CoNumericEditBox::get_ReadOnlyForeColor(OLE_COLOR* poleColor)
{
ATLTRACE( ATL::atlTraceControls, 2, _T("CoNumericEditBox::get_ReadOnlyForeColor\n") );
if ( !poleColor )
return E_POINTER;
*poleColor = m_ctlEdit.GetReadOnlyForeOleColor();
return S_OK;
}
STDMETHODIMP CoNumericEditBox::put_ReadOnlyForeColor(OLE_COLOR oleColor)
{
ATLTRACE( ATL::atlTraceControls, 2, _T("CoNumericEditBox::put_ReadOnlyForeColor\n") );
if ( m_nFreezeEvents == 0 && FireOnRequestEdit(DISPID_READONLYFORECOLOR) == S_FALSE )
return S_FALSE;
m_ctlEdit.SetReadOnlyForeOleColor(oleColor);
m_bRequiresSave = TRUE;
if ( m_nFreezeEvents == 0 )
FireOnChanged(DISPID_READONLYFORECOLOR);
m_ctlEdit._OnReadOnlyForeColorChanged();
FireViewChange();
SendOnDataChange(NULL);
return S_OK;
}
// ReadOnlyBackColor
STDMETHODIMP CoNumericEditBox::get_ReadOnlyBackColor(OLE_COLOR* poleColor)
{
ATLTRACE( ATL::atlTraceControls, 2, _T("CoNumericEditBox::get_ReadOnlyBackColor\n") );
if ( !poleColor )
return E_POINTER;
*poleColor = m_ctlEdit.GetReadOnlyBackOleColor();
return S_OK;
}
STDMETHODIMP CoNumericEditBox::put_ReadOnlyBackColor(OLE_COLOR oleColor)
{
ATLTRACE( ATL::atlTraceControls, 2, _T("CoNumericEditBox::put_ReadOnlyBackColor\n") );
if ( m_nFreezeEvents == 0 && FireOnRequestEdit(DISPID_READONLYBACKCOLOR) == S_FALSE )
return S_FALSE;
m_ctlEdit.SetReadOnlyBackOleColor(oleColor);
m_bRequiresSave = TRUE;
if ( m_nFreezeEvents == 0 )
FireOnChanged(DISPID_READONLYBACKCOLOR);
m_ctlEdit._OnReadOnlyBackColorChanged();
FireViewChange();
SendOnDataChange(NULL);
return S_OK;
}
// Font
STDMETHODIMP CoNumericEditBox::get_Font(IFontDisp** ppiFont)
{
ATLTRACE( ATL::atlTraceControls, 2, _T("CoNumericEditBox::get_Font\n") );
try
{
m_ctlEdit.GetOleFontDisp(ppiFont);
}
catch( ELogError& e )
{
return _AtlModule.ReportErrorWithCom(e, GetObjectCLSID(), IID_INumericEditBox);
}
return S_OK;
}
STDMETHODIMP CoNumericEditBox::put_Font(IFontDisp* piFont)
{
ATLTRACE( ATL::atlTraceControls, 2, _T("CoNumericEditBox::put_Font\n") );
ATLASSERT( m_pcoFontNS );
if ( m_nFreezeEvents == 0 && FireOnRequestEdit(DISPID_FONT) == S_FALSE )
return S_FALSE;
try
{
m_ctlEdit._OnFontChanging();
// Disconnect property notify sink
if ( m_pcoFontNS->GetCookie() )
m_pcoFontNS->Unadvise(m_ctlEdit.GetRefOleFont());
m_ctlEdit.SetCopyOleFontDisp(piFont);
m_bRequiresSave = TRUE;
// Connect property notify sink
if ( m_ctlEdit.GetRefOleFont() )
m_pcoFontNS->Advise(m_ctlEdit.GetRefOleFont());
if ( m_nFreezeEvents == 0 )
FireOnChanged(DISPID_FONT);
m_ctlEdit._OnFontChanged();
FireViewChange();
SendOnDataChange(NULL);
}
catch( ELogError& e )
{
return _AtlModule.ReportErrorWithCom(e, GetObjectCLSID(), IID_INumericEditBox);
}
return S_OK;
}
STDMETHODIMP CoNumericEditBox::putref_Font(IFontDisp* piFont)
{
ATLTRACE( ATL::atlTraceControls, 2, _T("CoNumericEditBox::piFont\n") );
ATLASSERT( m_pcoFontNS );
if ( m_nFreezeEvents == 0 && FireOnRequestEdit(DISPID_FONT) == S_FALSE )
return S_FALSE;
try
{
m_ctlEdit._OnFontChanging();
// Disconnect property notify sink
if ( m_pcoFontNS->GetCookie() )
m_pcoFontNS->Unadvise(m_ctlEdit.GetRefOleFont());
m_ctlEdit.SetOleFontDisp(piFont);
m_bRequiresSave = TRUE;
// Connect property notify sink
if ( m_ctlEdit.GetRefOleFont() )
m_pcoFontNS->Advise(m_ctlEdit.GetRefOleFont());
if ( m_nFreezeEvents == 0 )
FireOnChanged(DISPID_FONT);
m_ctlEdit._OnFontChanged();
FireViewChange();
SendOnDataChange(NULL);
}
catch( ELogError& e )
{
return _AtlModule.ReportErrorWithCom(e, GetObjectCLSID(), IID_INumericEditBox);
}
return S_OK;
}
// ReadOnly
STDMETHODIMP CoNumericEditBox::get_ReadOnly(VARIANT_BOOL* pvbValue)
{
ATLTRACE( ATL::atlTraceControls, 2, _T("CoNumericEditBox::get_ReadOnly\n") );
ATLASSERT( !::IsBadWritePtr(pvbValue, sizeof(VARIANT_BOOL)) );
if ( !pvbValue )
return E_POINTER;
*pvbValue = m_ctlEdit.GetReadOnly() ? ATL_VARIANT_TRUE : ATL_VARIANT_FALSE;
return S_OK;
}
STDMETHODIMP CoNumericEditBox::put_ReadOnly(VARIANT_BOOL vbValue)
{
ATLTRACE( ATL::atlTraceControls, 2, _T("CoNumericEditBox::put_ReadOnly\n") );
if ( m_nFreezeEvents == 0 && FireOnRequestEdit(DISPID_READONLY) == S_FALSE )
return S_FALSE;
m_ctlEdit.SetReadOnly(vbValue);
m_bRequiresSave = TRUE;
if ( m_nFreezeEvents == 0 )
FireOnChanged(DISPID_READONLY);
m_ctlEdit._OnReadOnlyChanged();
FireViewChange();
SendOnDataChange(NULL);
return S_OK;
}
// RightToLeft
STDMETHODIMP CoNumericEditBox::get_RightToLeft(VARIANT_BOOL* pvbValue)
{
ATLTRACE( ATL::atlTraceControls, 2, _T("CoNumericEditBox::get_RightToLeft\n") );
ATLASSERT( !::IsBadWritePtr(pvbValue, sizeof(VARIANT_BOOL)) );
if ( !pvbValue )
return E_POINTER;
*pvbValue = m_ctlEdit.GetRightToLeft() ? ATL_VARIANT_TRUE : ATL_VARIANT_FALSE;
return S_OK;
}
STDMETHODIMP CoNumericEditBox::put_RightToLeft(VARIANT_BOOL vbValue)
{
ATLTRACE( ATL::atlTraceControls, 2, _T("CoNumericEditBox::put_ReadOnly\n") );
if ( m_nFreezeEvents == 0 && FireOnRequestEdit(DISPID_RIGHTTOLEFT) == S_FALSE )
return S_FALSE;
m_ctlEdit.SetRightToLeft(vbValue);
m_bRequiresSave = TRUE;
if ( m_nFreezeEvents == 0 )
FireOnChanged(DISPID_RIGHTTOLEFT);
m_ctlEdit._OnRightToLeftChanged();
FireViewChange();
SendOnDataChange(NULL);
return S_OK;
}
// ErrorSymbol
STDMETHODIMP CoNumericEditBox::get_ErrorSymbol(BSTR* pbsErrorSymbol)
{
ATLTRACE( ATL::atlTraceControls, 2, _T("CoNumericEditBox::get_ErrorSymbol\n") );
ATLASSERT( !::IsBadWritePtr(pbsErrorSymbol, sizeof(BSTR)) );
if ( !pbsErrorSymbol )
return E_POINTER;
try
{
m_ctlEdit.GetErrorOleSymbol(pbsErrorSymbol);
}
catch ( ELogError& e )
{
return _AtlModule.ReportErrorWithCom(e, GetObjectCLSID(), IID_INumericEditBox);
}
return S_OK;
}
STDMETHODIMP CoNumericEditBox::put_ErrorSymbol(BSTR bsErrorSymbol)
{
ATLTRACE( ATL::atlTraceControls, 2, _T("CoNumericEditBox::put_ErrorSymbol\n") );
if ( m_nFreezeEvents == 0 && FireOnRequestEdit(DISPID_ERRORSYMBOL) == S_FALSE )
return S_FALSE;
try
{
m_ctlEdit.SetErrorOleSymbol(bsErrorSymbol);
m_bRequiresSave = TRUE;
if ( m_nFreezeEvents == 0 )
FireOnChanged(DISPID_ERRORSYMBOL);
m_ctlEdit._OnErrorSymbolChanged();
FireViewChange();
SendOnDataChange(NULL);
}
catch ( ELogError& e )
{
return _AtlModule.ReportErrorWithCom(e, GetObjectCLSID(), IID_INumericEditBox);
}
return S_OK;
}
// Formatter Params
STDMETHODIMP CoNumericEditBox::get_FormatterParams(BSTR* pbsParams)
{
ATLTRACE( ATL::atlTraceControls, 2, _T("CoNumericEditBox::get_FormatterParams\n") );
ATLASSERT( !::IsBadWritePtr(pbsParams, sizeof(BSTR)) );
if ( !pbsParams )
return E_POINTER;
try
{
const ValueTypeConstants enValueType =
m_ctlEdit.GetFormatter().GetOleValueType();
const FormatTypeConstants enFormatType =
m_ctlEdit.GetFormatter().GetOleFormatType();
CComBSTR cbsDisplayMask;
if ( m_ctlEdit.GetFormatter().IsOleUserMask(FM_DISPLAY) )
m_ctlEdit.GetFormatter().GetOleMask(FM_DISPLAY, &cbsDisplayMask);
CComBSTR cbsEditingMask;
if ( m_ctlEdit.GetFormatter().IsOleUserMask(FM_EDITING) )
m_ctlEdit.GetFormatter().GetOleMask(FM_EDITING, &cbsEditingMask);
BuildFormatterParamString(enValueType, enFormatType,
cbsDisplayMask, cbsEditingMask,
pbsParams);
}
catch( ELogError& e )
{
return _AtlModule.ReportErrorWithCom(e, GetObjectCLSID(), IID_INumericEditBox);
}
return S_OK;
}
STDMETHODIMP CoNumericEditBox::put_FormatterParams(BSTR bsParams)
{
ATLTRACE( ATL::atlTraceControls, 2, _T("CoNumericEditBox::put_FormatterParams\n") );
if ( m_nFreezeEvents == 0 && FireOnRequestEdit(DISPID_FORMATTERPARAMS) == S_FALSE )
return S_FALSE;
try
{
ValueTypeConstants enValueType;
FormatTypeConstants enFormatType;
CComBSTR cbsDisplayMask;
CComBSTR cbsEditingMask;
ParseFormatterParamString(bsParams, &enValueType, &enFormatType,
&cbsDisplayMask, &cbsEditingMask);
const ValueTypeConstants enOldValueType =
m_ctlEdit.GetFormatter().GetOleValueType();
// Set new formatter properties
const COleFormatterParams params(enValueType, enFormatType,
cbsDisplayMask, cbsEditingMask);
m_ctlEdit.GetFormatter().Configure(params);
m_ctlEdit._OnFormatterChanged(enOldValueType != enValueType);
m_bRequiresSave = TRUE;
if ( m_nFreezeEvents == 0 )
FireOnChanged(DISPID_FORMATTERPARAMS);
FireViewChange();
SendOnDataChange(NULL);
}
catch( ELogError& e )
{
return _AtlModule.ReportErrorWithCom(e, GetObjectCLSID(), IID_INumericEditBox);
}
return S_OK;
}
// Formatter
STDMETHODIMP CoNumericEditBox::get_Formatter(IFormatter** ppiFormatter)
{
ATLTRACE( ATL::atlTraceControls, 2, _T("CoNumericEditBox::get_Formatter\n") );
if ( !ppiFormatter )
return E_POINTER;
try
{
ProvideFormatter(ppiFormatter);
}
catch( ELogError& e )
{
return _AtlModule.ReportErrorWithCom(e, GetObjectCLSID(), IID_INumericEditBox);
}
return S_OK;
}
// HWND
STDMETHODIMP CoNumericEditBox::get_HWND(LONG_PTR* phWnd)
{
ATLTRACE( ATL::atlTraceControls, 2, _T("CoNumericEditBox::get_HWND\n") );
ATLASSERT( !::IsBadWritePtr(phWnd, sizeof(LONG_PTR)) );
if ( !phWnd )
return E_POINTER;
*phWnd = m_ctlEdit.IsWindow() ? reinterpret_cast<LONG_PTR>(m_ctlEdit.m_hWnd) : NULL;
return S_OK;
}
// Modify
STDMETHODIMP CoNumericEditBox::get_Modify(VARIANT_BOOL* pvbModify)
{
ATLTRACE( ATL::atlTraceControls, 2, _T("CoNumericEditBox::get_Modify\n") );
ATLASSERT( !::IsBadWritePtr(pvbModify, sizeof(VARIANT_BOOL)) );
if ( !pvbModify )
return E_POINTER;
*pvbModify = m_ctlEdit.IsModified() ? ATL_VARIANT_TRUE : ATL_VARIANT_FALSE;
return S_OK;
}
STDMETHODIMP CoNumericEditBox::put_Modify(VARIANT_BOOL vbModify)
{
ATLTRACE( ATL::atlTraceControls, 2, _T("CoNumericEditBox::put_Modify\n") );
m_ctlEdit.SetModify(vbModify);
m_ctlEdit._OnModifyChanged();
return S_OK;
}
// Value
STDMETHODIMP CoNumericEditBox::get_Value(VARIANT* pvValue)
{
ATLTRACE( ATL::atlTraceControls, 2, _T("CoNumericEditBox::get_Value\n") );
if ( !pvValue )
return E_POINTER;
try
{
m_ctlEdit.GetOleValue(pvValue);
}
catch( ELogError& e )
{
return _AtlModule.ReportErrorWithCom(e, GetObjectCLSID(), IID_INumericEditBox);
}
return S_OK;
}
STDMETHODIMP CoNumericEditBox::put_Value(VARIANT vValue)
{
ATLTRACE( ATL::atlTraceControls, 2, _T("CoNumericEditBox::put_Value\n") );
if ( m_nFreezeEvents == 0 && FireOnRequestEdit(DISPID_VALUE) == S_FALSE )
return S_FALSE;
try
{
while ( vValue.vt == (VT_BYREF|VT_VARIANT) )
{
CComVariant cvtTemp = *vValue.pvarVal;
vValue = cvtTemp;
}
m_ctlEdit.SetOleValue(vValue);
m_bRequiresSave = TRUE;
if ( m_nFreezeEvents == 0 )
FireOnChanged(DISPID_VALUE);
m_ctlEdit._OnValueChanged();
FireViewChange();
SendOnDataChange(NULL);
}
catch ( ELogError& e )
{
return _AtlModule.ReportErrorWithCom(e, GetObjectCLSID(), IID_INumericEditBox);
}
return S_OK;
}
// Display Text
STDMETHODIMP CoNumericEditBox::get_DisplayText(BSTR* pbsText)
{
ATLTRACE( ATL::atlTraceControls, 2, _T("CoNumericEditBox::get_DisplayText\n") );
if ( !pbsText )
return E_POINTER;
try
{
m_ctlEdit.GetDisplayOleText(pbsText);
}
catch( ELogError& e )
{
return _AtlModule.ReportErrorWithCom(e, GetObjectCLSID(), IID_INumericEditBox);
}
return S_OK;
}
// Edit Text
STDMETHODIMP CoNumericEditBox::get_EditingText(BSTR* pbsText)
{
ATLTRACE( ATL::atlTraceControls, 2, _T("CoNumericEditBox::get_EditingText\n") );
if ( !pbsText )
return E_POINTER;
try
{
m_ctlEdit.GetEditingOleText(pbsText);
}
catch( ELogError& e )
{
return _AtlModule.ReportErrorWithCom(e, GetObjectCLSID(), IID_INumericEditBox);
}
return S_OK;
}