Версия для печати темы

Нажмите сюда для просмотра этой темы в обычном формате

UoKit.com Форумы _ UO Pilot _ Меню окна, подскажите плз!

Автор: for2 4.12.2020, 17:48

Ребята, подскажите, куда копать! Есть программа InqSoft Window Scanner - просматривает главное меню окна любой программы, видит ID пунктов меню и позволяет на них нажимать и т.д. Как при помощи UOPilot так же работать с главным меню программы через скрипты, просматривать структуру меню и работать с дочерними окнами??

Автор: cirus 5.12.2020, 3:04

Меню окна
Код
--lua
local GA_ROOTOWNER = 3
local MF_BYPOSITION = 0x00000400
local ffi = require("ffi")

ffi.cdef[[
    int GetMenu(int hwnd);
    int GetAncestor(int hwnd, unsigned int gaFlags);
    int GetMenuItemCount(int hmenu);
    int GetMenuStringA(int hmenu, unsigned int idItem, char* lpsz, int cbMax, unsigned int fuFlags);
]]


-- Ctrl+A привязка к окну, можно проверить на окне пилота или блокнота
log 'clear' log 'mode compact'
local h_menu = ffi.C.GetMenu(ffi.C.GetAncestor(workwindow(), GA_ROOTOWNER))
if h_menu > 0 then
    local count_menu_item = ffi.C.GetMenuItemCount(h_menu)
    log('Количество элементов в меню: ' .. tostring(count_menu_item))

    for i=0, count_menu_item-1 do
        local len_str = ffi.C.GetMenuStringA(h_menu, i, nil, 0, MF_BYPOSITION)
        local name_item = ffi.new('char[?]', len_str+1)
        ffi.C.GetMenuStringA(h_menu, i, name_item, ffi.sizeof(name_item), MF_BYPOSITION)
        log(ffi.string(name_item))
    end
else
    log('У окна нет меню')
end

Цитата
и работать с дочерними окнами

Что именно хотите сделать? Getwindow если нужно найти дочернее окно.

Автор: FREEON 5.12.2020, 9:06

Скорее всего имелось ввиду нажатие кнопок по их имени или id

Автор: cirus 5.12.2020, 9:39

Цитата
Скорее всего имелось ввиду нажатие кнопок по их имени или id

Любые манипуляции с окнами выполняются через sendmessage.

Автор: for2 5.12.2020, 10:08

Цитата(cirus @ 5.12.2020, 9:39) *

Любые манипуляции с окнами выполняются через sendmessage.

Изображение
Есть программа -1
У нее нет горячей клавиши на сохранение конфига -2
При помощи InqSoft Window Scanner я могу видеть структуру меню программы и нажать -4, чтобы начать сохранение.
Как тоже самое сделать НЕ при помощи InqSoft Window Scanner, а скриптом и горячей клавиши??
Подскажите как это реализовать через sendmessage??

Автор: cirus 5.12.2020, 17:23

Цитата
Есть программа -1
У нее нет горячей клавиши на сохранение конфига -2
При помощи InqSoft Window Scanner я могу видеть структуру меню программы и нажать -4, чтобы начать сохранение.
Как тоже самое сделать НЕ при помощи InqSoft Window Scanner, а скриптом и горячей клавиши??

код
Код
--lua
local WM_COMMAND = 0x0111
local ffi = require("ffi")
ffi.cdef[[
    int GetMenu(int hwnd);
    int GetSubMenu(int hMenu, int nPos);
    unsigned int GetMenuItemID(int hMenu, int nPos);
    int PostMessageA(int hWnd, unsigned int Msg, unsigned int wParam, long lParam);
]]
log 'clear' log 'mode compact'

local handle = findwindow ("QUIK")  -- имя окна (можно указать часть имени)
if handle then   -- если окно найдено
    local h_menu = ffi.C.GetMenu(handle[1][1])   -- получить хендл меню окна
    if h_menu > 0 then     -- если меню есть
        local h_submenu = ffi.C.GetSubMenu(h_menu, 0)  -- получить хендл подменю, первого по порядку (для QUIK это 'Система')
        local id_item = ffi.C.GetMenuItemID(h_submenu, 5)  -- получить id итема подменю, шестого по порядку (для QUIK это 'Сохранить настройки в файл')
        if h_submenu and id_item then    -- если существуют
            ffi.C.PostMessageA(handle[1][1], WM_COMMAND, id_item, 0) -- отправить сообщение пункту меню
        else
            log('Не получен хенд подменю или id итема подменю')
        end
    else
        log('У окна нет меню')
    end
else
    log('Окно не найдено')
end

Пилот версии 2.41 или выше. Горячие клавиши для запуска скрипта во вкладке 'Ещё'.

Автор: for2 5.12.2020, 18:01

Цитата(cirus @ 5.12.2020, 17:23) *

Пилот версии 2.41 или выше. Горячие клавиши для запуска скрипта во вкладке 'Ещё'.

Офигительно!
Но есть нюанс. У меня программа Quik имеет кучу дочерних окон и все они раскиданы по нескольким рабочим столам через прожку Dexpot. На одном рабочем столе с Quik код работает отлично, но если запускать его с другого рабочего стола, то код уже не может найти Quik с меню. Можно ли модифицировать код??

Автор: cirus 5.12.2020, 18:17

