PureBasic - форум

Информация о пользователе

Привет, Гость! Войдите или зарегистрируйтесь.


Вы здесь » PureBasic - форум » Программирование на PureBasic » GlobalAutoCompletion - автозавершение текста


GlobalAutoCompletion - автозавершение текста

Сообщений 1 страница 8 из 8

1

GlobalAutoCompletion - автозавершение текста (пока только Linux, на Windows не проверял)

Скачать: yandex upload.ee

https://i.imgur.com/t1lOsHn.png https://i.imgur.com/Q5axXHn.png

Использование:
1. Выделяем в любом месте текст (в браузере, текстовом редакторе и т.д.)
2. Жмём горячую клавишу Ctrl+L (или другую назначенную)
3. Выбираем пункт в меню, появляется список возможных автозавершений. Кликаем любой пункт, программа сворачивается или закрывается, а в место выделения будет вставлен выбранный в списке текст или текст из файла.

Подробнее в ReadMe.txt

Отредактировано AZJIO (08.09.2021 08:54:24)

0

2

AutoCompletionPB

Скачать: yandex upload.ee

скриншот-Windows
скриншот-Linux

https://d.radikal.ru/d25/2109/18/bc7fe4bcdc8ct.jpg

https://b.radikal.ru/b24/2109/57/b38ddb3bfd69t.jpg

Сделал автозавершение индивидуально для IDE.
Командная строка для инструмента: %WORD %CURSOR
Цифра в конце файла-списка указывает на способ поиска (подробнее в ReadMe)
Число списков зависит от числа файлов lst
В заголовке указано время поиска, достаточно быстро, 4 мс.

Использовал регулярное выражение, файл конечно вырос в 2 раза, но скорость поиска минимальна, в 10 раз быстрее, но и 40 мс это мелочь, просто приходилось делать костыли.

Обновление AutoCompletionPB
Добавлено - цветные списки под цвет кода, я для себя цвета сделал.
Добавлено - при клике на заголовке списка он расширяется
Активный список подсвечивается, в Linux подсвечивается заголовок

Отредактировано AZJIO (16.09.2021 20:10:38)

0

3

На яндексе обновил AutoCompletionPB, добавив Windows-версию исходника.

На данный момент проблема во вставке текста из буфера обмена, выкладываю проблемную часть кода, она самостоятельная, то есть должна вставить то что сейчас в буфере обмена в окно документа PureBasic. Надо компилировать, так как работающий код не даст вставить, то есть вызвать как инструмент.

Код:
EnableExplicit
Global classText.s = Space(256), hWnd_Find = 0

Procedure.l enumChildren(hwnd.l)
	If hwnd
    GetClassName_(hwnd, @classText, 256)
    If classText = "Scintilla"
    	hWnd_Find = hwnd
    	ProcedureReturn 0
    EndIf
    ProcedureReturn 1
	EndIf
	ProcedureReturn 0
EndProcedure
    

