// =========================================================================
//       LEdit wrapper for Microsoft MFC 2.5 & 3.0 (16-/32-bit Windows)
//       ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//       Version 2.07
//       (c) 1996-1997 Andrey B. Yastrebov
//       Nobody can modify this file without written permission of author
//
//       Limitations of current version:
//       Summary length of all editing files: min(ca 60M,your memory)
//       Maximum line length: 8K
//
//       This file containts full definitions and documentation on constants
//       and functions needed to deal with LEdit MFC wrapper
//       !!! Many things have different meaning than in stanard "CEdit" !!!
//       ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
//       Windows      is a trademark of Microsoft corp.
//
//       If you have some questions please contact:  xor@aysoft.com
// =========================================================================
//
//   Defines CLEdit classes:
//
//  CWnd ------------------------> CLEdit                                 
//
//  CView -----------------------> CLEditView
//
//  When working with these objects you may use ES_* constants for
//  LEdit styles. See them in file LEDIT.H
//
//  File LEDIT.H also contains description of all structures
//  and options very important while using LEdit.
////////////////////////////////////////////////////////
#pragma pack(1)
#pragma warning ( disable : 4010 )
#include "ledit.h"
#pragma pack()

#ifdef WIN32
#define HUGE_PTR far
#else
#define HUGE_PTR huge
#endif
#if !defined(WM_CTLCOLOR)
#define WM_CTLCOLOR WM_CTLCOLOREDIT
#endif
#if !defined(FP_OFF)
#define FP_OFF(ptr) LOWORD((long)ptr)
#endif
#if !defined(FP_SEG)
#define FP_SEG(ptr) HIWORD((long)ptr)
#endif
/////////////////////////////////////////////////////////////////////////////
// CLEdit window

class CLEdit : public CWnd
{     
protected:
    DECLARE_DYNCREATE(CLEdit)

// Construction
public:
	CLEdit();

// Operations
public:
	 //
	 // Sets font
	 //
	 void SetFont(HFONT font)
		{SendMessage(WM_SETFONT,(WPARAM) font);}
	 void SetFont(LOGFONT& font)
		{SendMessage(EM_SETLOGFONT,0,(LPARAM) &font);}

	 void GetFont(LOGFONT& font)
		{SendMessage(EM_GETLOGFONT,0,(LPARAM) &font);}
	 //
	 // Sets syntax. May be used at any time. See LEDIT.H for
	 // detailed information. Or alternative form as in VBX
	 // or Delphi VCL wrappers may be used with string supplied
	 // to function.
	 //
	 void SetSyntax(SYNTAX far* syntax, int syntaxLength, int flags = 0)
	    {SendMessage(EM_SETSYNTAX,syntaxLength + (flags << 8),
	       (LPARAM) syntax);}
	 void SetSyntax(char far* syntax, int flags = 0);

	 //******* The following functions constitute syntax parser ************

	 //
	 // Starts parsing process and move pointer position (PP) to the
	 // beginning of the text
	 //
	 void SetScan()
		{SendMessage(EM_SETSCAN);}

	 //
	 // Retrieves current word from PP and move PP to the end of it.
	 // Return status of the operation
	 //
	 int GetWord(WORDDESC& wordDesc, BOOL skipLines = TRUE)
		{return LOWORD(SendMessage(EM_GETWORD,skipLines,(LPARAM) &wordDesc));}

	 //
	 // Moves PP to the begin of the next line
	 //
	 int NextLine()
		{return LOWORD(SendMessage(EM_NEXTLINE));}

	 //
	 // Gets the rest of line from PP to the next of line. Doesn't
	 // move PP.
	 // In the second form allocates memory using new and pass
	 // returns its address
	 //
	 int GetRestOfLine(char far* buf)
		{return LOWORD(SendMessage(EM_GETRESTOFLINE,0,(LPARAM) buf));}

	 //
	 // Retrieves position of last word read by GetWord() or start of
	 // new line set by NewLine()
	 //
	 int GetScan(LEDITPOSITION& Pos)
		{return LOWORD(SendMessage(EM_GETSCAN,0,(LPARAM) &Pos));}

	 //******* End of syntax parser *****************************************

	 //
	 // Retrieves current word from the caret position.
	 // Return status of the operation
	 //
	 int GetCurrentWord(WORDDESC& wordDesc)
		{return LOWORD(SendMessage(EM_GETCURRENTWORD,0,(LPARAM) &wordDesc));}

	 //
	 // Returns number of lines in LEdit
	 //
	 long GetNumLines()
		{return SendMessage(EM_EX_GETLINECOUNT);}
	 long GetLineCount()
	    {return SendMessage(EM_EX_GETLINECOUNT);}

	 //
	 // Returns the length of specified line
	 //
	 long GetLineLength(long lineNumber)
		{return SendMessage(EM_EX_LINELENGTH,0,lineNumber);}

	 //
	 // Returns specified line. Buffer str must be large enough.
	 // Returns the length of the line.
	 //
	 long GetLine(char far* str, long lineNumber)
	   { *(long far*) str = lineNumber;
	     return SendMessage(EM_EX_GETLINE,0,(LPARAM) str);}

     //
     // Returns number of screenlines composing current line
     //
     short GetWrapLineCount(long lineNumber)
       {return LOWORD(SendMessage(EM_GETWRAPLINECOUNT,0,lineNumber));}

     //
     // Returns the length of specified screenline within a line
     //
     long GetWrapLineLength(long lineNumber, short lineSkip)
       {return SendMessage(EM_GETWRAPLINELENGTH,lineSkip,lineNumber);}

     //
     // Returns specified screenline. Buffer str must be large enough.
     //
     long GetWrapLine(char far* str, long lineNumber, short lineSkip)
       { *(long*)str = lineNumber;
         return SendMessage(EM_GETWRAPLINE,lineSkip,(LPARAM) str);}

	 //
	 // Returns Selected position
	 //
	 void GetSelection(LEDITPOSITION& Pos)
		{SendMessage(EM_EX_GETSEL,0,(LPARAM) &Pos);}

	 //
	 // Sets selected position
	 //
	 void SetSelection(const LEDITPOSITION& Pos)
		{SendMessage(EM_EX_SETSEL,0,(LPARAM) &Pos);}
	 void SetSelection(long StartLine,short int StartPosition, long EndLine,
		short int EndPosition);

	 //
	 // Returns text length
	 //
	 long GetTextLength()
		{return SendMessage(EM_GETTEXTLENGTH,EMP_ALLTEXT);}

	 //
	 // Returns text
	 //
	 BOOL GetText(char HUGE_PTR* str)
		{return ! SendMessage(EM_GETTEXT,EMP_ALLTEXT,(LPARAM) str);}
	 BOOL GetText(char HUGE_PTR* str, long maxChars)
		{return ( maxChars > GetTextLength()) ? GetText(str) : FALSE; }
	 HANDLE GetText();

	 //
	 // Replaces text
	 //
	 void SetText(const char HUGE_PTR* str)
		{SendMessage(EM_SETTEXT,EMP_ALLTEXT,(LPARAM) str);}
	 void SetText(HANDLE hGlobal);

	 //
	 // Returns Selected text length
	 //
	 long GetSelLength()
		{return SendMessage(EM_GETSELTEXTLENGTH);}

	 //
	 // Returns Selected text
	 //
	 BOOL GetSelText(char HUGE_PTR* str)
		{return ! SendMessage(EM_GETSELTEXT,0,(LPARAM) str);}
	 BOOL GetSelText(char HUGE_PTR* str, long maxChars)
		{return ( maxChars > GetSelLength()) ? GetSelText(str) : FALSE;}
	 HANDLE GetSelText();

	 //
	 // Replaces Selected text
	 //
	 void SetSelText(const char HUGE_PTR* str)
		{SendMessage(EM_EX_REPLACESEL,0,(LPARAM) str);}
	 void SetSelText(HANDLE hGlobal);

	 //
	 // Verifies if the text was modified since last ClearModify()
	 //
	 BOOL IsModified(int flagNumber = 2)
		{return LOWORD(SendMessage(EM_EX_GETMODIFY,flagNumber));}

	 //
	 // Sets or Clears modify flag
	 //
	 void SetModify(int fSetOrClear, int flagNumber = 2)
		{SendMessage(EM_EX_SETMODIFY,fSetOrClear,flagNumber);}

	 //
	 // Clears modify flag
	 //
	 void ClearModify(int flagNumber = 2)
		{SetModify(EMP_CLEAR,flagNumber);}

	 //
	 // Deletes all text
	 //
	 void DeleteText()
		{SendMessage(EM_CLEAR,EMP_ALLTEXT);}

	 //
	 // The same as SetSelText - exists only for compatibility.
	 //
	 void Insert(const char far* str)
		{SetSelText(str);}

	 //
	 // Set number of cahrs equivalent to one tab (1 - 40)
	 //
	 void SetTabStops(int numTabs)
	    {SendMessage(EM_EX_SETTABSTOPS,numTabs);}

	 //
	 // Returns handle of pop-up menu
	 //
	 HMENU GetPopUpMenu()
		{SendMessage(EM_SETRUNTIMEFLAGS,EMP_16_AS32);
		 return (HMENU) SendMessage(EM_EX_GETHANDLE,EMP_32_POPUP);}

	 //
	 // Returns handle of main menu if ES_HASMENU
	 //
	 HMENU GetMenu()                      
		{SendMessage(EM_SETRUNTIMEFLAGS,EMP_16_AS32);
         return (HMENU) SendMessage(EM_EX_GETHANDLE,EMP_32_MENU);}

	 //
	 // Returns number of first visible line
	 //
	 long GetFirstVisibleLine()
		{return SendMessage(EM_EX_GETFIRSTVISIBLELINE);}

	 //
	 // Returns number of leftmost visible position in units that
	 // may be retrieved with GetUnitsHorizontal()
	 //
	 int GetFirstVisiblePos()
		{return LOWORD(SendMessage(EM_GETHORZPOSITION));}

	 //
	 // Gets line height in pixels
	 //
	 int GetUnitsVertical()
		{return HIWORD(SendMessage(EM_GETUNITS));}

	 //
	 // Gets horizontl scrolling unit in pixels
	 //
	 int GetUnitsHorizontal()
		{return LOWORD(SendMessage(EM_GETUNITS));}

	 //
	 // Sets/Clears read-only flag
	 //
	 void SetReadOnly(BOOL readOnly = TRUE)
	   {SendMessage(EM_EX_SETREADONLY,readOnly ? EMP_SET : EMP_CLEAR);}

     //
	 // Sets/Clears ES_HIGHLIGHT flag
	 //
	 void SetHighlight(BOOL highlight = TRUE)
	   {SendMessage(EM_SETHIGHLIGHT, highlight ? EMP_SET : EMP_CLEAR);}
	   
	 //
	 // Sets/Clears ES_TRANSPARENT flag
	 //
	 void SetTransparent(BOOL transparent = TRUE)
	   {SendMessage(EM_SETTRANSPARENT, transparent ? EMP_SET : EMP_CLEAR);}

     //
	 // Sets/Clears WS_HSCROLL and WS_VSCROLL flag
	 //
	 void SetScrollBars(BOOL horzScrollBar, BOOL vertScrollBar);
     void SetHorzScrollBar(BOOL horzSctollBar);
     void SetVertScrollBar(BOOL vertScrollBar);

     //
	 // Sets external spacing in Pixels. Works only when control
     // window is created and allow setting spacing in range 0 - 15
	 //
	 void SetExtraSpacing(short horzSpacing, short vertSpacing);
     void SetExtraHorzSpacing(short horzSpacing);
     void SetExtraVertSpacing(short vertSpacing);

     //
     // Resets file information and sets ES_HASFILE according to hasFile
     // This method doesn't change menu.
     //
     void ResetFileState(BOOL hasFile = TRUE)
       {SendMessage(EM_RESETFILESTATE,
         (hasFile) ? EMP_EMPTYFILE : EMP_NOFILE);}

	 //
	 // Sets insert mode
	 //
#define IM_INSERT    FALSE
#define IM_OVERWRITE TRUE
	 void SetInsertMode(BOOL insertMode = IM_INSERT)
	    {SendMessage(EM_SETINSERTMODE,insertMode);}
	   
	 //
	 // Sets AutoIndent state
	 //
	 void SetAutoIndent(BOOL autoIndent = TRUE)
	    {autoIndent ? SendMessage(EM_SETRUNTIMEFLAGS,EMP_AUTOINDENT)
	     : SendMessage(EM_SETRUNTIMEFLAGS,0,EMP_AUTOINDENT);}

	 //
	 // Sets DefaultSelection State
	 //
	 void SetDefaultSelection(BOOL defaultSelection = TRUE)
   	    {defaultSelection ? SendMessage(EM_SETRUNTIMEFLAGS,EMP_DEFAULTSELECTION)
	     : SendMessage(EM_SETRUNTIMEFLAGS,0,EMP_DEFAULTSELECTION);} 
	     
	 //
	 // Sets WrapKeys State
	 //
	 void SetWrapKeys(BOOL wrapKeys = TRUE)
   	    {wrapKeys ? SendMessage(EM_SETRUNTIMEFLAGS,EMP_WRAPKEYS)
	     : SendMessage(EM_SETRUNTIMEFLAGS,0,EMP_WRAPKEYS);}

 
     //
	 // Sets MultilineItems state
	 //
	 void SetMultilineItems(BOOL multilineItems = TRUE)
	    {multilineItems ? SendMessage(EM_SETRUNTIMEFLAGS,EMP_MULTILINEITEMS)
	     : SendMessage(EM_SETRUNTIMEFLAGS,0,EMP_MULTILINEITEMS);}

     //
	 // Sets MultilineStrings state
	 //
	 void SetMultilineStrings(BOOL multilineStrings = TRUE)
	    {multilineStrings ? SendMessage(EM_SETRUNTIMEFLAGS,EMP_MULTILINESTRINGS)
	     : SendMessage(EM_SETRUNTIMEFLAGS,0,EMP_MULTILINESTRINGS);}
	     
     //
	 // Sets SingleleneStrings state
	 //
	 void SetSinglelineStrings(BOOL singlelineStrings = TRUE)
	    {singlelineStrings ? SendMessage(EM_SETRUNTIMEFLAGS,EMP_SINGLELINESTRINGS)
	     : SendMessage(EM_SETRUNTIMEFLAGS,0,EMP_SINGLELINESTRINGS);}

     //
	 // Sets CurrentWordAsText state
	 //
	 void SetCurrentWordAsText(BOOL currentWordAsText = TRUE)
	    {currentWordAsText ? SendMessage(EM_SETRUNTIMEFLAGS,EMP_CURRENTWORDASTEXT)
	     : SendMessage(EM_SETRUNTIMEFLAGS,0,EMP_CURRENTWORDASTEXT);}

     //
	 // Sets UnixStyleSave state
	 //
	 void SetUnixStyleSave(BOOL unixStyleSave = TRUE)
	    {unixStyleSave ? SendMessage(EM_SETRUNTIMEFLAGS,EMP_UNIXSTYLESAVE)
	     : SendMessage(EM_SETRUNTIMEFLAGS,0,EMP_UNIXSTYLESAVE);}

     //
	 // Sets MacStyleSave state
	 //
	 void SetMacStyleSave(BOOL macStyleSave = TRUE)
   	    {macStyleSave ? SendMessage(EM_SETRUNTIMEFLAGS,EMP_MACSTYLESAVE)
	     : SendMessage(EM_SETRUNTIMEFLAGS,0,EMP_MACSTYLESAVE);}
     
     //
	 // Sets StartInComments flag that forces LEdit to think that
     // there's the line with open comment sign before the text
	 //
	 void SetStartInComments(BOOL startInComments = TRUE)
   	    {startInComments ? SendMessage(EM_SETRUNTIMEFLAGS,EMP_STARTINCOMMENTS)
	     : SendMessage(EM_SETRUNTIMEFLAGS,0,EMP_STARTINCOMMENTS);}

	//
	// Allows or not Print Dialog
	//
	void SetPrintDialog(BOOL printDialog = TRUE)
   	   {printDialog ? SendMessage(EM_SETRUNTIMEFLAGS,0,EMP_NOPRINTDIALOG)
	    : SendMessage(EM_SETRUNTIMEFLAGS,EMP_NOPRINTDIALOG);}

	//
	// Allows or not Print Progress Dialog
	//
	void SetPrintProgress(BOOL printProgress = TRUE)
   	   {printProgress ? SendMessage(EM_SETRUNTIMEFLAGS,0,EMP_NOPRINTPROGRESS)
	    : SendMessage(EM_SETRUNTIMEFLAGS,EMP_NOPRINTPROGRESS);}
	     
    //
    // Sets search flags. See EM_SETFINDFLAGS in LEDIT.H for details
    //
    void SetSearchFlags(long flags = 0)
      {SendMessage(EM_SETFINDFLAGS,0,flags);}

    //
    // Gets search flags.
    //
    long GetSearchFlags()
      {return SendMessage(EM_GETFINDFLAGS);}

    //
    // Sets the string to be found by Find and FindNext methods
    //
    void SetSearchFindText(char far* text)
      {SendMessage(EM_SETFINDTEXT,EMP_FIND,(LPARAM) text);}

    //
    // Gets the string to be found by Find and FindNext methods
    // buffer must be at least 128 bytes
    //
    void GetSearchFindText(char far* buffer)
      {SendMessage(EM_GETFINDTEXT,EMP_FIND,(LPARAM) buffer);}

    //
    // Sets the string to replace matches found in Replace and
    // ReplaceAll methods
    //
    void SetSearchReplaceText(char far* text)
      {SendMessage(EM_SETFINDTEXT,EMP_REPLACE,(LPARAM) text);}

    //
    // Sets the string to replace matches found in Replace and
    // ReplaceAll methods
    // buffer must be at least 128 bytes
    //
    void GetSearchReplaceText(char far* buffer)
      {SendMessage(EM_GETFINDTEXT,EMP_REPLACE,(LPARAM) buffer);}

    //
    // Finds the text specified. Returns 1 if match was found and
    // highlighted. -1 indicates error.
    //
    short Find()
      {return LOWORD(SendMessage(EM_FIND,EMP_FIND));}
    short Find(char far* what)
      {SetSearchFindText(what); return Find();}
    short Find(char far* what, long flags)
      {SetSearchFlags(flags); return Find(what);}
      
    //
	// Finds the text specified. Returns 1 if match was found and
	// highlighted. -1 indicates error. Unlike Find doesn't use
	// current selection, but LEDITPOSITION supplied
	//
	short QuietFind(const LEDITPOSITION& Pos)
	  {return LOWORD(SendMessage(EM_FIND,EMP_FIND,(LPARAM) &Pos));}
	short QuietFind(const LEDITPOSITION& Pos, char far* what)
	  {SetSearchFindText(what); return QuietFind(Pos);}
	short QuietFind(const LEDITPOSITION& Pos, char far* what, long flags)
	  {SetSearchFlags(flags); return QuietFind(Pos, what);}

    //
    // Verifies if currently selected text matches search criteria
    // and then replaces it. Returns 1 if match was found and
    // replaced. -1 indicates error.
    //
    short Replace()
      {return LOWORD(SendMessage(EM_FIND,EMP_REPLACE));}
    short Replace(char far* byWhat)
      {SetSearchReplaceText(byWhat); return Replace();}
    short Replace(char far* what, char far* byWhat)
      {SetSearchFindText(what); return Replace(byWhat);}
    short Replace(char far* byWhat, long flags)
      {SetSearchFlags(flags); return Replace(byWhat);}
    short Replace(char far* what, char far* byWhat, long flags)
      {SetSearchFlags(flags); return Replace(what, byWhat);}

    //
    // Replaces all occurrences of one string by another. Returns
    // number of occurrences replaced. -1 indicates error.
    //
    long ReplaceAll()
      {return SendMessage(EM_FIND,EMP_REPLACEALL);}
    long ReplaceAll(char far* what, char far* byWhat)
      {SetSearchFindText(what); SetSearchReplaceText(byWhat);
        return ReplaceAll();}
    long ReplaceAll(char far* what, char far* byWhat, long flags)
      {SetSearchFlags(flags); return ReplaceAll(what, byWhat);}
    long ReplaceAll(long flags)
      {SetSearchFlags(flags); return ReplaceAll();}
      
    //
    // Draws a page of text to the specified Device Context
    //                                                     
    void DrawPage(HDC hDC, DRAWPAGE far* drawPage)
      {SendMessage(EM_DRAWPAGE,(WPARAM)hDC,(LPARAM) drawPage);}
      
    //
    // Adjusts DrawPage to point to the next page
    //                       
    void NextPage(HDC hDC, DRAWPAGE far* drawPage)
      {SendMessage(EM_NEXTPAGE,(WPARAM)hDC,(LPARAM) drawPage);}

	//
    // Sets dialog locations for LEdit's dialogs. This refers to
	// their left corners. Constants for dialog types are listed in
	// LEDIT.H under EM_SETDIALOGLOCATION message.
	//
	void SetDialogLocation(int dlgType, int x, int y)
	  {SendMessage(EM_SETDIALOGLOCATION,dlgType,MAKELONG(x,y));}

	//
	// Gets dialog locations for LEdit's dialogs. This refers to
	// their left corners. Constants for dialog types are listed in
	// LEDIT.H under EM_SETDIALOGLOCATION message.
	//
	void GetDialogLocation(int dlgType, int &x, int &y);

	//
	// Translates screen coordinates to LEdit's position
	// line receives number of line; pos - position inside
	// line. If operation is set to EMP_TOLEFT returns
	// position to the left of specified location
	//
	void TranslateLocation(int x, int y, long &line, int &pos,
	  int operation = EMP_NEAREST);
	  
	//
	// Translate text position into screen coordinates. Returns
	// TRUE if successfull. Return FALSE if the position
	// specified don't extst or isn't visible
	//
	BOOL GetLocation(long line, int pos, int &x, int &y);

          
    //
    // Sets maximum possible number of bookmarks
    //
    void SetBookmarksMax(short number)
      {SendMessage(EM_SETBMLIMIT,number,0);}