Без понятия, у меня нет этой проги, используйте стандартные виртуальные столы.

Автор: for2 5.12.2020, 19:08

Цитата(cirus @ 5.12.2020, 18:17) *

Без понятия, у меня нет этой проги, используйте стандартные виртуальные столы.

Еще одна просьба, можно код, который копирует имя активного окна в буфер обмена?

Автор: cirus 5.12.2020, 19:24

Цитата
код, который копирует имя активного окна в буфер обмена?

Код
--lua
wait(3000)  -- пауза 3 секунды (можно убрать)
local name_active_window = getwindowtext(getwindow(0))  -- получить имя активного окна
clipboard (name_active_window)  -- скопировать в буфер обмена
hint (name_active_window)   -- подсказка в левом нижнем углу (можно убрать)


Автор: for2 5.12.2020, 19:34

Цитата(cirus @ 5.12.2020, 19:24) *

Код
--lua
wait(3000)  -- пауза 3 секунды (можно убрать)
local name_active_window = getwindowtext(getwindow(0))  -- получить имя активного окна
clipboard (name_active_window)  -- скопировать в буфер обмена
hint (name_active_window)   -- подсказка в левом нижнем углу (можно убрать)


Пишет: Неправильно указана задержка между строк..?
Да, теперь я знаю что в 10-тке есть стандартные вирт.столы )

Автор: cirus 5.12.2020, 19:38

Цитата
Пишет: Неправильно указана задержка между строк..?

Этот код не может такого писать.

Автор: for2 5.12.2020, 19:46

Цитата(cirus @ 5.12.2020, 19:38) *

Этот код не может такого писать.

Изображение

Да, это пишет пилот, но я как дилетант не знаю что с этим делать

Автор: cirus 5.12.2020, 19:50

А первую строку копировать кто будет?

Код
--lua

Автор: for2 5.12.2020, 19:56

Цитата(cirus @ 5.12.2020, 19:50) *

А первую строку копировать кто будет?
Код
--lua


мля.. )
Замечательно! Наверное это не последняя просьба..

Автор: cirus 5.12.2020, 20:05

Цитата
Наверное это не последняя просьба..

Смотрите примеры тут: https://uopilot.uokit.com/wiki/index.php?title=Список_функций_(Lua)
Если что-то непонятно, то поможем.



Автор: for2 5.12.2020, 20:07

Цитата(cirus @ 5.12.2020, 20:05) *

Если что-то непонятно, то поможем.

Благодарю, это важно..

Автор: for2 6.12.2020, 6:09

Цитата(cirus @ 5.12.2020, 17:23) *

код
Код
--lua
local WM_COMMAND = 0x0111
local ffi = require("ffi")
ffi.cdef[[
    int GetMenu(int hwnd);
    int GetSubMenu(int hMenu, int nPos);
    unsigned int GetMenuItemID(int hMenu, int nPos);
    int PostMessageA(int hWnd, unsigned int Msg, unsigned int wParam, long lParam);
]]
log 'clear' log 'mode compact'

local handle = findwindow ("QUIK")  -- имя окна (можно указать часть имени)
if handle then   -- если окно найдено
    local h_menu = ffi.C.GetMenu(handle[1][1])   -- получить хендл меню окна
    if h_menu > 0 then     -- если меню есть
        local h_submenu = ffi.C.GetSubMenu(h_menu, 0)  -- получить хендл подменю, первого по порядку (для QUIK это 'Система')
        local id_item = ffi.C.GetMenuItemID(h_submenu, 5)  -- получить id итема подменю, шестого по порядку (для QUIK это 'Сохранить настройки в файл')
        if h_submenu and id_item then    -- если существуют
            ffi.C.PostMessageA(handle[1][1], WM_COMMAND, id_item, 0) -- отправить сообщение пункту меню
        else
            log('Не получен хенд подменю или id итема подменю')
        end
    else
        log('У окна нет меню')
    end
else
    log('Окно не найдено')
end

Пилот версии 2.41 или выше. Горячие клавиши для запуска скрипта во вкладке 'Ещё'.


Изображение

В конце кода, требуется ещё
- нажать "Сохранить",
- затем подтвердить перезапись существующего файла
-вывести какое-нибудь сообщение в углу на пару секунд об удачном сохранении

Пжл, допишите код??

И ещё такая просьба,
На сколько сложно реализовать сортировку окон по рабочим столам, т.к. после перезагрузки получается свалка на столе №1.
Например, есть 6 рабочих столов.
Код должен сканировать все рабочие столы и сортировать окна по конкретным столам.
Вот правила перемещения окон на рабочие столы:
Изображение
Если можете, помогине пожалуйста с кодом

Автор: cirus 6.12.2020, 13:57

Цитата
В конце кода, требуется ещё
- нажать "Сохранить",
- затем подтвердить перезапись существующего файла
-вывести какое-нибудь сообщение в углу на пару секунд об удачном сохранении

код
Код
--lua
local WM_COMMAND = 0x0111
local ffi = require("ffi")
ffi.cdef[[
    int GetMenu(int hwnd);
    int GetSubMenu(int hMenu, int nPos);
    unsigned int GetMenuItemID(int hMenu, int nPos);
    int PostMessageA(int hWnd, unsigned int Msg, unsigned int wParam, long lParam);
    int FindWindowExA(int hWndParent, int hWndChildAfter, const char* lpszClass, const char* lpszWindow);
]]
log 'clear' log 'mode compact'

