GaryBeene scintilla Find/Replace ?

Started by Zlatko Vid, October 09, 2022, 11:41:56 AM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

Zlatko Vid

I don't know why this Gary snippet not work
anyone can explain what is missing ?

Quote'Primary Code:
'Other than the PowerBASIC code that creates the Find & Replace dialog itself, there are
'only 3 procedures which do most of the work FindNext(), ReplaceOnce(), and ReplaceAll().
'Within those procedures here are the Scintilla messages that are used to implement
'Find & Replace.

'The selected text position and length is found with these two messages:
  '%SCI_GetCurrentPos
' %SCI_GetLength

'The position/length information is used to find the next occurrence of a text string
'using this message:
' %SCI_FindText

'After text is found, it is selected with this message:
  ' %SCI_SetSel

'Then, if required, replacement of the selected text is done with this message:
  ' %SCI_ReplaceSel



'Compilable Example:  (Jose Includes)
#COMPILER PBWIN 9, PBWIN 10
#COMPILE EXE
#DIM ALL
%Unicode=1
#INCLUDE "Win32API.inc"
#INCLUDE "scintilla_gb.inc"
#RESOURCE "gbsnippets.pbr"

%IDF_FindThis     = 5001 : %IDF_FindText     = 5002 : %IDF_ReplaceThis  = 5003
%IDF_ReplaceText  = 5004 : %IDF_Find         = 5005 : %IDF_Replace      = 5006
%IDF_ReplaceAll   = 5007 : %IDF_Close        = 5008 : %IDF_MatchCase    = 5009
%IDF_MatchWhole   = 5010 : %IDF_Up           = 5011 : %IDF_Down         = 5012

%ID_Sci = 1000 : %ID_BtnA = 1001 : %ID_BtnB = 1002
GLOBAL hDlg, hSci, hLib, hFind AS DWORD

GLOBAL xFindText, xReplaceText, SelectedText AS STRING
GLOBAL MatchWord, MatchCase, Direction, FindFlags, SelLength, Anchor, CurPos AS LONG
GLOBAL FindStructure AS Sci_TextToFind

FUNCTION PBMAIN() AS LONG
   hLib = LoadLibrary("SCILEXER.DLL")
   DIALOG NEW PIXELS, 0, "Scintilla Example",300,300,320,160, %WS_OVERLAPPEDWINDOW TO hDlg
   CONTROL ADD BUTTON, hDlg, %ID_BtnA, "Find", 10,10,70,20, %WS_CHILD OR %WS_VISIBLE
   CONTROL ADD "Scintilla", hDlg, %ID_Sci, "", 100,10,180,130, %WS_CHILD OR %WS_VISIBLE
   CONTROL HANDLE hDlg, %ID_Sci TO hSci     'get handle to Scintilla window
   DIALOG SHOW MODAL hDlg CALL DlgProc
END FUNCTION

CALLBACK FUNCTION DlgProc() AS LONG
   LOCAL TXT AS STRING
   TXT = "Select Case var$ 'first line" + $CRLF + "End Select 'last line" + CHR$(0)
   SELECT CASE CB.MSG
      CASE %WM_INITDIALOG
         BuildAcceleratorTable
         InitializeScintilla
         PostMessage hSci, %SCI_SetSel, 0,0 'unselect initially
      CASE %WM_COMMAND
         SELECT CASE CB.CTL
            CASE %ID_BtnA : DisplayFindDialog
         END SELECT
      CASE %WM_SIZE
         CONTROL SET SIZE hDlg, %ID_Sci, LO(WORD, CB.LPARAM)-110, HI(WORD, CB.LPARAM)-20
      CASE %WM_DESTROY
         IF hLib THEN FreeLibrary hLib      'free the Scintilla library
   END SELECT
END FUNCTION

SUB InitializeScintilla
   LOCAL TXT AS STRING
   TXT = "If x = 2 Then" + $CRLF + "   'do nothing" + $CRLF
   TXT = TXT + "Else" + $CRLF + "   'keep doing NOTHING"
   TXT = TXT + $CRLF + "   'still nothinge" + $CRLF + "End If" + CHR$(0)
   SendMessage hSci, %SCI_SetText, 0, STRPTR(TXT)
   SendMessage hSci, %SCI_SetMarginWidthN, 0, 20
END SUB

SUB BuildAcceleratorTable
   LOCAL c AS LONG, ac() AS ACCELAPI, hAccelerator AS DWORD  ' for keyboard accelator table values
   DIM ac(1)
   ac(c).fvirt = %FVIRTKEY OR %FCONTROL : ac(c).key   = %VK_F : ac(c).cmd   = %ID_BtnA     : INCR c
   ac(c).fvirt = %FVIRTKEY              : ac(c).key   = %VK_F3 : ac(c).cmd  = %ID_BtnA     : INCR c
   ACCEL ATTACH hDlg, AC() TO hAccelerator
END SUB

   %IDF_FindThis     = 5001 : %IDF_FindText     = 5002 : %IDF_ReplaceThis  = 5003
   %IDF_ReplaceText  = 5004 : %IDF_Find         = 5005 : %IDF_Replace      = 5006
   %IDF_ReplaceAll   = 5007 : %IDF_Close        = 5008 : %IDF_MatchCase    = 5009
   %IDF_MatchWord    = 5010 : %IDF_Up           = 5011 : %IDF_Down         = 5012

SUB DisplayFindDialog()
   LOCAL h AS LONG, w AS LONG
   DIALOG GET CLIENT hDlg TO h,w
   DIALOG NEW PIXELS, hDlg, "Find & Replace", 100, 100, 360, 130, %WS_SYSMENU OR %WS_CAPTION OR %WS_CLIPCHILDREN TO hFind
   DIALOG SET ICON hFind, "aainfo"

   CONTROL ADD LABEL, hFind, %IDF_FindThis, "Find This:", 5, 10, 60, 20
   CONTROL ADD LABEL, hFind, %IDF_ReplaceThis, "Replace With:", 5, 40, 70, 20
   CONTROL ADD TEXTBOX, hFind, %IDF_FindText, "", 80, 10, 185, 20
   CONTROL ADD TEXTBOX, hFind, %IDF_ReplaceText, "", 80, 40, 185, 20

   CONTROL ADD CHECKBOX, hFind, %IDF_MatchCase, "Match Case", 15, 70, 90, 20
   CONTROL ADD CHECKBOX, hFind, %IDF_MatchWord, "Match Whole Word", 15, 90, 120, 20
   CONTROL ADD OPTION, hFind, %IDF_UP, "Up", 165, 70, 90, 20
   CONTROL ADD OPTION, hFind, %IDF_Down, "Down", 165, 90, 90, 20
   CONTROL SET OPTION hFind, %IDF_Down, %IDF_Up, %IDF_Down

   CONTROL ADD BUTTON, hFind, %IDF_Find, "Find Next", 275, 10, 75, 20
   CONTROL ADD BUTTON, hFind, %IDF_Replace, "Replace", 275, 40, 75, 20
   CONTROL ADD BUTTON, hFind, %IDF_ReplaceAll, "Replace All", 275, 65, 75, 20
   CONTROL ADD BUTTON, hFind, %IDCANCEL, "Close", 275, 100, 75, 20

   DIALOG SHOW MODAL hFind CALL SearchProc()
END SUB

   'Find dialog equates
   %IDF_FindThis     = 5001 : %IDF_FindText     = 5002 : %IDF_ReplaceThis  = 5003
   %IDF_ReplaceText  = 5004 : %IDF_Find         = 5005 : %IDF_Replace      = 5006
   %IDF_ReplaceAll   = 5007 : %IDF_Close        = 5008 : %IDF_MatchCase    = 5009
   %IDF_MatchWhole   = 5010 : %IDF_Up           = 5011 : %IDF_Down         = 5012

CALLBACK FUNCTION SearchProc() AS LONG
   LOCAL iCheck&, x AS LONG, y AS LONG
   SELECT CASE CB.MSG
      CASE %WM_INITDIALOG
         'get selected text and put into the FindText textbox
         SelLength = SendMessage(hSci, %SCI_GetSelText, 0, 0)       'get length of selected text with Chr$(0)
         SelectedText = STRING$(SelLength," ")                      'set buffer to that length
         SendMessage hSci, %SCI_GetSelText, 0, STRPTR(SelectedText) 'selected text + chr$(0)
         CONTROL SET TEXT hFind, %IDF_FindText, SelectedText
         GetFindDialogData
         EnableFindButtons
      CASE %WM_SYSCOMMAND
         IF (CB.WPARAM AND &HFFF0) = %SC_CLOSE THEN          'trap Alt-F4 and X Button
            CONTROL SET FOCUS hDlg, %ID_Sci
         END IF
      CASE %WM_COMMAND
         SELECT CASE CB.CTL
            CASE %IDCANCEL
               DIALOG END hFind
            CASE %IDF_Find       : FindNext(1)      'find, with warning
            CASE %IDF_Replace    : ReplaceOnce(0)   'replace current selection
            CASE %IDF_ReplaceAll : ReplaceAll       'replace all without warning
            CASE %IDF_CLose      : DIALOG END hFind
            CASE %IDF_FindText, %IDF_ReplaceText
               IF CB.CTLMSG = %EN_CHANGE THEN GetFindDialogData : EnableFindButtons
         END SELECT
      CASE %WM_DESTROY
         CONTROL SET FOCUS hDlg, %ID_Sci               'focus
         DIALOG END hFind
   END SELECT
END FUNCTION

FUNCTION FindNext(warning AS LONG) AS LONG
   LOCAL iResult AS LONG
   GetFindDialogData
   FindStructure.Chrg.cpMin = SendMessage(hSci,IIF(Direction, %SCI_GetCurrentPos, %SCI_GetAnchor),0,0) 'if up-curpos, if down-anchor
   FindStructure.Chrg.cpMax = Direction * SendMessage(hSci,%SCI_GetLength,0,0) 'if up-length   if down-0
   FindStructure.lpstrText = STRPTR(xFindText)
   iResult = SendMessage (hSci, %SCI_FindText, FindFlags, VARPTR(FindStructure))
   IF iResult = -1 THEN
      FUNCTION = 0   'no match
      IF Warning = 1 THEN
         IF Direction = 1 THEN MSGBOX "Match not found between current position and end of document!", %MB_OK OR %MB_ICONEXCLAMATION, "Find Text"
         IF Direction = 0 THEN MSGBOX "Match not found between current position and beginning of document!", %MB_OK OR %MB_ICONEXCLAMATION, "Find Text"
      END IF
   ELSE
      FUNCTION = 1   'match found
      SendMessage hSci, %SCI_SetSel, FindStructure.ChrgText.cpMin, FindStructure.ChrgText.cpMax
   END IF
END FUNCTION

FUNCTION ReplaceOnce(Repeat AS LONG) AS LONG
   GetFindDialogData
   IF SelLength = 1 THEN
      FUNCTION = 0
      IF Repeat = 0 THEN MSGBOX "No text selected for replacement!", %MB_OK OR %MB_ICONEXCLAMATION, "Find Text"  'notify user
      EXIT FUNCTION                               'exit if no selection and a Replace is in work
   END IF
   FUNCTION = 1
   SendMessage hSci, %SCI_ReplaceSel, 0, STRPTR(xReplaceText)
   FindNext(0)
END FUNCTION

SUB ReplaceAll
   LOCAL iResult AS LONG
   iResult = ReplaceOnce(1)
   DO WHILE iResult
      iResult = ReplaceOnce(1)
   LOOP
END SUB

SUB GetFindDialogData
   CONTROL GET TEXT hFind, %IDF_FindText TO xFindText          'find text
   IF TRIM$(xFindText)="" THEN EXIT SUB                        'no action is FindText is empty
   CONTROL GET TEXT hFind, %IDF_ReplaceText TO xReplaceText    'replace text
   xReplaceText = xReplaceText + CHR$(0)                        'replace text + chr$(0)
   xFindText = xFindText + CHR$(0)                              'find text + chr$(0)
   CONTROL GET CHECK hFind, %IDF_MatchWord TO MatchWord       'find whole words
   CONTROL GET CHECK hFind, %IDF_MatchCase TO MatchCase       'match case
   CONTROL GET CHECK hFind, %IDF_Down TO Direction            '1=down 0=up
   FindFlags = MatchCase * %SCFind_MatchCase + MatchWord * %SCFind_WholeWord  'search constraints
   SelLength = SendMessage(hSci, %SCI_GetSelText, 0, 0)       'get length of selected text with Chr$(0)
   SelectedText = STRING$(SelLength," ")                      'set buffer to that length
   SendMessage hSci, %SCI_GetSelText, 0, STRPTR(SelectedText) 'selected text + chr$(0)
   Anchor = SendMessage(hSci, %SCI_GetAnchor, 0, 0)           'anchor
   CurPos = SendMessage(hSci, %SCI_GetCurrentPos,0,0)         'current position
END SUB

SUB EnableFindButtons
   IF TRIM$(xFindText) = CHR$(0) THEN
      CONTROL DISABLE hFind, %IDF_Find : CONTROL DISABLE hFind, %IDF_ReplaceAll
   ELSE
      CONTROL ENABLE hFind, %IDF_Find  : CONTROL ENABLE hFind, %IDF_Find
   END IF
   IF SelLength THEN
      CONTROL ENABLE hFind, %IDF_Replace
   ELSE
      CONTROL DISABLE hFind, %IDF_Replace
   END IF
END SUB

   '  If ((MatchCase=1) AND (FindText = SelectedText)) Or ((MatchCase=0) AND (LCase$(FindText)=LCase$(SelectedText))) Then
   '  End If

Most problematic part are this 3 functions
Powerbasic use strange IIF ..so how this replace with o2 code
any clue?

FUNCTION FindNext(warning AS LONG) AS LONG
   LOCAL iResult AS LONG
   GetFindDialogData
   FindStructure.Chrg.cpMin = SendMessage(hSci,IIF(Direction, %SCI_GetCurrentPos, %SCI_GetAnchor),0,0) 'if up-curpos, if down-anchor
   FindStructure.Chrg.cpMax = Direction * SendMessage(hSci,%SCI_GetLength,0,0) 'if up-length   if down-0
   FindStructure.lpstrText = STRPTR(xFindText)
   iResult = SendMessage (hSci, %SCI_FindText, FindFlags, VARPTR(FindStructure))
   IF iResult = -1 THEN
      FUNCTION = 0   'no match
      IF Warning = 1 THEN
         IF Direction = 1 THEN MSGBOX "Match not found between current position and end of document!", %MB_OK OR %MB_ICONEXCLAMATION, "Find Text"
         IF Direction = 0 THEN MSGBOX "Match not found between current position and beginning of document!", %MB_OK OR %MB_ICONEXCLAMATION, "Find Text"
      END IF
   ELSE
      FUNCTION = 1   'match found
      SendMessage hSci, %SCI_SetSel, FindStructure.ChrgText.cpMin, FindStructure.ChrgText.cpMax
   END IF
END FUNCTION

FUNCTION ReplaceOnce(Repeat AS LONG) AS LONG
   GetFindDialogData
   IF SelLength = 1 THEN
      FUNCTION = 0
      IF Repeat = 0 THEN MSGBOX "No text selected for replacement!", %MB_OK OR %MB_ICONEXCLAMATION, "Find Text"  'notify user
      EXIT FUNCTION                               'exit if no selection and a Replace is in work
   END IF
   FUNCTION = 1
   SendMessage hSci, %SCI_ReplaceSel, 0, STRPTR(xReplaceText)
   FindNext(0)
END FUNCTION

SUB ReplaceAll
   LOCAL iResult AS LONG
   iResult = ReplaceOnce(1)
   DO WHILE iResult
      iResult = ReplaceOnce(1)
   LOOP
END SUB