Procedure SendHotKeyCtrlIns(hWnd, sleep = 20, sleep1=110)
;	Protected hWnd = GetForegroundWindow_()
; 	keybd_event_(#VK_CONTROL,0,0,0)
	SendMessage_(hWnd, #WM_KEYDOWN, #VK_SHIFT, 0)
	Delay(sleep1)
	SendMessage_(hWnd, #WM_KEYDOWN, #VK_INSERT, 0)
	Delay(sleep1)
	SendMessage_(hWnd, #WM_KEYUP, #VK_INSERT, 0)
	Delay(sleep1)
; 	keybd_event_(#VK_CONTROL,0,#KEYEVENTF_KEYUP,0)
	SendMessage_(hWnd, #WM_KEYUP, #VK_SHIFT, 0)
EndProcedure

Procedure Execute()
	Protected hWin, title$, Length, hWin2
	hWin = FindWindowEx_(0, 0, "WindowClass_2", 0)
	If hWin
    Length = GetWindowTextLength_(hWin)+2
    title$ = Space(Length)
    GetWindowText_(hWin,@title$, Length)
    If Left(title$ , 9) = "PureBasic"
;     	ShowWindow_(hWin, #SW_SHOWNORMAL)
;     	hWin2= FindWindowEx_(hWin, 0, "Scintilla", 0)
    	EnumChildWindows_(hWin, @enumChildren(), 0)
;     	MessageRequester("", "1")
;     	If hWin2
    	If hWnd_Find
;         MessageRequester("2", Str(hWnd_Find))
;         SetForegroundWindow_(hWnd_Find)
;         SendMessage_(hWnd_Find, #WM_KEYDOWN, #VK_SHIFT | #VK_INSERT, 0)
        SendHotKeyCtrlIns(hWnd_Find)
;         SendMessage_(hWnd_Find, #WM_KEYDOWN, #VK_CONTROL, 0)
;         Delay(200)
;         SendMessage_(hWnd_Find, #WM_KEYDOWN, #VK_V, 0)
    	EndIf
    EndIf
	Else
    MessageRequester("", "Окно не найдено")
	EndIf
EndProcedure

Execute()

Отредактировано AZJIO (06.09.2021 12:28:16)

0

4

Нужен какой то другой подход,по тому как имя класса относительно вдруг изменится,да и имя окна у каждой версии своё.
;и зачем нам тогда имя класса на данном этапе,если можно просто получить хендл по заголовку окна?

Код:


OpenWindow(0,0,0,100,180,"",#PB_Window_MinimizeGadget|#PB_Window_ScreenCentered)
StringGadget(1,2,2,96,96,"taimer",#PB_Text_Center)

Debug Str(FindWindow_(0,"PureBasic"))+"  "+Str(FindWindow_("WindowClass_2",0))

hwnd=FindWindow_("WindowClass_2",0)

buff.s=Space(200)
GetClassName_(hwnd,@buff,200)
Debug buff

Procedure.s GETWINDOWTEXT(HWNDokna.i,zagolovok.s="                          ")
  GetWindowText_(HWNDokna,@zagolovok,25)
  ProcedureReturn zagolovok
EndProcedure

Debug GETWINDOWTEXT(hwnd)

;и зачем нам тогда имя класса на данном этапе,если можно просто получить хендл по заголовку окна?

Debug FindWindow_(0,GETWINDOWTEXT(hwnd))

;а эта типа для поиска дочерних окон и  опять же будет ли имя класса постоянным и одинаковым во всех версиях?
;1 аргумент
;Дескриптор родительского окна, в дочерних окнах которого нужно искать.
;Если hwndParent имеет значение NULL , функция использует окно рабочего стола в качестве родительского окна.
;Функция ищет среди окон, которые являются дочерними окнамирабочего стола.

Debug FindWindowEx_(0,0,"WindowClass_2",0);



Repeat 
 Select WaitWindowEvent() 
   Case #PB_Event_CloseWindow
       Break
     Case #PB_Event_Gadget
       
       
    EndSelect
ForEver
End     

Может проще тогда предоставить пользователю указать в настройках свою версию пурика?

Отредактировано Sergeihik (06.09.2021 20:11:30)

0

5

Обновил AutoCompletionPB на яндексе.

Sergeihik написал(а):

и зачем нам тогда имя класса на данном этапе,если можно просто получить хендл по заголовку окна?

Можно получить хендл другого заголовка окна, например эксплорера с открытой папкой PureBasic

Sergeihik написал(а):

Нужен какой то другой подход,по тому как имя класса относительно вдруг изменится,да и имя окна у каждой версии своё.

Имя класса теперь прописывается в ini-файле
Имя окна не является точным совпадением, а изначально было в начале заголовка, теперь может быть в любом месте заголовка, так пришлось поступить из-за Notepad++, который вставляет своё имя в конец заголовка, а в начале заголовка путь к файлу.
Но так как классы у них индивидуальные, то невозможно получить такой же класс как у эксплорера или ещё какого-нибудь окна, он точно попадёт на окно соответствующей проги, проблема возможна только если у проги 2 окна одновременно открытых. Пока это не критично, а потом можно проверять какое окно является поверх всех окон, ну то есть выше в Z-последовательности.

Со вставкой все намного проще

Код:
SendMessage_(hWnd_Find, #WM_PASTE, 0, 0)

Добавлено поле, в котором можно подправить искомый текст.
Прога стала похожа на ранее известную Advanced_Search, помню как я увидел и сделал аналог на AutoIt3, теперь такие же списки, только нет прыжка в интернет, но долго ли сделать, конечно не такое продвинутое как раньше с выбором доменов, чтобы не захламлять прогу, но вполне можно сгенерировать меню на основе пунктов в ini-файле, см ReadMe.
Проверил в том числе на Notepad++ и AkelPad, работает надёжно, со вставкой.
Для Notepad++ в shortcuts.xml надо добавить:

Код:
<Command name="AutoCompletionPB" Ctrl="no" Alt="yes" Shift="no" Key="113">&quot;$(NPP_DIRECTORY)\Tools\AutoCompletionPB.exe&quot; &quot;$(CURRENT_WORD)&quot;</Command>

Для AkelPad пункт меню:

Код:
"AutoCompletionPB" Exec(`"%a\AkelFiles\Tools\AutoCompletionPB\AutoCompletionPB.exe"`, "%d") Icon("%a\AkelFiles\Tools\AutoCompletionPB\AutoCompletionPB.exe")

У AkelPad не передаётся параметр ком-строки, хотел быстро найти но не стал заострятся и добавил в прогу, что если ничего не передаётся через ком-строку, то попытатся SendMessage_(hWnd_Find, #WM_COPY, 0, 0) и это сработало.

Отредактировано AZJIO (08.09.2021 07:13:37)

0

6

Обновил
Добавил галку переключения поиска принудительно от начала или в центре
Добавлена кнопка поиска в интернете. В ini-файле секция ссылок.

Отредактировано AZJIO (10.09.2021 10:55:50)

0

7

Посмотри вот как вариант.(конечно оптимизировать немного нужно)

Код:

;;=====================
Procedure.s GETWINDOWTEXT(HWNDokna.i,zagolovok.s="                               ")
  GetWindowText_(HWNDokna,@zagolovok,30)
  ProcedureReturn zagolovok
EndProcedure
;

Procedure.s GetClassName(HWNDClassa.i,ClassName.s="                          ")
  GetClassName_(HWNDClassa,@ClassName,25)
  ProcedureReturn ClassName
EndProcedure
Procedure.s RealGetWindowClass(HWNDClassa.i,ClassName.s="                              ")
  RealGetWindowClass_(HWNDClassa,@ClassName,25)
  ProcedureReturn ClassName
EndProcedure





Global hwnd_p.i
Procedure.i enumfunczuy(HWND.i,lp.i)
    Protected s.s
  If  HWND<>0 
    s=GETWINDOWTEXT(HWND)
      s=Left(s,5)
    If s="PureB";сдесь можно сделать поиск подстроки
        hwnd_p=HWND
       ProcedureReturn #False
    EndIf
   ProcedureReturn #True
 Else
   ProcedureReturn #False
  EndIf
EndProcedure
Procedure.i enumfunczuy1(HWND.i,lp.i)
  ;Debug HWND
  If HWND<>0
    
    Debug GetClassName(HWND)
     Debug "hwnd окна  "+Str(HWND)
    ;Debug Str(GetClassLong_(HWND,#GCL_WNDPROC))
      Debug "hwnd родителя  "+Str(GetWindowLongPtr_(HWND,#GWLP_HWNDPARENT));дескриптор родительского окна, если он есть
        
     ;Debug Str(GetWindowLongPtr_(HWND,#GWLP_WNDPROC))
      Debug  "---------------------"
                 
    

       If GetClassName(HWND)="Scintilla"
           
         Debug Str(GetWindow_(HWND,#GW_HWNDFIRST));типа определяет верхнее окно из однотипных (а однотипные по сути это в классе)
         ;ну и для проверки рисуем в контект окна
         ds=GetDC_(GetWindow_(HWND,#GW_HWNDFIRST))

         s.s="5555554444444444444444444444444444444444444444444444444444444444444444444444444444444444455"
         TextOut_(ds,5,1,@s,Len(s))
         For i=0 To 20
         ;SendMessage_(GetWindow_(HWND,#GW_HWNDFIRST),#WM_CHAR,55,0);печать в каретку
         Next

          ProcedureReturn #False
       EndIf
   ProcedureReturn #True
 Else
   ProcedureReturn #False
  EndIf
EndProcedure

  

 
;========================
 EnumWindows_(@enumfunczuy(),0);перечисляет дискрипторы windows окон на рабочем столе
 Debug "===================="

  If hwnd_p<>0
   Debug "======Заголовок окна, Дескриптор окна и класс родителя========"
   Debug GETWINDOWTEXT(hwnd_p);заголовок окна
   Debug Str(hwnd_p)
   Debug RealGetWindowClass(hwnd_p)
   Debug Str(GetTopWindow_(hwnd_p));получает дискриптор самого верхнего окна в z порядке
   Debug "-----"
     

    EnumChildWindows_(hwnd_p,@enumfunczuy1(),0);перечисляет дискрипторы дочерних окон,nul=окна Windows
    
  EndIf



OpenWindow(0,0,0,100,180,"",#PB_Window_MinimizeGadget|#PB_Window_ScreenCentered)
StringGadget(1,2,2,96,96,"taimer",#PB_Text_Center)




Repeat
  Select WaitWindowEvent()
    Case #PB_Event_CloseWindow
     ;SetClassLong_(hwndd,#GCL_WNDPROC,calbac)
      Quit = 1
  EndSelect
Until Quit = 1

















Отредактировано Sergeihik (11.09.2021 00:10:58)

0

8

Обновление
Списки теперь содержать параметры, что делает их самостоятельными. Первые 6 строк содержат настройки.
Добавлен список "Калька", суть - русское имя для функции, пишем "Глобал", получаем в списке "Глобал|Global ", по клику вставляется "Global ", это проще чем делать через "Фрагменты".
Осталось вернуть способ захвата через выделение, так как PureBasicIDE не может передавать выделенный текст, а только слово под курсором, да и то если курсор стоит не в конце слова. Пока что эту проблему можно решить заранее выделив текст и нажать Ctrl+C, то если слово не будет получено то используется буфер обмена, ну и при условии что в ком-строке не используется позиция %CURSOR.

Ещё исправление
Добавил, чтобы имя папки фрагментов было так же как у файла списка
Добавил Ext = pb в ini-файл, чтобы использовать его в файлах-фрагментах, т.е. поддержка любого языка.

Отредактировано AZJIO (16.09.2021 23:30:28)

0


Вы здесь » PureBasic - форум » Программирование на PureBasic » GlobalAutoCompletion - автозавершение текста