Тема: AHK: при закрытии чужого окна минимизировать его
Как сделать так, чтобы при закрытии последнего окна FireFox, оно не закрывалось, а минимизировалось?
Вы не вошли. Пожалуйста, войдите или зарегистрируйтесь.
Страницы 1
Чтобы отправить ответ, вы должны войти или зарегистрироваться
Как сделать так, чтобы при закрытии последнего окна FireFox, оно не закрывалось, а минимизировалось?
Думаю, простого способа нет. Нужно динамически отслеживать положение на экране окна FF и его кнопки "Закрыть", и перед кликом проверять координаты. В FF этот элемент управления нестандартный, поэтому придётся использовать IAccessible или IUIAutomation интерфейсы.
teadrinker
Спасибо, понятно. ((
Я бы для данной задачи использовал WH_CBT хук.
https://www.autohotkey.com/boards/viewtopic.php?t=94344
Так придётся же dll на C++ писать? Хотя, возможно, ChatGpt такое может осилить. Потом чем-то компилировать нужно.
Наверно проще через поиск картинки отслеживать одну единственную вкладку.
Так придётся же dll на C++ писать? Хотя, возможно, ChatGpt такое может осилить. Потом чем-то компилировать нужно.
Зачем писать, можно анк длл инжектить. Я как то пробовал, хук на закрытие окна работал.
И скрипту висеть не надо, запустил заинжектил закрылся.
Пардон, на открытие его пробовал, надо было предотвращать появление окон. Но думаю разницы никакой, хук тот же.
Этак придётся в каждое открываемое окно инжектить. По-моему, проще уж мой первый вариант реализовать.
Без инжекта конечно правильней. А вот что проще, у каждого по своему.)
Я инжект рассматриваю, как самый крайний вариант, когда других нет, так как он потенциально может нарушить работоспособность программы. Да и с антивирусом придётся договариваться.
Вот кстати про этот хук и DLL для него разговоры уже давно, но пока никто не похвастался.
Я как-то вроде пробовал, запряг ChatGPT, но в итоге как-то с проблемами работало. Могу позже ещё раз попробовать.
Думаю, самым простым (но некрасивым) будет решение поверх кнопки [X] целевого окна каким-то образом прикрепить свою кнопку [X], которая уже будет делать то, что нам нужно.
Я бы для данной задачи использовал WH_CBT хук.
Попробовал WH_CBT. С блокнотом работает так:
#include <Windows.h>
extern "C" __declspec(dllexport) LRESULT CALLBACK CBTProc(int nCode, WPARAM wParam, LPARAM lParam)
{
if (nCode == HCBT_SYSCOMMAND && wParam == SC_CLOSE)
{
HWND hWnd = GetForegroundWindow();
char className[256];
GetClassNameA(hWnd, className, 256);
if (strcmp(className, "Notepad") == 0)
{
bool hasOtherWindows = false;
HWND hWndOther = FindWindowA("Notepad", NULL);
while (hWndOther != NULL)
{
if (hWndOther != hWnd)
{
hasOtherWindows = true;
break;
}
hWndOther = FindWindowExA(NULL, hWndOther, "Notepad", NULL);
}
if (!hasOtherWindows)
{
ShowWindow(hWnd, SW_MINIMIZE);
return 1;
}
}
}
return CallNextHookEx(NULL, nCode, wParam, lParam);
}
И так:
#include <Windows.h>
extern "C" __declspec(dllexport) LRESULT CALLBACK CBTProc(int nCode, WPARAM wParam, LPARAM lParam)
{
if (nCode == HCBT_DESTROYWND)
{
HWND hWnd = (HWND)wParam;
char className[256];
GetClassNameA(hWnd, className, 256);
if (strcmp(className, "Notepad") == 0)
{
bool hasOtherWindows = false;
HWND hWndOther = FindWindowA("Notepad", NULL);
while (hWndOther != NULL)
{
if (hWndOther != hWnd)
{
hasOtherWindows = true;
break;
}
hWndOther = FindWindowExA(NULL, hWndOther, "Notepad", NULL);
}
if (!hasOtherWindows)
{
ShowWindow(hWnd, SW_MINIMIZE);
return 1;
}
}
}
return CallNextHookEx(NULL, nCode, wParam, lParam);
}
С FF ни один из этих вариантов не работает. HCBT_SYSCOMMAND вообще не перехватывает, а HCBT_DESTROYWND отлавливает, сначала вроде минимизируется, но потом исчезает.
Там разве нельзя указать, что только для окон своего процесса, чтобы сделать немного универсальнее. Или с реестра читать свои настройки.
И с инжектом не пробовал?
только для окон своего процесса
Для какого — своего? Мы же окно чужого процесса отлавливаем. Когда для своего, dll не нужно писать.
С инжектом не пробовал.
Да, попутал, она же в процессе ахк выполняется.
teadrinker, да, с броузерами похоже такое не прокатывает, наверное посылаются сообщения о закрытии в другие потоки, не дожидаясь ответа.
Да, тоже так думаю.
Хотя HCBT_SYSCOMMAND у меня пресекается, возможно надо через uia запускать.
#include <Windows.h>
extern "C" __declspec(dllexport) LRESULT CALLBACK CBTProc(
_In_ int nCode,
_In_ WPARAM wParam,
_In_ LPARAM lParam
)
{
if (nCode < 0) return CallNextHookEx(nullptr, nCode, wParam, lParam);
switch(nCode)
{
case HCBT_DESTROYWND:
case HCBT_SYSCOMMAND:
return 1; // Prevent
}
return 0;
}
Компилирую через:
C:\TDM-GCC-64\bin\gcc -c source.cpp
C:\TDM-GCC-64\bin\gcc -shared -o mydll.dll source.o
У меня один раз перехватило сворачивание, и больше с FF не работало.
У меня всегда перехватывает HCBT_MINMAX.
Пробуй запускать через UIA.
Запускал, у меня нет разницы.
Со стандартными окнами работает, без UIA.
Возможно у броузеров дополнительная защита стоит, так как с хромом и фаерфоксом у меня стало срабатывать только после запуска через uia.
Попробовал ещё с Edge, минимизацию перехватывает, после закрытия крашится.
Спасибо, большое, всем откликнувшимся, но для меня это слишком сложно. Но, если бы кто-то реализовал такое да еще для окна любого приложения, то можно было бы написать что-то вроде Minimize(Close) To Tray. Хотя мне было бы достаточно для Firefox.
Страницы 1
Чтобы отправить ответ, вы должны войти или зарегистрироваться