76 (2021-01-30 19:39:03 отредактировано Balu)

Re: Автологин в QUIK (на Lua)

Доброго времени суток !!
Использовал скрипт все отлично работало. Пришлось переустанавливать QUIK.
Теперь заполнение полей происходит но кнопка не нажимается .
QUIK 8.12.0.41 dll версия 5.3 .
Dll лежит в папке QUIK
Понимаю что пробема где-то здесь как поправить не знаю.

w32.SetFocus(nBtnOk)
w32.PostMessage(nBtnOk, w32.BM_CLICK, 0, 0)

Скрипт

[+]Spoiler

-- Автологин терминала QUIK
-- (c) http://qui2dde.ru/
-- Версия: 1.0

local w32 = require("w32")

-- логин и пароль для терминала
QUIK_LOGIN = "11111"
QUIK_PASSW = "222222"


function FindLoginWindow()
  hLoginWnd = w32.FindWindow("", "Вход в систему")
  if hLoginWnd == 0 then
    hLoginWnd = w32.FindWindow("", "User identification")
  end
  return hLoginWnd
end

timeout = 1000  -- таймаут между попытками поиска окна логина
is_run = true

function main()
  while is_run do
    sleep(timeout)

    if isConnected() == 0 then
 
      local hWnd = FindLoginWindow()
      if hWnd ~= 0 then

        local hLoginWnd = w32.FindWindowEx(hWnd, 0, "", "")
        local hLogin = w32.FindWindowEx(hWnd, hLoginWnd, "", "")
        local nPassw = w32.FindWindowEx(hWnd, hLogin, "", "")
        local nBtnOk = w32.FindWindowEx(hWnd, nPassw, "", "")
       
        w32.SetWindowText(hLogin, QUIK_LOGIN)
        w32.SetWindowText(nPassw, QUIK_PASSW)

        w32.SetFocus(nBtnOk)
        w32.PostMessage(nBtnOk, w32.BM_CLICK, 0, 0)

      end
    end
    end
    end

77

Re: Автологин в QUIK (на Lua)

Balu пишет:

Доброго времени суток !!
Использовал скрипт все отлично работало. Пришлось переустанавливать QUIK.
Теперь заполнение полей происходит но кнопка не нажимается .
QUIK 8.12.0.41 dll версия 5.3 .
Dll лежит в папке QUIK
Понимаю что пробема где-то здесь как поправить не знаю.

Замените

w32.SetFocus(nBtnOk)
w32.PostMessage(nBtnOk, w32.BM_CLICK, 0, 0)

на

w32.PostMessage(hWnd,w32.WM_COMMAND,1,0)

78 (2021-01-31 21:17:24 отредактировано BlaZed)

Re: Автологин в QUIK (на Lua)

Собрал все "вкусности" которые счел полезными из обсуждений данной темы в один скрипт.
Ловите очередную версию скрипта.

-- Автологин терминала QUIK
-- (c) http://quik2dde.ru/
-- Версия: 4.1 (BlaZed Edition)
QUIK_LOGIN="логин"     -- Логин
QUIK_PASSW="пароль"    -- Пароль

function OnInit()
  local luadir="x32"
  if(_VERSION=="Lua 5.1")then luadir="x64-Lua51" end
  if(_VERSION=="Lua 5.3")then luadir="x64-Lua53" end
  if(_VERSION=="Lua 5.4")then luadir="x64-Lua54" end
  package.cpath=package.cpath..";"..getWorkingFolder().."\\w32\\"..luadir.."\\?.dll";
  w32 = require("w32")
end
function main()
  CurrentProcessId=w32.GetCurrentProcessId()     -- ID процесса QUIK
  QuikMainWindowHandle=GetWindowHandleByClassName("InfoClass") -- Дескриптор главного окна QUIK
  if(QuikMainWindowHandle==0) then message("Дескриптор главного окна QUIK не найден") return end
  serv_n=-1               -- Порядковый номер сервера
  is_run = true
  while is_run do
    if(isConnected()==0)then
      if(WorkTime()==true)then QuikConnect() end -- Нажать кнопку "Установить соединение с информационным сервером"
      QuikLogin()                                -- Ввести Логин/Пароль и нажать кнопку "Вход"
      collectgarbage()                           -- Сбор мусора
    else
      serv_n=-1
    end
    sleep(1000)
  end