    //
    // Sets bookmark with specified number at specified line
    // Operates only when LEdit window exists. number may be
    // between 0 and 15.
    //
    int SetBookmark(int number, int line)
      {return LOWORD(SendMessage(EM_SETBMLINE,number,line));}
    int SetBookmark(int line)
      {return SetBookmark(0,line);}

    //
    // Retrieves number of line at which bookmark with specified
    // number was set. This number of line may change as user
    // edits text and inserts/removes lines
    //
    long GetBookmarkLine(int number = 0)
      {return SendMessage(EM_GETBMLINE,number);}

    //
    // Set Foreground color to be used to highlight bookmark
    //
    void SetBookmarkForeColor(int number, COLORREF color)
      {SendMessage(EM_SETBMATTRIBUTES,number +
        ((EMP_SETTEXTCOLOR | EMP_STARTTEXTCOLOR) << 8),color);}
    void SetBookmarkForeColor(COLORREF color)
       {SetBookmarkForeColor(0,color);}

     //
     // Stops Foreground highlight of specified bookmark
     //
     void RemoveBookmarkForeColor(int number = 0)
        {SendMessage(EM_SETBMATTRIBUTES,number+(EMP_STOPTEXTCOLOR << 8));}

     //
     // Set Background color to be used to highlight bookmark
     //
     void SetBookmarkBackColor(int number, COLORREF color)
        {SendMessage(EM_SETBMATTRIBUTES,number +
          ((EMP_SETBKCOLOR | EMP_STARTBKCOLOR) << 8),color);}
     void SetBookmarkBackColor(COLORREF color)
        {SetBookmarkBackColor(0,color);}

     //
     // Stops Foreground highlight of specified bookmark
     //
     void RemoveBookmarkBackColor(int number = 0)
       {SendMessage(EM_SETBMATTRIBUTES,number+(EMP_STOPBKCOLOR << 8));}

	 //
	 // Gets maximum possible depth of Undo. Works only
	 // when window exists
	 //
	 int GetUndoMaxBuffer()
		{return LOWORD(SendMessage(EM_GETMAXUNDOBUFFER));}

	 //
	 // Sets the depth of undo. -1 means maximum possible depth
	 //
	 void SetUndoDepth(int undoDepth = -1)
		 {SendMessage(EM_SETUNDOPARAM,(undoDepth == -1)?
	         GetUndoMaxBuffer() : undoDepth);}
	 
	 //
     // Scrolls the control vertically. line becomes first visible
     // line and "skip" screenlines of it are left above screen
     //
     void ScrollVertically(long line, short skip)
       {SendMessage(EM_SCROLLVERTICALLY,skip,line);}

     //
     // Scrolls LEdit horizontally.
     //
     void ScrollHorizontally(short pos)
       {SendMessage(EM_SCROLLHORIZONTALLY,pos);}

     //
     // Return the number of invisible screenlines belonging to
     // the topmost visible line
     //
     short GetSkip()
       {return LOWORD(SendMessage(EM_GETSKIP));} 
       
     //
     // These two functions make sense only from within
     // ControlHighlight and return number of line and
     // position of the word being highlighted respectively
     //
     long HighlightedLine()
       {return SendMessage(EM_HIGHLIGHTEDLINE);}
     short HighlightedPos()
       {return LOWORD(SendMessage(EM_HIGHLIGHTEDPOS));}
       
     //
     // Return number of page being printed or zero
     //
     short PrintedPageNum()
       {return LOWORD(SendMessage(EM_PRINTEDPAGE));} 
       
     //
     // Sets Width of the caret
	 //
	 void SetCaretWidth(short caretWidth = 0)
	   {SendMessage(EM_SETCARETWIDTH,caretWidth);}

     //
     // Sets Word Wrap and its attributes. active means that words
     // will be wrapped, automatic means that WordBreakProc() won't
     // be called, width specifies a width, zero stands for window
     // width.
     //
     void SetWordWrap(BOOL active = TRUE, BOOL automatic = TRUE,
       short width = 0);


	 //
	 // Fill in the control with text from file
	 //
	 BOOL LoadFromFile(const char far* fileName)
		{return !LOWORD(SendMessage(EM_SETTEXTFROMFILE,0,(LPARAM) fileName));}
    
	 //
	 // Stores control containt into the file
	 //
	 BOOL StoreToFile(const char far* fileName)
		{return !LOWORD(SendMessage(EM_GETTEXTTOFILE,0,(LPARAM) fileName));}
      
