Author Topic: Окно на передний план.  (Read 3171 times)

0 Members and 1 Guest are viewing this topic.

Suslik

  • Зашел в гости
  • *
  • Posts: 8
    • View Profile
Окно на передний план.
« on: June 04, 2019, 06:13:33 AM »
Доброго времени суток!

Помогите решить задачу:
Есть окно и его нужно периодически вызвать по вверх всех окон, к примеру:

start:
$h = wndfind ("калькулятор")
Wndbumb ($h)
Waitms (2000)
Goto (start)

Собственно wndbump не справляется, где-то на 2-3 раз калькулятор просто висит в нижней панели, мигает, но не вызывается на передний план.
Хотел попробовать заменить wndbump на sendmessage/postmessage, к примеру:

SENDMESSAGE ($h, 0x0018, 0, 0)

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

Поделитесь опытом/советом кто как реализовывает вызов нужного окна по вверх всех.

Заранее огромное спасибо!

iggi

  • Освоившийся
  • **
  • Posts: 22
    • View Profile
Re: Окно на передний план.
« Reply #1 on: June 04, 2019, 08:53:25 AM »
Опытным путем установлено, что если после использования wndbump совершить какое либо действие с мышью, например клик или перемещение, то последующее использование wndbump работает нормально. Попробуй так:
Code: (clickermann) [Select]
start:
MOVE($_xmouse,$_ymouse)
$h = WNDFIND("Калькулятор")
WNDBUMP($h)
WAIT(2)
GOTO (start)

Suslik

  • Зашел в гости
  • *
  • Posts: 8
    • View Profile
Re: Окно на передний план.
« Reply #2 on: June 04, 2019, 09:24:54 AM »
Интересный костыль, а главное работает!
Единственный минус это задержка между переключениями двух окон (более одной секунды), хотелось бы чтоб побыстрее окна вылазилы на поверхность.
В любом случае спасибо за ответ.

Опытным путем установлено, что если после использования wndbump совершить какое либо действие с мышью, например клик или перемещение, то последующее использование wndbump работает нормально. Попробуй так:
Code: (clickermann) [Select]
start:
MOVE($_xmouse,$_ymouse)
$h = WNDFIND("Калькулятор")
WNDBUMP($h)
WAIT(2)
GOTO (start)

Oraven

  • Супермодератор
  • Герой форума
  • *
  • Posts: 3685
  • Котэ
    • View Profile
Re: Окно на передний план.
« Reply #3 on: June 04, 2019, 09:42:12 AM »
Если нужно закрепить окно выше всех то лучше иметь в арсенале специализированную для этого программу.

Сам использую DeskPins. На десятке все прекрасно работает, запускать нужно от админа.
https://yadi.sk/d/i_zGZv8tWxI1WQ

deskpins_ru.exe - это русифицированная версия собственного перевода.

Запускаешь программу, кликаешь по значку в трее, за тем булавкой прикалываешь нужное окно. Можно приколоть сколько хочешь окон.

Suslik

  • Зашел в гости
  • *
  • Posts: 8
    • View Profile
Re: Окно на передний план.
« Reply #4 on: June 04, 2019, 10:33:36 AM »
Нет, мне не нужно чтоб окно были постоянно зафиксированы на одном месте. У меня несколько окон просто должны всплывать друг за другом, в одинаковых координатах.
Оконный режим пока только изучаю и пока не очень подходит.

dramster

  • Герой форума
  • *****
  • Posts: 1134
    • View Profile
Re: Окно на передний план.
« Reply #5 on: June 05, 2019, 10:18:35 PM »
Нет, мне не нужно чтоб окно были постоянно зафиксированы на одном месте. У меня несколько окон просто должны всплывать друг за другом, в одинаковых координатах.
Оконный режим пока только изучаю и пока не очень подходит.

Я сам припоминаю, что с WNDBUMP были какието косяки.

Гдето встречал в делфи нужную для этого функцию. SetForegroundWindow называется, просто делает окно активным, поверх всех других.

Написал ради интереса длл, ничего сложного. Проверил, вроде работает четко и без сбоев.

Код делфи длл:
Code: (clickermann) [Select]
library cmann_plugin;

uses Windows;
//------------------------------------------------------------------------------
// Основное тело функции, идет на экспорт, вызывается из кликера
function execute( _mas: pInteger; _size: Integer): Integer; export; stdcall;
type
  pIntArr = array[0..0] of Integer;
var
  hwnd : Integer;
begin
 hwnd := pIntArr(_mas^)[0];
 if SetForegroundWindow(hwnd) then result := 1 else result := 0;
end;
//------------------------------------------------------------------------------

// список экспорта
exports execute;

begin
  // тело пусто
end.

Чтобы сделать окно активным с помощью моей длл, пишем такой код для км ("SetForegroundWindow.dll" в одной папке со скриптом):
Code: (clickermann) [Select]
CALL("SetForegroundWindow.dll", $hwnd)  // hwnd естественно нужный пишем
halt

CALL в этом случае вернет в системную переменную $_return1 результат "1" если такое окно существует, если же такого hwnd нет, то результатом будет "0"


Для теста, запустил 5 калькуляторов, и решил делать их активными рандомно:
Code: (clickermann) [Select]
WNDFINDARR ($arr_hwnd, "Калькулятор")  //ищем хендлы всех калькуляторов

FOR($a=0,$a < 15)  //количество переключений между ними

//делаем рандомное окно калькулятора активным каждые 500мс
   CALL("SetForegroundWindow.dll", $arr_hwnd[rnd(0,arrsize($arr_hwnd)-1)])
   waitms(500)
END_CYC

halt

Тест прошел успешно.

"SetForegroundWindow.dll" для 32-битной версии кликерман во вложении.



Suslik

  • Зашел в гости
  • *
  • Posts: 8
    • View Profile
Re: Окно на передний план.
« Reply #6 on: June 06, 2019, 10:55:17 AM »
Спасибо за ответ. Но мне не совсем понятно несколько вещей:
1) Что за функция WNDFINDARR? Такой функции я не нашел в описании версии 4.13.014?
2) Если она работает по принципу arrpush тоже не понятно т.к. arrpush не переключается между множеством одинаковых окон с названием, а запихивает все тоже первое найденное окно в конец массива.
3) Если упростить для возможности проверки dll, к примеру:

$hwnd = (wndfind ("Калькулятор"))
FOR($a=0,$a < 15) 
   CALL("SetForegroundWindow.dll", $hwnd)
   waitms(500)
END_CYC
halt

то скрипт всё-рано не выводит окно ;(

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

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

Я сам припоминаю, что с WNDBUMP были какието косяки.

Гдето встречал в делфи нужную для этого функцию. SetForegroundWindow называется, просто делает окно активным, поверх всех других.

Написал ради интереса длл, ничего сложного. Проверил, вроде работает четко и без сбоев.

Код делфи длл:
Code: (clickermann) [Select]
library cmann_plugin;

uses Windows;
//------------------------------------------------------------------------------
// Основное тело функции, идет на экспорт, вызывается из кликера
function execute( _mas: pInteger; _size: Integer): Integer; export; stdcall;
type
  pIntArr = array[0..0] of Integer;
var
  hwnd : Integer;
begin
 hwnd := pIntArr(_mas^)[0];
 if SetForegroundWindow(hwnd) then result := 1 else result := 0;
end;
//------------------------------------------------------------------------------

// список экспорта
exports execute;

begin
  // тело пусто
end.

Чтобы сделать окно активным с помощью моей длл, пишем такой код для км ("SetForegroundWindow.dll" в одной папке со скриптом):
Code: (clickermann) [Select]
CALL("SetForegroundWindow.dll", $hwnd)  // hwnd естественно нужный пишем
halt

CALL в этом случае вернет в системную переменную $_return1 результат "1" если такое окно существует, если же такого hwnd нет, то результатом будет "0"


Для теста, запустил 5 калькуляторов, и решил делать их активными рандомно:
Code: (clickermann) [Select]
WNDFINDARR ($arr_hwnd, "Калькулятор")  //ищем хендлы всех калькуляторов

FOR($a=0,$a < 15)  //количество переключений между ними

//делаем рандомное окно калькулятора активным каждые 500мс
   CALL("SetForegroundWindow.dll", $arr_hwnd[rnd(0,arrsize($arr_hwnd)-1)])
   waitms(500)
END_CYC

halt

Тест прошел успешно.

"SetForegroundWindow.dll" для 32-битной версии кликерман во вложении.

iggi

  • Освоившийся
  • **
  • Posts: 22
    • View Profile
Re: Окно на передний план.
« Reply #7 on: June 06, 2019, 11:06:51 AM »
Интересный костыль, а главное работает!
Единственный минус это задержка между переключениями двух окон (более одной секунды), хотелось бы чтоб побыстрее окна вылазилы на поверхность.

Странно, что такая большая задержка. Ради интереса попробовал на открытых у меня окнах - переключает очень быстро.

Code: (clickermann) [Select]
start:

$h = WNDFIND("Калькулятор")
$j = WNDFIND("Droid")
$k = WNDFIND("Adobe")
$l = WNDFIND("Проводник")

WNDBUMP($h)
MOVE($_xmouse,$_ymouse)
waitms(100)

WNDBUMP($j)
MOVE($_xmouse,$_ymouse)
waitms(100)

WNDBUMP($k)
MOVE($_xmouse,$_ymouse)
waitms(100)

WNDBUMP($l)
MOVE($_xmouse,$_ymouse)
waitms(100)

goto(start)

Suslik

  • Зашел в гости
  • *
  • Posts: 8
    • View Profile
Re: Окно на передний план.
« Reply #8 on: June 06, 2019, 12:03:57 PM »
После Вашего комментария задумался и попробовал на стационарном компе (мощнее конечно, чем ноут).
Да, действительно работаем ОЧЕНЬ быстро и напрямую зависит мощности компьютера.
Всё гениально и просто, спасибо!


Интересный костыль, а главное работает!
Единственный минус это задержка между переключениями двух окон (более одной секунды), хотелось бы чтоб побыстрее окна вылазилы на поверхность.

Странно, что такая большая задержка. Ради интереса попробовал на открытых у меня окнах - переключает очень быстро.

Code: (clickermann) [Select]
start:

$h = WNDFIND("Калькулятор")
$j = WNDFIND("Droid")
$k = WNDFIND("Adobe")
$l = WNDFIND("Проводник")

WNDBUMP($h)
MOVE($_xmouse,$_ymouse)
waitms(100)

WNDBUMP($j)
MOVE($_xmouse,$_ymouse)
waitms(100)

WNDBUMP($k)
MOVE($_xmouse,$_ymouse)
waitms(100)

WNDBUMP($l)
MOVE($_xmouse,$_ymouse)
waitms(100)

goto(start)

Suslik

  • Зашел в гости
  • *
  • Posts: 8
    • View Profile
Re: Окно на передний план.
« Reply #9 on: June 06, 2019, 03:24:56 PM »
Вполне вероятно, что dll не работает из-за того, что у меня стоит 64х система ;(


dramster

  • Герой форума
  • *****
  • Posts: 1134
    • View Profile
Re: Окно на передний план.
« Reply #10 on: June 06, 2019, 09:19:09 PM »
1) Что за функция WNDFINDARR? Такой функции я не нашел в описании версии 4.13.014?
2) Если она работает по принципу arrpush тоже не понятно т.к. arrpush не переключается между множеством одинаковых окон с названием, а запихивает все тоже первое найденное окно в конец массива.

Да, глянул в 4.13 такого еще нет. WNDFINDARR в бете 4.14 появился.

3) Если упростить для возможности проверки dll, к примеру:

$hwnd = (wndfind ("Калькулятор"))
FOR($a=0,$a < 15) 
   CALL("SetForegroundWindow.dll", $hwnd)
   waitms(500)
END_CYC
halt

то скрипт всё-рано не выводит окно ;(

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



Чтобы упростить, достаточно создать скрипт:
Code: (clickermann) [Select]
CALL("SetForegroundWindow.dll", wndfind ("Калькулятор"))
halt

Сохранить его рядом с файлом "SetForegroundWindow.dll", и запусить. Версия кликермана должна быть обязательно х32. И в настройках должно быть "запуск от админа".


ya12

  • Активный участник
  • ***
  • Posts: 165
    • View Profile
Re: Окно на передний план.
« Reply #11 on: June 06, 2019, 10:09:00 PM »
У меня был похожий случай. Оказалось, что ключ реестра блокировал фокус окна. Поменял, заработало.

HKEY_CURRENT_USER\Control Panel\Desktop
Параметры:
ForegroundFlashCount - сколько раз мигать (по дефолту 3)
ForegroundLockTimeout - если поставить в 0, то будет сразу вылазить, без миганий.

Suslik

  • Зашел в гости
  • *
  • Posts: 8
    • View Profile
Re: Окно на передний план.
« Reply #12 on: June 07, 2019, 12:48:34 AM »
Спасибо! У меня просто стояла 64х версия кликера, из-за чего dll не отрабатывал.