end
function OnStop()
  is_run=false
  return 100
end

function QuikConnect() -- Нажать кнопку "Установить соединение с информационным сервером"
  w32.PostMessage(QuikMainWindowHandle,w32.WM_COMMAND,100,0)
end
function QuikLogin() -- Ввести Логин/Пароль и нажать кнопку "Вход"
  local hWnd=GetWindowHandleByClassName("#32770")      -- Получить дескриптор окна логина QUIK
  if hWnd==0 then return end                           -- Дескриптор не найден, выход
  local hServe=w32.FindWindowEx(hWnd,0,"ComboBox","")  -- Сервер
  local hLogin=w32.FindWindowEx(hWnd,hServe,"Edit","") -- Логин
  local nPassw=w32.FindWindowEx(hWnd,hLogin,"Edit","") -- Пароль
  if(serv_count==nil)then serv_count=w32.SendMessage(hServe,w32.CB_GETCOUNT,0,0) end -- Количество серверов в списке
  if(serv_n>=0)then -- при первой попытке коннект к серверу из последнего соединения, при неудачном коннекте перебор
    serv_n=serv_n%serv_count
    w32.SendMessage(hServe,w32.CB_SETCURSEL,serv_n,0)
  end
  serv_n=serv_n+1
  w32.SetWindowText(hLogin,QUIK_LOGIN)
  w32.SetWindowText(nPassw,QUIK_PASSW)
  w32.PostMessage(hWnd,w32.WM_COMMAND,1,0)
end
function GetWindowHandleByClassName(ClassName) -- Получить дескриптор окна по ClassName
  local hWnd=0
  while true do
    hWnd=w32.FindWindowEx(0,hWnd,ClassName,"")
    if hWnd==0 then break end -- Окно не найдено
    local ThreadId,ProcessId=w32.GetWindowThreadProcessId(hWnd)
    if ProcessId==CurrentProcessId then break end -- Окно найдено
  end
  return hWnd
end

function WorkTime() -- Возвращает флаг рабочего времени
  local GMT3=10800   -- Часовой пояс биржи GMT+3 Москва (3*60*60=10800 - количество секунд в 3 часах)
  dt=os.date("!*t",os.time()+GMT3)
-- Торговый календарь московской биржи
-- 2021 год https://www.moex.com/s3196
-- true - рабочий день, false - не рабочий день, nil - проверяем день недели
  local calendar={[20210101]=false,[20210107]=false,[20210220]=true,[20210223]=false,[20210308]=false,[20210503]=false,[20210510]=false,[20210614]=false,[20211104]=false,[20211231]=false}
  local today=calendar[dt.year*10000+dt.month*100+dt.day]
  if(today==false)or((today==nil)and((dt.wday==1)or(dt.wday==7)))then return false end
  if(dt.hour*60+dt.min < 590) then return false end -- Отсекаем время до 9:50 (9*60+50=590 - количество минут с 0:00 до 9:50)
  return true
end

!!! ОБЯЗАТЕЛЬНО К ПРОЧТЕНИЮ !!!
Обратите внимание на изменение пути к библиотеке w32.dll

Чтобы скрипт нашел библиотеку, создаем в папке с квиком папку w32 и распаковываем архив с библиотекой в нее
В папке w32 должны появиться подпапки x32, x64-Lua51, x64-Lua53, x64-Lua54, в каждой из них должна находиться w32.dll для нужной версии LUA

Не забываем из папки с квиком удалить файл w32.dll, если ранее вы туда его помещали.

79 (2021-01-31 16:43:16 отредактировано swerg)

Re: Автологин в QUIK (на Lua)

BlaZed, спасибо вам!

PS
Посмотрел как вы предлагаете указывать путь.
Кстати да, наверное есть смысл во всех готовых сборках библиотека (на этом сайте) перейти на единую унифицированную структуру именования вложенных папок в архивах. А то я в каждой библиотеке что-то "новое" изобретаю, но вроде вариант в w32 получился достаточно удачным наконец-то в смысле понятности и краткости.
Быть может даже есть смысл делать "общий" архив, где складывать все библиотеки.