     //
     // Takes one of EC_* constants and determines whether the command
     // may be executed. 
     // 
     BOOL CanExecute(WORD commandId)
       {return LOWORD(SendMessage(EM_CANEXECUTECOMMAND,commandId));}

#define MENU_COMMAND(MC_fn,MC_cmd) \
	  void MC_fn() {SendMessage(WM_COMMAND,MC_cmd);}
	
	 //
	 // Edit operations
	 //
	 BOOL CanUndo()
		{return LOWORD(SendMessage(EM_EX_CANUNDO,EMP_UNDO));}
	 BOOL CanRedo()
		{return LOWORD(SendMessage(EM_EX_CANUNDO,EMP_REDO));}
	 BOOL IsSelection();

	 void Undo()
		{SendMessage(EM_EX_UNDO,EMP_UNDO);}
	 void Redo()
		{SendMessage(EM_EX_UNDO,EMP_REDO);}
	 void Cut()
		{SendMessage(WM_CUT);}
	 void Copy()
		{SendMessage(WM_COPY);}
	 void Paste()
		{SendMessage(WM_PASTE);}
	 MENU_COMMAND(Duplicate,EC_EDITDUPLICATE)
	 void DeleteSelection()
		{SendMessage(EM_CLEAR,EMP_SELECTION);}
	 MENU_COMMAND(SelectAll,EC_EDITSELECTALL)

	 //
	 // Search operations
	 //
	 BOOL CanFindNext()
		{return LOWORD(SendMessage(EM_CANFINDNEXT));}

	 MENU_COMMAND(ShowFindDialog,EC_SEARCHFIND)
	 MENU_COMMAND(FindNext,EC_SEARCHNEXT)
	 MENU_COMMAND(ShowReplaceDialog,EC_SEARCHREPLACE)
	 MENU_COMMAND(FindBrace,EC_SEARCHBRACE)
	 MENU_COMMAND(ShowGotoLineDialog,EC_SEARCHLINE)
	 MENU_COMMAND(FindBookmark,EC_SEARCHBOOKMARK)
	 MENU_COMMAND(SetBookmark,EC_SEARCHSETBOOKMARK)

	 //
	 // Tools operations
	 //
	 MENU_COMMAND(ShowFontDialog,EC_TOOLSCHANGEFONT)
	 void EmptyUndoBuffer()
		{SendMessage(EM_EX_EMPTYUNDOBUFFER);}
	 void Clear()
		{SendMessage(WM_CLEAR,EMP_ALLTEXT);}

	 //
	 // Return TRUE if this is LEditWindow
	 //
	 BOOL IsLEdit()
		{return (SendMessage(EM_ISLEDITWINDOW,0,543210L) == 543211L);}

	 // Returns file name. Buffer fileName must be large enough.
	 // Returns the length of the line.
	 //
	 long GetFileName(char far* fileName)
		{return SendMessage(EM_GETFILENAME,0,(LPARAM) fileName);}

	 //
	 // Sets File Mask/Filter (see EM_SETFILEMASK)
	 //
	 void SetFileMask(char far* fileMask)
	   {SendMessage(EM_SETFILEFILTER,0, (LPARAM) fileMask);}

	 //
	 // File operations
	 //
	 MENU_COMMAND(NewFile,EC_FILENEW)
	 MENU_COMMAND(OpenFile,EC_FILEOPEN)
	 MENU_COMMAND(ReloadFile,EC_FILEREOPEN)
	 MENU_COMMAND(SaveFile,EC_FILESAVE)
	 MENU_COMMAND(SaveFileAs,EC_FILESAVEAS)
	 MENU_COMMAND(Print,EC_FILEPRINT)
	 MENU_COMMAND(PrinterSetup,EC_FILEPRINTERSETUP)

    // Overrides
	// ClassWizard generated virtual function overrides
	//{{AFX_VIRTUAL(CLEdit)
	//}}AFX_VIRTUAL

// Implementation
public:
	virtual ~CLEdit();
    virtual BOOL Create(DWORD dwStyle, const RECT& rect, 
        CWnd* pParentWnd, UINT nID);

protected:
    WNDPROC* GetSuperWndProcAddr();

	//{{AFX_MSG(CLEdit)
		// NOTE - the ClassWizard will add and remove member functions here.
	//}}AFX_MSG
	DECLARE_MESSAGE_MAP()
};

/////////////////////////////////////////////////////////////////////////////

/////////////////////////////////////////////////////////////////////////////
// CLEditView view

