欢迎来到虫虫下载站 | 资源下载 资源专辑 关于我们
虫虫下载站

spellcheckdlg.cpp

管理项目进度工具的原代码
CPP
字号:
// SpellCheckDlg.cpp : implementation file
//

#include "stdafx.h"
#include "SpellCheckDlg.h"
#include "ispellcheck.h"
#include "enfiledialog.h"
#include "stringres.h"
#include "filemisc.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CSpellCheckDlg dialog

enum // control IDs
{
	IDC_DICTIONARIES = 1001,
	IDC_BROWSE,
	IDC_SUGGESTIONS,
	IDC_TEXT,
	IDC_MISSPELTWORD,
	IDC_REPLACE,
	IDC_CONTINUE,
	IDC_RESTART,
	IDC_URL,
};

CSpellCheckDlg::CSpellCheckDlg(LPCTSTR szDictionaryPath, ISpellCheck* pSpellCheck, LPCTSTR szText, CWnd* /*pParent*/) : 
	m_pSpellChecker(NULL), 
	m_reSpellCheck(m_reText),
    m_sSelDictionary(szDictionaryPath), 
	m_stURL("http://wiki.services.openoffice.org/wiki/Dictionaries"),
	m_bMadeChanges(FALSE),
	m_ptTopLeft(-1, -1)
{
	InitDialog(pSpellCheck, szText);
}

void CSpellCheckDlg::InitDialog(ISpellCheck* pSpellCheck, LPCTSTR szText)
{
	AfxEnableControlContainer();
	AfxInitRichEdit();

	AddRCControl("LTEXT", "", SPELLCHECK_ACTIVEDICT, 0,0, 7,9,65,8, (UINT)IDC_STATIC);
	AddRCControl("COMBOBOX", "", "", CBS_DROPDOWNLIST | WS_TABSTOP, 0, 66, 8, 182,100, IDC_DICTIONARIES);
	AddRCControl("PUSHBUTTON", "", SPELLCHECK_BROWSE,WS_TABSTOP, 0,256,7,50,14,IDC_BROWSE);
	AddRCControl("LTEXT", "", SPELLCHECK_DOWNLOADMORE, WS_TABSTOP,0, 66,21,90,8,IDC_URL);
	AddRCControl("LTEXT", "", SPELLCHECK_CHECKING, 0,0, 7,30,49,8, (UINT)IDC_STATIC);
	AddRCControl("CONTROL", "RICHEDIT", "",ES_MULTILINE | ES_AUTOVSCROLL | ES_NOHIDESEL |/*WS_BORDER | */ ES_READONLY | WS_VSCROLL | WS_TABSTOP | WS_DISABLED,0, 7,40,242,68,IDC_TEXT);
	AddRCControl("PUSHBUTTON", "", SPELLCHECK_RESTART,WS_TABSTOP, 0,256,40,50,14,IDC_RESTART);
	AddRCControl("LTEXT", "", SPELLCHECK_REPLACE,0, 0,7,112,30,8, (UINT)IDC_STATIC);
	AddRCControl("LTEXT", "", "Static",0, 0,44,112,205,8,IDC_MISSPELTWORD);
	AddRCControl("LTEXT", "", SPELLCHECK_WITH,0, 0,7,124,18,8, (UINT)IDC_STATIC);
	AddRCControl("LISTBOX", "", "", LBS_SORT | LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP | LBS_NOTIFY, 0,41,124,208,51, IDC_SUGGESTIONS);
	AddRCControl("PUSHBUTTON", "", SPELLCHECK_BTN_REPLACE,WS_TABSTOP, 0,256,124,50,14,IDC_REPLACE);
	AddRCControl("PUSHBUTTON", "", SPELLCHECK_NEXTWORD,WS_TABSTOP, 0,256,144,50,14,IDC_CONTINUE);
	AddRCControl("CONTROL", "static", "",SS_ETCHEDHORZ,0,7,182,299,1, (UINT)IDC_STATIC);

	if (!pSpellCheck)
	{
		AddRCControl("DEFPUSHBUTTON", "", BTN_OK, WS_TABSTOP, 0, 199,190,50,14,IDOK);
		AddRCControl("PUSHBUTTON", "", BTN_CANCEL, WS_TABSTOP, 0,256,190,50,14,IDCANCEL);

		SetText(szText);
	}
	else
	{
		AddRCControl("PUSHBUTTON", "", BTN_CLOSE, WS_TABSTOP, 0,256,190,50,14,IDCANCEL);

		SetSpellCheck(pSpellCheck);
	}

	// init spell checker dll path
#ifndef _DEBUG
	m_sEnginePath = AfxGetApp()->GetProfileString("SpellChecker", "EnginePath", "MySpellCheck.dll");
#else
	m_sEnginePath = "MySpellCheck.dll";
#endif

	if (!IsSpellCheckDll(m_sEnginePath))
	{
		CString sDllPath = FileMisc::GetModuleFileName(), sDrive, sFolder;

		FileMisc::SplitPath(sDllPath, &sDrive, &sFolder);
		FileMisc::MakePath(sDllPath, sDrive, sFolder, "*", ".dll");

		m_sEnginePath = sDllPath;
	}
}

CSpellCheckDlg::~CSpellCheckDlg()
{
	ReleaseSpellCheckerInterface(m_pSpellChecker);
}

void CSpellCheckDlg::DoDataExchange(CDataExchange* pDX)
{
	CRuntimeDlg::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CSpellCheckDlg)
	DDX_Control(pDX, IDC_SUGGESTIONS, m_lbSuggestions);
	DDX_Text(pDX, IDC_MISSPELTWORD, m_sMisspeltWord);
	DDX_LBString(pDX, IDC_SUGGESTIONS, m_sSuggestion);
	//}}AFX_DATA_MAP
	DDX_Control(pDX, IDC_URL, m_stURL);
	DDX_Control(pDX, IDC_DICTIONARIES, m_cbDictionaries);

	DDX_Text(pDX, IDC_TEXT, m_sText);
	DDX_Control(pDX, IDC_TEXT, m_reText);

	if (pDX->m_bSaveAndValidate)
	{
		int nCurSel = m_cbDictionaries.GetCurSel();

		if (nCurSel != CB_ERR)
			m_cbDictionaries.GetLBText(nCurSel, m_sSelDictionary);
		else
			m_sSelDictionary.Empty();
	}
	else
	{
		// make sure its in the list and move to top
		int nDic = m_cbDictionaries.FindStringExact(-1, m_sSelDictionary);

		if (nDic != CB_ERR)
			m_cbDictionaries.DeleteString(nDic);

		if (!m_sSelDictionary.IsEmpty())
		{
			m_cbDictionaries.InsertString(0, m_sSelDictionary);
			m_cbDictionaries.SetCurSel(0);
		}
	}
}

BEGIN_MESSAGE_MAP(CSpellCheckDlg, CRuntimeDlg)
	//{{AFX_MSG_MAP(CSpellCheckDlg)
	ON_BN_CLICKED(IDC_REPLACE, OnReplace)
	ON_BN_CLICKED(IDC_CONTINUE, OnContinue)
	ON_LBN_SELCHANGE(IDC_SUGGESTIONS, OnSelchangeSuggestions)
	ON_BN_CLICKED(IDC_RESTART, OnRestart)
	ON_WM_DESTROY()
	//}}AFX_MSG_MAP
	ON_BN_CLICKED(IDC_BROWSE, OnBrowse)
	ON_CBN_SELCHANGE(IDC_DICTIONARIES, OnChangeDictionary)
	ON_LBN_DBLCLK(IDC_SUGGESTIONS, OnDblClkSuggestions)
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CSpellCheckDlg message handlers

int CSpellCheckDlg::DoModal(BOOL bEndOnNoErrors) 
{ 
	m_bEndOnNoErrors = bEndOnNoErrors;

	// turn off centering if we saved the last position
	DWORD dwFlags = RTD_DEFSTYLE;

	if (m_ptTopLeft.x != -1 || m_ptTopLeft.y != -1)
		dwFlags &= ~DS_CENTER;

	return CRuntimeDlg::DoModal(SPELLCHECK_TITLE, dwFlags); 
}

BOOL CSpellCheckDlg::InitDictionary(LPCTSTR szDicPath)
{
	CString sAffixPath(szDicPath);
	sAffixPath.MakeLower();
	sAffixPath.Replace(".dic", ".aff");

	ISpellChecker* pTemp = CreateSpellCheckerInterface(m_sEnginePath, sAffixPath, szDicPath);

	if (pTemp) // alls well
	{
		ReleaseSpellCheckerInterface(m_pSpellChecker);
		m_pSpellChecker = pTemp;
		pTemp = NULL;

		m_sSelDictionary = szDicPath;
		UpdateData(FALSE);

		// clear the current word and reset 
		HighlightWord(FALSE);
	}

	return (NULL != m_pSpellChecker);
}

void CSpellCheckDlg::SetText(LPCTSTR szText) 
{ 
	m_sText = szText; 
	m_pSpellCheck = &m_reSpellCheck;

	m_sMisspeltWord.Empty();
	m_sSuggestion.Empty();

	if (GetSafeHwnd())
	{
		m_reText.SetBackgroundColor(TRUE, 0);
		m_lbSuggestions.ResetContent();

		UpdateData(FALSE);
		StartChecking();
	}
}

