Страница 2 из 4

Добавлено: Вт дек 02, 2014 23:54
Skif_off
MVV
Спасибо, буду пробовать, как доберусь до компа. Кстати, в примерах AutoHotkey после флагов нулевой символ не ставят, в функции на AutoIt тоже, кажется, не стал.
Вообще, производит впечатление своеобразного костыля для совместимости с неюникодными Win9x/Me: откуда я могу знать, какой путь попадётся? Проверять каждый раз, что символы строки не вылезли за диапазон 0-127 не очень удобно.

Добавлено: Ср дек 03, 2014 14:20
MVV
Если конкатенируешь строки, обычно в конце нулевой символ добавляется автоматически. Но однозначно будет не лишним его указать явно, тем более, его необходимо учитывать в длине строки, а завершающий нулевой обычно не включается в длины строк.
А где костыль? Посылай всегда в UTF-8. Функция эта в тотале появилась давно, юникодные пути тогда еще не были в моде, потом была добавлена поддержка юникода с сохранением совместимости.

Добавлено: Ср апр 22, 2015 02:42
LonerD
Flasher писал(а):На англофоруме есть примеры для AHK.
Подозреваю, что тут ответ можно получить быстрее и понятней, потому повторю свой вопрос.
Как эту конструкцию использовать внутри своих скриптов?
Например, надо нам узнать Source Path (SP) и передать его какой-то переменной.
Что-то наподобие вот этого
MyVariable := Send_WM_COPYDATA(cmd:="SP")

И ещё - если тут кто-то из AHK-шников заглянет - каким образом команда CD работает? Потому как объяснения Balderstrom весьма туманны.

Добавлено: Ср апр 22, 2015 10:38
Flasher
Там уже вроде как что-то отписали, но больше невнятицы про errorlevel.
Вот этот скрипт я попробовал на 1.1.05.02, gui возвращает данные. Теперь бы ещё по-отдельности отобразить, только с иероглифами первого значения получилось...

Добавлено: Ср апр 22, 2015 13:43
Skif_off
У меня с 1.1.21.03 ничего не показывает, активную панель скрипт показал только после изменения

Код: Выделить всё

inf:=Asc("G") + 256 * Asc("A")
;на
inf:=Asc("G") + 256 * Asc("W")
С 1.1.05.02 вообще ничего.

Добавлено: Ср апр 22, 2015 13:45
MVV
Skif_off,
Видимо, твоя версия AHK юникодная, поэтому и идентификатор сообщения нужно указывать юникодный.

Добавлено: Ср апр 22, 2015 14:47
Skif_off
MVV
Точно, проглядел
I used autohotkey_L ansi version 1.1.05.01
Юникод рулит, однако. На AutoIt сразу делал с юникодом.

Добавлено: Ср апр 22, 2015 15:37
LonerD
Flasher писал(а):Там уже вроде как что-то отписали, но больше невнятицы про errorlevel.
Вроде как низзя без перехватчика OnMessage... а как его прервать после получения сообщения - вопрос.
По нажатию хоткея выполняется Send_WM_COPYDATA - формируется запрос Тоталу с заданным параметром.
Далее этот запрос обрабатывается, получается какая-то фигня - строка (иероглиф) CopyDataStruct и этот запрос отправляется Тоталу.
Тотал даёт некий ответ, и висящий в трее AHK отслеживает появление ответа через OnMessage, обрабатывает в Receive_WM_COPYDATA и высвечивает результат...
Как всё это упростить - непонятно.



Добавлено спустя 49 минут:

Ага. Индусский код начинает вырисовываться.
Убираем #Persistent чтобы скрипт не висел постоянно в памяти, убираем горячие клавиши.
Убираем MsgBox, %retVal% и в начале функции Receive_WM_COPYDATA пишем global retVal (назначаем переменную глобальной, то есть результат отправляется в глобальную переменную, которая будет доступна вне скрипта).

Тогда тело скрипта будет выглядет так

Код: Выделить всё

  OnMessage(0x4a, "Receive_WM_COPYDATA")
  Send_WM_COPYDATA(cmd:="A")
; в переменной retVal - желаемое значение, делаем что хотим с этим значением, и в конце концов завершаем скрипт обязательно через ExitApp
ExitApp
Можно ли ещё проще?
И зачем совет "must have a wait loop arround onMessage in order to receive data from TC"? Ведь если запустить OnMessage внутри цикла, он продолжает висеть в памяти даже после прерывания цикла...
Как прервать OnMessage? Можно ли и нужно ли это делать?

Добавлено: Ср апр 22, 2015 16:12
Flasher
LonerD писал(а):Тогда тело скрипта будет выглядет так
А какого скрипта не хочешь рассказать? :)
LonerD писал(а):Можно ли ещё проще?
Тут про функции нужно думать, там основной код.
LonerD писал(а):Можно ли и нужно ли это делать?
Думаю, нет необходимости.

Добавлено: Ср апр 22, 2015 16:20
LonerD
Flasher писал(а):
LonerD писал(а):Тогда тело скрипта будет выглядет так
А какого скрипта не хочешь рассказать? :)
Я выше в теме указал - вот этот скрипт. Насколько я понимаю, он и есть финальный. Его всё время и пытаюсь "осмыслить" и адаптировать для своих потребностей.

