// XTPReportControlLocale.cpp : implementation of the CXTPReportControlLocale class. // // This file is a part of the XTREME REPORTCONTROL MFC class library. // (c)1998-2012 Codejock Software, All Rights Reserved. // // THIS SOURCE FILE IS THE PROPERTY OF CODEJOCK SOFTWARE AND IS NOT TO BE // RE-DISTRIBUTED BY ANY MEANS WHATSOEVER WITHOUT THE EXPRESSED WRITTEN // CONSENT OF CODEJOCK SOFTWARE. // // THIS SOURCE CODE CAN ONLY BE USED UNDER THE TERMS AND CONDITIONS OUTLINED // IN THE XTREME TOOLKIT PRO LICENSE AGREEMENT. CODEJOCK SOFTWARE GRANTS TO // YOU (ONE SOFTWARE DEVELOPER) THE LIMITED RIGHT TO USE THIS SOFTWARE ON A // SINGLE COMPUTER. // // CONTACT INFORMATION: // support@codejock.com // http://www.codejock.com // ///////////////////////////////////////////////////////////////////////////// #include "StdAfx.h" #include "Common/XTPDrawHelpers.h" #include "Common/XTPSystemHelpers.h" #include "Common/XTPImageManager.h" #include "Common/XTPPropExchange.h" #include "Common/XTPToolTipContext.h" #include "Common/XTPResourceManager.h" #include "Common/XTPMarkupRender.h" #include "Common/XTPCustomHeap.h" #include "Common/XTPSmartPtrInternalT.h" #include "Common/XTPColorManager.h" #include "XTPReportDefines.h" #include "Behavior/XTPReportBehavior.h" #include "XTPReportRows.h" #include "XTPReportSelectedRows.h" #include "XTPReportTip.h" #include "XTPReportRecordItem.h" #include "ItemTypes/XTPReportRecordItemText.h" #include "XTPReportRecord.h" #include "XTPReportRecords.h" #include "XTPReportHeader.h" #include "XTPReportColumn.h" #include "XTPReportColumns.h" #include "XTPReportRow.h" #include "XTPReportControl.h" #include "XTPReportPaintManager.h" #include "XTPReportNavigator.h" #include "XTPReportSubListControl.h" #include "XTPReportGroupRow.h" #include "XTPReportInplaceControls.h" #include "XTPReportRecordItemControls.h" #include "XTPReportHyperlink.h" #include "XTPReportRecordItemRange.h" #include "XTPReportSection.h" #include "XTPReportADO.h" #include "XTPReportDataManager.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif ////////////////////////////////////////////////////////////////////////// BOOL CXTPReportControlLocale::s_bUseResourceFileLocale = FALSE; //=========================================================================== BOOL CXTPReportControlLocale::IsUseResourceFileLocale() { return s_bUseResourceFileLocale; } void CXTPReportControlLocale::SetUseResourceFileLocale(BOOL bUseResourceFileLocale) { s_bUseResourceFileLocale = bUseResourceFileLocale; } LCID CXTPReportControlLocale::GetActiveLCID() { LCID lcidCurr = LOCALE_USER_DEFAULT; if (s_bUseResourceFileLocale) lcidCurr = MAKELCID(XTPResourceManager()->GetResourcesLangID(), SORT_DEFAULT); return lcidCurr; } BOOL AFX_CDECL CXTPReportControlLocale::VariantChangeTypeEx(VARIANT& rVarValue, VARTYPE vartype, BOOL bThrowError) { if (vartype != rVarValue.vt) { //if (rVarValue.vt == VT_BSTR) //{ // vartype = VT_BSTR; // return TRUE; //} LCID lcID = GetActiveLCID(); HRESULT hr = ::VariantChangeTypeEx(&rVarValue, &rVarValue, lcID, 0, vartype); if (bThrowError && FAILED(hr)) { if (hr == E_OUTOFMEMORY) AfxThrowMemoryException(); else AfxThrowOleException(hr); } return SUCCEEDED(hr); } return TRUE; } CString AFX_CDECL CXTPReportControlLocale::FormatDateTime(const COleDateTime& dt, LPCTSTR lpcszFormatString) { return _FormatDateTime(dt, lpcszFormatString, GetActiveLCID()); } CString CXTPReportControlLocale::_FormatDateTime(const COleDateTime& dt, LPCTSTR lpcszFormatString, LCID lcLocaleID) { if (dt.GetStatus() != COleDateTime::valid) { ASSERT(dt.GetStatus() == COleDateTime::null); return _T(""); } CString strDT = lpcszFormatString; SYSTEMTIME sysTime; ZeroMemory(&sysTime, sizeof(sysTime)); if (!dt.GetAsSystemTime(sysTime)) { ASSERT(FALSE); return _T(""); } // %% Percent sign strDT.Replace(_T("%%"), _T("\0x1")); _ProcessMappedSpecs(strDT, &sysTime, lcLocaleID); _ProcessDateTimeSpecs(strDT, &sysTime, lcLocaleID); // All locale dependent specifiers already processed _ProcessOtherSpecs(strDT, dt); strDT.Replace(_T("\0x1"), _T("%")); return strDT; } void CXTPReportControlLocale::_ProcessMappedSpecs(CString& rstrFormat, const SYSTEMTIME* pST, LCID lcLocaleID) { _InitMappedSpecs(); const int cnBufferSize = 96; TCHAR szBuffer[cnBufferSize]; int nCount = (int)s_arMappedSpecs.GetSize(); for (int i = 0; i < nCount; i++) { const XTP_TIMESPEC& specI = s_arMappedSpecs.ElementAt(i); if (rstrFormat.Find(specI.pcszSpec, 0) < 0) continue; ::ZeroMemory(szBuffer, sizeof(szBuffer)); int nResult; if (specI.bTime) { nResult = ::GetTimeFormat(lcLocaleID, 0, pST, specI.pcszFormat, szBuffer, cnBufferSize); } else { nResult = ::GetDateFormat(lcLocaleID, 0, pST, specI.pcszFormat, szBuffer, cnBufferSize); } ASSERT(nResult); if (nResult) { rstrFormat.Replace(specI.pcszSpec, szBuffer); } } } void CXTPReportControlLocale::_ProcessDateTimeSpecs(CString& rstrFormat, const SYSTEMTIME* pST, LCID lcLocaleID) { // %c Date and time representation appropriate for locale // %#c Long date and time representation // %x Date representation for current locale // %#x Long date representation for current locale // %X Time representation for current locale rstrFormat.Replace(_T("%c"), _T("%x %X")); rstrFormat.Replace(_T("%#c"), _T("%#x %X")); __ProcessDate_x(rstrFormat, pST, lcLocaleID); __ProcessTime_X(rstrFormat, pST, lcLocaleID); } void CXTPReportControlLocale::__ProcessDate_x(CString& rstrFormat, const SYSTEMTIME* pST, LCID lcLocaleID) { const int cnBufferSize = 96; TCHAR szBuffer[cnBufferSize]; // %x Date representation for current locale // %#x Long date representation for current locale TCHAR* arSpec2[2] = {_T("%x"), _T("%#x")}; for (int i = 0; i < 2; i++) { if (rstrFormat.Find(arSpec2[i], 0) >= 0) { ::ZeroMemory(szBuffer, sizeof(szBuffer)); DWORD dwFlags = (i == 0) ? DATE_SHORTDATE : DATE_LONGDATE; int nRes = ::GetDateFormat(lcLocaleID, dwFlags, pST, NULL, szBuffer, cnBufferSize); ASSERT(nRes); rstrFormat.Replace(arSpec2[i], szBuffer); } } } void CXTPReportControlLocale::__ProcessTime_X(CString& rstrFormat, const SYSTEMTIME* pST, LCID lcLocaleID) { if (rstrFormat.Find(_T("%X"), 0) >= 0) { const int cnBufferSize = 96; TCHAR szBuffer[cnBufferSize]; ::ZeroMemory(szBuffer, sizeof(szBuffer)); int nRes = ::GetTimeFormat(lcLocaleID, 0, pST, NULL, szBuffer, cnBufferSize); ASSERT(nRes); rstrFormat.Replace(_T("%X"), szBuffer); } } void CXTPReportControlLocale::_ProcessOtherSpecs(CString& rstrFormat, const COleDateTime& dt) { // %j Day of year as decimal number (001 - 366) // %w Weekday as decimal number (0 - 6; Sunday is 0) // %U Week of year as decimal number, with Sunday as first day of week (00 - 53) // %W Week of year as decimal number, with Monday as first day of week (00 - 53) // %z, %Z Either the time-zone name or time zone abbreviation, depending on registry settings; no characters if time zone is unknown static LPCTSTR arszSpecs[] = { _T("%j"), _T("%#j"), _T("%w"), _T("%#w"), _T("%U"), _T("%#U"), _T("%W"), _T("%#W"), _T("%z"), _T("%Z") }; int nCount = _countof(arszSpecs); for (int i = 0; i < nCount; i++) { if (rstrFormat.Find(arszSpecs[i], 0) < 0) continue; CString str = dt.Format(arszSpecs[i]); rstrFormat.Replace(arszSpecs[i], str); } } void CXTPReportControlLocale::_InitMappedSpecs() { if (s_arMappedSpecs.GetSize()) return; // date _AddsMappedSpec(_T("%a"), _T("ddd"), FALSE); _AddsMappedSpec(_T("%A"), _T("dddd"), FALSE); _AddsMappedSpec(_T("%b"), _T("MMM"), FALSE); _AddsMappedSpec(_T("%B"), _T("MMMM"), FALSE); _AddsMappedSpec(_T("%d"), _T("dd"), FALSE); _AddsMappedSpec(_T("%#d"), _T("d"), FALSE); _AddsMappedSpec(_T("%m"), _T("MM"), FALSE); _AddsMappedSpec(_T("%#m"), _T("M"), FALSE); _AddsMappedSpec(_T("%y"), _T("yy"), FALSE); _AddsMappedSpec(_T("%#y"), _T("y"), FALSE); _AddsMappedSpec(_T("%Y"), _T("yyyy"), FALSE); // time _AddsMappedSpec(_T("%H"), _T("HH"), TRUE); _AddsMappedSpec(_T("%#H"), _T("H"), TRUE); _AddsMappedSpec(_T("%I"), _T("hh"), TRUE); _AddsMappedSpec(_T("%#I"), _T("h"), TRUE); _AddsMappedSpec(_T("%M"), _T("mm"), TRUE); _AddsMappedSpec(_T("%#M"), _T("m"), TRUE); _AddsMappedSpec(_T("%S"), _T("ss"), TRUE); _AddsMappedSpec(_T("%#S"), _T("s"), TRUE); _AddsMappedSpec(_T("%p"), _T("tt"), TRUE); } void CXTPReportControlLocale::_AddsMappedSpec(LPCTSTR pcszSpec, LPCTSTR pcszFormat, BOOL bTime) { XTP_TIMESPEC tmpSpec = {pcszSpec, pcszFormat, bTime}; s_arMappedSpecs.Add(tmpSpec); }