class CLEditView : public CView
{
public:
	CLEditView(); // Constructor made public in V2.00

protected:
	DECLARE_DYNCREATE(CLEditView)
    static const DWORD dwStyleDefault;
    
// Attributes
public:                             
    // Color sheme
    COLORREF m_clrBackColor;
    COLORREF m_clrForeColor;
    COLORREF m_clrBackColorSelected;
    COLORREF m_clrForeColorSelected;
    COLORREF m_clrBackColorPrint;
    
    // Mode of behind text drawing
    BOOL m_bUseMemoryDC;

	// CLEdit control access
	CLEdit& GetLEditCtrl() const;

// Public access
public:

// Overrideables
protected:    

   // Command handlers
   virtual LRESULT WindowProc(UINT message, WPARAM wParam, LPARAM lParam);
   virtual BOOL OnCmdMsg(UINT nID, int nCode, void* pExtra,
        AFX_CMDHANDLERINFO* pHandlerInfo);

   // EVENTS  
   
   // Handles drawing behind the text. Needs ES_TRANSPARENT
   virtual void OnDrawBehind(CDC* pDC);                    
   
   // Handles highlight of every single word. Needs ES_HIGHLIGHT
   virtual void OnControlHighlight(WORDDESC& WD, CDC* pDC);     
   
   // Handles looking for brace.
   virtual short OnFindBrace(WORDDESC& WD);
   
   // Handles double-clicking over every word.
   virtual short OnWordClick(WORDDESC& WD);            
   
   // Handling printing footers/headers.
   virtual unsigned long OnPrint(CDC* pDC, short wWidth, short wHeight);

   // Handles EM_NOTIFYFOUND, is fired every time LEdit
   // is about to show message box about search results
   virtual short OnNotifyFound(long Code);
   
   // Word breaking procedure. Should return an offset within
   // lpszLine where to break it (no later than at wMaxPos)
   virtual short WordBreakProc(const char far* lpszLine, short wMaxPos);
   
   // Fired to allow preview buffer read from file. Buffer can
   // be changed, but size cannot.
   virtual void OnReadPreview(const char far* lpszBuffer, short wLength);
   
   // Any changes including caret movement               
   virtual void OnChange();
   
   // Scrolling
   virtual void OnHorzScroll();
   virtual void OnVertScroll(); 
   
   // Loading new file
   virtual void OnNewFile();
   
   // Loading new font
   virtual void OnNewFont();
   
   // Changing insertion mode
   virtual void OnChangeMode();
   
   // Closing file. Default implementation checks whether it's modified
   virtual short OnGoingToClose();
   
   // Should fire dialog about saving file
   virtual short OnAskIfStoreFile();
   
   // Different kinds of Errors
   virtual short OnFileError();
   virtual short OnClipboardError();
   virtual short OnMaxText();
   virtual short OnSpaceError();

// Implementation
public:
	virtual ~CLEditView();

	virtual void OnDraw(CDC* pDC);
	virtual void Serialize(CArchive& ar);
    virtual void SerializeRaw(CArchive& ar);
	virtual void DeleteContents();
	void ReadFromArchive(CArchive& ar, DWORD dwLen);
	void WriteToArchive(CArchive& ar);

protected:
	// construction
	WNDPROC* GetSuperWndProcAddr();
	virtual BOOL PreCreateWindow(CREATESTRUCT& cs);

	//{{AFX_MSG(CLEditView)
		// NOTE - the ClassWizard will add and remove member functions here.
	afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
    afx_msg HBRUSH OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor);
    afx_msg LRESULT OnEmCtlColor(WPARAM wp, LPARAM lp);
    afx_msg LRESULT OnEmCtlColorEx(WPARAM wp, LPARAM lp);
    afx_msg LRESULT OnEmDraw(WPARAM wp, LPARAM lp);
    afx_msg LRESULT OnEmFindBrace(WPARAM wp, LPARAM lp);
    afx_msg LRESULT OnEmWordClick(WPARAM wp, LPARAM lp);
    afx_msg LRESULT OnEmPrint(WPARAM wp, LPARAM lp);
    afx_msg LRESULT OnEmWordWrap(WPARAM wp, LPARAM lp);
	afx_msg LRESULT OnEmNotifyFound(WPARAM wp, LPARAM lp); 
	afx_msg LRESULT OnEmPrintJobName(WPARAM wp, LPARAM lp);
	afx_msg LRESULT OnEmReadPreview(WPARAM wp, LPARAM lp);
	afx_msg void OnPaint();
	//}}AFX_MSG
	DECLARE_MESSAGE_MAP()
};
	
/////////////////////////////////////////////////////////////////////////////
inline CLEdit& CLEditView::GetLEditCtrl() const
        { return *(CLEdit*)this; }
