RichEdit - speed up coloring

RichEdit - speed up coloring

Postby Antonio Linares » Tue Feb 28, 2012 11:45 am

A few days ago I was reviewing Enrico Maria Giordano's ED source code editor http://www.emagsoftware.it/Ed106.zip. As he explained me:

It is written in C, uses the RICHEDIT control and offers the minimal functionality I need. I can give you the source code if it can be useful for you.


I was interested to review how much functionality RichEdit could offer as a Windows built-in source code editor. I remembered that RichEdit coloring was very slow for large files and that was the main problem about it. So I decided to do some more research about it. First interesting info I found was this one:

http://bcbjournal.org/articles/vol3/9910/Faster_rich_edit_syntax_highlighting.htm

Its author uses C++ Builder and found some ways to speed it up. So I decided to create a plain C language self contained example to test how fast his optimizations are. You can easily build it using Borland C:

go.bat
Code: Select all  Expand view
set path=c:\bcc582\bin
bcc32 -W test.c
if errorlevel 0 test


test.c // RichEdit based editor with automatic syntax highligthing
Code: Select all  Expand view
#include <windows.h>
#include <richedit.h>
#include <stdio.h>

typedef struct
{
   char * txt;
   long len;
   FILE * out;
} COOKIE;

#define CLR_YELLOW  RGB( 255, 255,   0 )
#define CLR_HCYAN   RGB(   0, 255, 255 )
#define CLR_HGREEN  RGB(   0, 255,   0 )
#define CLR_WHITE   RGB( 255, 255, 255 )

void ParseAllText( HWND hRichEdit )
{
   LONG pos = 0, start = 1;
   CHARFORMAT cf;
   TEXTRANGE tr;
   char buffer[ 256 ];
   int eventMask = SendMessage( hRichEdit, EM_SETEVENTMASK, 0, 0 );

   SendMessage( hRichEdit, WM_SETREDRAW, FALSE, 0 );

   memset( &cf, 0, sizeof( cf ) );
   cf.cbSize = sizeof( cf );
   cf.dwMask = CFM_COLOR;
                         
   while( pos != start )
   {
      start = pos;
      pos = SendMessage( hRichEdit, EM_FINDWORDBREAK, WB_MOVEWORDRIGHT, pos );

      SendMessage( hRichEdit, EM_SETSEL, start, pos );

      tr.chrg.cpMin = start;
      tr.chrg.cpMax = pos;
      tr.lpstrText  = buffer; // malloc( pos - start + 1 + 1 );
      SendMessage( hRichEdit, EM_GETTEXTRANGE, 0, ( LPARAM ) &tr );      

      if( strstr( "# define ifdef ifndef endif pragma include ", tr.lpstrText ) )
      {
         cf.crTextColor = CLR_YELLOW;      
         SendMessage( hRichEdit, EM_SETCHARFORMAT, SCF_SELECTION, ( LPARAM ) &cf );
      }  
      else if( strstr( "local static extern public private nil for next if else endif do case endcase ", tr.lpstrText ) )
      {
         cf.crTextColor = CLR_HCYAN;               
         SendMessage( hRichEdit, EM_SETCHARFORMAT, SCF_SELECTION, ( LPARAM ) &cf );
      }  
      else if( strstr( "function CLASS  DATA  INIT METHOD INLINE VIRTUAL SETGET ENDCLASS procedure return ",  tr.lpstrText ) )
      {
         cf.crTextColor = CLR_HGREEN;              
         SendMessage( hRichEdit, EM_SETCHARFORMAT, SCF_SELECTION, ( LPARAM ) &cf );
      }  
      else if( strstr( "= + - ++ -- += -= *= /= / * < > <= >= % $ | ! ^ @ {} {}, { } {| [ ] ]: ( ) (- ), ): ); ),; () (): :: := != == += -= . , ; ,; .,; ",  tr.lpstrText ) )
      {
         cf.crTextColor = CLR_WHITE;               
         SendMessage( hRichEdit, EM_SETCHARFORMAT, SCF_SELECTION, ( LPARAM ) &cf );
      }  
         
      // free( tr.lpstrText );
   }

   SendMessage( hRichEdit, WM_SETREDRAW, TRUE, 0 );
   SendMessage( hRichEdit, EM_SETEVENTMASK, 0, eventMask );
   InvalidateRect( hRichEdit, 0, TRUE );
}  

#pragma argsused

DWORD CALLBACK StreamIn( DWORD dwCookie, LPBYTE pbBuff, LONG cb, LONG FAR *pcb )
{
   COOKIE * Cookie = ( COOKIE * ) dwCookie;

   if( cb > Cookie->len )
      cb = Cookie->len;

   if( cb > 0 )
   {
      memcpy( ( char * ) pbBuff, Cookie -> txt, cb );

      Cookie->txt += cb;
      Cookie->len -= cb;
   }

   * pcb = cb;

   return 0;
}

BOOL LoadText( HWND hRichEdit, const char * FileName )
{
   FILE * in = fopen( FileName, "rb" );
   int len;

   if( ! in )
      return FALSE;

   fseek( in, 0, SEEK_END );
   len = ftell( in );
   fseek( in, 0, SEEK_SET );

   if( len > 0 )
   {
      COOKIE Cookie;
      EDITSTREAM es;
      char * txt = malloc( len + 1 );

      fread( txt, 1, len, in );

      Cookie.txt = txt;
      Cookie.len = len;

      es.dwCookie    = ( DWORD ) &Cookie;
      es.pfnCallback = StreamIn;

      SendMessage( hRichEdit, EM_STREAMIN, SF_TEXT, ( LPARAM ) &es );

      free( txt );
   }

   fclose( in );
   
   return TRUE;
}

LRESULT WINAPI ParentWindowProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam )
{
     static HWND hRichEdit;
   static HFONT hFont;

     switch( msg )
   {
        case WM_CREATE:
               {
                  RECT r;
                  GetClientRect( hWnd, &r );
                  hRichEdit = CreateWindow( "RICHEDIT", "",
                                              WS_CHILD | WS_VISIBLE | WS_VSCROLL | ES_MULTILINE | ES_SUNKEN,
                                              0, 30, r.right - r.left, r.bottom - r.top - 50,
                                              hWnd, NULL, NULL, NULL );
              hFont  = CreateFont( 18, 0, 0, 0, 0, FALSE, FALSE, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH, "Courier New" );
              SendMessage( hRichEdit, WM_SETFONT, ( WPARAM ) hFont, 0 );
                  LoadText( hRichEdit, "window.prg" );
                  SendMessage( hRichEdit, EM_EXLIMITTEXT, 0, 0xFFFFFFF );
              ParseAllText( hRichEdit );
              SetFocus( hRichEdit );
               }  
             break;
       
        case WM_CLOSE:
               DeleteObject( hFont );
               DestroyWindow( hWnd );
               break;
             
        case WM_LBUTTONDOWN:
               break;
             
          case WM_SIZE:
               MoveWindow( hRichEdit, 0, 30, LOWORD( lParam ), HIWORD( lParam ) - 50, FALSE );
               break;  
               
        case WM_DESTROY:
               PostQuitMessage( 0 );
               break;
     }
   
   return DefWindowProc( hWnd, msg, wParam, lParam );
}

int PASCAL WinMain( HINSTANCE hInstance, HINSTANCE prev, LPSTR cmdline, int show )
{
   WNDCLASS cls;
     HWND hWnd;
     MSG msg;
   HINSTANCE hDll = LoadLibrary( "riched32" );

   cls.style         = CS_HREDRAW | CS_VREDRAW | CS_GLOBALCLASS;
   cls.lpfnWndProc   = ParentWindowProc;
   cls.cbClsExtra    = 0;
   cls.cbWndExtra    = 0;
     cls.hInstance     = hInstance;
   cls.hIcon         = LoadIcon( 0, IDI_APPLICATION );
   cls.hCursor       = LoadCursor( 0, IDC_ARROW );
   cls.hbrBackground = GetStockObject( WHITE_BRUSH );
   cls.lpszMenuName  = 0;
   cls.lpszClassName = "parentclass";

   if( ! RegisterClass( &cls ) )
        return FALSE;

   hWnd = CreateWindow( "parentClass", "RichEdit syntax highlight", WS_OVERLAPPEDWINDOW ,
                        100, 100, 1100, 600, 0, NULL, hInstance, 0 );

   ShowWindow( hWnd, SW_MAXIMIZE );
   UpdateWindow( hWnd );

     while( GetMessage( &msg, 0, 0, 0 ) )
     {
        TranslateMessage( &msg );
        DispatchMessage( &msg );
     }

   FreeLibrary( hDll );

     return 0;
}


No Harbour, no FWH, just pure C language speed to test it, but unfortunately still slow for large PRG files. So I decided to keep googling and then found this:

http://win32assembly.online.fr/tut35.html

It may result scaring at a first review as it is developed using assembler (ouch!) :-) but his author had a very interesting concept: to subclass RichEdit and do the coloring himself. Well, I decided to convert it from assembler to C to test it. Some code I implemented it myself, once I understood its purpouse. Here it is:

fresh.c // I thought about this name for a "Free RichEdit Editor Syntax Highlighted" acronym :-)
Code: Select all  Expand view
#pragma resource "fresh.res"

#include <windows.h>
#include <richedit.h>
#include <stdio.h>

typedef struct
{
   DWORD    WordLen;    // the length of the word: used as a quick comparison
     char * pszWord;    // pointer to the word
     COLORREF * pColor; // point to the dword that contains the color used to hilite the word
     void * NextLink;   // point to the next WORDINFO structure
} WORDINFO;

#define IDR_MAINMENU               101
#define IDM_OPEN                 40001
#define IDM_SAVE                 40002
#define IDM_CLOSE                40003
#define IDM_SAVEAS               40004
#define IDM_EXIT                 40005
#define IDM_COPY                 40006
#define IDM_CUT                  40007
#define IDM_PASTE                40008
#define IDM_DELETE               40009
#define IDM_SELECTALL            40010
#define IDM_OPTION                   40011
#define IDM_UNDO                       40012
#define IDM_REDO                       40013
#define IDD_OPTIONDLG              101
#define IDC_BACKCOLORBOX          1000
#define IDC_TEXTCOLORBOX          1001
#define IDR_MAINACCEL              105
#define IDD_FINDDLG                102
#define IDD_GOTODLG                103
#define IDD_REPLACEDLG             104
#define IDC_FINDEDIT              1000
#define IDC_MATCHCASE             1001
#define IDC_REPLACEEDIT           1001
#define IDC_WHOLEWORD             1002
#define IDC_DOWN                  1003
#define IDC_UP                    1004
#define IDC_LINENO                1005
#define IDM_FIND                 40014
#define IDM_FINDNEXT             40015
#define IDM_REPLACE              40016
#define IDM_GOTOLINE             40017
#define IDM_FINDPREV             40018