local handle = findwindow ("QUIK")  -- имя окна (можно указать часть имени)
if handle then   -- если окно найдено
    local h_menu = ffi.C.GetMenu(handle[1][1])   -- получить хендл меню окна
    if h_menu > 0 then     -- если меню есть
        local h_submenu = ffi.C.GetSubMenu(h_menu, 0)  -- получить хендл подменю, первого по порядку (для QUIK это 'Система')
        local id_item = ffi.C.GetMenuItemID(h_submenu, 5)  -- получить id итема подменю, шестого по порядку (для QUIK это 'Сохранить настройки в файл')
        if h_submenu and id_item then    -- если существуют
            ffi.C.PostMessageA(handle[1][1], WM_COMMAND, id_item, 0) -- отправить сообщение пункту меню

            -- поиск окна сохранения настроек
            local timeout = os.clock() + 3   -- 3 секунды ожидание появления окна
            local save_settings
            repeat
                save_settings = findwindow ("Выберите файл для сохранения текущих настроек")
                wait (10)
            until save_settings  or os.clock() > timeout
            if os.clock() >= timeout then  -- окно с настройками не открылось
                log('Окно сохранения настроек не найдено')
                end_script()
            end

            -- поиск кнопки сохранения настроек
            local save_button = ffi.C.FindWindowExA(save_settings[1][1], 0, 'Button', 'Со&хранить')
            if save_button ~= 0 then
                workwindow(save_button)
                left (10, 10)    -- клик на кнопку
            else
                log('Кнопка Сохранить не найдена')
                end_script()
            end

            -- поиск окна для подтверждения сохранения настроек
            local confirm_save
            timeout = os.clock() + 3
            repeat
                confirm_save = findwindow ("Подтвердить сохранение в виде")
                wait (10)
            until confirm_save or os.clock() > timeout
            if os.clock() >= timeout then
                log('Окно подтверждения настроек не найдено')
                end_script()
            end

            -- поиск кнопки Да
            local temp =  getwindow (confirm_save[1][1], 'CHILD')
            local temp2 = ffi.C.FindWindowExA(temp, 0, 'CtrlNotifySink', nil)
            local yes_button=ffi.C.FindWindowExA(temp2, 0, 'Button', '&Да')
            if yes_button == 0 then
                while temp2 ~= 0 do
                    temp2 = ffi.C.FindWindowExA(temp, temp2, 'CtrlNotifySink', nil)
                    yes_button=ffi.C.FindWindowExA(temp2, 0, 'Button', '&Да')
                    if yes_button ~=0 then break end
                end
            end
            if yes_button ~= 0 then
                workwindow(yes_button)
                left (10, 10)    -- клик на кнопку
            else
                log('Кнопка Да не найдена')
                end_script()
            end

            hint ('Готово')
        else
            log('Не получен хенд подменю или id итема подменю')
        end
    else
        log('У окна нет меню')
    end
else
    log('Окно не найдено')
end

Цитата
На сколько сложно реализовать сортировку окон по рабочим столам

Не знаю какая функция winapi выполняет перемещение окна на другой рабочий стол.

Автор: for2 6.12.2020, 15:00

Цитата(cirus @ 6.12.2020, 13:57) *


Не знаю какая функция winapi выполняет перемещение окна на другой рабочий стол.

Супер, спасибо, сохранение работает очень быстро!

Автор: for2 6.12.2020, 16:19

Цитата(cirus @ 5.12.2020, 19:24) *

Код
--lua
wait(3000)  -- пауза 3 секунды (можно убрать)
local name_active_window = getwindowtext(getwindow(0))  -- получить имя активного окна
clipboard (name_active_window)  -- скопировать в буфер обмена
hint (name_active_window)   -- подсказка в левом нижнем углу (можно убрать)


Для добавления звукового сигнала добавил в конец кода, без параметров
Alarm
- выдает ошибку

hint (name_active_window)
- Попытался увеличить шрифт, всяко разно дописывал цифры и со скобками и без согласно в описанию
- выдает ошибку
Вообще не въезжаю в синтаксис??
Подскажите как правильно, пжл

Автор: cirus 6.12.2020, 16:44

Цитата
Alarm
- выдает ошибку

Код
--lua
alarm()

Цитата
Попытался увеличить шрифт

Это работает только в старом синтаксисе. В луа нет.
Можно использовать такой вариант:
Код
--lua
-- тут какой-то код луа

--endlua

// тут используется старый синтаксис пилота
hint (24 clRed 500 500 -1 -1 (Готово))


--lua
-- дальше снова код на языке луа
-- какой-то код луа

Но, я бы не стал так делать, скорее всего никто не тестил насколько корректно будет работать такой скрипт.
Цитата
Вообще не въезжаю в синтаксис??

Не путайте старый синтаксис пилота и луа. Список функций, которые работают в луа без проблем: https://uopilot.uokit.com/wiki/index.php?title=Список_функций_(Lua)
Смотрите примеры именно тут.

Автор: for2 6.12.2020, 17:30

Цитата(cirus @ 6.12.2020, 16:44) *

Не путайте старый синтаксис пилота и луа. Список функций, которые работают в луа без проблем: https://uopilot.uokit.com/wiki/index.php?title=Список_функций_(Lua)
Смотрите примеры именно тут.