80 (2021-01-31 19:57:07 отредактировано BlaZed)

Re: Автологин в QUIK (на Lua)

Прошу проверить у кого какой Class Name присваивается окну логина QUIK

Просто сейчас ковырялся в свойствах окон и заметил, что у меня Class Name окна логина всегда "#32770"
И на разных версиях квика (проверил на 8.11.0.66 и 8.12.0.41) и при разных языках и под разными пользователями и после перезагрузки такой же остается.
Только на другой системе не могу проверить, под рукой всего лишь один сервер на винде.

Если вдруг у всех одинаково, то поиск окна логина можно сделать немного проще.

81

Re: Автологин в QUIK (на Lua)

BlaZed пишет:

Замените

w32.SetFocus(nBtnOk)
w32.PostMessage(nBtnOk, w32.BM_CLICK, 0, 0)

на

w32.PostMessage(hWnd,w32.WM_COMMAND,1,0)

Спасибо заработало !!

BlaZed пишет:

Прошу проверить у кого какой Class Name присваивается окну логина QUIK

С удовольствием это сделал бы если бы знал как ))

82

Re: Автологин в QUIK (на Lua)

BlaZed пишет:

Прошу проверить у кого какой Class Name присваивается окну логина QUIK

Просто сейчас ковырялся в свойствах окон и заметил, что у меня Class Name окна логина всегда "#32770"

В самом деле, имя класса именно такое.
Проверил на 8.11, 8.9, 8.6, 7.7, 7.5.

83

Re: Автологин в QUIK (на Lua)

Visual Studio

#32770 (Диалоговое окно)

84 (2021-01-31 21:18:05 отредактировано BlaZed)

Re: Автологин в QUIK (на Lua)

Спасибо за проверки
Поправил код в посте 78, будем искать окно логина по данному классу

85 (2021-02-04 10:18:32 отредактировано BlaZed)

Re: Автологин в QUIK (на Lua)

С поиском окна по классу возникла небольшая проблема.
Как оказалось ClassName="#32770" QUIK присваивает не только окну логина, а еще нескольким диалоговым окнам.
Например окну списка компонентов, о программе, окна закрытия приложения и т.д.

Так что рано радовался, от проверки по тексту заголовка окна пока корректно не получается отказаться.

Есть у кого идеи?

86

Re: Автологин в QUIK (на Lua)

я уже объяснял как. надо проверять по тексту заголовка, но чтобы не быть привязанным к выбранному языку и версии, нужно брать эти строки по идентификатору из ресурсов. вот библиотека и пример. https://github.com/untoxa/lua_quik_resources а эти все потуги выше - фигня.

87 (2021-02-05 18:52:10 отредактировано swerg)

Re: Автологин в QUIK (на Lua)

BlaZed пишет:

Есть у кого идеи?

Предлагаю пока вернуть скрипт в то состояние, в каком он был ранее.
Хотя бы потому, что в текущей версии он просто некорректно работает. А там уже думать.

BlaZed, у вас осталась предыдущая версия? Могли бы её вернуть в ваше сообщение?
А то я не сохранил, признаться.

88 (2021-02-21 17:37:53 отредактировано CyberTrader)

Re: Автологин в QUIK (на Lua)

local run = true

function FindWindowEx(ClassName, WindowName, PID)
  -- Получить хендл окна по ClassName и/или WindowName
  if PID == nil then PID = w32.GetCurrentProcessId() end
  local hWnd = 0
  while run do
    hWnd = w32.FindWindowEx(0, hWnd, ClassName or "", WindowName or "")
    if hWnd == 0 then break end
    local ProcId = select(2, w32.GetWindowThreadProcessId(hWnd))
    if ProcId == PID then return hWnd end
  end
  return 0
end