#define RichEditID                     300

#define CLR_HRED      RGB( 255,   0,   0 )
#define CLR_HGREEN    RGB(   0, 255,   0 )
#define CLR_HBLUE     RGB(   0,   0, 255 )
#define CLR_BLACK     RGB(   0,   0,   0 )
#define CLR_WHITE     RGB( 255, 255, 255 )

char FindBuffer[ 256 ];
char ReplaceBuffer[ 256 ];
HWND hWndRichEdit;
WNDPROC OldWndProc;
int RichEditVersion;

COLORREF BackGroundColor = CLR_WHITE;
COLORREF TextColor = CLR_BLACK;
COLORREF CommentColor = CLR_HBLUE;
COLORREF ColorArray[ 10 ] = { CLR_HRED, CLR_HGREEN, CLR_HBLUE, CLR_WHITE, CLR_BLACK,
                              CLR_BLACK, CLR_BLACK, CLR_BLACK, CLR_BLACK, CLR_BLACK };  
BOOL FileOpened = FALSE;
char * szFileFilter = "PRG source code (*.prg)\0*.prg\0All Files (*.*)\0*.*\0";
char FileName[ 256 ];
char AlternateFileName[ 256 ];
HANDLE hSearch = NULL;
char * OpenFileFail = "Cannot open the file";
char * AppName = "Fresh 1.0";
char * WordFileName = "wordfile.txt";
FINDTEXTEX findtext;
char * WannaSave = "The data in the control is modified. Want to save it ?";
HFONT hFont;
WORDINFO SyntaxArray[ 256 ];

void SetColor( void )
{
     CHARFORMAT cfm;     
   
     SendMessage( hWndRichEdit, EM_SETBKGNDCOLOR, 0, BackGroundColor );
     memset( &cfm, 0, sizeof( cfm ) );
     cfm.cbSize = sizeof( cfm );
     cfm.dwMask = CFM_COLOR;
     cfm.crTextColor = TextColor;
     SendMessage( hWndRichEdit, EM_SETCHARFORMAT, SCF_ALL, ( LPARAM ) &cfm );
}

void CenterWindow( HWND hWnd )
{
   RECT rWnd, rDsk;
   LONG Left, Top, Width, Height;

   GetWindowRect( hWnd, &rWnd );
   GetWindowRect( GetDesktopWindow(), &rDsk );

   Width  = rWnd.right - rWnd.left;
   Height = rWnd.bottom - rWnd.top;
   Left   = ( rDsk.right / 2 ) - ( Width / 2 );
   Top    = ( rDsk.bottom / 2 ) - ( Height / 2 );

   MoveWindow( hWnd, Left, Top, Width, Height, FALSE );
}

void ParseBuffer( char * pszTokens, DWORD dwGroup )
{
   char buffer[ 128 ];
   char * pStart = pszTokens;
   // BOOL InProgress = FALSE;
   BOOL bFound = FALSE;
   WORDINFO * pWordInfo;
   
   if( ! strlen( pszTokens ) )
      return;
       
   CharLower( pszTokens );
   
   while( * pszTokens )
   {
      if( ( ( * pszTokens ) == ' ' ) || ( ( * pszTokens ) == 9 ) ) // tab
         bFound = TRUE
         
      if( * pszTokens && bFound )
      { 
         pWordInfo = SyntaxArray + pStart[ 0 ];

         if( SyntaxArray[ pStart[ 0 ] ].WordLen )
         {
            while( pWordInfo->NextLink )
               pWordInfo = pWordInfo->NextLink;    
               
            pWordInfo->NextLink = ( WORDINFO * ) malloc( sizeof( WORDINFO ) );  
            memset( ( void * ) pWordInfo->NextLink, 0, sizeof( WORDINFO ) );
         }  

         pWordInfo->WordLen = pszTokens - pStart;
         pWordInfo->pszWord = ( char * ) malloc( pWordInfo->WordLen + 1 );
         strncpy( pWordInfo->pszWord, pStart, pWordInfo->WordLen );
         pWordInfo->pszWord[ pWordInfo->WordLen ] = 0;
         pWordInfo->pColor = ColorArray + dwGroup - 1;
         pWordInfo->NextLink = NULL;
         bFound = FALSE;
         // MessageBox( 0, pWordInfo->pszWord, "token", 0 );
         
         while( ( ( ( * pszTokens ) == ' ' ) || ( ( * pszTokens ) == 9 ) ) && ( * pszTokens ) )
            pszTokens++;
           
         pStart = pszTokens;
      }  
     
      if( * pszTokens )
         pszTokens++;
   }      
}   

void FillHiliteInfo( void )
{
   char filename[ 1024 ];
   char buffer[ 1024 ];
   char * pTemp;
   
   RtlZeroMemory( SyntaxArray, sizeof( SyntaxArray ) )

   GetModuleFileName( GetModuleHandle( NULL ), filename, sizeof( filename ) );
   pTemp = filename + lstrlen( filename );
   
   while( ( pTemp > filename ) && ( ( * pTemp ) != '\\' ) )
      pTemp--;
     
   * ++pTemp = 0;  
   lstrcat( pTemp, WordFileName );
   
   if( GetFileAttributes( filename ) != INVALID_FILE_ATTRIBUTES )
   {
      if( GetPrivateProfileString( "ASSEMBLY", "C1", NULL, buffer, sizeof( buffer ), filename ) )
         ParseBuffer( buffer, 1 );

      if( GetPrivateProfileString( "ASSEMBLY", "C2", NULL, buffer, sizeof( buffer ), filename ) )
         ParseBuffer( buffer, 2 );
         
      if( GetPrivateProfileString( "ASSEMBLY", "C3", NULL, buffer, sizeof( buffer ), filename ) )
         ParseBuffer( buffer, 3 );

      if( GetPrivateProfileString( "ASSEMBLY", "C4", NULL, buffer, sizeof( buffer ), filename ) )
         ParseBuffer( buffer, 4 );
         
      if( GetPrivateProfileString( "ASSEMBLY", "C5", NULL, buffer, sizeof( buffer ), filename ) )
         ParseBuffer( buffer, 5 );

      if( GetPrivateProfileString( "ASSEMBLY", "C6", NULL, buffer, sizeof( buffer ), filename ) )
         ParseBuffer( buffer, 6 );

      if( GetPrivateProfileString( "ASSEMBLY", "C7", NULL, buffer, sizeof( buffer ), filename ) )
         ParseBuffer( buffer, 7 );
         
      if( GetPrivateProfileString( "ASSEMBLY", "C8", NULL, buffer, sizeof( buffer ), filename ) )
         ParseBuffer( buffer, 8 );

      if( GetPrivateProfileString( "ASSEMBLY", "C9", NULL, buffer, sizeof( buffer ), filename ) )
         ParseBuffer( buffer, 9 );
         
      if( GetPrivateProfileString( "ASSEMBLY", "C10", NULL, buffer, sizeof( buffer ), filename ) )
         ParseBuffer( buffer, 10 );
   }  
   else
      MessageBox( 0, "wordfile.txt does not exist", "Attention", MB_ICONINFORMATION );                       
}  
   
BOOL CheckModifyState( HWND hWnd )
{
     int nResult;
     
   if( SendMessage( hWndRichEdit, EM_GETMODIFY, 0, 0 ) )
        if( ( nResult = MessageBox( hWnd, WannaSave, AppName, MB_YESNOCANCEL ) ) == IDYES )
               SendMessage( hWnd, WM_COMMAND, IDM_SAVE, 0 );
            else if( nResult == IDCANCEL )
               return FALSE;
                  
   return TRUE;
}

void PrepareEditMenu( HMENU hSubMenu )
{
   CHARRANGE chrg;

     if( ! SendMessage( hWndRichEdit, EM_CANPASTE, CF_TEXT, 0 ) )
        EnableMenuItem( hSubMenu, IDM_PASTE, MF_GRAYED );
     else  
          EnableMenuItem( hSubMenu, IDM_PASTE, MF_ENABLED );

     if( ! SendMessage( hWndRichEdit, EM_CANUNDO, 0, 0 ) )
        EnableMenuItem( hSubMenu, IDM_UNDO, MF_GRAYED );
     else  
          EnableMenuItem( hSubMenu, IDM_UNDO, MF_ENABLED );

     if( ! SendMessage( hWndRichEdit, EM_CANREDO, 0, 0 ) )
          EnableMenuItem( hSubMenu, IDM_REDO, MF_GRAYED );
     else
        EnableMenuItem( hSubMenu, IDM_REDO, MF_ENABLED );

     chrg.cpMin = SendMessage( hWndRichEdit, EM_EXGETSEL, 0, ( LPARAM ) &chrg );
     
     if( chrg.cpMin == chrg.cpMax )
     { 
        EnableMenuItem( hSubMenu, IDM_COPY,   MF_GRAYED );
          EnableMenuItem( hSubMenu, IDM_CUT,    MF_GRAYED );
          EnableMenuItem( hSubMenu, IDM_DELETE, MF_GRAYED );
     }   
     else
     { 
        EnableMenuItem( hSubMenu, IDM_COPY,   MF_ENABLED );
          EnableMenuItem( hSubMenu, IDM_CUT,    MF_ENABLED );
          EnableMenuItem( hSubMenu, IDM_DELETE, MF_ENABLED );
     }   
}

#pragma argsused

static INT_PTR CALLBACK OptionProc( HWND hDlg, UINT wMsg, WPARAM wParam, LPARAM lParam )
{
   switch( wMsg )
   {
      case WM_INITDIALOG:
           CenterWindow( hDlg );
           return TRUE;

      case WM_COMMAND:
           switch( wParam )
           {
              case IDOK:
                   EndDialog( hDlg, IDOK );
                   break;

              case IDCANCEL:
                   EndDialog( hDlg, IDCANCEL );
                   break;
           }
           break;
   }
   return FALSE;
}

#pragma argsused

static INT_PTR CALLBACK SearchProc( HWND hDlg, UINT wMsg, WPARAM wParam, LPARAM lParam )
{
   switch( wMsg )
   {
      case WM_INITDIALOG:
           CenterWindow( hDlg );
           return TRUE;

      case WM_COMMAND:
           switch( wParam )
           {
              case IDOK:
                   EndDialog( hDlg, IDOK );
                   break;

              case IDCANCEL:
                   EndDialog( hDlg, IDCANCEL );
                   break;
           }
           break;
   }
   return FALSE;
}

#pragma argsused

static INT_PTR CALLBACK ReplaceProc( HWND hDlg, UINT wMsg, WPARAM wParam, LPARAM lParam )
{
   switch( wMsg )
   {
      case WM_INITDIALOG:
           CenterWindow( hDlg );
           return TRUE;

      case WM_COMMAND:
           switch( wParam )
           {
              case IDOK:
                   EndDialog( hDlg, IDOK );
                   break;

              case IDCANCEL:
                   EndDialog( hDlg, IDCANCEL );
                   break;
           }
           break;
   }
   return FALSE;
}

#pragma argsused

static INT_PTR CALLBACK GoToProc( HWND hDlg, UINT wMsg, WPARAM wParam, LPARAM lParam )
{
   switch( wMsg )
   {
      case WM_INITDIALOG:
           CenterWindow( hDlg );
           return TRUE;

      case WM_COMMAND:
           switch( wParam )
           {
              case IDOK:
                   EndDialog( hDlg, IDOK );
                   break;

              case IDCANCEL:
                   EndDialog( hDlg, IDCANCEL );
                   break;
           }
           break;
   }
   return FALSE;
}

LRESULT WINAPI NewRichEditProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam )
{
   HDC hDC;
   HFONT hOldFont;
   RECT rect;
   TEXTRANGE txtrange;
   char buffer[ 1024 * 10 ];
   HRGN hRgn, hOldRgn;
   POINT pt;
   DWORD nChar, nLine, dwPos;
   WORDINFO * pWordInfo;
   BOOL bExit;

   switch( msg )
   {
      case WM_PAINT:       
           HideCaret( hWnd );
               CallWindowProc( OldWndProc, hWnd, msg, wParam, lParam );
               hDC = GetDC( hWnd );
               SetBkMode( hDC, TRANSPARENT );
               hOldFont = SelectObject( hDC, hFont );

               SendMessage( hWnd, EM_GETRECT, 0, ( LPARAM ) &rect );
               
             nChar = SendMessage( hWnd, EM_CHARFROMPOS, 0, ( LPARAM ) &rect );
               nLine = SendMessage( hWnd, EM_LINEFROMCHAR, nChar, 0 );
               txtrange.chrg.cpMin = SendMessage( hWnd, EM_LINEINDEX, nLine, 0 );
           txtrange.chrg.cpMax = SendMessage( hWnd, EM_CHARFROMPOS, 0, ( LPARAM ) &rect.right );               
               
               hRgn = CreateRectRgn( rect.left, rect.top, rect.right, rect.bottom );
           hOldRgn = SelectObject( hDC, hRgn );

           txtrange.lpstrText = buffer;
           if( SendMessage( hWnd, EM_GETTEXTRANGE, 0, ( LPARAM ) &txtrange ) )
           {
              char * pPos = buffer;
              char * pStart = buffer;
              char * pToken;
             
              while( * pPos )
              {
                 if( * pPos == ' ' || * pPos == 9 || * pPos == 0xD || * pPos == 0xA )
                 {
                    pToken = ( char * ) malloc( pPos - pStart + 1 );
                    strncpy( pToken, pStart, pPos - pStart );
                    pToken[ pPos - pStart ] = 0;
                    MessageBox( 0, pToken, "token", 0 );
                   
                    if( RichEditVersion == 3 )
                                   SendMessage( hWnd, EM_POSFROMCHAR, ( WPARAM ) &rect, ( LPARAM ) ( pStart - buffer ) + nChar );
                                else  
                                {   
                                 dwPos = SendMessage( hWnd, EM_POSFROMCHAR, ( WPARAM ) pStart, 0 );
                                   rect.left = LOWORD( dwPos );
                                   rect.top  = HIWORD( dwPos );
                                }
                               
                                if( pToken[ 0 ] >= 'A' && pToken[ 0 ] <= 'Z' )
                                   pWordInfo = SyntaxArray + pToken[ 0 ] - 'A' + 'a';
                                else  
                                   pWordInfo = SyntaxArray + pToken[ 0 ];
                               
                                bExit = FALSE;
                               
                                while( pWordInfo->WordLen && ! bExit )
                                {
                                   if( strlen( pToken ) == pWordInfo->WordLen &&
                                         lstrcmpi( pWordInfo->pszWord, pToken ) == 0 )
                                   {   
                                      bExit = TRUE;
                                      SetTextColor( hDC, * pWordInfo->pColor )
                                      DrawText( hDC, pToken, -1, &rect, 0 );  
                                   }
                                   else
                                   {
                                      if( pWordInfo->NextLink )
                                         pWordInfo= pWordInfo->NextLink;
                                      else
                                         bExit = TRUE;  
                                   }               
                                }
                                   
                    free( pToken );
                   
                    while( * pPos == ' ' || * pPos == 9 || * pPos == 0xD || * pPos == 0xA && * pPos )
                       pPos++;
                       
                    if( ! * pPos )
                       pPos++;   
                       
                    pStart = pPos;    
                 }  
                 pPos++;
              }  
           }  

           SelectObject( hDC, hOldRgn );
           DeleteObject( hRgn );
           SelectObject( hDC, hOldFont );
           ReleaseDC( hWnd, hDC );
           ShowCaret( hWnd );
           return 0;
   
      case WM_CLOSE:
             SetWindowLong( hWnd, GWL_WNDPROC, ( LONG ) OldWndProc );
             break;
   }
               
   return CallWindowProc( OldWndProc, hWnd, msg, wParam, lParam );
}

DWORD CALLBACK StreamInProc( DWORD dwCookie, LPBYTE pbBuff, LONG cb, LONG FAR * pcb )
{      
     ReadFile( ( HANDLE ) dwCookie, ( LPVOID ) pbBuff, ( DWORD ) cb, ( LPDWORD ) pcb, 0 );
   return 0;
}  

DWORD CALLBACK StreamOutProc( DWORD dwCookie, LPBYTE pbBuff, LONG cb, LONG FAR * pcb )
{
     WriteFile( ( HANDLE ) dwCookie, ( LPVOID ) pbBuff, ( DWORD ) cb, ( LPDWORD ) pcb, 0 );
   return 0;
}  
    