Хорошо, спасибо.
Ещё вопрос
Изображение
Речь идет о всё той же программе Quik. Я могу рисовать в ней простые геометрические объекты и удалять их.
Вопрос, видите ли вы возможность через код работать с графическими объектами? Т.е. в коде, который вы мне писали происходит поиск поиск кнопок, отправка сообщений. Может ли это работать с простыми графическими объектами? (вообще эта прога Quik поддерживает работу со скриптами Lua) или постановка задачи слишком туманна, чтобы внятно ответить? )

Автор: cirus 6.12.2020, 17:56

Цитата
или постановка задачи слишком туманна, чтобы внятно ответить?

Пожалуй, да.



Автор: for2 6.12.2020, 19:46

Цитата(cirus @ 6.12.2020, 17:56) *

Пожалуй, да.

Хорошо, можно ли организовать ввод с клавиатуры:
- после нажатия горячей клавиши скрипт ждет ввода с клавы
- ввожу ключевые буквы названия окна, Enter
- т.е. последовательность букв будет уникальна для каждого окна
- скрипт ищет и делает это окно активным, т.е. если свёрнуто или под другими окнами - раскрывается/вылезает вперед
Можно ли так сделать?
Суть в том, что
- сортировки по виртуальным столам - нету, т.е. после перезагрузки вся куча всё равно - на столе-1
- программа (Quik) работает корректно только со столом-1
??
rolleyes.gif

Автор: cirus 6.12.2020, 20:22

А не проще вызывать нужное окно при нажатии комбинации клавиш. Примерно так:

код
Код
--lua
local ffi = require("ffi")
local VK_CONTROL = 0x11
local key1 = 0x31
local key2 = 0x32
ffi.cdef[[
short GetKeyState(int nVirtKey);
short GetAsyncKeyState(int vKey);
]]
log 'clear' log 'mode compact'


while true do
    if ffi.C.GetAsyncKeyState(VK_CONTROL) < 0 and ffi.C.GetAsyncKeyState(key1) < 0 then   -- если нажаты Ctrl+1
        while ffi.C.GetKeyState(VK_CONTROL) < 0 and ffi.C.GetKeyState(key1) < 0 do wait(10) end
        log ("Активировать окно1")
    end

    if ffi.C.GetAsyncKeyState(VK_CONTROL) < 0 and ffi.C.GetAsyncKeyState(key2) < 0 then    -- если нажаты Ctrl+2
        while ffi.C.GetKeyState(VK_CONTROL) < 0 and ffi.C.GetKeyState(key2) < 0 do wait(10) end
        log ("Активировать окно2")
    end
    wait (10)
end

Автор: Fors1k 7.12.2020, 18:21

Цитата(for2 @ 6.12.2020, 6:09) *
И ещё такая просьба,
На сколько сложно реализовать сортировку окон по рабочим столам, т.к. после перезагрузки получается свалка на столе №1.
Например, есть 6 рабочих столов.
Код должен сканировать все рабочие столы и сортировать окна по конкретным столам.
Вот правила перемещения окон на рабочие столы:
Изображение
Если можете, помогине пожалуйста с кодом


Снять галочку
Прикрепленное изображение
Код
--lua
require"luaposh";log "clear";log "mode compact"
PScode('return',{[[#}
#
$windows = @{#}
    "Калькулятор" = 2
    "wordpad"     = 3
    "paint"       = 4
}

$windows.GetEnumerator()|ForEach{#}
    Move-WindowToDesktop (Find-Window $_.Key) $_.Value
}
#
]]})

Move-WindowToDesktop третий параметр можно не указывать (по умолчанию 200). Если будет некорректно работать, то указывайте его с увеличением: 250;300;350;... , пока не найдете подходящий.

Автор: for2 8.12.2020, 16:51

Цитата(cirus @ 6.12.2020, 20:22) *

А не проще вызывать нужное окно при нажатии комбинации клавиш. Примерно так:

Спасибо большое, но проблема в том, что открытых окон 40 шт blink.gif и это не предел smile.gif
При этом могут происходить изменения в наборе окон, перестановки.
Поэтому адекватно и оперативно работать с окнами я могу только вызывая их по ключевым буквам (имени окна)

Автор: for2 8.12.2020, 17:28

Цитата(cirus @ 6.12.2020, 20:22) *

А не проще вызывать нужное окно при нажатии комбинации клавиш. Примерно так:

А вообще лучше было бы плавающее окно поверх других такого вида
Изображение
Каждая клетка - это кнопка. Нажимаю SR (или Si, GZ, YN) + 1' (или 5', 30', D, W)
что дает такие сочетания:
SR1' или SRD или GZ5' и т.д.
А SR1' (или SRD или GZ5' и т.д.) - это и есть название окна (часть названия). Т.о. активируется необходимое окно.
Такой графический интерфейс сложно сделать?

Цитата(Fors1k @ 7.12.2020, 18:21) *

Move-WindowToDesktop третий параметр можно не указывать (по умолчанию 200). Если будет некорректно работать, то указывайте его с увеличением: 250;300;350;... , пока не найдете подходящий.

Интересно, но я выяснил, что мои окна нормально работают только на рабочем столе №1, на остальных - глючат. Поэтому пусть будет свалка окон на столе-1, но чтобы я мог оперативно активировать любое нужное окно по его названию

