📄 scintillawnd.cpp
字号:
/* @doc
* @module ScintillaWnd.cpp | Implementation of a Scintilla syntax coloring edit control for MFC
* This program is an example how to use the excellent scintilla edit control of Neil Hodgson.<nl>
* See www.scintilla.org for details<nl>
* Author: Horst Br點kner, hb@ec-logic.com<nl>
* Environment: VisualC++ Version 6, static Build of Scintilla, SciLexer.dll as Lexer<nl>
*/
#include "stdafx.h"
#include "ScintillaWnd.h"
#include "Tokenizer.h"
#include "scintilla\include\scintilla.h"
#include "scintilla\include\SciLexer.h"
#include "scintilla\include\Accessor.h"
#include "scintilla\include\Propset.h"
#include "scintilla\include\keywords.h"
#include <fstream.h>
#include <io.h>
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
// the next 2 arrays are used to determine lexer format from file extensions
static TCHAR *szExtensions[] =
{
"py", // SCLEX_PYTHON
"c|cc|cpp|cxx|cs|h|hh|hpp|hxx|sma|dlg|rc|rc2|idl|odl|mak|js|java", // SCLEX_CPP
"htm|html|shtml|htt|cfm|tpl|hta", // SCLEX_HTML
"xml|gcl|xsl|svg|xul|xsd|dtd|xslt|axl", // SCLEX_XML
"pl|pm|cgi|pod", // SCLEX_PERL
"sql|spec|body|sps|spb|sf|sp", // SCLEX_SQL
"vb|bas|frm|cls|ctl|pag|dsr|dob", // SCLEX_VB
"properties", // SCLEX_PROPERTIES
"err", // SCLEX_ERRORLIST
"iface|mak", // SCLEX_MAKEFILE
"bat|cmd|nt", // SCLEX_BATCH
"xcode", // SCLEX_XCODE
"tex|sty", // SCLEX_LATEX
"lua", // SCLEX_LUA
"diff", // SCLEX_DIFF
"conf", // SCLEX_CONF
"pas|inc|pp", // SCLEX_PASCAL
"ave", // SCLEX_AVE
"ada|ads|adb", // SCLEX_ADA
"lsp|lisp|scm|smd|ss", // SCLEX_LISP
"rb", // SCLEX_RUBY
"e", // SCLEX_EIFFEL
"e", // SCLEX_EIFFELKW
"tcl", // SCLEX_TCL
"tab|spf", // SCLEX_NNCRONTAB
"ant", // SCLEX_BULLANT
"vbs|dsm", // SCLEX_VBSCRIPT
"asp|aspx", // SCLEX_ASP
"php|php3|php4", // SCLEX_PHP
"bc|cln", // SCLEX_BAAN
"m", // SCLEX_MATLAB
"sol", // SCLEX_SCRIPTOL
"asm", // SCLEX_ASM
"cpp", // SCLEX_CPPNOCASE
"f|for|f90|f95", // SCLEX_FORTRAN
"f77", // SCLEX_F77
"css", // SCLEX_CSS
"pov", // SCLEX_POV
"lt|lot", // SCLEX_LOUT
"src|em", // SCLEX_ESCRIPT
0,
};
static int nFormats[] = {
SCLEX_PYTHON,
SCLEX_CPP,
SCLEX_HTML,
SCLEX_XML,
SCLEX_PERL,
SCLEX_SQL,
SCLEX_VB,
SCLEX_PROPERTIES,
SCLEX_ERRORLIST,
SCLEX_MAKEFILE,
SCLEX_BATCH,
SCLEX_XCODE,
SCLEX_LATEX,
SCLEX_LUA,
SCLEX_DIFF,
SCLEX_CONF,
SCLEX_PASCAL,
SCLEX_AVE,
SCLEX_ADA,
SCLEX_LISP,
SCLEX_RUBY,
SCLEX_EIFFEL,
SCLEX_EIFFELKW,
SCLEX_TCL,
SCLEX_NNCRONTAB,
SCLEX_BULLANT,
SCLEX_VBSCRIPT,
SCLEX_ASP,
SCLEX_PHP,
SCLEX_BAAN,
SCLEX_MATLAB,
SCLEX_SCRIPTOL,
SCLEX_ASM,
SCLEX_CPPNOCASE,
SCLEX_FORTRAN,
SCLEX_F77,
SCLEX_CSS,
SCLEX_POV,
SCLEX_LOUT,
SCLEX_ESCRIPT,
0,
};
/////////////////////////////////////
// @mfunc This is an empty constructor
// @rvalue void | not used
//
CScintillaWnd::CScintillaWnd()
{
m_bLinenumbers = FALSE;
m_bSelection = TRUE;
m_bFolding = FALSE;
m_nSearchflags = 0;
}
/////////////////////////////////////
// @mfunc This is a destructor
// @rvalue void | not used
//
CScintillaWnd::~CScintillaWnd()
{
}
/////////////////////////////////////
// @mfunc Create the window
// @rvalue BOOL | TRUE on success else FALSE on error
//
BOOL CScintillaWnd::Create (LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID)
{
if (!CWnd::CreateEx(WS_EX_CLIENTEDGE, STR_SCINTILLAWND,lpszWindowName, dwStyle, rect, pParentWnd,(UINT)nID))
{
LPVOID lpMsgBuf;
::FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &lpMsgBuf,0,NULL);
// Write to stderr
TRACE (_T("%s\n"), (LPCTSTR)lpMsgBuf);
// Free the buffer.
LocalFree( lpMsgBuf );
return FALSE;
}
return TRUE;
}
/////////////////////////////////////
// @mfunc Try to load the Scintilla dll - usually named "SciLexer.dll" or "Scintilla.dll". We try to locate the dll in
// the current dirtectory and along the path environment.
// Call this function in your CWinApp derived application in the InitInstance function by calling:<nl>
// CScintillaWnd::LoadScintillaDll()<nl>
// @rvalue BOOL | FALSE on error - TRUE on success
//
HMODULE CScintillaWnd::LoadScintillaDll (
LPCSTR szDllFile) //@parm filename of the lexer dll - default "SciLexer.dll"
{
CString strLexer = STR_LEXERDLL;
if (szDllFile != NULL)
strLexer = szDllFile;
// this call to LoadLibrary searches in:
// 1.) current directory
// 2.) wint
// 3.) winnt/system32
// 4.) path
HMODULE hModule = ::LoadLibrary(strLexer);
// if load fails get an extended error message
if (hModule == NULL)
{
LPVOID lpMsgBuf;
::FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &lpMsgBuf,0,NULL);
// Write to stderr
TRACE (_T("%s:%s\n"), (LPCSTR)strLexer, (LPCTSTR)lpMsgBuf);
// Free the buffer.
LocalFree( lpMsgBuf );
return NULL;
}
return hModule;
}
/////////////////////////////////////
// @mfunc Reset the Scintiall control and add new Text
// @rvalue void | not used
//
void CScintillaWnd::SetText (
LPCSTR szText) //@parm pointer to new text
{
LRESULT lResult = 0;
if (szText != NULL)
lResult = SendMessage(SCI_SETTEXT,0,(LPARAM)szText);
GotoPosition(0);
SetFocus();
}
/////////////////////////////////////
// @mfunc Get the text from the control
// @rvalue void | not used
//
void CScintillaWnd::GetText (
CString &strText) //@parm handle to receive text
{
LPSTR szText = GetText();
if (szText != NULL)
{
strText = szText;
delete [] szText;
}
}
/////////////////////////////////////
// @mfunc Get the text from the control
// @rvalue LPSTR | a character string with text from the control - NULL on error - the caller has to free pointer
//
LPSTR CScintillaWnd::GetText ()
{
long lLen = SendMessage(SCI_GETLENGTH, 0, 0) + 1;
if (lLen > 0)
{
TCHAR *pReturn = new TCHAR[lLen];
if (pReturn != NULL)
{
*pReturn = '\0';
SendMessage(SCI_GETTEXT, lLen, (long)pReturn);
return pReturn;
}
}
return NULL;
}
/////////////////////////////////////
// @mfunc Try to load a new file
// @rvalue BOOL | FALSE on error - TRUE on success
//
BOOL CScintillaWnd::LoadFile (
LPCSTR szPath) //@parm filename of to load
{
// if pathname is empty do nothing
if (szPath == NULL || *szPath == '\0')
return TRUE;
// try to get extension and figure out what lexer to use
CString strFile(szPath);
int nIndex = strFile.ReverseFind('.');
CString strExtension = strFile.Right(strFile.GetLength()-nIndex-1);
SendMessage(SCI_SETLEXER, GetFormatFromExtension(strExtension), 0);
BOOL bReturn = TRUE;
// ty to open file in sharing mode
::ifstream file;
long len = 0L;
long nTotal;
TCHAR *szBuffer = NULL;
file.open(szPath, ios::in, filebuf::sh_read);
// ok success - try to get length of file
if (file.is_open())
{
len = _filelength(file.fd());
if (len > 0)
{
// alloc new buffer of sie = filesize+1 for termination NULL
szBuffer = new TCHAR[len+1];
if (szBuffer != NULL)
{
file.read(szBuffer, len);
nTotal = file.gcount();
if (nTotal > 0 && nTotal <= len)
szBuffer[nTotal] = '\0';
// read error
if (file.bad())
{
file.close();
bReturn = FALSE;
}
}
else
{
file.close();
bReturn = FALSE;
}
}
file.close();
// set text to control
SetText (szBuffer);
// tell scintilla that we have an unmodified document
SendMessage(SCI_SETSAVEPOINT,0 , 0);
GotoPosition(0);
}
// file open error - return
else
bReturn = FALSE;
// clean up
if (szBuffer != NULL)
delete [] szBuffer;
return bReturn;
}
/////////////////////////////////////
// @mfunc Try to save the file
// @rvalue BOOL | FALSE on error - TRUE on success
//
BOOL CScintillaWnd::SaveFile (
LPCSTR szPath) //@parm filename to save to
{
::ofstream file;
file.open(szPath);
if (file.fail())
{
return FALSE;
}
int buflen = SendMessage(SCI_GETLENGTH)+1; //last NULL
TCHAR *pBuffer = new TCHAR[buflen];
if (pBuffer != NULL)
{
SendMessage(SCI_GETTEXT, buflen,(long)pBuffer);
file.write(pBuffer, buflen-1);
delete [] pBuffer;
}
file << ends;
file.close();
return TRUE;
}
/////////////////////////////////////
// @mfunc Try to find format for lexer by looking at the file extension.<nl>
// See global arrays at top of file.
// @rvalue int | Scintilla integer format for lexer
//
int CScintillaWnd::GetFormatFromExtension (
LPCSTR szExtension) //@parm filename extension without dot e.g. "cpp"
{
int i = 0;
TCHAR *pExtension = szExtensions[i];
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -