?? diction.cpp
字號:
// cfgedit.cpp : implementation file
//
#include "stdafx.h"
#include "diction.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
#ifdef _USE_DICTION_
#define DICT_MARK _T("WinDict ")
#define MAX_TRANS 800
#define START_MARK _T("$") _T("{")
#define END_MARK '}'
//////////////////////////////////////////////////////////////////////
// Iterate for all child windows (incude child of child)
class CWndChildIterator
{
public:
CWndChildIterator();
void InitIterator(CWnd* pParentWnd);
void operator ++(int);
void operator ++();
operator int();
CWnd* operator()(); //return current child window
protected:
virtual BOOL TestChild(CWnd* pParent, CWnd* pChild);
CWnd* pParent;
private:
CWnd* pChild;
};
// --------- INLINES ------------
inline CWndChildIterator::CWndChildIterator() {
pChild=NULL;
pParent=NULL;
}
inline void CWndChildIterator::operator ++() {
ASSERT(operator int());
operator++(1);
}
inline CWndChildIterator::operator int() {
return pChild!=NULL;
}
inline CWnd* CWndChildIterator::operator()() {
ASSERT(operator int());
return pChild;
}
//////////////////////////////////////////////////////////////////////
// Iterate for all controls from Dlg
class CDlgItemIterator : public CWndChildIterator
{
protected:
virtual BOOL TestChild(CWnd* pParent, CWnd* pChild);
};
//////////////////////////////////////////////////////////////////////
void CWndChildIterator::InitIterator(CWnd * pParentWnd)
{
pChild = NULL;
pParent = NULL;
ASSERT(pParentWnd);
if (!pParentWnd)
return;
pParent = pParentWnd;
pChild = pParentWnd->GetTopWindow();
if (pChild && !TestChild(pParent, pChild))
operator++ ();
}
// CWndChildIterator
BOOL CWndChildIterator::TestChild(CWnd * /* pParent */ , CWnd * /* hChild */ )
{
return TRUE; // All children
}
void CWndChildIterator::operator++ (int)
{
ASSERT(pChild);
while (pChild)
{
pChild = pChild->GetNextWindow(GW_HWNDNEXT);
if (pChild && TestChild(pParent, pChild))
break;
}
}
void GetMark(LPCTSTR pSrc, CString& sRet)
{
sRet.Empty();
if (!pSrc || *pSrc!='[')
return;
pSrc++;
LPTSTR pEnd = _tcsrchr(pSrc, ']');
if (!pEnd)
return;
*pEnd = 0;
sRet = pSrc;
*pEnd = ']';
}
//////////////////////////////////////////////////////////////////////
// CDlgItemIterator
BOOL CDlgItemIterator::TestChild(CWnd * pParent, CWnd * pChild)
{
ASSERT(pParent);
ASSERT(pChild);
if (!pParent)
return FALSE;
if (!pChild)
return FALSE;
if (!pParent->IsChild(pChild))
return FALSE;
return TRUE;
}
CDictionary Diction;
CDictionary* GetDictionary()
{
return &Diction;
}
CDictionary::CDictionary():m_Words(300)
{
}
BOOL CDictionary::SetDictionary(LPCTSTR sFile, BOOL bAll)
{
m_Words.RemoveAll();
return LoadDiction(sFile, bAll);
}
BOOL CDictionary::LoadDiction(LPCTSTR sFile, BOOL bAll, int nOnlyNew, BOOL bGetData )
{
if (!sFile)
return TRUE; // default language
CString sFullPath(sFile);
DicData temp;
DicData* pData = &temp;
if (bGetData)
pData = &m_Data;
if (!CheckFile(sFile, pData, &sFullPath))
return FALSE;
sFile = sFullPath;
CStdioFile file;
if (!file.Open(sFile, CFile::modeRead|CFile::typeText, NULL))
return FALSE;
CString s;
CString s2;
while ( file.ReadString(s) )
{
s.TrimLeft();
if (s.IsEmpty())
continue;
if (s[0]==_T(';') || s[0]==_T('['))
continue;
BOOL bIgnore = FALSE;
if (nOnlyNew)
{
if (m_Words.Lookup(s, s2))
bIgnore = TRUE;
}
// key
if (!bIgnore && (bAll || nOnlyNew) )
{
s2.Empty();
AddEntry(s, s2);
}
if (!file.ReadString(s2))
break;
if (bIgnore || nOnlyNew==2)
continue;
if (s2.IsEmpty() || s2[0]==';')
continue;
AddEntry(s, s2);
}
return TRUE;
}
BOOL CDictionary::CBTranslate(CWnd* pIt)
{
if (!pIt)
return FALSE;
int nC = pIt->SendMessage(CB_GETCOUNT);
int nCur = pIt->SendMessage(CB_GETCURSEL);
CString str;
for (int i=0; i<nC; i++)
{
int len=pIt->SendMessage(CB_GETLBTEXTLEN, i);
if (len<0 || len>200)
return FALSE; // that's probably not CB
if (!len)
continue;
pIt->SendMessage(CB_GETLBTEXT, i, (LPARAM)str.GetBufferSetLength(len));
if (str.Find(START_MARK)<0)
continue;
StrTranslate(str);
DWORD dwData = pIt->SendMessage(CB_GETITEMDATA, i);
pIt->SendMessage(CB_INSERTSTRING, i, (LPARAM)(LPCTSTR)str);
pIt->SendMessage(CB_SETITEMDATA, i, dwData);
pIt->SendMessage(CB_DELETESTRING, i+1);
}
if (nCur>=0)
pIt->SendMessage(CB_SETCURSEL, nCur);
return TRUE;
}
BOOL CDictionary::DlgTranslate(CWnd* pDlg)
{
if (!pDlg)
return FALSE;
CString str;
pDlg->GetWindowText(str);
StrTranslate(str);
pDlg->SetWindowText(str);
CDlgItemIterator I;
static TCHAR szClass[10];
for (I.InitIterator(pDlg); I; I++)
{
if (I()->GetWindowTextLength() > 0)
{
I()->GetWindowText(str);
StrTranslate(str);
I()->SetWindowText(str);
}
CWnd* pW = I();
if (pW && ::GetClassName(pW->m_hWnd, szClass, 10))
{
if (_tcsicmp(szClass, _T("COMBOBOX"))==0)
CBTranslate(pW);
}
}
return TRUE;
}
static TCHAR szTrans[MAX_TRANS];
static TCHAR szOrig[MAX_TRANS];
BOOL CDictionary::StrTranslate(CString& s)
{
// strip {} marks
int nLen = s.GetLength();
if (nLen < 3 || nLen>= MAX_TRANS)
return TRUE;
LPCTSTR pStr = s;
LPTSTR pStart= _tcsstr(pStr, START_MARK);
if (!pStart)
return TRUE;
LPTSTR pCurNew = szTrans;
while (1)
{
// copy pre string
if (pStart)
{
int n = pStart-pStr;
if (n>0)
{
memcpy(pCurNew, pStr, n*sizeof(TCHAR));
pCurNew+=n;
}
}
else // copy last chars
{
if (*pStr)
_tcscpy(pCurNew, pStr);
else
*pCurNew = 0;
break;
}
pStart+=_tcslen(START_MARK);
LPTSTR pEnd=_tcschr(pStart, END_MARK);
if (pEnd) // got closing bracket
{
*pEnd = 0;
CString tr;
int bFound = 0;
if (m_Words.GetCount()==0)
{
bFound = -1;
}
else
bFound = m_Words.Lookup(pStart, tr);
if (bFound > 0 && !tr.IsEmpty())
_tcscpy(pCurNew, tr);
else
{ // may be there is same without &?
LPTSTR pT = NULL;
if (bFound==0)
_tcschr(pStart, '&');
if (!pT) // no &! or empty
_tcscpy(pCurNew, pStart);
else
{
TCHAR ch = *(pT+1);
int nBefore = pT-pStart;
if (nBefore)
memcpy(szOrig, pStart, nBefore*sizeof(TCHAR));
_tcscpy(szOrig+nBefore, pStart+nBefore+1);
if (m_Words.Lookup(szOrig, tr) && !tr.IsEmpty())
{ // same char for '&'
nBefore = tr.Find(ch);
if (nBefore>=0)
{
if (nBefore)
memcpy(pCurNew, (LPCTSTR)tr, nBefore*sizeof(TCHAR));
_tcscpy(pCurNew+nBefore, _T("&"));
_tcscpy(pCurNew+nBefore+1, (LPCTSTR)tr + nBefore);
}
else
{
_tcscpy(pCurNew, _T("&"));
_tcscpy(pCurNew+1, tr);
}
}
else
_tcscpy(pCurNew, pStart);
}
}
pCurNew+=_tcslen(pCurNew);
*pEnd = END_MARK;
}
else
return FALSE;
pStr = pEnd + 1;
pStart = _tcsstr(pStr, START_MARK);
}
s = szTrans;
return TRUE;
}
BOOL CDictionary::MenuTranslate(HMENU HM)
{
ASSERT(HM);
if (!HM)
return FALSE;
CUIntArray aStack;
aStack.SetSize(0, 20);
aStack.Add((UINT)HM);
int nTop = 0;
CString str;
while (nTop>=0)
{
HMENU hm = (HMENU)aStack.GetAt(nTop);
nTop--;
int nItems = ::GetMenuItemCount(hm);
MENUITEMINFO mi;
for (int i=0; i<nItems; i++)
{
ZeroMemory(&mi, sizeof(mi));
mi.cbSize = sizeof(mi);
mi.fMask = MIIM_TYPE|MIIM_SUBMENU|MIIM_DATA;
mi.dwTypeData = szOrig;
mi.cch = MAX_TRANS;
if (!GetMenuItemInfo(hm, i, TRUE, &mi))
continue;
if (mi.fType!= MFT_STRING )
continue;
// deal with submenu
if (mi.hSubMenu)
{
aStack.SetAtGrow(++nTop, (UINT)mi.hSubMenu);
}
str = (LPCTSTR)mi.dwTypeData;
StrTranslate(str);
mi.dwTypeData = (LPTSTR)(LPCTSTR)str;
SetMenuItemInfo(hm, i, TRUE, &mi);
}
}
return TRUE;
}
void CDictionary::FindDictions(Dictions& aDics, LPCTSTR sP)
{
CString sPath(sP);
CString sBuf;
LPTSTR pBuf = sBuf.GetBuffer(MAX_PATH*2);
if (sP)
_tcscpy(pBuf, sP);
else
{
GetModuleFileName(NULL, pBuf, MAX_PATH*2);
LPTSTR pEnd = _tcsrchr(pBuf, '\\');
if (pEnd)
{
pEnd++;
*pEnd = 0;
}
}
DWORD dwDir = GetFileAttributes(pBuf);
if (dwDir==(UINT)-1 || !(dwDir & FILE_ATTRIBUTE_DIRECTORY) )
{
sBuf.ReleaseBuffer();
return;
}
LPTSTR pEnd = pBuf + _tcslen(pBuf);
_tcscat(pBuf, _T("*.dic"));
WIN32_FIND_DATA fd;
HANDLE hFind = FindFirstFile(pBuf, &fd);
if (hFind == INVALID_HANDLE_VALUE)
{
sBuf.ReleaseBuffer();
return;
}
DicData dat;
while (1)
{
_tcscpy(pEnd, fd.cFileName);
if (CheckFile(pBuf, &dat, NULL))
{
aDics.Add(dat);
}
if (!FindNextFile(hFind , &fd))
break;
}
FindClose(hFind);
sBuf.ReleaseBuffer();
}
BOOL CDictionary::CheckFile(LPCTSTR sFileName, DicData* pData, CString* sFull )
{
CString sFile(sFileName);
// try to find file
if (GetFileAttributes(sFileName)==(DWORD)-1)
{
LPTSTR pUnused = NULL;
SearchPath(NULL, sFileName, NULL, MAX_PATH*2, sFile.GetBuffer(MAX_PATH*2),
&pUnused);
sFile.ReleaseBuffer();
}
CStdioFile file;
if (!file.Open(sFile, CFile::modeRead|CFile::typeText, NULL))
return FALSE;
CString s;
if (!file.ReadString(s))
return FALSE;
// WinDict
CString sMark;
GetMark(s, sMark);
if (sMark.Find(DICT_MARK)!=0)
return FALSE;
if (!file.ReadString(s))
return FALSE;
if(!pData)
return TRUE;
TCHAR szExt[_MAX_EXT];
_tsplitpath(sFile, NULL, NULL, pData->sFile.GetBuffer(MAX_PATH), szExt);
pData->sFile.ReleaseBuffer();
pData->sFile+=szExt;
GetMark(s, pData->sLang);
if (!file.ReadString(s))
return FALSE;
GetMark(s, pData->sAuthor);
if (file.ReadString(s))
GetMark(s, pData->sRem);
if (sFull)
*sFull = sFile;
return TRUE;
}
DicData& DicData::operator=(const DicData& a)
{
sLang = a.sLang;
sFile = a.sFile;
sAuthor = a.sAuthor;
sRem = a.sRem;
return *this;
}
void CDictionary::RemoveCRs(CString& sKey)
{
if (sKey.IsEmpty() || sKey.Find(_T("\\n"))<0)
return;
LPTSTR pBuf = sKey.GetBuffer(sKey.GetLength());
while (1)
{
LPTSTR pCR = _tcsstr(pBuf, _T("\\n"));
if (!pCR)
break;
int nLen = _tcslen(pBuf);
*pCR = 0x0A;
int nCR = pCR-pBuf;
memmove(pCR+1, pCR+2, (nLen-nCR-1)*sizeof(TCHAR));
pBuf[nLen-1]=0;
}
sKey.ReleaseBuffer();
}
void CDictionary::AddEntry(CString& sKey, CString& sTrans)
{
// remove \n
RemoveCRs(sKey);
RemoveCRs(sTrans);
m_Words.SetAt(sKey, sTrans);
}
BOOL CDictionary::SheetTranslate(CPropertySheet* p)
{
if (!p)
return FALSE;
// Translate caption
CString sTemp;
p->GetWindowText(sTemp);
StrTranslate(sTemp);
p->SetWindowText(sTemp);
static UINT nIDs[] = {IDOK, IDCANCEL, IDHELP, ID_APPLY_NOW};
for (int j=0; j<4; j++)
{
CWnd *pBtn = p->GetDlgItem( nIDs[j] );
if (!pBtn)
continue;
LOAD_STRING(sTemp, nIDs[j]);
pBtn->SetWindowText(sTemp);
}
// Translate Tab text
TC_ITEM Item;
Item.mask = TCIF_TEXT;
Item.cchTextMax = 50;
Item.pszText = new char[50];
CTabCtrl* pTC = p->GetTabControl();
ASSERT( pTC );
for( int i = 0; i<pTC->GetItemCount(); i++ )
if( pTC->GetItem( i, &Item) )
{
sTemp = Item.pszText; StrTranslate(sTemp);
strncpy(Item.pszText, sTemp, Item.cchTextMax);
pTC->SetItem( i, &Item);
};
delete [] Item.pszText;
return TRUE;
}
#endif // _USE_DICTION_
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -