Search in RichEdit 5

Search in RichEdit 5

Postby Natter » Fri Oct 27, 2023 1:48 pm

Hi,

Search in RichEdit5. I need to find in it all the positions of underlined characters on a white background.
Is it possible to do this ?
Natter
 
Posts: 1120
Joined: Mon May 14, 2007 9:49 am

Re: Search in RichEdit 5

Postby Jimmy » Fri Oct 27, 2023 5:00 pm

hi Natter,

i "think" that "commdlg_FindReplace" also work with RTF

Problem : Fivewin have "only" CLASS TDlgFind ( c:\fwh\source\classes\dlgfind.prg )

---

have "begin" to re-write HMG for FiveWin to REDIFEINE "commdlg_FindReplace"
Code: Select all  Expand view
FUNCTION DlgFindReplace( cFind, oWnd, bSearch, lReplace, cReplace, cTitle, lNoUpDown, lNoMatchCase, lNoWholeWord, lCheckDown, lCheckMatchCase, lCheckWholeWord, nClrText, nClrBack, oMGet, cMemo, oBrush )
LOCAL oDlg
   IF FINDREPLACEDLGISRELEASE() == .F.
      FINDREPLACEDLGRELEASE( .T. )
   ENDIF
   oDlg := TDlgReplace() :New( cFind, oWnd, bSearch, lReplace, cReplace, cTitle, lNoUpDown, lNoMatchCase, lNoWholeWord, lCheckDown, lCheckMatchCase, lCheckWholeWord, nClrText, nClrBack, oMGet, cMemo, oBrush )
RETURN oDlg

Code: Select all  Expand view
CLASS TDlgReplace FROM TDialog

   CLASSDATA nFindMsgString

   DATA l410 INIT .F.
   DATA l411 INIT .F.
   DATA nStartReplace INIT 1
   DATA cFind INIT ""
   DATA bSearch INIT { || NIL }
   DATA lReplace INIT .T.
   DATA cReplace INIT ""
   DATA cTitle INIT "Search / Replace"
   DATA lNoUpDown INIT .F.
   DATA lNoMatchCase INIT .F.
   DATA lNoWholeWord INIT .F.
   DATA lCheckDown INIT .F.
   DATA lCheckMatchCase INIT .F.
   DATA lCheckWholeWord INIT .F.
   DATA nClrText INIT GetSysColor( COLOR_BTNTEXT )
   DATA nClrBack INIT GetSysColor( COLOR_BTNFACE )
   DATA oMGet
   DATA cMemo INIT ""
   DATA BackColor INIT CreateSolidBrush( BGcolor )

   METHOD New( cText, oWnd, bSearch, lReplace, cReplace, cTitle, lNoUpDown, lNoMatchCase, lNoWholeWord, lCheckDown, lCheckMatchCase, lCheckWholeWord, nClrText, nClrBack, oMGet, cMemo ) CONSTRUCTOR
   METHOD DoRunOnce()
   METHOD FindReplTXTProc( oMGet, cFind, cMemo )

ENDCLASS

METHOD New( cFind, oWnd, bSearch, lReplace, cReplace, cTitle, lNoUpDown, lNoMatchCase, lNoWholeWord, lCheckDown, lCheckMatchCase, lCheckWholeWord, nClrText, nClrBack, oMGet, cMemo, oBrush ) CLASS TDlgReplace
LOCAL nFindMsgString, lForward := .T.
LOCAL bMethod
LOCAL hThread
LOCAL ox1, ox2, hWnd, hDC
LOCAL oGrp, oRadio
LOCAL nRadio         := 2

   DEFAULT oWnd := GetWndDefault()
   DEFAULT bSearch := { || NIL }
   DEFAULT lReplace := .T.
   DEFAULT cReplace := ""
   DEFAULT cTitle := "Find and Replace"

   DEFAULT lNoUpDown := .F.
   DEFAULT lNoMatchCase := .F.
   DEFAULT lNoWholeWord := .F.
   DEFAULT lCheckDown := .F.
   DEFAULT lCheckMatchCase := .F.
   DEFAULT lCheckWholeWord := .F.

   DEFAULT nClrText := GetSysColor( COLOR_BTNTEXT )
   DEFAULT nClrBack := GetSysColor( COLOR_BTNFACE )

   ::oWnd := oWnd

   ::cFind := cFind
   ::bSearch := bSearch
   ::lReplace := lReplace
   ::cReplace := cReplace
   ::cTitle := cTitle
   ::nClrText := nClrText
   ::nClrBack := nClrBack
   ::oMGet := oMGet
   ::cMemo := cMemo

   ::lNoUpDown := lNoUpDown
   ::lNoMatchCase := lNoMatchCase
   ::lNoWholeWord := lNoWholeWord
   ::lCheckDown := lCheckDown
   ::lCheckMatchCase := lCheckMatchCase
   ::lCheckWholeWord := lCheckWholeWord

   ::lModal := .F.
   ::lCentered := .T.
   ::lHelpIcon := .F.
   ::lTransparent := .F.
   ::lResize16 := .F.
   ::lCenterInWnd := .T.
   ::aControls := {}

   //    RegDialog( ::hWnd := FindText( cFind, oWnd:hWnd, @nFindMsgString ) )
   RegDialog( ::hWnd := FindReplaceDlg( NIL, ;
              lNoUpDown, ;
              lNoMatchCase, ;
              lNoWholeWord, ;
              lCheckDown, ;
              lCheckMatchCase, ;
              lCheckWholeWord, ;
              cFind, ;
              cReplace, ;
              lReplace, ;
              cTitle ) )

   REDEFINE BUTTON ID IDOK OF Self ;
           ACTION EVAL( ::bSearch, ;
           GetWindowText( GetWindow( GetWindow( ::hWnd, GW_CHILD ), GW_HWNDNEXT ) ), ;
           lForward, Self )

   IF lReplace = .T.
      REDEFINE BUTTON ID 0x400 OF Self ;
              ACTION GetWindowText( GetWindow( GetWindow( ::hWnd, GW_CHILD ), GW_HWNDNEXT ) )

      REDEFINE BUTTON ID 0x401 OF Self ;
              ACTION GetWindowText( GetWindow( GetWindow( ::hWnd, GW_CHILD ), GW_HWNDNEXT ) )
   ELSE
      REDEFINE GROUP oGrp ID 0x430 OF Self
      REDEFINE RADIO oRadio VAR nRadio ID 0x420, 0x421 OF Self
   ENDIF

   REDEFINE BUTTON ID IDCANCEL OF Self
   //    REDEFINE BTNBMP ID IDCANCEL OF Self ACTION MsgInfo( "IDCANCEL" )
   //    REDEFINE BTNBMP ID IDCANCEL OF Self ACTION ::SendMsg( oWnd:hWnd, _HMG_MsgIDFindDlg )

   REDEFINE CHECKBOX ::l410 ID 0x410 OF Self ;
           ON CHANGE MsgInfo( "410" )

   REDEFINE CHECKBOX ::l411 ID 0x411 OF Self ;
           ON CHANGE MsgInfo( "411" )

   SetWindowTheme( ::hWnd, "", "" )

   IF ::Initiate()
      ::SetColor( nClrText, nClrBack )
      ::SetFocus()
   ENDIF

   IF ::nFindMsgString == nil
      ::nFindMsgString = nFindMsgString
   ENDIF

   INVALIDATERECT( ::hWnd )

   bMethod := { || ::DoRunOnce( ::hWnd, nClrText, nClrBack, oBrush ) }
   hThread := hb_threadDetach( hb_threadStart( HB_BITOR( HB_THREAD_INHERIT_PUBLIC, HB_THREAD_MEMVARS_COPY ), @bMethod ) )

   ::Link( .F. )

   ::bKeyDown := { | nKey, nFlag | IF( nKey = VK_ESCAPE, ::End(), nil ) }

RETURN Self

Code: Select all  Expand view
METHOD FindReplTXTProc( oMGet, cFind, cMemo, cReplace, lReplace ) CLASS TDlgReplace
LOCAL nPosi, nLine
LOCAL nCtrl := 0
LOCAL lRet  := .T.
LOCAL nRow, nRowStart
LOCAL nCol

   //  FWLOG "FindReplTXTProc(", _HMG_FindReplaceOptions

   IF NIL <> FindReplaceDlg.RetValue
      nCtrl := FindReplaceDlg.RetValue
   ENDIF
   IF NIL <> FindReplaceDlg.Find
      cFind := FindReplaceDlg.Find
   ENDIF
   IF NIL <> FindReplaceDlg.Replace
      cReplace := FindReplaceDlg.Replace
   ENDIF

   nPosi := hb_at( UPPER( cFind ), UPPER( cMemo ), ::nStartReplace )
   //  FWLOG "suche ... ", cFind, ::nStartReplace, nPosi, nCtrl

   IF nPosi > 0
      nRowStart := oMGet:GetRow()

      oMGet:nPos := nPosi
      // must setfocus else NO Color
      oMGet:Setfocus()
      oMGet:SetSel( nPosi - 1, nPosi + LEN( cFind ) - 1 )

      nRow := oMGet:GetRow()
      oMGet:SendMsg( EM_LINESCROLL, 0, nRow - nRowStart - 1 )

      oMGet:SetSel( nPosi - 1, nPosi + LEN( cFind ) - 1 )

      DO CASE
         CASE nCtrl = 1
         CASE nCtrl = 2
            IF lReplace
               oMGet:Replace( cReplace )
            ELSE
               DeleteObject( ::BackColor )
            ENDIF
         CASE nCtrl = 3
            oMGet:Replace( cReplace )
            ::nStartReplace := nPosi + 1
            ::FindReplTXTProc( oMGet, cFind, cMemo )
         CASE nCtrl = 4 .OR. nCtrl = 0
            DeleteObject( ::BackColor )
      ENDCASE
      //      ::nStartReplace := nPosi + 1
      ::nStartReplace := nPosi
   ELSE
      msginfo( "no more found" )
      lRet := .F.
   ENDIF

RETURN lRet

but i have Problem with UNICODE in HB_FUNC() ( ANSI Version work )
Code: Select all  Expand view
static TCHAR       cFindWhat[ 1024 ];
static TCHAR       cReplaceWith[ 1024 ];
static FINDREPLACE FindReplace;
static HWND        hDlgFindReplace = NULL;

HB_FUNC( REGISTERFINDMSGSTRING )
{
   UINT MessageID = RegisterWindowMessage( FINDMSGSTRING );
   hb_retnl( ( LONG ) MessageID );
}

Code: Select all  Expand view
HB_FUNC( FINDREPLACEDLG )
{
//   HWND hWnd           = HB_ISNIL( 1 ) ? GetActiveWindow() : ( HWND ) hb_parnl( 1 );
   HWND hWnd           = GetActiveWindow() ;
   BOOL NoUpDown       = ( BOOL ) ( HB_ISNIL( 2 ) ? FALSE : hb_parl( 2 ) );
   BOOL NoMatchCase    = ( BOOL ) ( HB_ISNIL( 3 ) ? FALSE : hb_parl( 3 ) );
   BOOL NoWholeWord    = ( BOOL ) ( HB_ISNIL( 4 ) ? FALSE : hb_parl( 4 ) );
   BOOL CheckDown      = ( BOOL ) ( HB_ISNIL( 5 ) ? TRUE  : hb_parl( 5 ) );
   BOOL CheckMatchCase = ( BOOL ) ( HB_ISNIL( 6 ) ? FALSE : hb_parl( 6 ) );
   BOOL CheckWholeWord = ( BOOL ) ( HB_ISNIL( 7 ) ? FALSE : hb_parl( 7 ) );
   BOOL lReplace       = ( BOOL ) hb_parl( 10 );

#ifndef UNICODE
   LPSTR FindWhat    = ( LPSTR ) hb_parc( 8 );
   LPSTR ReplaceWith = ( LPSTR ) hb_parc( 9 );
   LPSTR cTitle      = ( LPSTR ) hb_parc( 11 );
#else
   LPWSTR FindWhat    = AnsiToWide( ( TCHAR * ) hb_parc( 8 ) );
   LPWSTR ReplaceWith = AnsiToWide( ( TCHAR * ) hb_parc( 9 ) );
   LPWSTR cTitle      = AnsiToWide( ( TCHAR * ) hb_parc( 11 ) );
#endif

   if( hDlgFindReplace == NULL )
   {
      ZeroMemory( &FindReplace, sizeof( FindReplace ) );

      lstrcpy( cFindWhat   , TEXT(FindWhat   ) );
      lstrcpy( cReplaceWith, TEXT(ReplaceWith) );

      FindReplace.lStructSize = sizeof( FindReplace );
      FindReplace.Flags       = ( NoUpDown ? FR_HIDEUPDOWN : 0 ) | ( NoMatchCase ? FR_HIDEMATCHCASE : 0 ) | ( NoWholeWord ? FR_HIDEWHOLEWORD : 0 )
                              | ( CheckDown ? FR_DOWN : 0 ) | ( CheckMatchCase ? FR_MATCHCASE : 0 ) | ( CheckWholeWord ? FR_WHOLEWORD : 0 );
      FindReplace.hwndOwner        = hWnd;
      FindReplace.lpstrFindWhat    = cFindWhat;
      FindReplace.wFindWhatLen     = sizeof( cFindWhat ) / sizeof( TCHAR );
      FindReplace.lpstrReplaceWith = cReplaceWith;
      FindReplace.wReplaceWithLen  = sizeof( cReplaceWith ) / sizeof( TCHAR );

      if( lReplace )
         hDlgFindReplace = ReplaceText( &FindReplace );
      else
         hDlgFindReplace = FindText( &FindReplace );

      if( HB_ISCHAR( 11 ) )
         SetWindowText( hDlgFindReplace, cTitle );

      ShowWindow( hDlgFindReplace, SW_SHOW );
   }

#ifdef UNICODE
   hb_xfree( ( TCHAR * ) FindWhat );
   hb_xfree( ( TCHAR * ) ReplaceWith );
   hb_xfree( ( TCHAR * ) cTitle );
#endif

   #ifndef _WIN64
    hb_retnl( ( LONG ) hDlgFindReplace );
   #else
    hb_retnll( ( LONGLONG ) hDlgFindReplace );
   #endif
}

Code: Select all  Expand view
HB_FUNC( FINDREPLACEDLGGETOPTIONS )
{
   #ifndef _WIN64
      LPARAM lParam = (LPARAM) hb_parnl (1);
   #else
      LPARAM lParam = (LPARAM) hb_parnll (1);
   #endif
   FINDREPLACE *FR = (FINDREPLACE *) lParam;
   LONG nRet = -1;
   LPSTR pStr;

   if ( FR->Flags & FR_DIALOGTERM )
       nRet =  0;

   if ( FR->Flags & FR_FINDNEXT )
       nRet =  1;

   if ( FR->Flags & FR_REPLACE )
       nRet =  2;

   if ( FR->Flags & FR_REPLACEALL )
       nRet =  3;

   hb_reta (6);

   hb_storvnl ( (LONG) nRet,                       -1,  1 );

   #ifndef UNICODE
      hb_storvc (  FR->lpstrFindWhat,              -1,  2 );
      hb_storvc (  FR->lpstrReplaceWith,           -1,  3 );
   #else
      pStr = WideToAnsi( ( WCHAR *) FR->lpstrFindWhat );
      hb_storvc (  pStr,                           -1,  2 );
      pStr = WideToAnsi( ( WCHAR *) FR->lpstrReplaceWith );
      hb_storvc (  pStr,                           -1,  3 );
   #endif

   hb_storvl  ( (BOOL) (FR->Flags & FR_DOWN),      -1,  4 );
   hb_storvl  ( (BOOL) (FR->Flags & FR_MATCHCASE), -1,  5 );
   hb_storvl  ( (BOOL) (FR->Flags & FR_WHOLEWORD), -1,  6 );
}
greeting,
Jimmy
User avatar
Jimmy
 
Posts: 1585
Joined: Thu Sep 05, 2019 5:32 am
Location: Hamburg, Germany

Re: Search in RichEdit 5

Postby Natter » Fri Oct 27, 2023 7:07 pm

Hi Jimmy,

Thanks for the help. I think to do so:
1. Open an RTF document via OLE and do a search (via VBA) for all underlined characters to get an array of their positions.
2. Upload an RTF document to RichEdit5 and color it according to the parsing of its structure. At the same time, I also get an array of colorized characters
3. Compare these 2 arrays
Natter
 
Posts: 1120
Joined: Mon May 14, 2007 9:49 am


Return to FiveWin for Harbour/xHarbour

Who is online

Users browsing this forum: No registered users and 93 guests