LRESULT WINAPI WndProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam )
{
     RECT rect;
   OPENFILENAME ofn;
     char buffer[ 256 ];
     EDITSTREAM editstream;
     FILE * hFile;
     HMENU hPopup;
     POINT pt;
     CHARRANGE chrg;
   
     switch( msg )
   {
        case WM_CREATE:
               GetClientRect( hWnd, &rect );
               hWndRichEdit = CreateWindowEx( WS_EX_CLIENTEDGE, "RichEdit20A", 0,
                                              WS_CHILD | WS_VISIBLE | ES_MULTILINE | WS_VSCROLL |
                                              WS_HSCROLL | ES_NOHIDESEL, 0, 0,
                                              rect.right - rect.left, rect.bottom - rect.top,
                                              hWnd, ( HMENU ) RichEditID, GetModuleHandle( NULL ), 0 );
           
           SendMessage( hWndRichEdit, EM_SETTYPOGRAPHYOPTIONS, TO_SIMPLELINEBREAK, TO_SIMPLELINEBREAK );
           if( ! SendMessage( hWndRichEdit, EM_GETTYPOGRAPHYOPTIONS, 1, 1 ) )
                    RichEditVersion = 2;
               else
                    RichEditVersion = 3;
                 
                 SendMessage( hWndRichEdit, EM_SETEDITSTYLE, SES_EMULATESYSEDIT, SES_EMULATESYSEDIT );
       
               OldWndProc = ( WNDPROC ) SetWindowLong( hWndRichEdit, GWL_WNDPROC, ( LONG ) NewRichEditProc );
               SendMessage( hWndRichEdit, EM_LIMITTEXT, -1, 0 );
           // SetColor();
               SendMessage( hWndRichEdit, EM_SETMODIFY, FALSE, 0 );
               SendMessage( hWndRichEdit, EM_SETEVENTMASK, 0, ENM_MOUSEEVENTS );
               SendMessage( hWndRichEdit, EM_EMPTYUNDOBUFFER, 0, 0 );

           hFont  = CreateFont( 18, 0, 0, 0, 0, FALSE, FALSE, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH, "Courier New" );
           SendMessage( hWndRichEdit, WM_SETFONT, ( WPARAM ) hFont, 0 );

               FillHiliteInfo();
               SetFocus( hWndRichEdit );
               break;
               
        case WM_NOTIFY:
               if( ( ( NMHDR * ) lParam )->code == EN_MSGFILTER )
               {
              if( ( ( MSGFILTER * ) lParam )->msg == WM_RBUTTONDOWN )                                  
                      {
                         hPopup = GetSubMenu( GetMenu( hWnd ), 1 );
                         PrepareEditMenu( hPopup );
                         pt.x = LOWORD( lParam );
                         pt.y = HIWORD( lParam );
                         ClientToScreen( hWnd, &pt );
                         TrackPopupMenu( hPopup, TPM_LEFTALIGN | TPM_BOTTOMALIGN, pt.x, pt.y,
                                         NULL, hWnd, NULL );
              }
            }
            break;    
       
           case WM_INITMENUPOPUP:
            if( lParam == 0 )
            {
               if( FileOpened )
               {   
                          EnableMenuItem( ( HMENU ) wParam, IDM_OPEN,   MF_GRAYED );
                          EnableMenuItem( ( HMENU ) wParam, IDM_CLOSE,  MF_ENABLED );
                          EnableMenuItem( ( HMENU ) wParam, IDM_SAVE,   MF_ENABLED );
                          EnableMenuItem( ( HMENU ) wParam, IDM_SAVEAS, MF_ENABLED );
                     }
                     else
                     { 
                          EnableMenuItem( ( HMENU ) wParam, IDM_OPEN, MF_ENABLED );
                          EnableMenuItem( ( HMENU ) wParam, IDM_CLOSE, MF_GRAYED );
                          EnableMenuItem( ( HMENU ) wParam, IDM_SAVE, MF_GRAYED );
                          EnableMenuItem( ( HMENU ) wParam, IDM_SAVEAS, MF_GRAYED );
                       }  
                    }
                   
                    else if( lParam == 1 )  
                     PrepareEditMenu( ( HMENU ) wParam );
                 
                  else if( lParam == 2 )  
            {
               if( FileOpened )
               {
                  EnableMenuItem( ( HMENU ) wParam, IDM_FIND,     MF_ENABLED );
                          EnableMenuItem( ( HMENU ) wParam, IDM_FINDNEXT, MF_ENABLED );
                          EnableMenuItem( ( HMENU ) wParam, IDM_FINDPREV, MF_ENABLED );
                          EnableMenuItem( ( HMENU ) wParam, IDM_REPLACE,  MF_ENABLED );
                          EnableMenuItem( ( HMENU ) wParam, IDM_GOTOLINE, MF_ENABLED );
                       }
                       else
                       {
                          EnableMenuItem( ( HMENU ) wParam, IDM_FIND,     MF_GRAYED );
                          EnableMenuItem( ( HMENU ) wParam, IDM_FINDNEXT, MF_GRAYED );
                          EnableMenuItem( ( HMENU ) wParam, IDM_FINDPREV, MF_GRAYED );
                          EnableMenuItem( ( HMENU ) wParam, IDM_REPLACE,  MF_GRAYED );
                          EnableMenuItem( ( HMENU ) wParam, IDM_GOTOLINE, MF_GRAYED );
                       }
                    }
                    break;
               
                case WM_COMMAND:
                 if( ! lParam ) // menu commands
                 { 
                      switch( LOWORD( wParam ) )
                      {
                         case IDM_OPEN:
                         { 
                              memset( &ofn, 0, sizeof( ofn ) );
                              ofn.lStructSize = sizeof( ofn );
                              ofn.hwndOwner = hWnd;
                              ofn.hInstance = GetModuleHandle( NULL );
                              ofn.lpstrFilter = szFileFilter;
                              FileName[ 0 ] = 0;
                              ofn.lpstrFile = FileName;
                            ofn.nMaxFile = sizeof( FileName );
                              ofn.Flags = OFN_FILEMUSTEXIST | OFN_HIDEREADONLY | OFN_PATHMUSTEXIST;
                           
                              if( GetOpenFileName( &ofn ) )
                              { 
                                   if( ( hFile = CreateFile( FileName, GENERIC_READ, FILE_SHARE_READ, NULL,
                                                               OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0 ) ) !=
                                                               INVALID_HANDLE_VALUE )
                                   {
                                        editstream.dwCookie = ( DWORD_PTR ) hFile;
                                        editstream.pfnCallback = StreamInProc;
                                        SendMessage( hWndRichEdit, EM_STREAMIN, SF_TEXT, ( LPARAM ) &editstream );
                                        SendMessage( hWndRichEdit, EM_SETMODIFY, FALSE, 0 );
                                        CloseHandle( hFile );
                                        FileOpened = TRUE;
                                     }
                                     else  
                                      MessageBox( hWnd, OpenFileFail, AppName, MB_OK | MB_ICONERROR );
                            }          
                     }
                     break

                   case IDM_CLOSE:
                        {
                                 if( CheckModifyState( hWnd ) )
                                        SetWindowText( hWndRichEdit, NULL );
                                     FileOpened = FALSE;
                                  }
                                  break;  

                   case IDM_SAVE:
                        {
                           if( ( hFile = CreateFile( FileName, GENERIC_WRITE, FILE_SHARE_READ, NULL,
                                                       CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0 ) ) !=
                                                       INVALID_HANDLE_VALUE )
                           {                           
                                        editstream.dwCookie = ( DWORD_PTR ) hFile;
                                        editstream.pfnCallback = StreamOutProc;
                                        SendMessage( hWndRichEdit, EM_STREAMOUT, SF_TEXT, ( LPARAM ) &editstream );
                                        SendMessage( hWndRichEdit, EM_SETMODIFY, FALSE, 0 );
                                        CloseHandle( hFile );
                                     }  
                               else                  
                                        MessageBox( hWnd, OpenFileFail, AppName, MB_OK | MB_ICONERROR );
                                  }      
                                  break;

                   case IDM_COPY:
                                SendMessage( hWndRichEdit, WM_COPY, 0, 0 );
                                break;

                   case IDM_CUT:
                                SendMessage( hWndRichEdit, WM_CUT, 0, 0 );
                                break;
                       
                   case IDM_PASTE:
                                SendMessage( hWndRichEdit, WM_PASTE, 0, 0 );
                                break;
                       
                   case IDM_DELETE:
                                SendMessage( hWndRichEdit, EM_REPLACESEL, TRUE, 0 );
                                break;

                   case IDM_SELECTALL:
                        {
                           chrg.cpMin = 0;
                                   chrg.cpMax = -1;
                                   SendMessage( hWndRichEdit, EM_EXSETSEL, 0, ( LPARAM ) &chrg );
                                }
                                break;  

                   case IDM_UNDO:
                        SendMessage( hWndRichEdit, EM_UNDO, 0, 0 );
                        break;

                   case IDM_REDO:
                                SendMessage( hWndRichEdit, EM_REDO, 0, 0 );
                                break;

                   case IDM_OPTION:
                                DialogBoxParam( GetModuleHandle( NULL ), ( LPCTSTR ) IDD_OPTIONDLG, hWnd, OptionProc, 0 );
                                break;

                   case IDM_SAVEAS:
                        {
                           RtlZeroMemory( &ofn, sizeof( ofn ) );
                                   ofn.lStructSize = sizeof( ofn );
                                   ofn.hwndOwner = hWnd;
                                   ofn.hInstance = GetModuleHandle( NULL );
                                   ofn.lpstrFilter = szFileFilter;
                                   AlternateFileName[ 0 ] = 0;
                                   ofn.lpstrFile = AlternateFileName;
                                   ofn.nMaxFile = sizeof( AlternateFileName );
                                   ofn.Flags = OFN_FILEMUSTEXIST | OFN_HIDEREADONLY | OFN_PATHMUSTEXIST;
                       
                                   if( GetSaveFileName( &ofn ) )
                                   {   
                              if( CreateFile( AlternateFileName, GENERIC_WRITE, FILE_SHARE_READ, NULL,
                                              CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0 ) !=
                                              INVALID_HANDLE_VALUE )
                              {
                              }             
                                       }
                                    }
                                    break;      

                   case IDM_FIND:
                        if( ! hSearch )
                                     CreateDialogParam( GetModuleHandle( NULL ), ( LPCTSTR ) IDD_FINDDLG, hWnd, SearchProc, 0 );
                        break;

                   case IDM_REPLACE:
                        if( ! hSearch )
                           CreateDialogParam( GetModuleHandle( NULL ), ( LPCTSTR ) IDD_REPLACEDLG, hWnd, ReplaceProc, 0 );
                        break;

                   case IDM_GOTOLINE:
                        if( ! hSearch )
                                     CreateDialogParam( GetModuleHandle( NULL ), ( LPCTSTR ) IDD_GOTODLG, hWnd, GoToProc, 0 );
                        break;

                   case IDM_FINDNEXT:
                        if( lstrlen( FindBuffer ) )
                        {   
                                     SendMessage( hWndRichEdit, EM_EXGETSEL, 0, ( LPARAM ) &findtext.chrg );

                                     if( findtext.chrg.cpMin != findtext.chrg.cpMax )
                                          findtext.chrg.cpMin = findtext.chrg.cpMax;
                             
                                     findtext.chrg.cpMax = -1;
                                     findtext.lpstrText = FindBuffer;

                                     if( SendMessage( hWndRichEdit, EM_FINDTEXTEX, FR_DOWN, ( LPARAM ) &findtext ) != -1 )
                                        SendMessage( hWndRichEdit, EM_EXSETSEL, 0, ( LPARAM ) &findtext.chrgText );
                                  }
                                  break;      

                   case IDM_FINDPREV:
                        if( lstrlen( FindBuffer ) )
                        {   
                                     SendMessage( hWndRichEdit, EM_EXGETSEL, 0, ( LPARAM ) &findtext.chrg );
                             
                                     findtext.chrg.cpMax = 0;
                                     findtext.lpstrText = FindBuffer;
                             
                                     if( SendMessage( hWndRichEdit, EM_FINDTEXTEX, 0, ( LPARAM ) &findtext ) != -1 )
                                          SendMessage( hWndRichEdit, EM_EXSETSEL, 0, ( LPARAM ) &findtext.chrgText );
                                    }
                                    break;      

                   case IDM_EXIT:
                        SendMessage( hWnd, WM_CLOSE, 0, 0 );
                        break;
                }
             }  
             break;  
   
          case WM_CLOSE:
               if( CheckModifyState( hWnd ) )
               {
                    DeleteObject( hFont )
                      DestroyWindow( hWnd );
                   }  
                   break;
                 
          case WM_SIZE:
                 MoveWindow( hWndRichEdit, 0, 0, LOWORD( lParam ), HIWORD( lParam ), TRUE );
                 break;    
   
          case WM_DESTROY:
                 PostQuitMessage( 0 );
                 break;
     }     
   return DefWindowProc( hWnd, msg, wParam, lParam );      
}  

#pragma argsused

int PASCAL WinMain( HINSTANCE hInstance, HINSTANCE prev, LPSTR cmdline, int show )
{
   WNDCLASSEX wc;
   MSG msg;
   HWND hWnd;
   char * szClassName = "FreshClass";
   HACCEL hAccel;
   HINSTANCE hDll = LoadLibrary( "riched32" );
   
   wc.cbSize = sizeof( WNDCLASSEX );
   wc.style  = CS_HREDRAW | CS_VREDRAW;
   wc.lpfnWndProc = WndProc;
   wc.cbClsExtra  = 0;
   wc.cbWndExtra  = 0;
   wc.hInstance   = hInstance;
   wc.hbrBackground = GetStockObject( WHITE_BRUSH );
   wc.lpszMenuName  = ( LPCTSTR ) IDR_MAINMENU;
   wc.lpszClassName = szClassName;
   wc.hIcon = wc.hIconSm = LoadIcon( NULL, IDI_APPLICATION );
   wc.hCursor = LoadCursor( NULL, IDC_ARROW );
   RegisterClassEx( &wc );
   
   hWnd = CreateWindowEx( NULL, szClassName, "Fresh 1.0",
                          WS_OVERLAPPEDWINDOW, 70, 70,
                          1130, 630, 0, NULL, hInstance, NULL );
 
   ShowWindow( hWnd, SW_SHOWNORMAL );
   UpdateWindow( hWnd );
 
   hAccel = LoadAccelerators( hInstance, ( LPCTSTR ) IDR_MAINACCEL );
                 
     while( GetMessage( &msg, 0, 0, 0 ) )
     {
        if( IsDialogMessage( hSearch, &msg ) )
               TranslateAccelerator( hWnd, hAccel, &msg );
            else
            {
               TranslateMessage( &msg );
                 DispatchMessage( &msg );
            }
     }       

   FreeLibrary( hDll );

   return 0;
}


fresh.rc
Code: Select all  Expand view
// #include "resource.h"

#define IDC_NEXT                        1003
#define IDR_MAINMENU                    101
#define IDD_OPTIONDLG                   101
#define IDD_FINDDLG                     102
#define IDD_GOTODLG                     103
#define IDD_REPLACEDLG                  104
#define IDR_MAINACCEL                   105
#define IDC_BACKCOLORBOX                1000
#define IDC_FINDEDIT                    1000
#define IDC_TEXTCOLORBOX                1001
#define IDC_MATCHCASE                   1001
#define IDC_REPLACEEDIT                 1001
#define IDC_WHOLEWORD                   1002
#define IDC_DOWN                        1003
#define IDC_UP                          1004
#define IDC_LINENO                      1005
#define IDM_OPEN                        40001
#define IDM_SAVE                        40002
#define IDM_CLOSE                       40003
#define IDM_SAVEAS                      40004
#define IDM_EXIT                        40005
#define IDM_COPY                        40006
#define IDM_CUT                         40007
#define IDM_PASTE                       40008
#define IDM_DELETE                      40009
#define IDM_SELECTALL                   40010
#define IDM_OPTION                      40011
#define IDM_UNDO                        40012
#define IDM_REDO                        40013
#define IDM_FIND                        40014
#define IDM_FINDNEXT                    40015
#define IDM_REPLACE                     40016
#define IDM_GOTOLINE                    40017
#define IDM_FINDPREV                    40018

IDR_MAINMENU MENU DISCARDABLE
BEGIN
    POPUP "&File"
    BEGIN
        MENUITEM "&Open",                       IDM_OPEN
        MENUITEM "&Close",                      IDM_CLOSE
        MENUITEM "&Save",                       IDM_SAVE
        MENUITEM "Save &As",                    IDM_SAVEAS
        MENUITEM SEPARATOR
        MENUITEM "E&xit",                       IDM_EXIT
    END
    POPUP "&Edit"
    BEGIN
        MENUITEM "&Undo",                       IDM_UNDO
        MENUITEM "&Redo",                       IDM_REDO
        MENUITEM "&Copy",                       IDM_COPY
        MENUITEM "C&ut",                        IDM_CUT
        MENUITEM "&Paste",                      IDM_PASTE
        MENUITEM SEPARATOR
        MENUITEM "&Delete",                     IDM_DELETE
        MENUITEM SEPARATOR
        MENUITEM "Select &All",                 IDM_SELECTALL
    END
    POPUP "&Search"
    BEGIN
        MENUITEM "&Find...\tCtrl+F",            IDM_FIND
        MENUITEM "Find &Next\tF3",              IDM_FINDNEXT
        MENUITEM "Find &Prev.\tCtrl+F3",        IDM_FINDPREV
        MENUITEM "&Replace..\tCtrl+R",          IDM_REPLACE
        MENUITEM SEPARATOR
        MENUITEM "&Go To Line\tCtrl+G",         IDM_GOTOLINE
    END
    MENUITEM "Options",                     IDM_OPTION
END

IDD_OPTIONDLG DIALOG DISCARDABLE  0, 0, 183, 54
STYLE DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_VISIBLE | WS_CAPTION |
    WS_SYSMENU
CAPTION "Options"
FONT 8, "MS Sans Serif"
BEGIN
    DEFPUSHBUTTON   "OK",IDOK,137,7,39,14
    PUSHBUTTON      "Cancel",IDCANCEL,137,25,39,14
    GROUPBOX        "",IDC_STATIC,5,0,124,49
    LTEXT           "Background Color:",IDC_STATIC,20,14,60,8
    LTEXT           "",IDC_BACKCOLORBOX,85,11,28,14,SS_NOTIFY | WS_BORDER
    LTEXT           "Text Color:",IDC_STATIC,20,33,35,8
    LTEXT           "",IDC_TEXTCOLORBOX,85,29,28,14,SS_NOTIFY | WS_BORDER
END

IDD_FINDDLG DIALOG DISCARDABLE  0, 0, 186, 54
STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
CAPTION "Find.."
FONT 8, "MS Sans Serif"
BEGIN
    EDITTEXT        IDC_FINDEDIT,42,3,94,12,ES_AUTOHSCROLL
    CONTROL         "Match Case",IDC_MATCHCASE,"Button",BS_AUTOCHECKBOX |
                    WS_TABSTOP,6,24,54,10
    CONTROL         "Whole Word",IDC_WHOLEWORD,"Button",BS_AUTOCHECKBOX |
                    WS_TABSTOP,6,37,56,10
    CONTROL         "Down",IDC_DOWN,"Button",BS_AUTORADIOBUTTON | WS_TABSTOP,
                    83,27,35,10
    CONTROL         "Up",IDC_UP,"Button",BS_AUTORADIOBUTTON | WS_TABSTOP,83,
                    38,25,10
    DEFPUSHBUTTON   "OK",IDOK,141,3,39,12
    PUSHBUTTON      "Cancel",IDCANCEL,141,18,39,12
    LTEXT           "Find what:",IDC_STATIC,5,4,34,8
    GROUPBOX        "Direction",IDC_STATIC,70,18,64,32
END

IDD_GOTODLG DIALOGEX 0, 0, 106, 30
STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
EXSTYLE WS_EX_TOOLWINDOW
CAPTION "Go To Line"
FONT 8, "MS Sans Serif", 0, 0
BEGIN
    EDITTEXT        IDC_LINENO,29,4,35,11,ES_AUTOHSCROLL | ES_NUMBER,
                    WS_EX_CLIENTEDGE
    DEFPUSHBUTTON   "OK",IDOK,70,4,31,11
    PUSHBUTTON      "Cancel",IDCANCEL,70,17,31,11
    LTEXT           "Line :",IDC_STATIC,8,5,18,8
END

IDD_REPLACEDLG DIALOG DISCARDABLE  0, 0, 186, 33
STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
CAPTION "Replace"
FONT 8, "MS Sans Serif"
BEGIN
    EDITTEXT        IDC_FINDEDIT,51,3,84,12,ES_AUTOHSCROLL
    EDITTEXT        IDC_REPLACEEDIT,51,17,84,11,ES_AUTOHSCROLL
    DEFPUSHBUTTON   "OK",IDOK,142,3,39,11
    PUSHBUTTON      "Cancel",IDCANCEL,142,17,39,11
    LTEXT           "Find what:",IDC_STATIC,3,4,34,8
    LTEXT           "Replace with",IDC_STATIC,3,18,42,8
END

IDR_MAINACCEL ACCELERATORS DISCARDABLE
BEGIN
    "F",            IDM_FIND,               VIRTKEY, CONTROL, NOINVERT
    "G",            IDM_GOTOLINE,           VIRTKEY, CONTROL, NOINVERT
    "R",            IDM_REPLACE,            VIRTKEY, CONTROL, NOINVERT
    VK_F3,          IDM_FINDNEXT,           VIRTKEY, NOINVERT
    VK_F3,          IDM_FINDPREV,           VIRTKEY, CONTROL, NOINVERT
END


go.bat:
Code: Select all  Expand view
set path=c:\bcc582\bin
brc32 -r fresh.rc
bcc32 -W fresh.c
if errorlevel 0 fresh


It uses a wordfile.txt to specify the tokens to highlight:
Code: Select all  Expand view
[ASSEMBLY]
C1=CLASS ENDCLASS DATA METHOD INLINE
C2=#include #pragma #ifdef #endif #define another
C3=local static public private
C4=if else endif return do case end endcase
C5=
C6=
C7=
C8=
C9=
C10=


It already works though it is not complete and still has some bugs while parsing. But the concept is there and it is quite interesting :-)

Original source code and idea belongs to Iczelion@win32asm.cjb.net.
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Antonio Linares
Site Admin
 
Posts: 42086
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain

Re: RichEdit - speed up coloring

Postby Antonio Linares » Tue Feb 28, 2012 10:02 pm

Enhanced version

fresh.c
Code: Select all  Expand view
#pragma resource "fresh.res"

#include <windows.h>
#include <richedit.h>
#include <stdio.h>

typedef struct
{
   DWORD    WordLen;    // the length of the word: used as a quick comparison
     char * pszWord;    // pointer to the word
     COLORREF * pColor; // point to the dword that contains the color used to hilite the word
     void * NextLink;   // point to the next WORDINFO structure
} WORDINFO;

#define IDR_MAINMENU               101
#define IDM_OPEN                 40001
#define IDM_SAVE                 40002
#define IDM_CLOSE                40003
#define IDM_SAVEAS               40004
#define IDM_EXIT                 40005
#define IDM_COPY                 40006
#define IDM_CUT                  40007
#define IDM_PASTE                40008
#define IDM_DELETE               40009
#define IDM_SELECTALL            40010
#define IDM_OPTION                   40011
#define IDM_UNDO                       40012
#define IDM_REDO                       40013
#define IDD_OPTIONDLG              101
#define IDC_BACKCOLORBOX          1000
#define IDC_TEXTCOLORBOX          1001
#define IDR_MAINACCEL              105
#define IDD_FINDDLG                102
#define IDD_GOTODLG                103
#define IDD_REPLACEDLG             104
#define IDC_FINDEDIT              1000
#define IDC_MATCHCASE             1001
#define IDC_REPLACEEDIT           1001
#define IDC_WHOLEWORD             1002
#define IDC_DOWN                  1003
#define IDC_UP                    1004
#define IDC_LINENO                1005
#define IDM_FIND                 40014
#define IDM_FINDNEXT             40015
#define IDM_REPLACE              40016
#define IDM_GOTOLINE             40017
#define IDM_FINDPREV             40018

#define RichEditID                     300

#define CLR_HRED      RGB( 255,   0,   0 )
#define CLR_HGREEN    RGB(   0, 255,   0 )
#define CLR_GREEN     RGB(   0, 128,   0 )
#define CLR_HBLUE     RGB(   0,   0, 255 )
#define CLR_YELLOW    RGB( 255, 255,   0 )
#define CLR_HCYAN     RGB(   0, 255, 255 )
#define CLR_BLACK     RGB(   0,   0,   0 )
#define CLR_WHITE     RGB( 255, 255, 255 )

char FindBuffer[ 256 ];
char ReplaceBuffer[ 256 ];
HWND hWndRichEdit;
WNDPROC OldWndProc;
int RichEditVersion;

COLORREF BackGroundColor = CLR_WHITE;
COLORREF TextColor = CLR_BLACK;
COLORREF CommentColor = CLR_HBLUE;
COLORREF ColorArray[ 10 ] = { CLR_HBLUE, CLR_GREEN, CLR_HCYAN, CLR_HBLUE, CLR_BLACK,
                                CLR_BLACK, CLR_BLACK, CLR_BLACK, CLR_BLACK, CLR_BLACK };  
BOOL FileOpened = FALSE;
char * szFileFilter = "PRG source code (*.prg)\0*.prg\0All Files (*.*)\0*.*\0";
char FileName[ 256 ];
char AlternateFileName[ 256 ];
HANDLE hSearch = NULL;
char * OpenFileFail = "Cannot open the file";
char * AppName = "Fresh 1.0";
char * WordFileName = "wordfile.txt";
FINDTEXTEX findtext;
char * WannaSave = "The data in the control is modified. Want to save it ?";
HFONT hFont;
WORDINFO SyntaxArray[ 256 ];

void SetColor( void )
{
     CHARFORMAT cfm;     
   
     SendMessage( hWndRichEdit, EM_SETBKGNDCOLOR, 0, BackGroundColor );
     memset( &cfm, 0, sizeof( cfm ) );
     cfm.cbSize = sizeof( cfm );
     cfm.dwMask = CFM_COLOR;
     cfm.crTextColor = TextColor;
     SendMessage( hWndRichEdit, EM_SETCHARFORMAT, SCF_ALL, ( LPARAM ) &cfm );
}

void CenterWindow( HWND hWnd )
{
   RECT rWnd, rDsk;
   LONG Left, Top, Width, Height;

   GetWindowRect( hWnd, &rWnd );
   GetWindowRect( GetDesktopWindow(), &rDsk );

   Width  = rWnd.right - rWnd.left;
   Height = rWnd.bottom - rWnd.top;
   Left   = ( rDsk.right / 2 ) - ( Width / 2 );
   Top    = ( rDsk.bottom / 2 ) - ( Height / 2 );

   MoveWindow( hWnd, Left, Top, Width, Height, FALSE );
}

void ParseBuffer( char * pszTokens, DWORD dwGroup )
{
   char * pStart;
   WORDINFO * pWordInfo;
   
   if( ! strlen( pszTokens ) )
      return;
       
   CharLower( pszTokens );
   
   while( * pszTokens )
   {
      while( * pszTokens == ' ' || * pszTokens == 9 && * pszTokens )
         pszTokens++;
         
      if( * pszTokens )
      { 
         pStart = pszTokens;

         while( * pszTokens != ' ' && * pszTokens != 9 && * pszTokens )
            pszTokens++;
         
         pWordInfo = SyntaxArray + pStart[ 0 ];

         if( SyntaxArray[ pStart[ 0 ] ].WordLen )
         {
            while( pWordInfo->NextLink )
               pWordInfo = pWordInfo->NextLink;    
               
            pWordInfo->NextLink = ( WORDINFO * ) malloc( sizeof( WORDINFO ) );  
            memset( ( void * ) pWordInfo->NextLink, 0, sizeof( WORDINFO ) );
            pWordInfo = pWordInfo->NextLink;
         }  

         pWordInfo->WordLen = pszTokens - pStart;
         pWordInfo->pszWord = ( char * ) malloc( pWordInfo->WordLen + 1 );
         strncpy( pWordInfo->pszWord, pStart, pWordInfo->WordLen );
         // pWordInfo->pszWord[ 0 ] = '*';
         // pWordInfo->pszWord[ pWordInfo->WordLen - 1 ] = '*';
         pWordInfo->pszWord[ pWordInfo->WordLen ] = 0;
         pWordInfo->pColor = ColorArray + dwGroup - 1;
         pWordInfo->NextLink = NULL;
         // MessageBox( 0, pWordInfo->pszWord, "token", 0 );
      }  
   }      
}   

void FillHiliteInfo( void )
{
   char filename[ 1024 ];
   char buffer[ 1024 ];
   char * pTemp;
   
   RtlZeroMemory( SyntaxArray, sizeof( SyntaxArray ) )

   GetModuleFileName( GetModuleHandle( NULL ), filename, sizeof( filename ) );
   pTemp = filename + lstrlen( filename );
   
   while( ( pTemp > filename ) && ( ( * pTemp ) != '\\' ) )
      pTemp--;
     
   * ++pTemp = 0;  
   lstrcat( pTemp, WordFileName );
   
   if( GetFileAttributes( filename ) != INVALID_FILE_ATTRIBUTES )
   {
      if( GetPrivateProfileString( "ASSEMBLY", "C1", NULL, buffer, sizeof( buffer ), filename ) )
         ParseBuffer( buffer, 1 );

      if( GetPrivateProfileString( "ASSEMBLY", "C2", NULL, buffer, sizeof( buffer ), filename ) )
         ParseBuffer( buffer, 2 );
         
      if( GetPrivateProfileString( "ASSEMBLY", "C3", NULL, buffer, sizeof( buffer ), filename ) )
         ParseBuffer( buffer, 3 );

      if( GetPrivateProfileString( "ASSEMBLY", "C4", NULL, buffer, sizeof( buffer ), filename ) )
         ParseBuffer( buffer, 4 );
         
      if( GetPrivateProfileString( "ASSEMBLY", "C5", NULL, buffer, sizeof( buffer ), filename ) )
         ParseBuffer( buffer, 5 );

      if( GetPrivateProfileString( "ASSEMBLY", "C6", NULL, buffer, sizeof( buffer ), filename ) )
         ParseBuffer( buffer, 6 );

      if( GetPrivateProfileString( "ASSEMBLY", "C7", NULL, buffer, sizeof( buffer ), filename ) )
         ParseBuffer( buffer, 7 );
         
      if( GetPrivateProfileString( "ASSEMBLY", "C8", NULL, buffer, sizeof( buffer ), filename ) )
         ParseBuffer( buffer, 8 );

      if( GetPrivateProfileString( "ASSEMBLY", "C9", NULL, buffer, sizeof( buffer ), filename ) )
         ParseBuffer( buffer, 9 );
         
      if( GetPrivateProfileString( "ASSEMBLY", "C10", NULL, buffer, sizeof( buffer ), filename ) )
         ParseBuffer( buffer, 10 );
   }  
   else
      MessageBox( 0, "wordfile.txt does not exist", "Attention", MB_ICONINFORMATION );                       
}  
   
BOOL CheckModifyState( HWND hWnd )
{
     int nResult;
     
   if( SendMessage( hWndRichEdit, EM_GETMODIFY, 0, 0 ) )
        if( ( nResult = MessageBox( hWnd, WannaSave, AppName, MB_YESNOCANCEL ) ) == IDYES )
               SendMessage( hWnd, WM_COMMAND, IDM_SAVE, 0 );
            else if( nResult == IDCANCEL )
               return FALSE;
                  
   return TRUE;
}

void PrepareEditMenu( HMENU hSubMenu )
{
   CHARRANGE chrg;

     if( ! SendMessage( hWndRichEdit, EM_CANPASTE, CF_TEXT, 0 ) )
        EnableMenuItem( hSubMenu, IDM_PASTE, MF_GRAYED );
     else  
          EnableMenuItem( hSubMenu, IDM_PASTE, MF_ENABLED );

     if( ! SendMessage( hWndRichEdit, EM_CANUNDO, 0, 0 ) )
        EnableMenuItem( hSubMenu, IDM_UNDO, MF_GRAYED );
     else  
          EnableMenuItem( hSubMenu, IDM_UNDO, MF_ENABLED );

     if( ! SendMessage( hWndRichEdit, EM_CANREDO, 0, 0 ) )
          EnableMenuItem( hSubMenu, IDM_REDO, MF_GRAYED );
     else
        EnableMenuItem( hSubMenu, IDM_REDO, MF_ENABLED );

     chrg.cpMin = SendMessage( hWndRichEdit, EM_EXGETSEL, 0, ( LPARAM ) &chrg );
     
     if( chrg.cpMin == chrg.cpMax )
     { 
        EnableMenuItem( hSubMenu, IDM_COPY,   MF_GRAYED );
          EnableMenuItem( hSubMenu, IDM_CUT,    MF_GRAYED );
          EnableMenuItem( hSubMenu, IDM_DELETE, MF_GRAYED );
     }   
     else
     { 
        EnableMenuItem( hSubMenu, IDM_COPY,   MF_ENABLED );
          EnableMenuItem( hSubMenu, IDM_CUT,    MF_ENABLED );
          EnableMenuItem( hSubMenu, IDM_DELETE, MF_ENABLED );
     }   
}

#pragma argsused

static INT_PTR CALLBACK OptionProc( HWND hDlg, UINT wMsg, WPARAM wParam, LPARAM lParam )
{
   switch( wMsg )
   {
      case WM_INITDIALOG:
           CenterWindow( hDlg );
           return TRUE;

      case WM_COMMAND:
           switch( wParam )
           {
              case IDOK:
                   EndDialog( hDlg, IDOK );
                   break;

              case IDCANCEL:
                   EndDialog( hDlg, IDCANCEL );
                   break;
           }
           break;
   }
   return FALSE;
}

#pragma argsused

static INT_PTR CALLBACK SearchProc( HWND hDlg, UINT wMsg, WPARAM wParam, LPARAM lParam )
{
   switch( wMsg )
   {
      case WM_INITDIALOG:
           CenterWindow( hDlg );
           return TRUE;

      case WM_COMMAND:
           switch( wParam )
           {
              case IDOK:
                   EndDialog( hDlg, IDOK );
                   break;

              case IDCANCEL:
                   EndDialog( hDlg, IDCANCEL );
                   break;
           }
           break;
   }
   return FALSE;
}

#pragma argsused

static INT_PTR CALLBACK ReplaceProc( HWND hDlg, UINT wMsg, WPARAM wParam, LPARAM lParam )
{
   switch( wMsg )
   {
      case WM_INITDIALOG:
           CenterWindow( hDlg );
           return TRUE;

      case WM_COMMAND:
           switch( wParam )
           {
              case IDOK:
                   EndDialog( hDlg, IDOK );
                   break;

              case IDCANCEL:
                   EndDialog( hDlg, IDCANCEL );
                   break;
           }
           break;
   }
   return FALSE;
}

#pragma argsused

static INT_PTR CALLBACK GoToProc( HWND hDlg, UINT wMsg, WPARAM wParam, LPARAM lParam )
{
   switch( wMsg )
   {
      case WM_INITDIALOG:
           CenterWindow( hDlg );
           return TRUE;

      case WM_COMMAND:
           switch( wParam )
           {
              case IDOK:
                   EndDialog( hDlg, IDOK );
                   break;

              case IDCANCEL:
                   EndDialog( hDlg, IDCANCEL );
                   break;
           }
           break;
   }
   return FALSE;
}

