Advertisement
AZJIO

Example Scintilla PureBasic

Jan 3rd, 2021
2,943
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. EnableExplicit
  2. InitScintilla()
  3.  
  4. ; #MENU_EXTEND_SELECTION=10
  5. Define txt$, txtLen, marginWidth, Gadget
  6. Declare Color(*regex, regexLength, n)
  7. Declare Color2(*regex, regexLength, n)
  8. Declare MakeUTF8Text(text.s)
  9. Declare MakeScintillaText(text.s, *sciLength.Integer=0)
  10. Declare OpenFileR(*sciLength.Integer=0)
  11. Declare SciNotification(Gadget, *scinotify.SCNotification)
  12. Declare ReadFileR(Path$)
  13.  
  14. ; Procedure ExtendScintillaSelection()
  15. ;    Protected mainSel, selStart, selEnd
  16. ;    mainSel=ScintillaSendMessage(0, #SCI_GETMAINSELECTION)
  17. ;    selStart=ScintillaSendMessage(0, #SCI_GETSELECTIONNSTART, mainSel)
  18. ;    selEnd=ScintillaSendMessage(0, #SCI_GETSELECTIONNEND, mainSel)
  19. ;
  20. ; EndProcedure
  21.  
  22. txt$="Вставка теста "+#LF$+
  23. "вы можете  использовать это код как пример работы со Scintilla"+#LF$+
  24. "ссылка http://purebasic.info/phpBB3ex/index.php"+#LF$+
  25. "Это поиск, маркеры, стилизация, и т.д. 2222 "+#LF$
  26. ; Define i
  27. ; For i = 1 To 500
  28. ;   txt$+#LF$+"Line: "+Str(i)
  29. ; Next
  30. txtLen=StringByteLength(txt$, #PB_UTF8)
  31.  
  32.  
  33. OpenWindow(100, 0, 0, 900, 600, "Редактор Scintilla", #PB_Window_SystemMenu | #PB_Window_ScreenCentered | #PB_Window_SizeGadget | #PB_Window_MaximizeGadget | #PB_Window_MinimizeGadget)
  34.  
  35. ; Создание гаджета размером на всё окно
  36. ScintillaGadget(0, 0, 0, WindowWidth(100), WindowHeight(100), @SciNotification())
  37. ; Устанавливает режим текста
  38. ScintillaSendMessage(0, #SCI_SETWRAPMODE, #SC_WRAP_NONE) ; без переносов строк
  39. ScintillaSendMessage(0, #SCI_SETCODEPAGE, #SC_CP_UTF8)   ; в кодировке UTF-8
  40.                                                          ; ScintillaSendMessage(0, #SCI_SETVIRTUALSPACEOPTIONS, #SCVS_RECTANGULARSELECTION | #SCVS_USERACCESSIBLE) ; позволить установить курсор и выделение за пределами конца строки
  41.                                                          ; Устанавливает текущую подсветку строки
  42. ScintillaSendMessage(0, #SCI_SETCARETLINEVISIBLE, 1)     ; подсвечивает текущую строку
  43. ScintillaSendMessage(0, #SCI_SETCARETLINEVISIBLEALWAYS, 1) ; подсвечивает всегда, даже при потере фокуса
  44.                                                            ; ScintillaSendMessage(0, #SCI_SETCARETLINEBACKALPHA, 255) ; прозрачность подсветки текущей строки (0-255), 255 прозрачна на 100%
  45. ScintillaSendMessage(0, #SCI_SETCARETLINEBACK, RGB(0, 0, 0)) ; цвет подсвеченной строки
  46.                                                              ; Устанавливает стиль текста
  47. ScintillaSendMessage(0, #SCI_STYLESETFONT, #STYLE_DEFAULT, MakeUTF8Text("Arial")) ; выделение прямоугольником лучше работает с моноширинным шрифтом Courier New
  48. ScintillaSendMessage(0, #SCI_STYLESETBACK, #STYLE_DEFAULT, RGB(63, 63, 63))       ; цвет фона
  49. ScintillaSendMessage(0, #SCI_STYLESETFORE, #STYLE_DEFAULT, RGB(153, 153, 153))    ; цвет текста
  50. ScintillaSendMessage(0, #SCI_STYLECLEARALL)
  51. ; Устанавливает размер отступа и стиль колонки номеров строк
  52. ScintillaSendMessage(0, #SCI_STYLESETFONT, #STYLE_LINENUMBER, MakeUTF8Text("Arial")) ; шрифт номеров строк
  53. ScintillaSendMessage(0, #SCI_STYLESETBACK, #STYLE_LINENUMBER, RGB(33, 33, 33))       ; цвет фона поля номеров строк
  54. ScintillaSendMessage(0, #SCI_STYLESETFORE, #STYLE_LINENUMBER, RGB(153, 153, 153))    ; цвет текста поля номеров строк
  55. marginWidth=ScintillaSendMessage(0, #SCI_TEXTWIDTH, #STYLE_LINENUMBER, MakeUTF8Text("_999")) ; ширина поля номеров строк
  56. ScintillaSendMessage(0, #SCI_SETMARGINTYPEN, 0, #SC_MARGIN_NUMBER)
  57. ScintillaSendMessage(0, #SCI_SETMARGINWIDTHN, 0, marginWidth) ; Устанавливает ширину поля номеров строк
  58. marginWidth=0
  59. ScintillaSendMessage(0, #SCI_SETMARGINMASKN, 2, #SC_MASK_FOLDERS) ; Устанавливает отступ для поля свёртывания с запасом сгиба
  60. ScintillaSendMessage(0, #SCI_SETMARGINWIDTHN, 2, marginWidth)     ; Устанавливает ширину поля свёртывания
  61. ScintillaSendMessage(0, #SCI_SETMARGINSENSITIVEN, 2, #True)       ; Устанавливает чуствительность поля к клику
  62.                                                                   ; Устанавливает стиль текстовго курсора и выделения
  63. ScintillaSendMessage(0, #SCI_SETCARETSTICKY, 1)                   ; делает всегда видимым (?)
  64. ScintillaSendMessage(0, #SCI_SETCARETWIDTH, 1)                    ; толщина текстовго курсора
  65. ScintillaSendMessage(0, #SCI_SETCARETFORE, RGB(255, 255, 255))    ; цвет текстовго курсора
  66. ScintillaSendMessage(0, #SCI_SETSELALPHA, 100)                    ; прозрачность выделения
  67. ScintillaSendMessage(0, #SCI_SETSELBACK, 1, RGB(255, 255, 255))   ; цвет фона выделения
  68. ScintillaSendMessage(0, #SCI_SETSELFORE, 1, RGB(160, 160, 160))   ; цвет текста выделения
  69.                                                                   ; Устанавливает дополнительные стили при использовании множественного курсора и выделения
  70. ScintillaSendMessage(0, #SCI_SETADDITIONALCARETFORE, RGB(255, 160, 160)) ; цвет дополнительного текстовго курсора
  71. ScintillaSendMessage(0, #SCI_SETADDITIONALCARETSBLINK, 1)                ; мигание дополнительного текстовго курсора
  72. ScintillaSendMessage(0, #SCI_SETADDITIONALSELALPHA, 100)                 ; прозрачность дополнительного выделения
  73. ScintillaSendMessage(0, #SCI_SETADDITIONALSELBACK, RGB(255, 255, 100))   ; цвет фона дополнительного выделения
  74. ScintillaSendMessage(0, #SCI_SETADDITIONALSELFORE, RGB(255, 255, 130))   ; цвет текста дополнительного выделения
  75.                                                                          ; Разрешает множественный курсор
  76. ScintillaSendMessage(0, #SCI_SETRECTANGULARSELECTIONMODIFIER, #SCMOD_ALT); выделить, удерживая нажатой клавишу Alt
  77. ScintillaSendMessage(0, #SCI_SETMULTIPLESELECTION, 1)                    ; позволяет выделить несколько раз удерживая нажатой клавишу CTRL или CMD
  78. ScintillaSendMessage(0, #SCI_SETMULTIPASTE, #SC_MULTIPASTE_EACH)         ; множественная вставка текста
  79. ScintillaSendMessage(0, #SCI_SETADDITIONALSELECTIONTYPING, 1)            ; позволяет ввод текста, перемешение курсора и т.д. сразу в нескольких местах
  80.  
  81. ; ScintillaSendMessage(0, #SCI_USEPOPUP, 1)
  82. ; ScintillaSendMessage(0, #SCI_SETVSCROLLBAR, 1)             ; вертикальная полоса прокрутки всегда
  83.  
  84. ; Разрешить горячую клаваишу CTRL + D для дополнительного авто выделения
  85. ; AddKeyboardShortcut(100, #PB_Shortcut_Control | #PB_Shortcut_D, #MENU_EXTEND_SELECTION)
  86. ; BindEvent(#PB_Event_Menu, ExtendScintillaSelection())
  87.  
  88.  
  89. ScintillaSendMessage(0, #SCI_SETTEXT, 0, MakeUTF8Text(txt$)) ; Установить текст гаджета
  90. ScintillaSendMessage(0, #SCI_GOTOPOS, txtLen)                ; Курсор в конец текста
  91. SetActiveGadget(0)                                           ; Установить гаджет активным, фокус ввода
  92.  
  93. ; Эти константы будут использоватся для подсветки синтаксиса.
  94. Enumeration 0
  95.     #LexerState_Space
  96.     #LexerState_Number
  97.     #LexerState_Keyword
  98.     #LexerState_String
  99.     #LexerState_Preprocessor
  100.     #LexerState_Operator
  101.     #LexerState_Comment
  102.     #LexerState_FoldKeyword
  103. EndEnumeration
  104. ScintillaSendMessage(0, #SCI_STYLESETFORE, #LexerState_Comment, RGB(113, 174, 113)) ; Цвет комментариев
  105. ScintillaSendMessage(0, #SCI_STYLESETFORE, #LexerState_Number, $ABCEE3)             ; Цвет чисел, BGR
  106. ScintillaSendMessage(0, #SCI_STYLESETFORE, #LexerState_Keyword, $FF9F00)            ; Цвет ключевых слов, BGR
  107. ScintillaSendMessage(0, #SCI_STYLESETFORE, #LexerState_Preprocessor, $DE97D9)       ; Цвет препроцессор, BGR
  108. ScintillaSendMessage(0, #SCI_STYLESETFORE, #LexerState_Operator, $8080FF)           ; Цвет препроцессор, BGR
  109. ScintillaSendMessage(0, #SCI_STYLESETFORE, #LexerState_FoldKeyword, RGB(0, 136, 0)) ; Цвет ключевых слов со сворачиванием.
  110. ScintillaSendMessage(0, #SCI_STYLESETBOLD, #LexerState_Number, 1)                   ; Выделять чисел жирным шрифтом
  111. ScintillaSendMessage(0, #SCI_STYLESETITALIC, #LexerState_Comment, 1)                ; Выделять комментарии наклонным шрифтом
  112.                                                                                     ; MessageRequester(Str(#STYLE_LINENUMBER) , Str(#STYLE_DEFAULT)) ; тут проверяем константы других стилей, почем они не мешают
  113.  
  114. ; Для RGB из Веб
  115. ; Global num.i = Val("$71AE71")
  116. ; Global num_text.s = Str(Red(num)) + ", " + Str(Green(num)) + ", " + Str(Blue(num))
  117. ; Debug num_text ; Отображает цвет в формате функции RGB
  118.  
  119. ; Пробуем применить стиль (проблема с позиционированием и длинной)
  120. ScintillaSendMessage(0, #SCI_STARTSTYLING, 50, 0) ; позиция начала (с 50-го)
  121. ScintillaSendMessage(0, #SCI_SETSTYLING, 14, #LexerState_Comment) ; ширина и номер стиля
  122.  
  123. If CreateMenu(0, WindowID(100))  ; Здесь начинается создание меню....
  124.     MenuTitle("Меню")
  125.     MenuItem(1, "Открыть файл")
  126.     MenuItem(2, "Вставить текущую дату")
  127.     MenuItem(3, "Вставить из буфера обмена")
  128.     MenuBar() ; разделитель
  129.     MenuItem(4, "Выход")
  130.     MenuItem(5, "Найти числа (индикаторы)")
  131.     MenuItem(6, "Найти числа (стиль)")
  132.     MenuItem(7, "Очистить стиль")
  133. EndIf
  134.  
  135. Global Event, em, Text$, TextLength, regex$
  136. Repeat
  137.     Event = WaitWindowEvent()
  138.     Select Event
  139.         Case #PB_Event_SizeWindow
  140.             ResizeGadget(0, #PB_Ignore, #PB_Ignore, WindowWidth(100), WindowHeight(100))
  141.         Case #PB_Event_Menu
  142.             em = EventMenu()
  143.             Select em
  144.                 Case 1
  145.                     OpenFileR()
  146.                 Case 2
  147.                     Text$ =  FormatDate("%dd.%mm.%yyyy", Date()) ; Возвращает текущую дату
  148.                     ; ScintillaSendMessage(0, #SCI_APPENDTEXT, Len(Text$), MakeUTF8Text(Text$)) ; не работает с UTF-8
  149.                      ; ScintillaSendMessage(0, #SCI_INSERTTEXT, txtLen, MakeUTF8Text(Text$)) ; проблема измерять длину текста в Scintilla каждый раз
  150.                     ScintillaSendMessage(0, #SCI_APPENDTEXT, TextLength, MakeScintillaText(Text$, @TextLength))
  151.                 Case 3
  152.                     ;                   Text$ = "вставленный текст" ; перед вставкой приводится к формату UTF-8
  153.                     Text$ = GetClipboardText()
  154.                     ScintillaSendMessage(0, #SCI_APPENDTEXT, TextLength, MakeScintillaText(Text$, @TextLength))
  155.                 Case 4
  156.                     Break
  157.                 Case 5
  158.                     regex$ = "\d+"
  159.                     Color(MakeScintillaText(regex$, @TextLength), Len(regex$), 7)
  160.                 Case 6
  161.                     regex$ = "\d+"
  162.                     Color2(MakeScintillaText(regex$, @TextLength), Len(regex$), 7)
  163.                 Case 7
  164.                     ScintillaSendMessage(0, #SCI_CLEARDOCUMENTSTYLE)
  165.             EndSelect
  166.         Case #PB_Event_CloseWindow
  167.             Break
  168.     EndSelect
  169. ForEver
  170.  
  171. FreeMenu(0)
  172. CloseWindow(100)
  173. End
  174.  
  175. ; Уведомления
  176. ProcedureDLL SciNotification(Gadget, *scinotify.SCNotification)
  177.     Protected Path$, pos
  178. ;   Select Gadget
  179. ;       Case 0 ; уведомление гаджету 0 (Scintilla)
  180.     With *scinotify
  181.         Select \nmhdr\code
  182.             Case #SCN_URIDROPPED ; о броске файлов в окно
  183. ;               Debug PeekS(*scinotify.SCNotification\text, -1, #PB_Ascii)
  184.                 Path$ = PeekS(*scinotify.SCNotification\text, -1, #PB_UTF8 | #PB_ByteLength)
  185. ;               Path$ = PeekS(*scinotify.SCNotification\text, -1, #PB_Ascii)
  186.                 pos = FindString(Path$, Chr(10)) ; обрезка, оставляя 1 файл
  187.                 If pos
  188.                     Path$ = LSet(Path$ , pos-2)
  189.                 EndIf
  190.                 Path$ = RemoveString(Path$ , "file://", #PB_String_CaseSensitive, 1, 1) ; удалить 1 раз
  191.                 Debug Path$
  192.                 ReadFileR(Path$)
  193.         EndSelect
  194.     EndWith
  195. ;   EndSelect
  196. EndProcedure
  197.  
  198.  
  199. ; Преобразование текста в текст для вставки в Scintilla
  200. Procedure MakeUTF8Text(text.s)
  201.     Static buffer.s
  202.     buffer=Space(StringByteLength(text, #PB_UTF8))
  203.     PokeS(@buffer, text, -1, #PB_UTF8)
  204.     ProcedureReturn @buffer
  205. EndProcedure
  206.  
  207. Procedure MakeScintillaText(text.s, *sciLength.Integer=0)
  208.     Static sciLength : sciLength=StringByteLength(text, #PB_UTF8) ; #TextEncoding
  209.     Static sciText.s : sciText = Space(sciLength)
  210.     If *sciLength : *sciLength\i=sciLength : EndIf ;<--- Возвращает длину буфера scintilla  (требуется для определенной команды scintilla)
  211.     PokeS(@sciText, text, -1, #PB_UTF8)            ; #TextEncoding
  212.     ProcedureReturn @sciText
  213. EndProcedure
  214.  
  215. Procedure OpenFileR(*sciLength.Integer=0)
  216.     ;   Запрос пути к файлу
  217.     Protected Path$ = OpenFileRequester("Выберите файл","","Текст|*.txt;*.bat;*.pb|Все файлы (*.*)|*.*",0)
  218.     If Path$ ; так как sciLength = 0 это критерий отмены для следующей функции
  219.         ReadFileR(Path$)
  220.     EndIf
  221. EndProcedure
  222.  
  223. Procedure ReadFileR1(Path$) ; свой вариант заменил вариантом из справки, см ниже
  224.     Protected sizefile, *MemoryBuffer
  225.     sizefile = FileSize(Path$) ; определяем размер данных в байтах
  226.     If sizefile => 0 ; файл существует
  227.         *MemoryBuffer = AllocateMemory(sizefile) ; выделение памяти под размер файла
  228.         ReadFile(0 , Path$, #PB_UTF8)
  229.         ReadData(0, *MemoryBuffer, sizefile) ; чтение файла в память
  230.         CloseFile(0)                         ; закрытие файла
  231.         ScintillaSendMessage(0, #SCI_SETTEXT, 0, *MemoryBuffer)
  232.         ;       ScintillaSendMessage(0, #SCN_UPDATEUI, #SC_UPDATE_V_SCROLL) ; не то, надо обновить прокрутку
  233.         FreeMemory(*MemoryBuffer)
  234.     EndIf
  235. EndProcedure
  236.  
  237. Procedure ReadFileR(Path$)
  238.     Protected length, *MemoryID
  239.     If ReadFile(0, Path$)
  240.         length = Lof(0)                            ; получаем длину открытого файла
  241.         *MemoryID = AllocateMemory(length)        ; выделяем необходимую память
  242.         If *MemoryID
  243.             ReadData(0, *MemoryID, length)  ; считаем все данные в блок памяти
  244.         EndIf
  245.         CloseFile(0)
  246.         ScintillaSendMessage(0, #SCI_SETTEXT, 0, *MemoryID)
  247.         FreeMemory(*MemoryID)
  248.     EndIf
  249. EndProcedure
  250.  
  251. ; Подсвечивание через индикаторы
  252. Procedure Color(*regex, regexLength, n)
  253.     Protected txtLen, StartPos, EndPos, firstMatchPos
  254.  
  255.     ; Устанавливает режим поиска (REGEX + POSIX фигурные скобки)
  256.     ScintillaSendMessage(0, #SCI_SETSEARCHFLAGS, #SCFIND_REGEXP | #SCFIND_POSIX)
  257.  
  258.     ; Устанавливает целевой диапазон поиска
  259.     txtLen = ScintillaSendMessage(0, #SCI_GETTEXTLENGTH) ; получает длину текста
  260.     ScintillaSendMessage(0, #SCI_INDICSETSTYLE, n, 6)    ; #INDIC_TEXTFORE = 17 создаёт индикатор под номером 7 (занятые по уиолчанию 0, 1, 2)
  261.     ScintillaSendMessage(0, #SCI_INDICSETFORE, n, $71AE71) ; назначает цвет индикатора под номером 7 - зелёный
  262.  
  263.     EndPos = 0
  264.     Repeat
  265.         ScintillaSendMessage(0, #SCI_SETTARGETSTART, EndPos)       ; от начала (задаём область поиска) используя позицию конца предыдущего поиска
  266.         ScintillaSendMessage(0, #SCI_SETTARGETEND, txtLen)         ; до конца по длине текста
  267.         firstMatchPos=ScintillaSendMessage(0, #SCI_SEARCHINTARGET, regexLength, *regex) ; возвращает позицию первого найденного. В параметрах длина искомого и указатель
  268.         If firstMatchPos>-1                                                             ; если больше -1, то есть найдено, то
  269.             StartPos=ScintillaSendMessage(0, #SCI_GETTARGETSTART)                       ; получает позицию начала найденного
  270.             EndPos=ScintillaSendMessage(0, #SCI_GETTARGETEND)                           ; получает позицию конца найденного
  271.             ScintillaSendMessage(0, #SCI_SETINDICATORCURRENT, n)                        ; делает индикатор под номером 7 текущим
  272.             ScintillaSendMessage(0, #SCI_INDICATORFILLRANGE, StartPos, EndPos - StartPos)  ; выделяет текст используя текущий индикатор
  273.         Else
  274.             Break
  275.         EndIf
  276.     ForEver
  277. EndProcedure
  278.  
  279. ; Подсвечивание через стиль
  280. Procedure Color2(*regex, regexLength, n)
  281.     Protected txtLen, StartPos, EndPos, firstMatchPos
  282.  
  283.     ; Устанавливает режим поиска (REGEX + POSIX фигурные скобки)
  284.     ScintillaSendMessage(0, #SCI_SETSEARCHFLAGS, #SCFIND_REGEXP | #SCFIND_POSIX)
  285.  
  286.     ; Устанавливает целевой диапазон поиска
  287.     txtLen = ScintillaSendMessage(0, #SCI_GETTEXTLENGTH) ; получает длину текста
  288.  
  289.     EndPos = 0
  290.     Repeat
  291.         ScintillaSendMessage(0, #SCI_SETTARGETSTART, EndPos)       ; от начала (задаём область поиска) используя позицию конца предыдущего поиска
  292.         ScintillaSendMessage(0, #SCI_SETTARGETEND, txtLen)         ; до конца по длине текста
  293.         firstMatchPos=ScintillaSendMessage(0, #SCI_SEARCHINTARGET, regexLength, *regex) ; возвращает позицию первого найденного. В параметрах длина искомого и указатель
  294.         If firstMatchPos>-1                                                             ; если больше -1, то есть найдено, то
  295.             StartPos=ScintillaSendMessage(0, #SCI_GETTARGETSTART)                       ; получает позицию начала найденного
  296.             EndPos=ScintillaSendMessage(0, #SCI_GETTARGETEND)                           ; получает позицию конца найденного
  297.             ScintillaSendMessage(0, #SCI_STARTSTYLING, StartPos, 0)                     ; позиция начала (с 50-го)
  298.             ScintillaSendMessage(0, #SCI_SETSTYLING, EndPos - StartPos, #LexerState_Number) ; ширина и номер стиля
  299.         Else
  300.             Break
  301.         EndIf
  302.     ForEver
  303. EndProcedure
  304.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement