Переключение задач в Windows

Автор Tigrik, 9 февраля 2022, 20:00

0 Пользователи и 1 гость просматривают эту тему.

Tigrik

Здравствуйте!

Windows 7 Максимальная (6.1 Service Pack 1 Build 7601)
LibreOffice 7.2.5.2 (x64)


Алгоритм макроса, который я хочу попробовать "сложить", вроде бы и не сложный.
- По запуску макроса открывается небольшой диалог, где всего два текстовых поля и кнопка завершения работы макроса.
- На компе, помимо различных открытых приложений запущен и веб-браузер, допустим Яндекс. Там много открытых страниц, но необходимая веб-страничка, так сказать, в "фокусе", которая и активируется (выводится на экран).
- После нажатия клавиши «ENTER», происходит переключение на открытый диалог. В ручную производится запись в первое текстовое поле формы. После очередного нажатия клавиши «ENTER», по определенному алгоритму (ещё, пока, это в разработке) набранный текст перекодируется и заносится во второе текстовое поле и, снова, переключается на ту самую веб-страничку.

То есть, переключение этих окон: веб-страничка и диалог - это аналогично переключению задач по «ALT»+«TAB», но я хочу попробовать сделать это с помощью макроса и через «ENTER». Это реальная для меня задача, но и некоторая тренировка для освоения программного переключения окон (задач) Winsows.

Были долгие поиски в книге Питоньяка, на этом форуме и на просторах Интернета, но так и не смог найти необходимый сервис и методы, чтобы переключаться между Виндусовскими окнами. У Питоньяка есть целая глава о Рабочем столе LibreOffice: StarDesktop и некоторых сервисах и интерфейсов, но если я правильно понял, то это можно использовать только для офисных документов. Многие примеры из его книги испробовал, но не нашёл нужного для моей задачи решения.
Что-то мне подсказывает, что нужные мне "инструменты" могут быть в модуле Frame (или Container), но самостоятельно не могу найти.

Пожалуйста, подскажите, хотя бы, верное направление поисков.

Спасибо.

sokol92

#1
Добрый день!
Для работы с окнами Windows необходимо обращаться к Windows API (насколько я понимаю).
Не видел ни одного примера работы в Basic с Windows API в 64-разрядном LibreOffice.
На Python это, скорее всего, возможно.

Когда-то написал для Excel надстройку, которая переносит значение ячейки Excel в произвольно выбранное окно Windows.
Владимир.

Tigrik

Владимир, Благодарю за ответ.
Буду думать!

economist

Видятся две стратегии:
1) Python c pywin32 или либами для создания программных роботов RPA
2) http://crapware.aidf.org/page/clickermann
Руб. за сто, что Питоньяк
Любит водку и коньяк!
Потому что мне, без оных, -
Не понять его никак...

Tigrik

Цитата: economist от  9 февраля 2022, 21:03Видятся две стратегии:
1) Python c pywin32 или либами для создания программных роботов RPA
2) http://crapware.aidf.org/page/clickermann
Благодарю.
Попробую с кликерменом разобраться.

mikekaganski

С уважением,
Михаил Каганский

akelot


sokol92

#7
Здравствуйте, Михаил!

Спасибо за интересную ссылку. Я в своих вчeрашних попытках перебора открытых окон Windows остановился на:
Option Explicit
Option Compatible
Declare PtrSafe Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As LongPtr
Sub test
 Dim hwnd
 hwnd = FindWindow(vbnullstring, vbNullString)
 Msgbox hwnd
End Sub

У меня (Win10) в hwnd возвращается Null. LongPtr это указатель (HANDLE). Как с этим типом работать в Basic (64-разрядная платформа)?
Владимир.

mikekaganski

#8
Цитата: sokol92 от 10 февраля 2022, 14:30
У меня (Win10) в hwnd возвращается Null. LongPtr это указатель. Как с этим типом работать в Basic (64-разрядная платформа)?

Во-первых, эта функция и возвратит 0 для указанных аргументов.
Но вопрос очень правильный. HANDLE - платформозависимый тип, размер которого равен размеру указателя; а поскольку у нас фактически не реализован целый 64-разрядный тип, у нас проблема. Читая код, я могу только предложить использовать Double как чёрный ящик для этого значения.

Однако нет. double возвращается, видимо, иначе...
С уважением,
Михаил Каганский

sokol92

Цитата: mikekaganski от 10 февраля 2022, 15:47Во-первых, эта функция и возвратит 0 для указанных аргументов.
Михаил, извините, я исправил (не с того места перенес).
Владимир.

sokol92

#10
Этот тип (64-разрядное целое) поддерживается и в 32-разрядном Excel, но "хитро" (через Variant).
Win10, Excel 2016 (32-):
Sub test()
 Dim v
 v = ActiveSheet.Cells.CountLarge
 MsgBox v * 2       ' поддерживаются арифметические операции
 MsgBox VarType(v)  ' 20: в 64-разрядных версиях это Longlong
End Sub


Еще тип Currency в Excel является 64-разрядным целым числом, которое интерпретируется как сумма, умноженная на 10000.
Владимир.

mikekaganski

Цитата: sokol92 от 10 февраля 2022, 14:30
Option Explicit
Option Compatible
Declare PtrSafe Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As LongPtr
Sub test
 Dim hwnd
 hwnd = FindWindow(vbnullstring, vbNullString)
 Msgbox hwnd
End Sub


Давайте разберём то, что "работает" (конечно, принимая во внимание проблему 64-битных возвращаемых значений).

Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName, ByVal lpWindowName) As Long
Sub test
 MsgBox FindWindow("SALFRAME", 0)
End Sub


PtrSafe на данный момент игнорируется. LongPtr - не определён в языке.
Задавая тип аргументов (As String), Вы включаете преобразование фактических аргументов к формальному типу по правилам Basic. И в любом случае vbNullString передаётся у нас в виде пустой строки, а не в виде нулевого указателя. А используя аргумент типа Variant, я определяю тип фактическим аргументом, и 0 передастся нулевым 64-разрядным значением.

Ну а возврат обрежется пополам. Нужно что-то думать по поддержке больших чисел...
С уважением,
Михаил Каганский

sokol92

#12
Добрый день!
В примере я "на автомате" взял описание FindWindow из Win32API_PtrSafe.TXT.
Функция "FindWindowA" является реликтом - нужно всегда брать unicode версии функций, которые оканчиваюются на "W". Наш пример в VBA будет выглядеть так:
Option Explicit
Declare PtrSafe Function FindWindow Lib "user32" Alias "FindWindowW" (ByVal lpClassName As LongPtr, ByVal lpWindowName As LongPtr) As LongPtr
Sub test()
 Dim hwnd
 hwnd = FindWindow(StrPtr("SALFRAME"), 0)
 MsgBox hwnd
End Sub

(заодно и параметры выглядят естественно).
Для переноса в LO Basic дополнительно(?) нужна функция StrPtr.
Владимир.

mikekaganski

Цитата: sokol92 от 12 февраля 2022, 16:14Функция "FindWindowA" является реликтом - нужно всегда брать unicode версии функций, которые оканчиваюются на "W".

Эх, если бы это было возможно. К сожалению, маршалинг строк из бейсика реализован жёстко через char*.
С уважением,
Михаил Каганский

sokol92

#14
Поэтому и нужна StrPtr, которая возвращает указатель на строку (параметр функции) в Unicode. Или я что-то не понимаю?
В "W" функциях всегда используются указатели на строки в формате Unicode.
Как VBA работает с "A" функциями Владимир Захаров (MVP) описал здесь.
Python использует "W" функции (например, FindFirstFileW).
Владимир.