LRESULT WINAPI NewRichEditProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam )
{
   HDC hDC;
   HFONT hOldFont;
   RECT rect;
   TEXTRANGE txtrange;
   char buffer[ 1024 * 10 ];
   HRGN hRgn, hOldRgn;
   POINT pt;
   DWORD nChar, nLine, dwPos;
   WORDINFO * pWordInfo;
   BOOL bExit;

   switch( msg )
   {
      case WM_PAINT:       
           HideCaret( hWnd );
               CallWindowProc( OldWndProc, hWnd, msg, wParam, lParam );
               hDC = GetDC( hWnd );
               SetBkMode( hDC, TRANSPARENT );
               hOldFont = SelectObject( hDC, hFont );

               SendMessage( hWnd, EM_GETRECT, 0, ( LPARAM ) &rect );
               
             nChar = SendMessage( hWnd, EM_CHARFROMPOS, 0, ( LPARAM ) &rect );
               nLine = SendMessage( hWnd, EM_LINEFROMCHAR, nChar, 0 );
               txtrange.chrg.cpMin = SendMessage( hWnd, EM_LINEINDEX, nLine, 0 );
           txtrange.chrg.cpMax = SendMessage( hWnd, EM_CHARFROMPOS, 0, ( LPARAM ) &rect.right );               
               
               hRgn = CreateRectRgn( rect.left, rect.top, rect.right, rect.bottom );
           hOldRgn = SelectObject( hDC, hRgn );

           txtrange.lpstrText = buffer;
           if( SendMessage( hWnd, EM_GETTEXTRANGE, 0, ( LPARAM ) &txtrange ) )
           {
              char * pPos = buffer;
              char * pStart = buffer;
              char * pToken;
             
              while( * pPos )
              {
                 if( * pPos == ' ' || * pPos == 9 || * pPos == 0xD || * pPos == 0xA )
                 {
                    pToken = ( char * ) malloc( pPos - pStart + 1 );
                    strncpy( pToken, pStart, pPos - pStart );
                    pToken[ pPos - pStart ] = 0;
                    // MessageBox( 0, pToken, "token", 0 );
                   
                    if( RichEditVersion == 3 )
                                   SendMessage( hWnd, EM_POSFROMCHAR, ( WPARAM ) &rect, ( LPARAM ) ( pStart - buffer ) + nChar );
                                else  
                                {   
                                 dwPos = SendMessage( hWnd, EM_POSFROMCHAR, ( WPARAM ) pStart, 0 );
                                   rect.left = LOWORD( dwPos );
                                   rect.top  = HIWORD( dwPos );
                                }
                               
                                if( pToken[ 0 ] >= '0' && pToken[ 0 ] <= '9' )
                                {   
                                   SetTextColor( hDC, CLR_HRED );   
                                   DrawText( hDC, pToken, -1, &rect, 0 );
                                }
                                else if( pToken[ 0 ] == '"' || pToken[ 0 ] == ''' )
                                {
                                   SetTextColor( hDC, CLR_YELLOW )
                                   DrawText( hDC, pToken, -1, &rect, 0 );
                                }      
                    else
                    {   
                                   if( pToken[ 0 ] >= 'A' && pToken[ 0 ] <= 'Z' )
                                      pWordInfo = SyntaxArray + pToken[ 0 ] - 'A' + 'a';
                                   else  
                                      pWordInfo = SyntaxArray + pToken[ 0 ];
                               
                                   bExit = FALSE;
                               
                                   while( pWordInfo->WordLen && ! bExit )
                                   {
                                      if( ( strlen( pToken ) == pWordInfo->WordLen ) &&
                                            ( lstrcmpi( pWordInfo->pszWord, pToken ) == 0 ) )
                                      { 
                                         bExit = TRUE;
                                         SetTextColor( hDC, * pWordInfo->pColor )
                                         DrawText( hDC, pToken, -1, &rect, 0 );  
                                      }
                                      else
                                      {
                                         if( pWordInfo->NextLink )
                                            pWordInfo= pWordInfo->NextLink;
                                         else
                                            bExit = TRUE;  
                                      }                
                                   }
                                }  
                                   
                    free( pToken );
                   
                    while( * pPos == ' ' || * pPos == 9 || * pPos == 0xD || * pPos == 0xA && * pPos )
                       pPos++;
                       
                    if( ! * pPos )
                       pPos++;   
                       
                    pStart = pPos;    
                 }  
                 pPos++;
              }  
           }  

           SelectObject( hDC, hOldRgn );
           DeleteObject( hRgn );
           SelectObject( hDC, hOldFont );
           ReleaseDC( hWnd, hDC );
           ShowCaret( hWnd );
           return 0;
   
      case WM_CLOSE:
             SetWindowLong( hWnd, GWL_WNDPROC, ( LONG ) OldWndProc );
             break;
   }
               
   return CallWindowProc( OldWndProc, hWnd, msg, wParam, lParam );
}

DWORD CALLBACK StreamInProc( DWORD dwCookie, LPBYTE pbBuff, LONG cb, LONG FAR * pcb )
{      
     ReadFile( ( HANDLE ) dwCookie, ( LPVOID ) pbBuff, ( DWORD ) cb, ( LPDWORD ) pcb, 0 );
   return 0;
}  

DWORD CALLBACK StreamOutProc( DWORD dwCookie, LPBYTE pbBuff, LONG cb, LONG FAR * pcb )
{
     WriteFile( ( HANDLE ) dwCookie, ( LPVOID ) pbBuff, ( DWORD ) cb, ( LPDWORD ) pcb, 0 );
   return 0;
}  
    
LRESULT WINAPI WndProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam )
{
     RECT rect;
   OPENFILENAME ofn;
     char buffer[ 256 ];
     EDITSTREAM editstream;
     FILE * hFile;
     HMENU hPopup;
     POINT pt;
     CHARRANGE chrg;
   
     switch( msg )
   {
        case WM_CREATE:
               GetClientRect( hWnd, &rect );
               hWndRichEdit = CreateWindowEx( WS_EX_CLIENTEDGE, "RichEdit20A", 0,
                                              WS_CHILD | WS_VISIBLE | ES_MULTILINE | WS_VSCROLL |
                                              WS_HSCROLL | ES_NOHIDESEL, 0, 0,
                                              rect.right - rect.left, rect.bottom - rect.top,
                                              hWnd, ( HMENU ) RichEditID, GetModuleHandle( NULL ), 0 );
           
           SendMessage( hWndRichEdit, EM_SETTYPOGRAPHYOPTIONS, TO_SIMPLELINEBREAK, TO_SIMPLELINEBREAK );
           if( ! SendMessage( hWndRichEdit, EM_GETTYPOGRAPHYOPTIONS, 1, 1 ) )
                    RichEditVersion = 2;
               else
                    RichEditVersion = 3;
                 
                 SendMessage( hWndRichEdit, EM_SETEDITSTYLE, SES_EMULATESYSEDIT, SES_EMULATESYSEDIT );
       
               OldWndProc = ( WNDPROC ) SetWindowLong( hWndRichEdit, GWL_WNDPROC, ( LONG ) NewRichEditProc );
               SendMessage( hWndRichEdit, EM_LIMITTEXT, -1, 0 );
           // SetColor();
               SendMessage( hWndRichEdit, EM_SETMODIFY, FALSE, 0 );
               SendMessage( hWndRichEdit, EM_SETEVENTMASK, 0, ENM_MOUSEEVENTS );
               SendMessage( hWndRichEdit, EM_EMPTYUNDOBUFFER, 0, 0 );

           hFont  = CreateFont( 18, 0, 0, 0, 0, FALSE, FALSE, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH, "Courier New" );
           SendMessage( hWndRichEdit, WM_SETFONT, ( WPARAM ) hFont, 0 );

               FillHiliteInfo();
               SetFocus( hWndRichEdit );
               break;
               
        case WM_NOTIFY:
               if( ( ( NMHDR * ) lParam )->code == EN_MSGFILTER )
               {
              if( ( ( MSGFILTER * ) lParam )->msg == WM_RBUTTONDOWN )                                  
                      {
                         hPopup = GetSubMenu( GetMenu( hWnd ), 1 );
                         PrepareEditMenu( hPopup );
                         pt.x = LOWORD( lParam );
                         pt.y = HIWORD( lParam );
                         ClientToScreen( hWnd, &pt );
                         TrackPopupMenu( hPopup, TPM_LEFTALIGN | TPM_BOTTOMALIGN, pt.x, pt.y,
                                         NULL, hWnd, NULL );
              }
            }
            break;    
       
           case WM_INITMENUPOPUP:
            if( lParam == 0 )
            {
               if( FileOpened )
               {   
                          EnableMenuItem( ( HMENU ) wParam, IDM_OPEN,   MF_GRAYED );
                          EnableMenuItem( ( HMENU ) wParam, IDM_CLOSE,  MF_ENABLED );
                          EnableMenuItem( ( HMENU ) wParam, IDM_SAVE,   MF_ENABLED );
                          EnableMenuItem( ( HMENU ) wParam, IDM_SAVEAS, MF_ENABLED );
                     }
                     else
                     { 
                          EnableMenuItem( ( HMENU ) wParam, IDM_OPEN, MF_ENABLED );
                          EnableMenuItem( ( HMENU ) wParam, IDM_CLOSE, MF_GRAYED );
                          EnableMenuItem( ( HMENU ) wParam, IDM_SAVE, MF_GRAYED );
                          EnableMenuItem( ( HMENU ) wParam, IDM_SAVEAS, MF_GRAYED );
                       }  
                    }
                   
                    else if( lParam == 1 )  
                     PrepareEditMenu( ( HMENU ) wParam );
                 
                  else if( lParam == 2 )  
            {
               if( FileOpened )
               {
                  EnableMenuItem( ( HMENU ) wParam, IDM_FIND,     MF_ENABLED );
                          EnableMenuItem( ( HMENU ) wParam, IDM_FINDNEXT, MF_ENABLED );
                          EnableMenuItem( ( HMENU ) wParam, IDM_FINDPREV, MF_ENABLED );
                          EnableMenuItem( ( HMENU ) wParam, IDM_REPLACE,  MF_ENABLED );
                          EnableMenuItem( ( HMENU ) wParam, IDM_GOTOLINE, MF_ENABLED );
                       }
                       else
                       {
                          EnableMenuItem( ( HMENU ) wParam, IDM_FIND,     MF_GRAYED );
                          EnableMenuItem( ( HMENU ) wParam, IDM_FINDNEXT, MF_GRAYED );
                          EnableMenuItem( ( HMENU ) wParam, IDM_FINDPREV, MF_GRAYED );
                          EnableMenuItem( ( HMENU ) wParam, IDM_REPLACE,  MF_GRAYED );
                          EnableMenuItem( ( HMENU ) wParam, IDM_GOTOLINE, MF_GRAYED );
                       }
                    }
                    break;
               
                case WM_COMMAND:
                 if( ! lParam ) // menu commands
                 { 
                      switch( LOWORD( wParam ) )
                      {
                         case IDM_OPEN:
                         { 
                              memset( &ofn, 0, sizeof( ofn ) );
                              ofn.lStructSize = sizeof( ofn );
                              ofn.hwndOwner = hWnd;
                              ofn.hInstance = GetModuleHandle( NULL );
                              ofn.lpstrFilter = szFileFilter;
                              FileName[ 0 ] = 0;
                              ofn.lpstrFile = FileName;
                            ofn.nMaxFile = sizeof( FileName );
                              ofn.Flags = OFN_FILEMUSTEXIST | OFN_HIDEREADONLY | OFN_PATHMUSTEXIST;
                           
                              if( GetOpenFileName( &ofn ) )
                              { 
                                   if( ( hFile = CreateFile( FileName, GENERIC_READ, FILE_SHARE_READ, NULL,
                                                               OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0 ) ) !=
                                                               INVALID_HANDLE_VALUE )
                                   {
                                        editstream.dwCookie = ( DWORD_PTR ) hFile;
                                        editstream.pfnCallback = StreamInProc;
                                        SendMessage( hWndRichEdit, EM_STREAMIN, SF_TEXT, ( LPARAM ) &editstream );
                                        SendMessage( hWndRichEdit, EM_SETMODIFY, FALSE, 0 );
                                        CloseHandle( hFile );
                                        FileOpened = TRUE;
                                     }
                                     else  
                                      MessageBox( hWnd, OpenFileFail, AppName, MB_OK | MB_ICONERROR );
                            }          
                     }
                     break

                   case IDM_CLOSE:
                        {
                                 if( CheckModifyState( hWnd ) )
                                        SetWindowText( hWndRichEdit, NULL );
                                     FileOpened = FALSE;
                                  }
                                  break;  

                   case IDM_SAVE:
                        {
                           if( ( hFile = CreateFile( FileName, GENERIC_WRITE, FILE_SHARE_READ, NULL,
                                                       CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0 ) ) !=
                                                       INVALID_HANDLE_VALUE )
                           {                           
                                        editstream.dwCookie = ( DWORD_PTR ) hFile;
                                        editstream.pfnCallback = StreamOutProc;
                                        SendMessage( hWndRichEdit, EM_STREAMOUT, SF_TEXT, ( LPARAM ) &editstream );
                                        SendMessage( hWndRichEdit, EM_SETMODIFY, FALSE, 0 );
                                        CloseHandle( hFile );
                                     }  
                               else                  
                                        MessageBox( hWnd, OpenFileFail, AppName, MB_OK | MB_ICONERROR );
                                  }      
                                  break;

                   case IDM_COPY:
                                SendMessage( hWndRichEdit, WM_COPY, 0, 0 );
                                break;

                   case IDM_CUT:
                                SendMessage( hWndRichEdit, WM_CUT, 0, 0 );
                                break;
                       
                   case IDM_PASTE:
                                SendMessage( hWndRichEdit, WM_PASTE, 0, 0 );
                                break;
                       
                   case IDM_DELETE:
                                SendMessage( hWndRichEdit, EM_REPLACESEL, TRUE, 0 );
                                break;

                   case IDM_SELECTALL:
                        {
                           chrg.cpMin = 0;
                                   chrg.cpMax = -1;
                                   SendMessage( hWndRichEdit, EM_EXSETSEL, 0, ( LPARAM ) &chrg );
                                }
                                break;  

                   case IDM_UNDO:
                        SendMessage( hWndRichEdit, EM_UNDO, 0, 0 );
                        break;

                   case IDM_REDO:
                                SendMessage( hWndRichEdit, EM_REDO, 0, 0 );
                                break;

                   case IDM_OPTION:
                                DialogBoxParam( GetModuleHandle( NULL ), ( LPCTSTR ) IDD_OPTIONDLG, hWnd, OptionProc, 0 );
                                break;

                   case IDM_SAVEAS:
                        {
                           RtlZeroMemory( &ofn, sizeof( ofn ) );
                                   ofn.lStructSize = sizeof( ofn );
                                   ofn.hwndOwner = hWnd;
                                   ofn.hInstance = GetModuleHandle( NULL );
                                   ofn.lpstrFilter = szFileFilter;
                                   AlternateFileName[ 0 ] = 0;
                                   ofn.lpstrFile = AlternateFileName;
                                   ofn.nMaxFile = sizeof( AlternateFileName );
                                   ofn.Flags = OFN_FILEMUSTEXIST | OFN_HIDEREADONLY | OFN_PATHMUSTEXIST;
                       
                                   if( GetSaveFileName( &ofn ) )
                                   {   
                              if( CreateFile( AlternateFileName, GENERIC_WRITE, FILE_SHARE_READ, NULL,
                                              CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0 ) !=
                                              INVALID_HANDLE_VALUE )
                              {
                              }             
                                       }
                                    }
                                    break;      

                   case IDM_FIND:
                        if( ! hSearch )
                                     CreateDialogParam( GetModuleHandle( NULL ), ( LPCTSTR ) IDD_FINDDLG, hWnd, SearchProc, 0 );
                        break;

                   case IDM_REPLACE:
                        if( ! hSearch )
                           CreateDialogParam( GetModuleHandle( NULL ), ( LPCTSTR ) IDD_REPLACEDLG, hWnd, ReplaceProc, 0 );
                        break;

                   case IDM_GOTOLINE:
                        if( ! hSearch )
                                     CreateDialogParam( GetModuleHandle( NULL ), ( LPCTSTR ) IDD_GOTODLG, hWnd, GoToProc, 0 );
                        break;

                   case IDM_FINDNEXT:
                        if( lstrlen( FindBuffer ) )
                        {   
                                     SendMessage( hWndRichEdit, EM_EXGETSEL, 0, ( LPARAM ) &findtext.chrg );

                                     if( findtext.chrg.cpMin != findtext.chrg.cpMax )
                                          findtext.chrg.cpMin = findtext.chrg.cpMax;
                             
                                     findtext.chrg.cpMax = -1;
                                     findtext.lpstrText = FindBuffer;

                                     if( SendMessage( hWndRichEdit, EM_FINDTEXTEX, FR_DOWN, ( LPARAM ) &findtext ) != -1 )
                                        SendMessage( hWndRichEdit, EM_EXSETSEL, 0, ( LPARAM ) &findtext.chrgText );
                                  }
                                  break;      

                   case IDM_FINDPREV:
                        if( lstrlen( FindBuffer ) )
                        {   
                                     SendMessage( hWndRichEdit, EM_EXGETSEL, 0, ( LPARAM ) &findtext.chrg );
                             
                                     findtext.chrg.cpMax = 0;
                                     findtext.lpstrText = FindBuffer;
                             
                                     if( SendMessage( hWndRichEdit, EM_FINDTEXTEX, 0, ( LPARAM ) &findtext ) != -1 )
                                          SendMessage( hWndRichEdit, EM_EXSETSEL, 0, ( LPARAM ) &findtext.chrgText );
                                    }
                                    break;      

                   case IDM_EXIT:
                        SendMessage( hWnd, WM_CLOSE, 0, 0 );
                        break;
                }
             }  
             break;  
   
          case WM_CLOSE:
               if( CheckModifyState( hWnd ) )
               {
                    DeleteObject( hFont )
                      DestroyWindow( hWnd );
                   }  
                   break;
                 
          case WM_SIZE:
                 MoveWindow( hWndRichEdit, 0, 0, LOWORD( lParam ), HIWORD( lParam ), TRUE );
                 break;    
   
          case WM_DESTROY:
                 PostQuitMessage( 0 );
                 break;
     }     
   return DefWindowProc( hWnd, msg, wParam, lParam );      
}  

#pragma argsused

int PASCAL WinMain( HINSTANCE hInstance, HINSTANCE prev, LPSTR cmdline, int show )
{
   WNDCLASSEX wc;
   MSG msg;
   HWND hWnd;
   char * szClassName = "FreshClass";
   HACCEL hAccel;
   HINSTANCE hDll = LoadLibrary( "riched32" );
   
   wc.cbSize = sizeof( WNDCLASSEX );
   wc.style  = CS_HREDRAW | CS_VREDRAW;
   wc.lpfnWndProc = WndProc;
   wc.cbClsExtra  = 0;
   wc.cbWndExtra  = 0;
   wc.hInstance   = hInstance;
   wc.hbrBackground = GetStockObject( WHITE_BRUSH );
   wc.lpszMenuName  = ( LPCTSTR ) IDR_MAINMENU;
   wc.lpszClassName = szClassName;
   wc.hIcon = wc.hIconSm = LoadIcon( NULL, IDI_APPLICATION );
   wc.hCursor = LoadCursor( NULL, IDC_ARROW );
   RegisterClassEx( &wc );
   
   hWnd = CreateWindowEx( NULL, szClassName, "Fresh 1.0",
                          WS_OVERLAPPEDWINDOW, 70, 70,
                          1130, 630, 0, NULL, hInstance, NULL );
 
   ShowWindow( hWnd, SW_SHOWNORMAL );
   UpdateWindow( hWnd );
 
   hAccel = LoadAccelerators( hInstance, ( LPCTSTR ) IDR_MAINACCEL );
                 
     while( GetMessage( &msg, 0, 0, 0 ) )
     {
        if( IsDialogMessage( hSearch, &msg ) )
               TranslateAccelerator( hWnd, hAccel, &msg );
            else
            {
               TranslateMessage( &msg );
                 DispatchMessage( &msg );
            }
     }       

   FreeLibrary( hDll );

   return 0;
}


wordfile.txt
Code: Select all  Expand view
[ASSEMBLY]
C1=#include #pragma #ifdef #ifndef #else #endif #define
C2=CLASS ENDCLASS DATA CLASSDATA METHOD INLINE VIRTUAL SETGET ACCESS DEFAULT
C3=local static public private nil
C4=if else endif function return do case end otherwise endcase
C5=
C6=
C7=
C8=
C9=
C10=
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Antonio Linares
Site Admin
 
Posts: 42086
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain


Return to FiveWin for Harbour/xHarbour

Who is online

Users browsing this forum: Google [Bot] and 83 guests