|
Please hold your breadth. In case you do not know, software is engineering the Engineers choose the tools that can do the job. If the so-called CRichEditView can do the job, Microsoft would have used it too in the Visual Studio editor.
Best regards,
Paul.
Paul Selormey, Bsc (Elect Eng), MSc (Mobile Communication) is currently Windows open source developer in Japan, and open for programming contract anywhere!
|
|
|
|
|
What a stupid comments! I meant really stupid. Look Andrei, you just opened up a way of writing a syntax editor that uses our own implementation of data structure (I haven't found anyone has even written just a text editor that uses owner data). Edmond, you can rely on the GetWindowText in the CWnd; but others want more control. I also read someone was asking about .NET style editor and Andrei has shown it the way.;P
Gali
|
|
|
|
|
I would say the opposite : AWESOME JOB !
Philippe
|
|
|
|
|
I cant get the ln, col display to work in my mdi application, can you help me please (I am using CRichEditView). It starts off at 0, the when i type one character, it changes, to Ln 1, Col 1, but then does not change even if I make a new document.
==================================================
The Eclypse
|
|
|
|
|
hi dear i also have the same problem
can any body help out
jits
jitender
|
|
|
|
|
Hi,
I would want to know, if it would be possible to have syntax coloring for other scripting languages, like javascript, vbscript. I understand there is a function that should be overridden for this purpose. In anycase, I just wanted to know whether syntax coloring is possible for other languages.
I would be grateful, if you can provide me with some info' on this.
thanks.
Cheers
kannan
|
|
|
|
|
What I have to say here may be for expert users very obvious, but I lost
a bit of time about solving this problem
I was wondering how to insert the editres.rc resource in the project
(in external dependencies).
Simply look at the file Sample.rc2, you will see
#include "editres.rc"
Follow this instruction.
jlouis
|
|
|
|
|
I would truely like to see this in a CE port..I've been working on porting it but the fix font proves to be troublesome. Has anybody been successful with this?...it does work after removing the drag and drop (OLE) and printing capabilities.
-Blair
|
|
|
|
|
Hi,
Are these the latest sources, they don't seem very up to date, also is there an HTML parser available for download.
Thanks
George
|
|
|
|
|
See the post about TextCenter (http://www.egroups.com/group/textcenter).
-=- James.
|
|
|
|
|
When I used Select All in a large file (23000 lines), not everything was invalidated correctly, causing only the current line to be redrawn. I think this is because some MFC code doesn't support int, but only short.
|
|
|
|
|
I use sticky keys (e.g. the ["] char, the ['] char, the [`] char and the [^] char) these keys can be used in combination with other keys such as the "e", so when typing ["] and [e] I get ë. It works in any application and in any view except yours, I get the most ugly errors, really try it yourself.
CString Dutch = "Double Dutch";
|
|
|
|
|
Hello,
I try to expand the "CArray m_aLines" of CrystalEditor for the buffer of a file to a "Carray m_aFiles" for a group of files.
So, I define the following elements:
struct SLineInfo
{ ...
};
struct SFileInfo
{
LPCTSTR FileName;
CArray<slineinfo,slineinfo&> m_aLines;
SFileInfo() { memset(this, 0, sizeof(SFileInfo));};
}
CArray<sfileinfo,sfileinfo&> m_aFiles;
Then, I try to create a SFileInfo in m_aFile.
SFileInfo fi;
m_aFiles.Add(fi);
But, the compilator refuse "m_aFiles.Add(fi);" !
Moreover, the compilator accept the following instructions:
SLineInfo li;
Carray<slineinfo,slineinfo&> T;
T.add(li);
So, Can you help me to solve the problem ? I think it's possible the fact I use a Carray with a struct of struct.
Thank you,
Franck
|
|
|
|
|
Hi Franck,
unfortunately, I did not revisit the sources, but perhaps the SLineInfo struct has a copy or a = operator, while SFileInfo has not. Therefore, you can do an array of SLineInfo per reference (the CArray will call the = operator), but it refuses CFileInfo.
HTH,
Thomas
|
|
|
|
|
Hi
Can you help me to understand the mean of the following instruction "AFX_ZERO_INIT_OBJECT(CView)" in the constructor of the class CCrystalTextView ?
Thanks you, Franck
|
|
|
|
|
It is another MFC macro to initialize base class.
If you want to really know what it is, take look at in afx.h file in MFC include.
|
|
|
|
|
After a long wait a preview of the upcoming update, with a fork name TextCenter, is now available. To participate in the events, please join the mailing list at
http://groups.yahoo.com/group/textcenter
Best regards,
Paul.
|
|
|
|
|
Crystal edit is great. One of the problems that I have is with the behavior of the undo feature.
The code in CCrystalEditView::OnChar goes like this:
if (nChar > 31)
{
if (QueryEditable() && m_pTextBuffer != NULL)
{
m_pTextBuffer->BeginUndoGroup(nChar != _T(' ') );
// code goes on....
}
}
This above code causes any space anywhere to create a new undo group, and
sometimes causes an undesireable undo mechanism. For example,
I move down three lines and type somehairycpluspluscode without any spaces,
the text that I typed was merged with my previous action, which
was three lines up and a separate thought/operation, if I undo at that
point I wipe them both out. Here is a proposed solution to this problem.
Forgive me for making this confusing, as it is a confusing theory.
First declare the variable's
CPoint m_ptLastCharAt and
int m_nLastChar
int the CCrystalEditView.h file
at public scope, this variable will hold the last cursor position, and last key pressed.
Next we need to track the last character position by changing all instances
of cursor movement to update this variable.
in the constructor of CCrystalEditView:
m_ptLastCharAt = CPoint(0,0)
in the Paste, Cut, OnEditTab, and OnEditUnTab of CCrystalEditView:
m_ptLastCharAt.y = -1 // this will force a new undo group to be created.
the OnChar code above should be changed:
// check to see if we hit an alpha numeric key and we're in the same word
// as previously in, or merge non-alpha with non-alpha if we're in the same edit position
if (nChar > 31)
{
if (QueryEditable() && m_pTextBuffer != NULL)
{
BOOL bIsAl =isalnum(nChar);
BOOL bWasAl=isalnum(m_nLastChar);
if((bIsAl && m_ptLastCharAt.x == ptSelEnd.x &&
m_ptLastCharAt.y == ptSelEnd.y && bWasAl) ||
(!bIsAl && m_ptLastCharAt.x == ptSelEnd.x &&
m_ptLastCharAt.y == ptSelEnd.y && !bWasAl) )
m_pTextBuffer->BeginUndoGroup(TRUE);
else
m_pTextBuffer->BeginUndoGroup(FALSE);
// code goes on....
// now update the last position
m_ptLastCharAt = ptCursorPos;
// and update the last character pressed
m_nLastChar=nChar;
}
I've found this method to be a more desirable way of determining when to begin
an undo group. Anyway, that's my 2 cents
|
|
|
|
|
Hello Ted,
First of all thanks for the contribution. I verified your claim and it is true. I applied your patches and it works now correctly.
1. The position of the codes with relation to the line
if (QueryEditable() && m_pTextBuffer != NULL)
is misleading since the if() uses ptSelEnd which is defined later.
2. What is your suggestion for initialization of the m_nLastChar in the constructor? zero (0)?
3. Any reason for requesting a public access to the data members you declared?
4. Does it matter where in the methods the ff. suggested line is added
in the Paste, Cut, OnEditTab, and OnEditUnTab of CCrystalEditView:
m_ptLastCharAt.y = -1
5. Can you provide your full name so that I could add you to the list of bug fixers? You can send it to me directly if you do not want it displayed here.
Best regards,
Paul.
|
|
|
|
|
1.) Yes I moved the definition of ptSelEnd and ptSelStart as follows
if (QueryEditable() && m_pTextBuffer != NULL)
{
CPoint ptSelStart, ptSelEnd;
GetSelection(ptSelStart, ptSelEnd);
CPoint ptCursorPos;
///my check for isalnum and ugly if statment here
}
2.) I initialized m_nLastChar to -99 so that it will never be true on the first
call.
3.) No reason for public access to this variable, unless a subclass needs it. In
my case it did.
4.) I should have placed the specifics on this one.
The paste routine checks
if (! QueryEditable())
return;
if (m_pTextBuffer == NULL)
return;
// i put my code here
m_ptLastCharAt.y=-1; // force a new undo group on next char pressed;
The cut routine checks
if (! QueryEditable())
return;
if (m_pTextBuffer == NULL)
return;
if (! IsSelection())
return;
// i put my code here
m_ptLastCharAt.y=-1; // force a new undo group on next char pressed;
The OnEditTab and OnEditUnTab routine's code
//.. code
if (bTabify)
{
// i put my code here
m_ptLastCharAt.y=-1; // force a new undo group on next char pressed;
}
5.) No problem, I fully support the enhancement of this editor. My full name is
Ted Maylar, and my email address is TedMaylar@hotmail.com
|
|
|
|
|
// Implementation of the ParseLine() virtual function for Visual C++ highlighting
//
// Author: Egipko Nikolay
// E-mail: Egipko@Artis-Inventum.de
//
////////////////////////////////////////////////////////////////////////////
// Description: Some months ago I have written own realization ParseLine()
// function for C++ highlighting. On my opinion this realization is little
// bit better than existing in CrystalEditor. In this code I wanted to realize
// the greatest conformity with Visual C++ text editor highlighting.
//
// I also have the modified code of the editor supporting concept
// of the VirtualSpace (see Visual C++ Options/Compatibility - "Enable virtual space").
// Unfortunately, the changes were rather difficult and I can't here
// them describe.
// Visual C++ highlighting implementation:
// First: define color enums and C++ keywords
enum
{
// Base colors
COLORINDEX_WHITESPACE = 0,
COLORINDEX_BKGND,
COLORINDEX_NORMALTEXT,
COLORINDEX_SELMARGIN,
COLORINDEX_SELBKGND,
COLORINDEX_SELTEXT,
// Syntax colors
COLORINDEX_KEYWORD,
COLORINDEX_OPERATOR,
COLORINDEX_COMMENT,
COLORINDEX_NUMBER,
COLORINDEX_STRING,
COLORINDEX_PREPROCESSOR,
COLORINDEX_VARIABLE,
// Compiler/debugger colors
COLORINDEX_ERRORBKGND,
COLORINDEX_ERRORTEXT,
COLORINDEX_EXECUTIONBKGND,
COLORINDEX_EXECUTIONTEXT,
COLORINDEX_BREAKPOINTBKGND,
COLORINDEX_BREAKPOINTTEXT,
// ...
// Expandable: custom elements are allowed.
COLORINDEX_LASTINDEX,
};
// C++ keywords (MSVC6.0)
static LPTSTR s_apszCppKeywordList[] =
{
_T("__asm"),
_T("__assume"),
_T("auto"),
_T("__based"),
_T("bool"),
_T("break"),
_T("case"),
_T("catch"),
_T("__cdecl"),
_T("char"),
_T("class"),
_T("const"),
_T("const_cast"),
_T("continue"),
_T("__declspec"),
_T("default"),
_T("delete"),
_T("dllexport"),
_T("dllimport"),
_T("do"),
_T("double"),
_T("dynamic_cast"),
_T("else"),
_T("enum"),
_T("__except"),
_T("explicit"),
_T("extern"),
_T("false"),
_T("__fastcall"),
_T("__finally"),
_T("float"),
_T("for"),
_T("friend"),
_T("goto"),
_T("if"),
_T("inline"),
_T("__inline"),
_T("int"),
_T("__int8"),
_T("__int16"),
_T("__int32"),
_T("__int64"),
_T("interface"),
_T("__leave"),
_T("long"),
_T("main"),
_T("__multiple_inheritance"),
_T("__single_inheritance"),
_T("__virtual_inheritance"),
_T("mutable"),
_T("naked"),
_T("namespace"),
_T("new"),
_T("noreturn"),
_T("operator"),
_T("private"),
_T("protected"),
_T("public"),
_T("register"),
_T("reinterpret_cast"),
_T("return"),
_T("short"),
_T("signed"),
_T("sizeof"),
_T("static"),
_T("static_cast"),
_T("__stdcall"),
_T("struct"),
_T("switch"),
_T("template"),
_T("this"),
_T("thread"),
_T("throw"),
_T("true"),
_T("try"),
_T("__try"),
_T("typedef"),
_T("typeid"),
_T("typename"),
_T("union"),
_T("unsigned"),
_T("using"),
_T("uuid"),
_T("__uuidof"),
_T("virtual"),
_T("void"),
_T("volatile"),
_T("wmain"),
_T("while"),
NULL
};
#define PPD_PRAGMA_INDEX 0
#define PPD_PRAGMA_IF 1
#define PPD_PRAGMA_ELIF 2
#define PPD_INCLUDE_BRACKETS 3
// C++ preprocessor directives (MSVC6.0)
static LPTSTR s_apszPPDirective[] =
{
// preprocessor specific keywords must be first
// Indexes see above
_T("pragma"),
_T("if"),
_T("elif"),
_T("include"),
// preprocessor keywords
_T("define"),
_T("else"),
_T("endif"),
_T("error"),
_T("ifdef"),
_T("ifndef"),
_T("import"),
_T("line"),
_T("undef"),
NULL,
};
static LPTSTR s_apszPPDirective_pragma[] =
{
_T("alloc_text"),
_T("auto_inline"),
_T("bss_seg"),
_T("check_stack"),
_T("code_seg"),
_T("comment"),
_T("component"),
_T("const_seg"),
_T("data_seg"),
_T("function"),
_T("hdrstop"),
_T("include_alias"),
_T("init_seg"),
_T("inline_depth"),
_T("inline_recursion"),
_T("intrinsic"),
_T("message"),
_T("once"),
_T("optimize"),
_T("pack"),
_T("pointers_to_members"),
_T("setlocale"),
_T("vtordisp"),
_T("warning"),
_T("on"),
_T("off"),
_T("pop"),
_T("push"),
_T("disable"),
_T("error"),
NULL,
};
// Second: implement custom GetColor() function
COLORREF CMyCrystalEditView::GetColor(int nColorIndex)
{
switch (nColorIndex)
{
// Basic color
case COLORINDEX_WHITESPACE:
case COLORINDEX_BKGND:
return ::GetSysColor(COLOR_WINDOW);
case COLORINDEX_NORMALTEXT:
return ::GetSysColor(COLOR_WINDOWTEXT);
case COLORINDEX_SELMARGIN:
return ::GetSysColor(COLOR_SCROLLBAR);
case COLORINDEX_SELBKGND:
return RGB(0, 0, 0);
case COLORINDEX_SELTEXT:
return RGB(255, 255, 0);
// Syntax colors
case COLORINDEX_KEYWORD:
return RGB(0, 0, 255);
case COLORINDEX_OPERATOR:
return RGB(0, 0, 128);
case COLORINDEX_COMMENT:
return RGB(0, 128, 0);
case COLORINDEX_NUMBER:
return RGB(128, 0, 128);
case COLORINDEX_STRING:
return RGB(255, 0, 0);
case COLORINDEX_PREPROCESSOR:
return RGB(0, 0, 255);
case COLORINDEX_VARIABLE:
return RGB(0, 0, 0);
// Compiler/debugger colors
// None... (expandable: custom elements are allowed)
}
return RGB(255, 0, 0);
}
// Third: implement helper functions, classes and ParseLine()
class CMapKeywords : public CMapStringToPtr
{
public:
CMapKeywords() : CMapStringToPtr()
{
Init();
};
void Init()
{
for (int L = 0; s_apszCppKeywordList[L] != NULL; L ++)
SetAt(s_apszCppKeywordList[L], s_apszCppKeywordList[L]);
};
inline BOOL IsKeyword(LPCSTR sKeyword)
{
static LPCSTR str;
return Lookup(sKeyword, (void*&)str);
};
} g_MapKeywords;
class CMapPPD_pragma : public CMapStringToPtr
{
public:
CMapPPD_pragma() : CMapStringToPtr()
{
Init();
};
void Init()
{
for (int L = 0; s_apszPPDirective_pragma[L] != NULL; L ++)
SetAt(s_apszPPDirective_pragma[L], s_apszPPDirective_pragma[L]);
};
inline BOOL IsKeyword(LPCSTR sKeyword)
{
static LPCSTR str;
return Lookup(sKeyword, (void*&)str);
};
} g_MapPPD_pragma;
static LPTSTR s_apszPPDirective_if_elif[] =
{
_T("defined"),
NULL,
};
static BOOL IsCppKeyword(LPCTSTR pszChars, int nLength, int nIndexPPD)
{
// Base list
static CHAR chBuff[255];
strncpy(chBuff, pszChars, nLength);
chBuff[nLength] = 0;
if(g_MapKeywords.IsKeyword(chBuff))
return TRUE;
// Preprocessor specific
if (nIndexPPD == PPD_PRAGMA_INDEX)
{
if (g_MapPPD_pragma.IsKeyword(chBuff))
return TRUE;
}
if (nIndexPPD == PPD_PRAGMA_IF || nIndexPPD == PPD_PRAGMA_ELIF)
for (int L = 0; s_apszPPDirective_if_elif[L] != NULL; L ++)
{
if (strncmp(s_apszPPDirective_if_elif[L], pszChars, nLength) == 0
&& s_apszPPDirective_if_elif[L][nLength] == 0)
return TRUE;
}
return FALSE;
}
static BOOL IsCppNumber(LPCTSTR pszChars, int nLength)
{
if ( isdigit(pszChars[0])
|| (nLength >= 2 && pszChars[0] == '.' && isdigit(pszChars[1])))
return TRUE;
return FALSE;
}
static int IsPPDirective(LPCTSTR pszChars, int nLength)
{
// skip leading spaces
for(int S = 0; S < nLength && isspace(pszChars[S]); S ++);
// find preprocessor directive
for (int L = 0; s_apszPPDirective[L] != NULL; L ++)
{
if (strncmp(s_apszPPDirective[L], pszChars + S, nLength - S) == 0
&& s_apszPPDirective[L][nLength - S] == 0)
return L;
}
return -1;
}
#define DEFINE_BLOCK(pos, colorindex)\
ASSERT((pos) >= 0 && (pos) <= nLength);\
if (pBuf != NULL)\
{\
if (nActualItems == 0 || pBuf[nActualItems - 1].m_nCharPos <= (pos)){\
pBuf[nActualItems].m_nCharPos = (pos);\
pBuf[nActualItems].m_nColorIndex = (colorindex);\
nActualItems ++;}\
}
#define COOKIE_COMMENT 0x0001
#define COOKIE_PREPROCESSOR 0x0002
#define CO
|
|
|
|
|
To implement search for matching brace (VC++ style), add a command handler for CCrystalTextView::OnEditFindBrace() and insert the following three new functions:
void CCrystalTextView::OnEditFindBrace()
{
// TODO: Add your command handler code here
char cTarget = '\0'; // One of {}()[]
CString text;
int Direction; // +1: forward, -1: Backward, 0: No brace
CPoint pStart; // Row & column position of target character (1 based)
if (IsSelection())
{ // Take the current selection, if any
CPoint ptSelStart, ptSelEnd;
GetSelection(ptSelStart, ptSelEnd);
if(ptSelStart.y == ptSelEnd.y)
{
GetText(ptSelStart, ptSelEnd, text);
cTarget = text[0];
pStart = ptSelStart; // Place left of character
if(Direction = BraceDirection(cTarget, pStart)) {
FindClosingBrace(cTarget, Direction, pStart);
return;
}
}
}
// Character right of cursor. First priority
if(m_ptCursorPos.x < GetLineLength(m_ptCursorPos.y)) {
GetText(m_ptCursorPos, CPoint(m_ptCursorPos.x+1, m_ptCursorPos.y), text);
if(text.GetLength()) {
cTarget = text[0];
pStart = m_ptCursorPos;
if(Direction = BraceDirection(cTarget, pStart)) {
FindClosingBrace(cTarget, Direction, pStart);
return;
}
}
}
// Search left of cursor
if(m_ptCursorPos.x == 0) return;
// Place left of character
pStart.x = m_ptCursorPos.x-1;
pStart.y = m_ptCursorPos.y;
GetText(pStart, m_ptCursorPos, text);
if(text.GetLength()) {
cTarget = text[0];
if(Direction = BraceDirection(cTarget, pStart)) {
FindClosingBrace(cTarget, Direction, pStart);
return;
}
}
}
int CCrystalTextView::BraceDirection(char cTarget, CPoint &pStart)
{ // Find search direction and adjust starting search position
// pStart = Cursor position (0 based) at left of target character
// Input: pStart must contain the 0-based indices of target character
int nChars = GetLineLength(pStart.y); // Number of chars in line
int nLines = GetLineCount(); // Number of lines
// Backward direction
if(cTarget == '}' || cTarget == ')' || cTarget == ']') {
// Is this the first character?
if(pStart.x == 0 && pStart.y == 0) return 0;
return -1;
}
else // Forward search
if(cTarget == '{' || cTarget == '(' || cTarget == '['){
// Is this the last character?
if(pStart.x == nChars-1 && pStart.y == nLines-1) return 0;
return 1;
}
return 0;
}
BOOL CCrystalTextView::FindClosingBrace(char cTarget, int Direction,
const CPoint &ptStartPosition)
{
// cTarget: target brace whose closing brace is to be found
// CPoint* ptStartPosition: x:character index in line, y: line index (both 0-based)
// ptStartPosition already placed beyond the first target character.
int Count = 0; // Target character will start Count at 1
CPoint ptCurrentPos = ptStartPosition;
CPoint ptFoundPos;
char cClosing;
LPCTSTR pStart, pEnd;
if (cTarget == '}') cClosing = '{';
else if (cTarget == '{') cClosing = '}';
else if (cTarget == ')') cClosing = '(';
else if (cTarget == '(') cClosing = ')';
else if (cTarget == '[') cClosing = ']';
else if (cTarget == ']') cClosing = '[';
ASSERT_VALIDTEXTPOS(ptCurrentPos);
if(Direction < 0) { // Search backward
while (ptCurrentPos.y >= 0)
{
if(ptCurrentPos.x < 0) {
if(--ptCurrentPos.y >= 0)
ptCurrentPos.x = GetLineLength(ptCurrentPos.y)-1; // 0 base
continue;
}
pStart = GetLineChars(ptCurrentPos.y);
pEnd = pStart + ptCurrentPos.x;
int nPos = -1, i = ptCurrentPos.x;
while (pEnd >= pStart) {
if(*pEnd == cTarget) Count++;
else
if (*pEnd == cClosing) {
Count--;
if(Count == 0) {
nPos = i;
break;
}
}
i--; pEnd--;
}
if (nPos >= 0) // Found closing brace!
{
ptCurrentPos.x = nPos;
// High light closing brace here
HighlightText(ptCurrentPos,1);
return TRUE;
}
if(--ptCurrentPos.y >= 0)
ptCurrentPos.x = GetLineLength(ptCurrentPos.y)-1; // 0 base
else return FALSE;
}
// Begin of text reached
return FALSE;
}
else
{ // Search forward
while (ptCurrentPos.y <= GetLineCount() - 1)
{
pStart = (pEnd = GetLineChars(ptCurrentPos.y)) + ptCurrentPos.x;
int Len = GetLineLength(ptCurrentPos.y);
if (Len == 0 ) // Empty line
{
ptCurrentPos.x = 0;
ptCurrentPos.y ++;
continue;
}
pEnd += (Len - 1);
// Perform search in the line
int nPos = -1, i = ptCurrentPos.x;
while (pStart <= pEnd) {
if(*pStart == cTarget) Count++;
else
if (*pStart == cClosing) {
Count--;
if(Count == 0) {
nPos = i;
break;
}
}
if(pStart == pEnd) break;
i++; pStart++;
}
if (nPos >= 0) // Found closing brace!
{
ptCurrentPos.x = nPos;
// High light closing brace here
HighlightText(ptCurrentPos,1);
return TRUE;
}
// Go further, text was not found
ptCurrentPos.x = 0;
ptCurrentPos.y ++;
}
// End of text reached
return FALSE;
}
ASSERT(FALSE); // Unreachable
return FALSE;
|
|
|
|
|
Hello,
Nice work. Unfortunately, we have one in the upcoming update codes. But, I will study it to see if this implementation is better or if there is something that can be used from this code.
Sorry, for my inability to release the codes in time, but I am working around the clock to put all in place and release the codes for discussions soon.
Regards,
Paul.
|
|
|
|
|
Run the demo project and enter following line into the view:
dgdfddDGBsrdg{} DGB
Search for the string "DGB" with paramters 'match case' AND 'whole word' set. This will
result in highlighting " DG". Bug.
Andreas
|
|
|
|
|
Good work,
It is really a funny bug. It only happens with three or less characters. With four or more characters no problem
I will take a closer look.
Regards,
Paul.
|
|
|
|
|