void CSpellCheckDlg::SetSpellCheck(ISpellCheck* pSpellCheck) 
{ 
	m_sText.Empty(); 
	m_pSpellCheck = pSpellCheck;

	m_sMisspeltWord.Empty();
	m_sSuggestion.Empty();

	if (GetSafeHwnd())
	{
		m_reText.SetBackgroundColor(FALSE, GetSysColor(COLOR_3DFACE));
		m_lbSuggestions.ResetContent();

		UpdateData(FALSE);
		StartChecking();
	}
}

void CSpellCheckDlg::OnChangeDictionary()
{
	UpdateData();

	if (InitDictionary(m_sSelDictionary))
		StartChecking(CH_CURRENT);
}

void CSpellCheckDlg::OnBrowse()
{
	UpdateData();
	CEnFileDialog dialog(TRUE, "dic", m_sSelDictionary, OFN_PATHMUSTEXIST, SPELLCHECK_DICT_FILTER);
	
	dialog.m_ofn.lpstrTitle = SPELLCHECK_BROWSE_TITLE;
	
	if (dialog.DoModal() == IDOK)
	{
		if (InitDictionary(dialog.GetPathName()))
			StartChecking(CH_CURRENT);
	}
}

void CSpellCheckDlg::OnReplace() 
{
	if (!m_pSpellChecker)
		return;

	UpdateData();
	ASSERT (!m_sSuggestion.IsEmpty());

	m_pSpellCheck->ReplaceCurrentWord(m_sSuggestion);
	m_pSpellCheck->ClearSelection();
	m_bMadeChanges = TRUE;

	UpdateData();
	
	OnContinue();
}

void CSpellCheckDlg::OnContinue() 
{
	if (!m_pSpellChecker)
		return;

	StartChecking(CH_NEXT);
}

BOOL CSpellCheckDlg::FindNextWord(CString& sWord, CHECKFROM nFrom)
{
	switch (nFrom)
	{
	case CH_START:
		sWord = m_pSpellCheck->GetFirstWord();
		break;

	case CH_CURRENT:
		sWord = m_pSpellCheck->GetCurrentWord();
		break;

	case CH_NEXT:
		sWord = m_pSpellCheck->GetNextWord();
		break;
	}

	return (!sWord.IsEmpty());
}

BOOL CSpellCheckDlg::FindNextMisspeltWord(CString& sWord, CHECKFROM nFrom)
{
	while (TRUE)
	{
		if (!FindNextWord(sWord, nFrom))
			return FALSE;

		else if (IsWordMisspelt(sWord))
			return TRUE;

		// else continue
		nFrom = CH_NEXT;
	}

	// cant get here
	ASSERT (0);
	return FALSE;
}

BOOL CSpellCheckDlg::OnInitDialog() 
{
	CRuntimeDlg::OnInitDialog();

	m_ncBorder.Initialize(m_reText);
	m_bMadeChanges = FALSE;

	// reload dictionary list
	int nDicCount = AfxGetApp()->GetProfileInt("SpellChecker", "DictionaryCount", 0);

	for (int nDic = 0; nDic < nDicCount; nDic++)
	{
		CString sKey;
		sKey.Format("Dictionary%d", nDic);

		CString sPath = AfxGetApp()->GetProfileString("SpellChecker", sKey);

		if (GetFileAttributes(sPath) != 0xffffffff)
		{
			if (m_cbDictionaries.FindStringExact(-1, sPath) == CB_ERR)
				m_cbDictionaries.AddString(sPath);
		}
	}

	if (m_sSelDictionary.IsEmpty())
		m_sSelDictionary = AfxGetApp()->GetProfileString("SpellChecker", "ActiveDictionary");

	// check spell check engine is initialized
	BOOL bCancel = FALSE;

	if (!IsSpellCheckDll(m_sEnginePath))
	{
		bCancel = (IDCANCEL == AfxMessageBox(SPELLCHECK_SETUP_MSG, MB_OKCANCEL));

		while (!bCancel && !IsSpellCheckDll(m_sEnginePath))
		{
			// notify user and browse for dll
			CEnFileDialog dialog(TRUE, "dll", m_sEnginePath, OFN_PATHMUSTEXIST, SPELLCHECK_ENGINE_FILTER);

			dialog.m_ofn.lpstrTitle = SPELLCHECK_ENGINE_TITLE;

			if (dialog.DoModal() == IDOK)
				m_sEnginePath = dialog.GetPathName();
			else
				bCancel = TRUE;
		}
	}

	if (bCancel)
	{
		EndDialog(IDCANCEL);
		return FALSE;
	}

	// make the rich edit appear disabled if not using text
	if (m_pSpellCheck != &m_reSpellCheck)
		m_reText.SetBackgroundColor(FALSE, GetSysColor(COLOR_3DFACE));

	if (IsInitialized() || InitDictionary(m_sSelDictionary))
	{
		if (!StartChecking() && m_bEndOnNoErrors)
		{
			EndDialog(IDNOERRORS);
			return FALSE;
		}
	}

	return TRUE;  // return TRUE unless you set the focus to a control
				  // EXCEPTION: OCX Property Pages should return FALSE
}