Автор: Fors1k 8.12.2020, 20:02

Цитата(for2 @ 6.12.2020, 19:46) *

- после нажатия горячей клавиши скрипт ждет ввода с клавы
- ввожу ключевые буквы названия окна, Enter
- т.е. последовательность букв будет уникальна для каждого окна
- скрипт ищет и делает это окно активным, т.е. если свёрнуто или под другими окнами - раскрывается/вылезает вперед

Код
set hotkeystart @{F1}
--lua
require"luaposh";log"clear";log"mode compact"
window=PScode('return',{[[$return=text_prompt]]})
showwindow(findwindow(window)[1][1], 'top')

- hotkey: Alt+F1.
- Вводить имя окна с учетом регистра, например: WordPad.

Автор: cirus 9.12.2020, 2:26

Цитата
Такой графический интерфейс сложно сделать?

Скачать архив LuaWindow.zip из этой темы: https://forum.uokit.com/index.php?showtopic=70165, распаковать в папку с exe пилота.
код

Код
--lua
package.path = "LuaWindow\\winapi\\?.lua;" .. package.path
package.path = "LuaWindow\\events\\?.lua;" .. package.path
package.path = "LuaWindow\\?.lua;" .. package.path
setfenv(1, require'winapi')
require'ansi_utf'
require'winapi'
require'winapi.windowclass'
require'winapi.buttonclass'

-- создание окна и контролов
local win = Window{w = 290, h = 170, x = 200, y = 100, title = utf('Диалог'), topmost = true}
local buttonSR = Button{parent = win, x = 10, y = 10, w = 60, h = 20, text = utf('SR')}
local buttonSi = Button{parent = win, x = 10, y = 35, w = 60, h = 20, text = utf('Si')}
local buttonGZ = Button{parent = win, x = 10, y = 60, w = 60, h = 20, text = utf('GZ')}
local buttonYN = Button{parent = win, x = 10, y = 85, w = 60, h = 20, text = utf('YN')}
local button1 = Button{parent = win, x = 80, y = 10, w = 30, h = 95, text = utf('1')}
local button5 = Button{parent = win, x = 115, y = 10, w = 30, h = 95, text = utf('5')}
local button30 = Button{parent = win, x = 150, y = 10, w = 30, h = 95, text = utf('30')}
local buttonD = Button{parent = win, x = 185, y = 10, w = 30, h = 95, text = utf('D')}
local buttonW = Button{parent = win, x = 220, y = 10, w = 30, h = 95, text = utf('W')}


local window_name = ''

-- флаги
local flag_close = 0
local flag_buttonSR, flag_buttonSi, flag_buttonGZ, flag_buttonYN = 0, 0, 0, 0
local flag_button1, flag_button5, flag_button30, flag_buttonD, flag_buttonW = 0, 0, 0, 0, 0

function activate_window(window_name)
    if #window_name < 3 then return end
    local h = findwindow(window_name)
    if h then
        showwindow(h[1][1], 'TOP')  -- или RESTORE
    else
        hint('Окно с именем: ' .. window_name .. ' Не найдено')
    end
    window_name = ''
end

-- функции сообщений
function buttonSR:on_click() flag_buttonSR = 1 end
function buttonSi:on_click() flag_buttonSi = 1 end
function buttonGZ:on_click() flag_buttonGZ = 1 end
function buttonYN:on_click() flag_buttonYN = 1 end
function button1:on_click() flag_button1 = 1 end
function button5:on_click() flag_button5 = 1 end
function button30:on_click() flag_button30 = 1 end
function buttonD:on_click() flag_buttonD = 1 end
function buttonW:on_click() flag_buttonW = 1 end
function win:on_close() flag_close = bit.bxor(flag_close, 1) end


win:show()  

while flag_close == 0 do
    while ProcessNextMessage() do wait (1) end

    if flag_buttonSR == 1 then flag_buttonSR = 0 window_name='SR' end
    if flag_buttonSi == 1 then flag_buttonSi = 0 window_name='Si' end
    if flag_buttonGZ == 1 then flag_buttonGZ = 0 window_name='GZ' end
    if flag_buttonYN == 1 then flag_buttonYN = 0 window_name='YN' end

    if flag_button1 == 1 then flag_button1 = 0 activate_window(window_name .. '1') window_name='' end
    if flag_button5 == 1 then flag_button5 = 0 activate_window(window_name .. '5')  window_name='' end
    if flag_button30 == 1 then flag_button30 = 0 activate_window(window_name .. '30') window_name='' end
    if flag_buttonD == 1 then flag_buttonD = 0 activate_window(window_name .. 'D')  window_name='' end
    if flag_buttonW == 1 then flag_buttonW = 0 activate_window(window_name .. 'W')  window_name='' end

    wait(10)
end


Закрывать окно можно только через крестик, а не остановкой скрипта.

Автор: for2 9.12.2020, 16:51

Цитата(Fors1k @ 8.12.2020, 20:02) *

- Вводить имя окна с учетом регистра, например: WordPad.

Очень интересно, надо пробовать smile.gif

Цитата(cirus @ 9.12.2020, 2:26) *

