|
|
// MLLBCons.h : Declaration of the CMLLBCons
#ifndef __MLLBCONS_H_
#define __MLLBCONS_H_
#include "mlatl.h"
class CMultiLanguage;
/////////////////////////////////////////////////////////////////////////////
// CMLLBCons
class ATL_NO_VTABLE CMLLBCons : public CComTearOffObjectBase<CMultiLanguage>, public IMLangLineBreakConsole { public: CMLLBCons(void) { DllAddRef(); m_pMLStrClass = NULL; } ~CMLLBCons(void) { if (m_pMLStrClass) m_pMLStrClass->Release(); DllRelease(); }
DECLARE_NO_REGISTRY()
BEGIN_COM_MAP(CMLLBCons) COM_INTERFACE_ENTRY(IMLangLineBreakConsole) END_COM_MAP()
public: // IMLangLineBreakConsole
STDMETHOD(BreakLineML)(/*[in]*/ IMLangString* pSrcMLStr, /*[in]*/ long lSrcPos, /*[in]*/ long lSrcLen, /*[in]*/ long cMinColumns, /*[in]*/ long cMaxColumns, /*[out]*/ long* plLineLen, /*[out]*/ long* plSkipLen); STDMETHOD(BreakLineW)(/*[in]*/ LCID locale, /*[in, size_is(cchSrc)]*/ const WCHAR* pszSrc, /*[in]*/ long cchSrc, /*[in]*/ long cMaxColumns, /*[out]*/ long* pcchLine, /*[out]*/ long* pcchSkip); STDMETHOD(BreakLineA)(/*[in]*/ LCID locale, /*[in]*/ UINT uCodePage, /*[in, size_is(cchSrc)]*/ const CHAR* pszSrc, /*[in]*/ long cchSrc, /*[in]*/ long cMaxColumns, /*[out]*/ long* pcchLine, /*[out]*/ long* pcchSkip);
protected: template <DWORD INFOTYPE, int CACHESIZE> class CCharType { public: #ifdef ASTRIMPL
inline CCharType(void); #else
inline CCharType(LCID locale); #endif
inline ~CCharType(void); inline void Flush(void); #ifdef ASTRIMPL
WORD GetCharType(IMLangString* pMLStr, long lPos, long lLen, HRESULT* phr = NULL); #else
WORD GetCharType(LPCWSTR psz, int cch); #endif
protected: LPWORD m_pwBuf; #ifdef ASTRIMPL
IMLangStringAStr* m_pMLStrAStr; long m_lPos; long m_lLen; #else
LPSTR m_pszConv; LPCWSTR m_psz; int m_cch; LCID m_locale; UINT m_uCodePage; #endif
WORD m_wHalfWidth; };
HRESULT PrepareMLStrClass(void) { if (m_pMLStrClass) return S_OK; else return ::_Module.GetClassObject(CLSID_CMLangString, IID_IClassFactory, (void**)&m_pMLStrClass); }
IClassFactory* m_pMLStrClass; };
template <DWORD INFOTYPE, int CACHESIZE> #ifdef ASTRIMPL
CMLLBCons::CCharType<INFOTYPE, CACHESIZE>::CCharType(void) #else
CMLLBCons::CCharType<INFOTYPE, CACHESIZE>::CCharType(LCID locale) #endif
{ #ifndef ASTRIMPL
TCHAR szCodePage[8]; #endif
m_pwBuf = NULL; #ifdef ASTRIMPL
m_pMLStrAStr = NULL;
// TODO: Set m_wHaldWidth here.
m_wHalfWidth = 0; #else
m_pszConv = NULL; m_locale = locale; ::GetLocaleInfo(m_locale, LOCALE_IDEFAULTANSICODEPAGE, szCodePage, ARRAYSIZE(szCodePage)); m_uCodePage = _ttoi(szCodePage);
CPINFO cpi; ::GetCPInfo(m_uCodePage, &cpi); m_wHalfWidth = (cpi.LeadByte[0]) ? 0 : C3_HALFWIDTH; #endif
}
template <DWORD INFOTYPE, int CACHESIZE> CMLLBCons::CCharType<INFOTYPE, CACHESIZE>::~CCharType(void) { if (m_pwBuf) delete[] m_pwBuf; #ifdef ASTRIMPL
if (m_pMLStrAStr) m_pMLStrAStr->Release(); #else
if (m_pszConv) delete[] m_pszConv; #endif
}
template <DWORD INFOTYPE, int CACHESIZE> void CMLLBCons::CCharType<INFOTYPE, CACHESIZE>::Flush(void) { #ifdef ASTRIMPL
m_lPos = 0; m_lLen = 0; #else
m_psz = NULL; m_cch = 0; #endif
}
template <DWORD INFOTYPE, int CACHESIZE> #ifdef ASTRIMPL
WORD CMLLBCons::CCharType<INFOTYPE, CACHESIZE>::GetCharType(IMLangString* pMLStr, long lPos, long lLen, HRESULT* phr) #else
WORD CMLLBCons::CCharType<INFOTYPE, CACHESIZE>::GetCharType(LPCWSTR psz, int cch) #endif
{ #ifdef ASTRIMPL
if (lPos >= m_lPos + m_lLen || lPos + lLen <= m_lPos) #else
if (psz < m_psz || psz >= m_psz + m_cch) #endif
{ #ifdef ASTRIMPL
HRESULT hr; #endif
LPWORD pwCharType; #ifdef ASTRIMPL
WORD wCharType; CHAR* psz; long cch; LCID locale; UINT uCodePage;
if (m_pMLStrAStr) { m_pMLStrAStr->Release(); m_pMLStrAStr = NULL; }
if (SUCCEEDED(hr = pMLStr->QueryInterface(IID_IMLangStringAStr, (void**)&m_pMLStrAStr))) { if (!m_pwBuf) m_pwBuf = new WORD[CACHESIZE];
if (m_pwBuf) { pwCharType = m_pwBuf; cch = CACHESIZE; } else { pwCharType = &wCharType; cch = 1; }
lLen = min(lLen, cch);
if (SUCCEEDED(hr = m_pMLStrAStr->GetLocale(lPos, lLen, &locale, NULL, &lLen)) && SUCCEEDED(hr = ::LocaleToCodePage(locale, &uCodePage)) && SUCCEEDED(hr = m_pMLStrAStr->LockAStr(lPos, lLen, MLSTR_READ, uCodePage, 0, NULL, &psz, &cch, NULL))) { if (!::GetStringTypeExA(locale, INFOTYPE, psz, cch, pwCharType)) hr = E_FAIL; // NLS failed
ASSIGN_IF_FAILED(hr, m_pMLStrAStr->UnlockAStr(psz, 0, NULL, NULL)); } }
if (phr) *phr = hr;
if (SUCCEEDED(hr)) { m_lPos = lPos; m_lLen = lLen; return pwCharType[0] | m_wHalfWidth; } else { m_lPos = 0; m_lLen = 0; return 0 | m_wHalfWidth; } #else
LPSTR pszConv; WORD wCharType = 0; CHAR szTemp[2];
if (!m_pwBuf) m_pwBuf = new WORD[CACHESIZE];
if (m_pwBuf) { pwCharType = m_pwBuf; cch = min(cch, CACHESIZE); } else { pwCharType = &wCharType; cch = 1; }
if (!m_pszConv) m_pszConv = new CHAR[CACHESIZE * 2];
if (m_pszConv) { pszConv = m_pszConv; } else { pszConv = szTemp; cch = 1; }
if (m_pwBuf && m_pszConv) { m_psz = psz; m_cch = cch; }
int cchTemp = ::WideCharToMultiByte(m_uCodePage, 0, psz, cch, pszConv, CACHESIZE * 2, NULL, NULL); ::GetStringTypeExA(m_locale, INFOTYPE, pszConv, cchTemp, pwCharType);
return pwCharType[0] | m_wHalfWidth; #endif
} else { #ifdef ASTRIMPL
return m_pwBuf[lPos - m_lPos] | m_wHalfWidth; #else
return m_pwBuf[psz - m_psz] | m_wHalfWidth; #endif
} }
#endif //__MLLBCONS_H_
|