function GetQUIKLoginWindowHandle()
  -- Возвращает хендл окна логина QUIK
  local PID = w32.GetCurrentProcessId()
  local hWnd = 0
  if 0+getInfoParam("VERSION"):match("^(%d+)") < 8 then
    hWnd = FindWindowEx("#32770", "Идентификация пользователя", PID)
    if hWnd == 0 then
      hWnd = FindWindowEx("#32770", "User identification", PID)
    end
  else
    hWnd = FindWindowEx("#32770", "Вход в систему", PID)
    if hWnd == 0 then
      hWnd = FindWindowEx("#32770", "System Login", PID)
    end
  end
  return hWnd
end

89

Re: Автологин в QUIK (на Lua)

Добрый день, уважаемые форумчане.
BlaZed попытался следовать вашим инструкциям, ничего не получилось((. Выдает вот такую ошибку. Что-то пока не пойму тут скрины можно вставлять?)). Ошибка звучит:
Syntax error while compiling C:\QUIK\lua\Автозапуск QUIK QLUA\Автозапуск.lua: C:\QUIK\lua\Автозапуск QUIK QLUA\Автозапуск.lua:1: unexpected symbol near '-'

90

Re: Автологин в QUIK (на Lua)

С квик совсем недавно работаю. Скрипты совсем для меня тема темная. До меня уже стояли скрипты по автологину и автоснятию заявок с расчетами ТОД. Тоже вышел из строя. Начал смотреть в инете, по автологину нашел на этом форуме, но не получилось. А вот по снятию заявок совсем беда((

91

Re: Автологин в QUIK (на Lua)

vfu81 пишет:

Ошибка звучит:
Syntax error while compiling C:\QUIK\lua\Автозапуск QUIK QLUA\Автозапуск.lua: C:\QUIK\lua\Автозапуск QUIK QLUA\Автозапуск.lua:1: unexpected symbol near '-'

В какой кодировке сохранен файл со скриптом? Должно быть Ansi или оно же Windows 1251

92

Re: Автологин в QUIK (на Lua)

Добрый день. Подскажите, пжт, где я могу проверить эту кодировку?

93

Re: Автологин в QUIK (на Lua)

Нашел как это сделать. Через фар. Вин 1251

94

Re: Автологин в QUIK (на Lua)

подскажите скрипт для квика 8.12 способ с заменой строк не подошел, кнопка всеравно не нажимается

95 (2021-02-25 23:22:25 отредактировано BlaZed)

Re: Автологин в QUIK (на Lua)

На данный момент пользуюсь таким вариантом скрипта.
QUIK 8.12.0.41

-- Автологин терминала QUIK
-- (c) http://quik2dde.ru/
-- Версия: 4.2 (BlaZed Edition)
QUIK_LOGIN="Логин"     -- Логин
QUIK_PASSW="Пароль"    -- Пароль

function OnInit()
  local luadir="x32"
  if(_VERSION=="Lua 5.1")then luadir="x64-Lua51" end
  if(_VERSION=="Lua 5.3")then luadir="x64-Lua53" end
  if(_VERSION=="Lua 5.4")then luadir="x64-Lua54" end
  package.cpath=package.cpath..";"..getWorkingFolder().."\\w32\\"..luadir.."\\?.dll";
  w32 = require("w32")
  CurrentProcessId=w32.GetCurrentProcessId()            -- ID процесса QUIK
  QuikMainWindowHandle=GetWindowHandle("InfoClass","")  -- Дескриптор главного окна QUIK
  if(QuikMainWindowHandle==0) then message("Дескриптор главного окна QUIK не найден") return end
  MainWindowText=w32.GetWindowText(QuikMainWindowHandle) -- Текст заголовка главного окна QUIK
  LoginWindowText="Идентификация пользователя"           -- Текст заголовка окна логина Язык RU (по умолчанию)
  if(string.find(MainWindowText,"version")~=nil) then LoginWindowText="User identification" end -- Язык EN
  serv_n=-1 -- Порядковый номер сервера
end
function main()
  is_run = true
  while is_run do
    if(isConnected()==0)then
      if(WorkTime()==true)then QuikConnect() end -- Нажать кнопку "Установить соединение с информационным сервером"
      QuikLogin()                                -- Ввести Логин/Пароль и нажать кнопку "Вход"
      collectgarbage()                           -- Сбор мусора
    else
      serv_n=-1
    end
    sleep(1000)
  end
end
function OnStop()
  is_run=false
  return 100
end

function QuikConnect() -- Нажать кнопку "Установить соединение с информационным сервером"
  w32.PostMessage(QuikMainWindowHandle,w32.WM_COMMAND,100,0)
end
function QuikLogin() -- Ввести Логин/Пароль и нажать кнопку "Вход"
  local hWnd=GetWindowHandle("#32770",LoginWindowText) -- Получить дескриптор окна логина QUIK
  if hWnd==0 then return end                           -- Дескриптор не найден, выход
  local hServe=w32.FindWindowEx(hWnd,0,"ComboBox","")  -- Сервер
  local hLogin=w32.FindWindowEx(hWnd,hServe,"Edit","") -- Логин
  local nPassw=w32.FindWindowEx(hWnd,hLogin,"Edit","") -- Пароль
  if(serv_count==nil)then serv_count=w32.SendMessage(hServe,w32.CB_GETCOUNT,0,0) end -- Количество серверов в списке
  if(serv_n>=0)then -- при первой попытке коннект к серверу из последнего соединения, при неудачном коннекте перебор
    serv_n=serv_n%serv_count
    w32.SendMessage(hServe,w32.CB_SETCURSEL,serv_n,0)
  end
  serv_n=serv_n+1
  w32.SetWindowText(hLogin,QUIK_LOGIN)
  w32.SetWindowText(nPassw,QUIK_PASSW)
  w32.PostMessage(hWnd,w32.WM_COMMAND,1,0)
end
function GetWindowHandle(ClassName,Text) -- Получить дескриптор окна
  local hWnd=0
  while true do
    hWnd=w32.FindWindowEx(0,hWnd,ClassName,Text)
    if hWnd==0 then break end -- Окно не найдено
    local ThreadId,ProcessId=w32.GetWindowThreadProcessId(hWnd)
    if ProcessId==CurrentProcessId then break end -- Окно найдено
  end
  return hWnd
end

function WorkTime() -- Возвращает флаг рабочего времени
  local GMT3=10800   -- Часовой пояс биржи GMT+3 Москва (3*60*60=10800 - количество секунд в 3 часах)
  dt=os.date("!*t",os.time()+GMT3)
-- Торговый календарь московской биржи
-- 2021 год https://www.moex.com/s3196
-- true - рабочий день, false - не рабочий день, nil - проверяем день недели
  local calendar={[20210101]=false,[20210107]=false,[20210220]=true,[20210223]=false,[20210308]=false,[20210503]=false,[20210510]=false,[20210614]=false,[20211104]=false,[20211231]=false}
  local today=calendar[dt.year*10000+dt.month*100+dt.day]
  if(today==false)or((today==nil)and((dt.wday==1)or(dt.wday==7)))then return false end
  if(dt.hour*60+dt.min<590) then return false end -- Отсекаем время до 9:50 (9*60+50=590 - количество минут с 0:00 до 9:50)
  return true
end

!!! ОБЯЗАТЕЛЬНО К ПРОЧТЕНИЮ !!!
Обратите внимание на изменение пути к библиотеке w32.dll

Чтобы скрипт нашел библиотеку, создаем в папке с квиком папку w32 и распаковываем архив с библиотекой в нее
В папке w32 должны появиться подпапки x32, x64-Lua51, x64-Lua53, x64-Lua54, в каждой из них должна находиться w32.dll для нужной версии LUA

Не забываем из папки с квиком удалить файл w32.dll, если ранее вы туда его помещали.

96

Re: Автологин в QUIK (на Lua)

Blazed,спасибо помогло

97

Re: Автологин в QUIK (на Lua)

Всем, привет. С третьей попытки поставить новый скрипт все заработало. Спасибо огромное!!!!!

98

Re: Автологин в QUIK (на Lua)

Внимание тем, кто торгует на срочном рынке!
С сегодняшнего дня (1.03.2021) срочный рынок на ММВБ открывается ни с 10:00 как было раньше, а с 7:00.
Исправьте время подключения в скрипте.