Скачать архив LuaWindow.zip из этой темы: [url=https://forum.uokit.com/index.php?

Оооочень круто, буду тестить временем удобство и скорость и поведение системы
Ещё напишу smile.gif

Автор: for2 9.1.2021, 18:36

Цитата(cirus @ 9.12.2020, 2:26) *

Скачать архив LuaWindow.zip из этой темы: https://forum.uokit.com/index.php?showtopic=70165, распаковать в папку с exe пилота.
Закрывать окно можно только через крестик, а не остановкой скрипта.

Доброго времени! Скрипт показывает себя очень хорошо, спасибо!
Ещё есть просьба,
Есть окно очереди печати принтера
Изображение
Можно ли в интерфейс вашего кода добавить "галочку"?
- я ставлю галку и для принтера ставится галка "Приостановить печать"
- убираю галку и галка с "Приостановить печать" - убирается
???
В ваш код я уже добавил много других кнопок, изменил их размер, поэтому в вашем оригинальном коде добавьте пжл кусок кода с "галкой", чтобы я мог его перенести в свой модифицированный код
rolleyes.gif rolleyes.gif

Автор: cirus 9.1.2021, 23:50

Цитата
Можно ли в интерфейс вашего кода добавить "галочку"?
- я ставлю галку и для принтера ставится галка "Приостановить печать"
- убираю галку и галка с "Приостановить печать" - убирается

Как-то так:
код
Код
--lua
local WM_COMMAND = 0x0111
local ffi = require("ffi")
ffi.cdef[[
    unsigned int GetMenuItemID(int hMenu, int nPos);
    int PostMessageA(int hWnd, unsigned int Msg, unsigned int wParam, long lParam);
]]

package.path = "LuaWindow\\winapi\\?.lua;" .. package.path
package.path = "LuaWindow\\events\\?.lua;" .. package.path
package.path = "LuaWindow\\?.lua;" .. package.path
setfenv(1, require'winapi')
require'ansi_utf'
require'winapi'
require'winapi.windowclass'
require'winapi.buttonclass'
require'winapi.checkboxclass'


-- создание окна и контролов
local win = Window{w = 290, h = 200, x = 200, y = 100, title = utf('Диалог'), topmost = true}
local buttonSR = Button{parent = win, x = 10, y = 10, w = 60, h = 20, text = utf('SR')}
local buttonSi = Button{parent = win, x = 10, y = 35, w = 60, h = 20, text = utf('Si')}
local buttonGZ = Button{parent = win, x = 10, y = 60, w = 60, h = 20, text = utf('GZ')}
local buttonYN = Button{parent = win, x = 10, y = 85, w = 60, h = 20, text = utf('YN')}
local button1 = Button{parent = win, x = 80, y = 10, w = 30, h = 95, text = utf('1')}
local button5 = Button{parent = win, x = 115, y = 10, w = 30, h = 95, text = utf('5')}
local button30 = Button{parent = win, x = 150, y = 10, w = 30, h = 95, text = utf('30')}
local buttonD = Button{parent = win, x = 185, y = 10, w = 30, h = 95, text = utf('D')}
local buttonW = Button{parent = win, x = 220, y = 10, w = 30, h = 95, text = utf('W')}

local check1 = CheckBox{parent = win, x = 10, y = 120, w = 80, h = 20,    text = 'Check1', checked = false}

local window_name = ''

-- флаги
local flag_close = 0
local flag_buttonSR, flag_buttonSi, flag_buttonGZ, flag_buttonYN = 0, 0, 0, 0
local flag_button1, flag_button5, flag_button30, flag_buttonD, flag_buttonW = 0, 0, 0, 0, 0

function activate_window(window_name)
    if #window_name < 3 then return end
    local h = findwindow(window_name)
    if h then
        showwindow(h[1][1], 'TOP')  -- или RESTORE
    else
        hint('Окно с именем: ' .. window_name .. ' Не найдено')
    end
    window_name = ''
end

-- функции сообщений
function buttonSR:on_click() flag_buttonSR = 1 end
function buttonSi:on_click() flag_buttonSi = 1 end
function buttonGZ:on_click() flag_buttonGZ = 1 end
function buttonYN:on_click() flag_buttonYN = 1 end
function button1:on_click() flag_button1 = 1 end
function button5:on_click() flag_button5 = 1 end
function button30:on_click() flag_button30 = 1 end
function buttonD:on_click() flag_buttonD = 1 end
function buttonW:on_click() flag_buttonW = 1 end
function win:on_close() flag_close = bit.bxor(flag_close, 1) end


function check1:on_click()   -- если был клик по галке
    local menuiteminfo = ffi.new('MENUITEMINFOW', {ffi.sizeof('MENUITEMINFOW'), MIIM_STATE })
    local handle = findwindow('Canon iP2700')   -- имя окна очереди печати
    if handle then
        local h_menu = ffi.C.GetMenu(ffi.cast('HWND', handle[1][1]))
        if h_menu then
            local h_submenu = ffi.C.GetSubMenu(h_menu, 0)   -- 0 - Принтер
            local id_item = ffi.C.GetMenuItemID(ffi.cast('int', h_submenu), 6)  -- 6 - Приостановить печать
            if check1.checked then menuiteminfo.fState = MFS_CHECKED
            else menuiteminfo.fState = MFS_UNCHECKED
            end
            ffi.C.SetMenuItemInfoW(h_submenu, id_item, false, menuiteminfo)  -- установить галку на пункт меню
            -- ffi.C.PostMessageA(handle[1][1], WM_COMMAND, id_item, 0)   -- может надо, может нет
        end
    else
        log ('Окно очереди печати не найдено')
    end
end


win:show()


while flag_close == 0 do
    while ProcessNextMessage() do wait (1) end

    if flag_buttonSR == 1 then flag_buttonSR = 0 window_name='SR' end
    if flag_buttonSi == 1 then flag_buttonSi = 0 window_name='Si' end
    if flag_buttonGZ == 1 then flag_buttonGZ = 0 window_name='GZ' end
    if flag_buttonYN == 1 then flag_buttonYN = 0 window_name='YN' end

    if flag_button1 == 1 then flag_button1 = 0 activate_window(window_name .. '1') window_name='' end
    if flag_button5 == 1 then flag_button5 = 0 activate_window(window_name .. '5')  window_name='' end
    if flag_button30 == 1 then flag_button30 = 0 activate_window(window_name .. '30') window_name='' end
    if flag_buttonD == 1 then flag_buttonD = 0 activate_window(window_name .. 'D')  window_name='' end
    if flag_buttonW == 1 then flag_buttonW = 0 activate_window(window_name .. 'W')  window_name='' end

    wait(10)
end


Автор: for2 10.1.2021, 19:19

Цитата(cirus @ 9.1.2021, 23:50) *

Как-то так:

Офигительно! Буду тестить, спасибо!

Автор: for2 10.1.2021, 19:35

Да, строка "может надо, может нет" оказалась нужна, без нее не работало rolleyes.gif

Автор: for2 13.2.2021, 11:13

Цитата(cirus @ 9.1.2021, 23:50) *

Как-то так:
код
Код
--lua
local WM_COMMAND = 0x0111
local ffi = require("ffi")
ffi.cdef[[
    unsigned int GetMenuItemID(int hMenu, int nPos);
    int PostMessageA(int hWnd, unsigned int Msg, unsigned int wParam, long lParam);
]]

package.path = "LuaWindow\\winapi\\?.lua;" .. package.path
package.path = "LuaWindow\\events\\?.lua;" .. package.path
package.path = "LuaWindow\\?.lua;" .. package.path
setfenv(1, require'winapi')
require'ansi_utf'
require'winapi'
require'winapi.windowclass'
require'winapi.buttonclass'
require'winapi.checkboxclass'
-- создание окна и контролов
local win = Window{w = 290, h = 200, x = 200, y = 100, title = utf('Диалог'), topmost = true}
local buttonSR = Button{parent = win, x = 10, y = 10, w = 60, h = 20, text = utf('SR')}
local buttonSi = Button{parent = win, x = 10, y = 35, w = 60, h = 20, text = utf('Si')}
local buttonGZ = Button{parent = win, x = 10, y = 60, w = 60, h = 20, text = utf('GZ')}
local buttonYN = Button{parent = win, x = 10, y = 85, w = 60, h = 20, text = utf('YN')}
local button1 = Button{parent = win, x = 80, y = 10, w = 30, h = 95, text = utf('1')}
local button5 = Button{parent = win, x = 115, y = 10, w = 30, h = 95, text = utf('5')}
local button30 = Button{parent = win, x = 150, y = 10, w = 30, h = 95, text = utf('30')}
local buttonD = Button{parent = win, x = 185, y = 10, w = 30, h = 95, text = utf('D')}
local buttonW = Button{parent = win, x = 220, y = 10, w = 30, h = 95, text = utf('W')}

local check1 = CheckBox{parent = win, x = 10, y = 120, w = 80, h = 20,    text = 'Check1', checked = false}

local window_name = ''

-- флаги
local flag_close = 0
local flag_buttonSR, flag_buttonSi, flag_buttonGZ, flag_buttonYN = 0, 0, 0, 0
local flag_button1, flag_button5, flag_button30, flag_buttonD, flag_buttonW = 0, 0, 0, 0, 0

function activate_window(window_name)
    if #window_name < 3 then return end
    local h = findwindow(window_name)
    if h then
        showwindow(h[1][1], 'TOP')  -- или RESTORE
    else
        hint('Окно с именем: ' .. window_name .. ' Не найдено')
    end
    window_name = ''
end

-- функции сообщений
function buttonSR:on_click() flag_buttonSR = 1 end
function buttonSi:on_click() flag_buttonSi = 1 end
function buttonGZ:on_click() flag_buttonGZ = 1 end
function buttonYN:on_click() flag_buttonYN = 1 end
function button1:on_click() flag_button1 = 1 end
function button5:on_click() flag_button5 = 1 end
function button30:on_click() flag_button30 = 1 end
function buttonD:on_click() flag_buttonD = 1 end
function buttonW:on_click() flag_buttonW = 1 end
function win:on_close() flag_close = bit.bxor(flag_close, 1) end
function check1:on_click()   -- если был клик по галке
    local menuiteminfo = ffi.new('MENUITEMINFOW', {ffi.sizeof('MENUITEMINFOW'), MIIM_STATE })
    local handle = findwindow('Canon iP2700')   -- имя окна очереди печати
    if handle then
        local h_menu = ffi.C.GetMenu(ffi.cast('HWND', handle[1][1]))
        if h_menu then
            local h_submenu = ffi.C.GetSubMenu(h_menu, 0)   -- 0 - Принтер
            local id_item = ffi.C.GetMenuItemID(ffi.cast('int', h_submenu), 6)  -- 6 - Приостановить печать
            if check1.checked then menuiteminfo.fState = MFS_CHECKED
            else menuiteminfo.fState = MFS_UNCHECKED
            end
            ffi.C.SetMenuItemInfoW(h_submenu, id_item, false, menuiteminfo)  -- установить галку на пункт меню
            -- ffi.C.PostMessageA(handle[1][1], WM_COMMAND, id_item, 0)   -- может надо, может нет
        end
    else
        log ('Окно очереди печати не найдено')
    end
end
win:show()
while flag_close == 0 do
    while ProcessNextMessage() do wait (1) end

    if flag_buttonSR == 1 then flag_buttonSR = 0 window_name='SR' end
    if flag_buttonSi == 1 then flag_buttonSi = 0 window_name='Si' end
    if flag_buttonGZ == 1 then flag_buttonGZ = 0 window_name='GZ' end
    if flag_buttonYN == 1 then flag_buttonYN = 0 window_name='YN' end

    if flag_button1 == 1 then flag_button1 = 0 activate_window(window_name .. '1') window_name='' end
    if flag_button5 == 1 then flag_button5 = 0 activate_window(window_name .. '5')  window_name='' end
    if flag_button30 == 1 then flag_button30 = 0 activate_window(window_name .. '30') window_name='' end
    if flag_buttonD == 1 then flag_buttonD = 0 activate_window(window_name .. 'D')  window_name='' end
    if flag_buttonW == 1 then flag_buttonW = 0 activate_window(window_name .. 'W')  window_name='' end

    wait(10)
end



Добавьте, пожалуйста в код что-то rolleyes.gif чтобы
- при клике в чекбокс Окно очереди печати сначала делалось активным, а потом в него отправлялось сообщение снять/установить галку приостановки печати
Т.к. когда Окно очереди печати не активно, то клик в чекбокс почему-то работает не всегда, делаю Окно очереди печати активным - тогда всё четко! smile.gif

Автор: cirus 13.2.2021, 11:24

Код
local handle = findwindow('Canon iP2700') 
if handle then
    showwindow(handle , 'TOP')  -- добавить эту строку

Автор: for2 13.2.2021, 11:47

Цитата(cirus @ 13.2.2021, 11:24) *

Код
local handle = findwindow('Canon iP2700') 
if handle then
    showwindow(handle , 'TOP')  -- добавить эту строку


Почему-то окно не делается активным
Строку вставил:
код
Код

function check1:on_click()   -- если был клик по галке
    local menuiteminfo = ffi.new('MENUITEMINFOW', {ffi.sizeof('MENUITEMINFOW'), MIIM_STATE })
    local handle = findwindow('Canon iP2700')   -- имя окна очереди печати
    if handle then
        showwindow(handle , 'TOP')
        local h_menu = ffi.C.GetMenu(ffi.cast('HWND', handle[1][1]))
        if h_menu then
            local h_submenu = ffi.C.GetSubMenu(h_menu, 0)   -- 0 - Принтер
            local id_item = ffi.C.GetMenuItemID(ffi.cast('int', h_submenu), 6)  -- 6 - Приостановить печать
            if check1.checked then menuiteminfo.fState = MFS_CHECKED
            else menuiteminfo.fState = MFS_UNCHECKED
            end
            ffi.C.SetMenuItemInfoW(h_submenu, id_item, false, menuiteminfo)  -- установить галку на пункт меню
            ffi.C.PostMessageA(handle[1][1], WM_COMMAND, id_item, 0)   -- может надо, может нет
        end
    else
        log ('Окно очереди печати не найдено')
    end
end


Автор: cirus 13.2.2021, 11:56

Вот так:

Код
showwindow(handle[1][1], 'TOP')

Автор: for2 13.2.2021, 12:03

Цитата(cirus @ 13.2.2021, 11:56) *

Вот так:
Код
showwindow(handle[1][1], 'TOP')


thumb.gif thumb.gif thumb.gif

Автор: for2 19.2.2021, 16:46

Цитата(cirus @ 13.2.2021, 11:56) *

Вот так:
Код
showwindow(handle[1][1], 'TOP')


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

Автор: cirus 20.2.2021, 2:43

Цитата
есть ли для вас способ написать код, чтобы рисовать векторные линии, квадраты на рабочем столе, поверх окон.

Есть, но времени на это нет.

Автор: for2 25.2.2021, 19:08

Цитата(cirus @ 20.2.2021, 2:43) *

Есть, но времени на это нет.

Можно вас попросить написать код:
- в графич. окне пилота поверх окон
- выводится название активного окна
- возможность настройки размера шрифта

Автор: cirus 27.2.2021, 1:35

Цитата
- в графич. окне пилота поверх окон
- выводится название активного окна
- возможность настройки размера шрифта

https://forum.uokit.com/index.php?s=&showtopic=70167&view=findpost&p=436867

Автор: for2 28.2.2021, 7:38

Цитата(cirus @ 27.2.2021, 1:35) *

https://forum.uokit.com/index.php?s=&showtopic=70167&view=findpost&p=436867

Даже с подсказкой для меня нерешаемо. Но задача не критична. Спасибо за большую работу и помощь, которую вы делаете. Всё что вы написали для меня, я активно юзаю - очень облегчает

Русская версия Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)