BOOL CSpellCheckDlg::StartChecking(CHECKFROM nFrom)
{
	CString sWord; 

	BOOL bMisspelt = FindNextMisspeltWord(sWord, nFrom);

	// if starting from the beginning and no misspelt words are found
	// then e return FALSE to indicate no further checking required
	if (nFrom == CH_START && !bMisspelt)
		return FALSE;

	else if (bMisspelt)
	{
		ProcessMisspeltWord(sWord);
		return TRUE;
	}

	// else reached the end so start again
	ProcessMisspeltWord("");

	return StartChecking(CH_START);
}

void CSpellCheckDlg::ProcessMisspeltWord(LPCTSTR szWord)
{
	if (!szWord || !*szWord) // no misspelling
	{
		m_lbSuggestions.ResetContent();
		GetDlgItem(IDC_REPLACE)->EnableWindow(FALSE);

		m_sMisspeltWord.Empty();
		UpdateData(FALSE);

		return;
	}

	// else
	m_sMisspeltWord.Format("'%s'", szWord);
	UpdateData(FALSE);

	// set new selection
	HighlightWord(TRUE);

	// add suggestions
	m_lbSuggestions.ResetContent();

	if (m_pSpellChecker)
	{
		char** pSuggestions = NULL;
		int nNumSuggestions = 0;

		m_pSpellChecker->CheckSpelling(szWord, pSuggestions, nNumSuggestions);

		for (int nSugg = 0; nSugg < nNumSuggestions; nSugg++)
			m_lbSuggestions.AddString(pSuggestions[nSugg]);

		m_pSpellChecker->FreeSuggestions(pSuggestions);
	}

	if (m_lbSuggestions.GetCount())
		m_lbSuggestions.GetText(0, m_sSuggestion);
	else
		m_sSuggestion.Empty();

	m_lbSuggestions.SelectString(-1, m_sSuggestion);
	GetDlgItem(IDC_REPLACE)->EnableWindow(m_lbSuggestions.GetCount());
}

void CSpellCheckDlg::HighlightWord(BOOL bHighlight)
{
	if (bHighlight)
		m_pSpellCheck->SelectCurrentWord();
	else
		m_pSpellCheck->ClearSelection();
}

BOOL CSpellCheckDlg::IsWordMisspelt(LPCTSTR szWord)
{
	if (m_pSpellChecker)
		return (m_pSpellChecker->CheckSpelling(szWord) == 0);

	return FALSE;
}

void CSpellCheckDlg::OnSelchangeSuggestions() 
{
	UpdateData();
	
	GetDlgItem(IDC_REPLACE)->EnableWindow(!m_sSuggestion.IsEmpty());
}

void CSpellCheckDlg::OnRestart() 
{
	if (m_pSpellChecker)
	{
		if (m_pSpellCheck == &m_reSpellCheck)
			m_bMadeChanges = FALSE;

		StartChecking();	
	}
}

void CSpellCheckDlg::OnDestroy() 
{
	m_pSpellCheck->ClearSelection();

	// save position
	if (m_ptTopLeft.x == -1 && m_ptTopLeft.y == -1)
	{
		CRect rWindow;
		GetWindowRect(rWindow);

		m_ptTopLeft = rWindow.TopLeft();
	}
	
	CRuntimeDlg::OnDestroy();
	
	AfxGetApp()->WriteProfileString("SpellChecker", "EnginePath", m_sEnginePath);
	AfxGetApp()->WriteProfileString("SpellChecker", "ActiveDictionary", m_sSelDictionary);

	// save dictionary list
	int nDicCount = m_cbDictionaries.GetCount();
	AfxGetApp()->WriteProfileInt("SpellChecker", "DictionaryCount", nDicCount);

	for (int nDic = 0; nDic < nDicCount; nDic++)
	{
		CString sKey;
		sKey.Format("Dictionary%d", nDic);

		CString sPath;
		m_cbDictionaries.GetLBText(nDic, sPath);

		AfxGetApp()->WriteProfileString("SpellChecker", sKey, sPath);
	}
}

void CSpellCheckDlg::OnDblClkSuggestions()
{
	UpdateData();

	if (m_lbSuggestions.GetCount() && !m_sSuggestion.IsEmpty())
		OnReplace();
}

CPoint CSpellCheckDlg::GetInitialPos() const 
{ 
	CPoint ptTemp(m_ptTopLeft);

	m_ptTopLeft.x = m_ptTopLeft.y = -1;  // reset

	return ptTemp;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -