AkelPad Forum Index AkelPad
Support forum
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

AkelPad и другие приложения
Goto page 1, 2  Next
 
Post new topic   Reply to topic    AkelPad Forum Index -> Discussion (Russian)
View previous topic :: View next topic  
Author Message
Skif_off



Joined: 20 Oct 2013
Posts: 479

PostPosted: Wed Jul 23, 2014 11:49 am    Post subject: AkelPad и другие приложения Reply with quote

Возможно ли посылать полноценные команды AkelPad из другого приложения? Забирать текст как скрипты, а не передавая путь файла внешней утилите (предварительно сохранив этот самый файл (только так работает, например, Tidy AutoIt: вероятно, утилита крайне заточена под SciTE)) и делать с ним что угодно? Или хотя бы то, что можно записать как строку меню или кнопку тулбара. И если да, то как?

Научился скриптом AutoIt посылать внутренние команды (4101-5001, без опциональных параметров):
Code:
$hAkelPad = WinGetHandle("[CLASS:AkelPad4]")
WinActivate($hAkelPad)

_SendMessage($hAkelPad, $WM_COMMAND, 4157, 0) ; Выделить все
If @error Then
    MsgBox(4096, "", "_SendMessage Error: " & @error)
    Exit
EndIf   

Описание функции _SendMessage, с @error пока не разбирался. Так понимаю, аналог SendMessage

WinActivate($hAkelPad), кажется, не обязательно.

Не знаю, что правильнее - класс окна AkelPad или окна редактирования - AkelPad4 или AkelEditW? Вероятно, зависит от целей?

$WM_COMMAND = 0x0111 - непонятно, это действительно константа или нужно менять? Для одной из команд ТС мне подсказали с оговоркой "в данном случае равно %число%", значит надо где-то посмотреть? Smile Вероятно, грозит вдумчивое чтение AkelEdit.c?

Или только через COM-объекты и мне, как дилетанту, нечего соваться? Smile

И если возможно, пару-тройку примеров: вызов плагина, скрипта с хотя бы одним параметром и что-нибудь из методов из Script-Rus.txt.
Back to top
View user's profile Send private message
Instructor
Site Admin


Joined: 06 Jul 2006
Posts: 5507

PostPosted: Wed Jul 23, 2014 12:31 pm    Post subject: Reply with quote

Skif_off
Из другого приложения в одностороннем порядке можно посылать командую строку на обработку AkelPad'у с помощью WM_COPYDATA с CD_PARSECMDLINEW (см. AkelDLL.h).

Для целей двухстороннего диалога можно использовать Scripts плагин. Недавно была тема в англоязычной ветке.

Skif_off wrote:
$WM_COMMAND = 0x0111 - непонятно, это действительно константа или нужно менять?
Это константа.

Quote:
И если возможно, пару-тройку примеров: вызов плагина, скрипта с хотя бы одним параметром и что-нибудь из методов из Script-Rus.txt.
Это лучше спросить у пользователей AutoIt как послать WM_COPYDATA.
Back to top
View user's profile Send private message Send e-mail
Skif_off



Joined: 20 Oct 2013
Posts: 479

PostPosted: Wed Jul 23, 2014 3:40 pm    Post subject: Reply with quote

Instructor
Кажется, не по Сеньке, так сказать, шапка Smile Но энтузиазм (самонадеянность?) пока не угас: перегнал все Defines из AkelDLL.h в Global Const, нашел образец, но DllStructCreate пока за гранью понимания.

Вы можете привести пример кода на С/С++ для отправки AkelPad, например
Code:
Call("Scripts::Main", 1, "ChmKeyword.js", `-Name="AutoIt.chm" -Maximize=false -CatchEsc=false`)

?
Back to top
View user's profile Send private message
FeyFre



Joined: 07 Aug 2007
Posts: 2060
Location: Vinnitsa, Ukraine

PostPosted: Wed Jul 23, 2014 4:27 pm    Post subject: Reply with quote

Quote:
Вы можете привести пример кода на С/С++ для отправки AkelPad, например
Hotkeys плагин один большой пример Smile)
Back to top
View user's profile Send private message AIM Address Yahoo Messenger MSN Messenger
Skif_off



Joined: 20 Oct 2013
Posts: 479

PostPosted: Wed Jul 23, 2014 5:43 pm    Post subject: Reply with quote

FeyFre
Еще ToolBar Smile Я мало того, что не программист, бывает - туплю, особенно с абстрактными примерами. Конкретный актуальный пример - самое оно.

Собственно, у меня есть запасной вариант: найти подходящий скрипт с подходящим окном Smile Хотя, конечно, сразу сдаваться нехорошо.
Back to top
View user's profile Send private message
Skif_off



Joined: 20 Oct 2013
Posts: 479

PostPosted: Wed Jul 30, 2014 6:11 pm    Post subject: Reply with quote

Посмотрел AkelEdit.h, кажется, можно попробовать SendMessage.
Back to top
View user's profile Send private message
Skif_off



Joined: 20 Oct 2013
Posts: 479

PostPosted: Tue Oct 28, 2014 8:00 pm    Post subject: Reply with quote

Продолжим потихоньку:
обсуждение Как работать с окнами многооконного приложения с одинаковыми Title/Class? на примере AkelPad.

После высказанной мысли одолело любопытство, родился аналог "Выбор окна..." Command(4327), не закрывающийся после выбора вкладки:
скрипт AutoIt
Code:
#NoTrayIcon

#Include <GUIConstantsEx.au3>
#Include <GUIListBox.au3>
#Include <WinAPI.au3>
#Include <WindowsConstants.au3>
#include <Array.au3>
#include <GuiTab.au3>
#include <ListBoxConstants.au3>

;Смотрите справку AutoItSetOption()
Opt('MustDeclareVars', 1)
Opt('GUIDataSeparatorChar','|')

Global $hForm, $Msg, $Dummy, $List, $hList, $hWin, $hTab, $iCount, $aTabs, $F, $index

;Получаем дескриптор окна AkelPad
$hWin = WinGetHandle('[Class:AkelPad4]')
If Not $hWin Then Exit 1
;Получаем указатель для элемента SysTabControl32 (вкладки AkelPad)
$hTab = ControlGetHandle($hWin, '', '[CLASS:SysTabControl32; INSTANCE:1]')
If Not $hTab Then Exit 2
;Получаем количество вкладок
$iCount = _GUICtrlTab_GetItemCount($hTab)
;Создаем массив с названиями вкладок
Local $aTabs[1]
$aTabs[0] = $iCount
For $i = 0 To $iCount - 1
    _ArrayAdd($aTabs, _GUICtrlTab_GetItemText($hTab, $i))
Next

;Рисуем GUI
$hForm = GUiCreate('Выбор вкладки AkelPad', 280, 380)
$List = GUICtrlCreateList('', 5, 5, 270, 370, $GUI_SS_DEFAULT_LIST + BitNOT($LBS_SORT))
$hList = GUICtrlGetHandle(-1)
;и набиваем List списком вкладок
$F = ''
For $i = 1 To $iCount
    $F &= $aTabs[$i]
    $F &= '|'
Next
GUICtrlSetData(-1, $F, $aTabs[1])
;Создаем элемент Dummy
$Dummy = GUICtrlCreateDummy()
;Регистрация пользовательской функции и горячей клавиши
GUIRegisterMsg($WM_COMMAND, 'WM_COMMAND')
HotKeySet('{ENTER}', 'HKEnter')
GUISetState()

While 1
    $Msg = GUIGetMsg()
    Switch $Msg
        Case $GUI_EVENT_CLOSE
            ExitLoop
        Case $Dummy
            $index = _GUICtrlListBox_GetCurSel($hList)
            WinActivate($hWin)
            _GUICtrlTab_SetCurFocus($hTab, $index)
    EndSwitch