Добавлено: Ср апр 22, 2015 16:30
Flasher
LonerD
Финальный? Это просто вариант. Предыдущый как-то покомпактней смотрится. А тут какие-то навороты отладочные, ну их. Нужно скомпоновать самый наипростейший и компактный вариант с записью в переменную и msgbox для одного значения. В данном случае SС больше всего интересует.

Добавлено: Ср апр 22, 2015 19:29
LonerD
Flasher писал(а):Предыдущый как-то покомпактней смотрится. А тут какие-то навороты отладочные, ну их. Нужно скомпоновать самый наипростейший и компактный вариант с записью в переменную и msgbox для одного значения. В данном случае SС больше всего интересует.
Предыдущий - это вот этот имеешь в виду?
Не очень-то и компактно, если принять во внимание, что разные команды нужно отсылать - посмотри вначале скрипта конструкцию if A_IsUnicode ... else и доп. функцию StrPutVar
Flasher писал(а):А тут какие-то навороты отладочные, ну их.
Что ты подразумеваешь под отладочными наворотами? Защиту от дурака можно просто убрать (или переделать по-своему).
Для меня туманным остаётся смысл проверки if( A_IsUnicode ). На первый взгляд все AutoHotkey.exe-шники работает и без неё.

Добавлено спустя 48 минут:

В общем, получился вот такой примерчик. Переключение панелей - определяем активную панель, и переходим на другую.
Основная суть достигнута - получено значение retVal использовано дальше в скрипте.

Код: Выделить всё

; #Warn
#NoEnv
#NoTrayIcon
#SingleInstance, Force
;SetBatchLInes, -1
;SendMode, Input

If WinExist("ahk_class TTOTAL_CMD") && WinActive("ahk_class TTOTAL_CMD")
{
  WinGet, TCHWND, ID, A

  OnMessage(0x4a, "Receive_WM_COPYDATA")  ; 0x4a is WM_COPYDATA
  Send_WM_COPYDATA(cmd:="A")

  if ( retVal = "R" )
    SendMessage, 1075, 4001,,, % "ahk_id " TCHWND
    else
      SendMessage, 1075, 4002,,, % "ahk_id " TCHWND
}
ExitApp

Send_WM_COPYDATA(ByRef cmd, aWinID=0x0)
{
  global TCHWND
  Critical
  if(!RegExMatch(cmd, "^(A|[LRST][PCIN]?)$"))
    return

  len:=StrLen(cmd) + 1
  if( A_IsUnicode )   ; This needs to be done, as TC is expecting
  {      ; "chars" for the cmd string.
     cmdStr:=cmd
     VarSetCapacity(cmd, StrPut(cmd, "cp0"))
     Loop, % len
        NumPut( Asc(SubStr(cmdStr, A_Index, 1)), cmd, A_Index - 1, "Char")
  }
  VarSetCapacity(CopyDataStruct, A_PtrSize * 3)
  NumPut(Asc("G") + 256 * Asc(A_IsUnicode ? "W" : "A"), CopyDataStruct)
  NumPut(len , CopyDataStruct, A_PtrSize)
  NumPut(&cmd, CopyDataStruct, A_PtrSize * 2)

  SendMessage, 0x4A, %A_ScriptHwnd%, &CopyDataStruct, , % "ahk_id " TCHWND
  return ErrorLevel
}

Receive_WM_COPYDATA(wParam, lParam, msg, hwnd)
{
  global retVal
  retVal:=StrGet(NumGet(lParam + A_PtrSize * 2))
  return 1
}

Добавлено: Чт апр 23, 2015 05:19
Flasher
LonerD писал(а):Предыдущий - это вот этот имеешь в виду?
Его.
LonerD писал(а):Не очень-то и компактно
У тебя получилось компактней? Что-то не заметил. :)
LonerD писал(а):Основная суть достигнута - получено значение retVal использовано дальше в скрипте.
А я как просил? Для SC, SI или SN (типа Send_WM_COPYDATA("SC") | msgbox retVal).

Добавлено: Чт апр 23, 2015 14:27
LonerD
Flasher писал(а):У тебя получилось компактней?
Да, примерно на 8 строк.
Чтобы ещё сократить - в моём варианте можно убрать безболезненно "защиту от дурака"

Код: Выделить всё

  if(!RegExMatch(cmd, "^(A|[LRST][PCIN]?)$")) 
     return
Хотя сейчас посмотрел - почерпнул из того скрипта переменную A_ScriptHwnd, исправил свой скрипт.
Flasher писал(а):А я как просил? Для SC, SI или SN (типа Send_WM_COPYDATA("SC") | msgbox retVal).
Заменить
Send_WM_COPYDATA(cmd:="A")
на желаемое, например
Send_WM_COPYDATA(cmd:="SC").
Входные данные - ByRef, потому не ("SC"), а (cmd:="SC")

Также заменить
if ( retVal = "R" ) и три строки ниже на
msgbox, % retVal

Добавлено: Чт апр 23, 2015 16:18
Flasher
LonerD писал(а):if ( retVal = "R" ) и три строки ниже на
msgbox, % retVal
Хм. Сравнение без %, а вывод с? Как интересно.