WEnd

Func WM_COMMAND($hWnd, $iMsg, $wParam, $lParam)

    Local $Index

    Switch $lParam
        Case $hList
            Switch _WinAPI_HiWord($wParam)
                Case $LBN_DBLCLK
                    $Index = _GUICtrlListBox_GetCurSel($hList)
                    If ($Index > -1) And (_GUICtrlListBox_GetCaretIndex($hList) = $Index) Then
                        GUICtrlSendToDummy($Dummy, $Index)
                    EndIf
            EndSwitch
    EndSwitch
    Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_COMMAND

Func HKEnter()

    Local $Index

    If _WinAPI_GetFocus() = $hList Then
        $Index = _GUICtrlListBox_GetCurSel($hList)
        If $Index > -1 Then
            GUICtrlSendToDummy($Dummy, $Index)
            Return
        EndIf
    EndIf
    HotKeySet('{ENTER}')
    Send('{ENTER}')
    HotKeySet('{ENTER}', 'HKEnter')
EndFunc   ;==>HKEdit


По сути - функциональный набросок: список создаётся один раз при запуске, не запоминает положение, жёстко задан размер окна (добавить изменение размера и положение окна сравнительно легко, можно даже попробовать рассчитывать свободное место и открывать окно вне области, занятой окном AkelPad).

Нюансы: скомпилированный скрипт или интерпретатор должны быть той же разрядности, что и AkelPad; антивирусник/проактивка могут сделать стойку на строку
Code:
    _ArrayAdd($aTabs, _GUICtrlTab_GetItemText($hTab, $i))

Точнее, вызов функции
Code:
DllCall("User32.dll", "dword", "GetWindowThreadProcessId", "hwnd", $hWnd, "dword*", 0)

внутри _GUICtrlTab_GetItemText() (это не считая 2-3 вендоров на вирустотал, традиционно гавкающих на скомпилированные скрипты и/или UPX)

З.Ы. Это не WSH и плагин Scripts, не представляю, как получить полное имя файла, по сути: список создаётся для благообразного вида, фактически происходит оперирование индексами (номер вкладки от 0 до N и индекс в списке от 0 до N).
Back to top
View user's profile Send private message
Skif_off



Joined: 20 Oct 2013
Posts: 479

PostPosted: Tue Nov 04, 2014 3:53 am    Post subject: Reply with quote

Instructor
А как должна выглядеть строка запуска скрипта с WM_COPYDATA?
Code:
Call("Scripts::Main", 1, "scriptname.js")
Call("Scripts::Main", 2, "scriptname.js")
/Call("Scripts::Main", 1, "scriptname.js")
AkelPad.CallW("Scripts::Main", 1, "scriptname.js")
AkelPad.CallW("Scripts::Main", 2, "scriptname.js")

Или вообще /Exec? Нужна ли точка с запятой в конце? AkelPad.ScriptNoMutex()?
Наверное, AkelPad.xxx не то, раз методы плагина?
Back to top
View user's profile Send private message
Instructor
Site Admin


Joined: 06 Jul 2006
Posts: 5507

PostPosted: Tue Nov 04, 2014 8:38 am    Post subject: Reply with quote

Skif_off
Instructor wrote:
Из другого приложения в одностороннем порядке можно посылать командую строку на обработку AkelPad'у с помощью WM_COPYDATA с CD_PARSECMDLINEW (см. AkelDLL.h).

Возможно так будет понятнее (взято из AkelDLL.h):
Code:
 COPYDATASTRUCT cds;
 PARSECMDLINEPOSTW *pclp;
 wchar_t *wpCmdLine=L"/Call(\"Scripts::Main\", 1, \"scriptname.js\") "

 if (pclp=(PARSECMDLINEPOSTW *)GlobalAlloc(GMEM_FIXED, sizeof(PARSECMDLINEPOSTW)))
 {
   pclp->bPostMessage=TRUE;
   pclp->nCmdLineLen=lstrcpynW(pclp->szCmdLine, wpCmdLine, COMMANDLINE_SIZE);
   pclp->nWorkDirLen=GetCurrentDirectoryWide(MAX_PATH, pclp->szWorkDir);

   cds.dwData=CD_PARSECMDLINEW;
   cds.cbData=sizeof(PARSECMDLINEPOSTW);
   cds.lpData=(PVOID)pclp;
   SendMessage(hWnd, WM_COPYDATA, (WPARAM)hWnd, (LPARAM)&cds);
   GlobalFree((HGLOBAL)pclp);
 }
Back to top
View user's profile Send private message Send e-mail
Andrey_A_A



Joined: 03 Jun 2010
Posts: 622
Location: Сочи, Хоста

PostPosted: Sat Dec 06, 2014 9:45 am    Post subject: Reply with quote

Code:
Возможно ли посылать полноценные команды AkelPad из другого приложения? Забирать текст

Если конечно актуально ещё..

В Autoit есть функция ControlCommand

К примеру возвращает номер строки, в котором находится курсор в элементе
Code:
$n=ControlCommand('[CLASS:AkelPad4]','','AkelEditW1','GetCurrentLine','')
MsgBox(4096,"Переменная ","$n =>" & $n & "<=")


или вставляет слово привет
Code:
ControlCommand('[CLASS:AkelPad4]','','AkelEditW1','EditPaste','привет')


Можно посмотреть в сторону GuiEdit.au3 и получить текст и не только...

Code:
#include <GuiEdit.au3>
#include <GUIConstantsEx.au3>

$hEdit=ControlGetHandle('[CLASS:AkelPad4]','','AkelEditW1')
MsgBox(4096,"Переменная ","$hEdit =>" & $hEdit & "<=")

$sText=_GUICtrlEdit_GetText($hEdit)
MsgBox(4096,"Переменная ","$sText =>" & $sText & "<=")


или без include напрямую

Code:
Local $hEdit=ControlGetHandle('[CLASS:AkelPad4]','','AkelEditW1'),$iTextLen=_SendMessage($hEdit,14),$tText=DllStructCreate("wchar Text["&$iTextLen&"]")
_SendMessage($hEdit,13,$iTextLen,$tText,0,"wparam","struct*")
$sText=DllStructGetData($tText,"Text")
MsgBox(4096,"Переменная ","$sText =>" & $sText & "<=")

Func _SendMessage($hWnd,$iMsg,$wParam=0,$lParam=0,$iReturn=0,$wParamType="wparam",$lParamType="lparam",$sReturnType="lresult")
    $aResult=DllCall("user32.dll",$sReturnType,"SendMessageW","hwnd",$hWnd,"uint",$iMsg,$wParamType,$wParam,$lParamType,$lParam)
    Return @error ? SetError(@error,@extended,"") : (($iReturn>=0 And $iReturn<=4) ? $aResult[$iReturn] : $aResult)
EndFunc


Если не актуально, то так для информации...
Back to top
View user's profile Send private message Send e-mail Visit poster's website
Skif_off



Joined: 20 Oct 2013
Posts: 479

PostPosted: Sat Dec 06, 2014 10:37 am    Post subject: Reply with quote

Andrey_A_A
Code:
ControlCommand('[CLASS:AkelPad4]','','AkelEditW1','EditPaste','привет')

вставит текст в позицию курсора или заменив выделение. Для замены всего текста есть ControlSetText(), но с неприятностью: документ не изменит статус на "изменен" (запрос сохранения не вылезет при закрытии AkelPad). _GUICtrlEdit_SetText() и _GUICtrlEdit_InsertText() сработают аналогично? До их проверки не дошёл Smile
Это если по взрослому, не задействуя буфер обмена.

Ну и добавлю, если кому-то понадобиться автоматизировать обработку:
WM_COPYDATA с CD_PARSECMDLINEW позволят если не всё, что угодно, то очень многое (см. параметры командной строки, включая методы, конечно).
Но есть нюанс: антивирусник может гавкнуть на попытку послать оконное сообщение.

Насчёт актуальности: сейчас, наверное, для информации Smile Практически всё так или иначе решается плагинами и скриптами WSH. Ну, для декодирования Quoted-Printable скрипт всё-таки перепишу, наверное.
Back to top
View user's profile Send private message
Andrey_A_A



Joined: 03 Jun 2010
Posts: 622
Location: Сочи, Хоста

PostPosted: Sat Dec 06, 2014 12:03 pm    Post subject: Reply with quote

Quote:
но с неприятностью: документ не изменит статус на "изменен"

В Autoit часто приходится считать разные выражения с участием функций к примеру
Code:
BitOR(4,64,768)

Захотелось сделать кнопку по быстрому вычислению и вставки обратно без буфера.
Так вот кнопка
Code:
-"Вычислить выделенное выражение и вставить результат" Call("Scripts::Main", 1, "TCIMG.vbs", `"exect=ControlCommand('[ACTIVE]','''','AkelEditW1','EditPaste',#stext#)"`) Icon("%a\AkelPadImage.dll",1284)

При вставке обратно вычисленного изменяет документ
Code:
вставит текст в позицию курсора или заменив выделение.

Как раз то что мне и надо.
А когда это сделал, то и вспомнил про эту тему... всё можно сделать, если есть в этом какая-то необходимость.
Back to top
View user's profile Send private message Send e-mail Visit poster's website
VladSh



Joined: 29 Nov 2006
Posts: 2701
Location: Киев, Русь

PostPosted: Sat Dec 06, 2014 12:38 pm    Post subject: Reply with quote

А не проще ли зарегистрировать AkelPad в системе, как ActiveX и иметь из любых приложений доступ напрямую ко всему API Scripts-плагина?
Back to top
View user's profile Send private message Visit poster's website
Andrey_A_A



Joined: 03 Jun 2010
Posts: 622
Location: Сочи, Хоста

PostPosted: Sat Dec 06, 2014 12:46 pm    Post subject: Reply with quote

Code:
А не проще ли зарегистрировать AkelPad в системе

Для меня нет. Я сторонник портабельности. Да и без регистрации все решаемо, если очень надо.
Back to top
View user's profile Send private message Send e-mail Visit poster's website
Skif_off



Joined: 20 Oct 2013
Posts: 479

PostPosted: Sat Dec 06, 2014 1:19 pm    Post subject: Reply with quote

Andrey_A_A
ControlCommand() изменяет документ, да, но я писал о ControlSetText(), которая не изменяет, т.е., такой скрипт
Code:
$hAkelPad = WinGetHandle('[Class:AkelPad4]')
If Not $hAkelPad Then Exit

$Text = ControlGetText($hAkelPad, '', 'AkelEditW1')
$Text = StringRegExpReplace($Text, '(\r\n|\r|\n){2,}', ' ')
ControlSetText($hAkelPad, '', 'AkelEditW1', $Text)

; Закрываем вкладку
_SendMessage($hAkelPad, $WM_COMMAND, 4318, 0)
; или закрываем AkelPad
_SendMessage($hAkelPad, $WM_COMMAND, 4109, 0)

не изменит файл и AkelPad не выдаст запрос на сохранение изменений. Нужно дополнительно послать команду сохранения изменений (4105) и только потом закрывать.

Надо ещё проверить _GUICtrlEdit_SetText() и _GUICtrlEdit_InsertText() (только я не понял - они для собственных окон или любых?), но этот нюанс определённо нужно иметь в виду.
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    AkelPad Forum Index -> Discussion (Russian) All times are GMT
Goto page 1, 2  Next
Page 1 of 2

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


SourceForge.net Logo Powered by phpBB © 2001, 2005 phpBB Group