Форум программистов, компьютерный форум, киберфорум
Delphi
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.94/16: Рейтинг темы: голосов - 16, средняя оценка - 4.94
 Аватар для Kukuxumushu
1624 / 806 / 146
Регистрация: 13.06.2015
Сообщений: 3,266

Отслеживание "Свернуть все окна"

07.03.2017, 01:37. Показов 3502. Ответов 20

Студворк — интернет-сервис помощи студентам
Гружу программу в трей, с панели задач убираю вообще (даже когда окно активно). Show/Hide - по клику трея, стандартным способом . И всё бы хорошо, но вот какая подстава - кнопка винды "свернуть все окна" сворачивает их каким-то нестандартным способом, после которого окно из трея обратно уже не разворачивается. Гугление навело на ветку какого-то форума, где проблему пытаются решить аж с 2006 года всевозможными костылями, но ни 1 из них нормально не сработал. Заведомо известно, что решение есть - многие программы либо распознают нажатие "свернуть все окна" и идут от него в трей, либо просто нормально разворачиваются из трея, либо и вовсе не сворачиваются в него.
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
07.03.2017, 01:37
Ответы с готовыми решениями:

Как свернуть все окна кроме нашей формы?
Нашёл в интернете интересный код: Как свернуть все окна системы ? // Любимая наша процедура. {Для того чтобы использовать данный...

Кнопки и окна: передвинуть, свернуть, развернуть, закрыть.
как передвинуть кнопки свернуть, развернуть, закрыть на несколько пикселов влево, и как в CAPTION расположить свой текст или рисунок с...

Свернуть все процедуры
Есть ли команда чтобы свернуть все процедуры, что бы они были по одной строке. Delphi 2007.

20
пофигист широкого профиля
4770 / 3205 / 862
Регистрация: 15.07.2013
Сообщений: 18,613
07.03.2017, 02:00
Цитата Сообщение от Kukuxumushu Посмотреть сообщение
кнопка винды "свернуть все окна" сворачивает их каким-то нестандартным способом
Действительно очень нестандартным. Она их не только не "сворачивает", но и вообще ничего с ними не делает.
0
 Аватар для GoodWeather
886 / 588 / 179
Регистрация: 28.02.2017
Сообщений: 2,359
Записей в блоге: 1
07.03.2017, 08:13
Цитата Сообщение от Kukuxumushu Посмотреть сообщение
нажатие "свернуть все окна"
Оно работает хитро. И походу в разных версиях ОС по-разному.
В древних вроде сдвигало, в других сворачивает без сообщений окну, кое-где утверждали что в их версии аж виртуальный рабочий стол дёргает.

Версия IDE? VCL? Application OnMinimize? Показывайте код.
0
 Аватар для Kukuxumushu
1624 / 806 / 146
Регистрация: 13.06.2015
Сообщений: 3,266
07.03.2017, 11:11  [ТС]
Цитата Сообщение от GoodWeather Посмотреть сообщение
Версия IDE?
XE10
Цитата Сообщение от GoodWeather Посмотреть сообщение
Показывайте код.
Что там показывать, если его нет? Вставил рабочий пример отсюда же, на "свернуть все окна" он не реагирует.
0
 Аватар для GoodWeather
886 / 588 / 179
Регистрация: 28.02.2017
Сообщений: 2,359
Записей в блоге: 1
07.03.2017, 17:08
Так, хорошо. И всё же - вы на VCL делаете проект или на чём? *
0
 Аватар для Kukuxumushu
1624 / 806 / 146
Регистрация: 13.06.2015
Сообщений: 3,266
07.03.2017, 20:17  [ТС]
GoodWeather, да, это VCL. Я наверное не до конца корректно описал, что мне надо.
Есть иконка в трее, на панели задач вообще нет никогда ничего. И вот 1 раз кликаешь иконку - форма скрывается, второй раз - появляется. Проблема возникает, когда юзер нажимает "свернуть все окна" - форма переходит в неведомое мне состояние, и прога фактически умирает, т.к. вытащить её обратно можно только через таскменеджер. Вот от этого избавиться надо.
0
 Аватар для GoodWeather
886 / 588 / 179
Регистрация: 28.02.2017
Сообщений: 2,359
Записей в блоге: 1
10.03.2017, 03:47
Извиняюсь за задержку, дел навалилось.
Да, проблема повторяется. Оно ещё осложнено тем что главное окно - Application, а основная Form1 - как бы ведомое, скорее всего без подобной этажерки было бы проще.
Думаю VCL не замечает что свойства окна изменились и игнорирует команды.
Вы используете встроенный TrayIcon1? Какой BorderStyle? А как конкретно скрываете с панели?
0
 Аватар для Kukuxumushu
1624 / 806 / 146
Регистрация: 13.06.2015
Сообщений: 3,266
10.03.2017, 19:46  [ТС]
Цитата Сообщение от GoodWeather Посмотреть сообщение
Думаю VCL не замечает что свойства окна изменились и игнорирует команды.
Точно так, и с этим надо что-то сделать.
Цитата Сообщение от GoodWeather Посмотреть сообщение
Вы используете встроенный TrayIcon1?
Delphi
1
2
3
4
5
6
7
8
9
with FIconData do begin
 cbSize:=FIconData.SizeOf;
 Wnd:=Handle;
 uID:=1;
 uFlags:=NIF_MESSAGE+NIF_ICON+NIF_TIP;
 uCallbackMessage:=WM_USER+1;
 hIcon:=Application.Icon.Handle;
 end;
Shell_NotifyIcon(NIM_ADD, @FIconData);
Цитата Сообщение от GoodWeather Посмотреть сообщение
Какой BorderStyle?
Обычный bsSizeable
Цитата Сообщение от GoodWeather Посмотреть сообщение
А как конкретно скрываете с панели?
Вот так, ибо больше не знаю, куда это можно было прописать, чтобы на панели вообще ничего никогда не выскакивало
Delphi
1
2
3
4
procedure TAPOform.FormShow(Sender: TObject);
begin
ShowWindow(Application.Handle,SW_HIDE);
end;
Добавлено через 7 часов 41 минуту
Немного покурив WinAPI, я пришёл к следующим выводам:
1) При нажатии "свернуть все окна" visible окна остаётся в true, просто оно перемещается куда-то в конец Z-буфера.
2) При клике по иконке в трее окно, даже если оно было активным, сначала делается неактивным, перемещаясь в Z-буфере на довольно произвольную (не "следующее за активным"), и только потом управление передаётся на обработчик.
Соответственно, нужно:
а) Если окно вообще невидимо (visible=false) - сделать его видимым и активным. С этим проблем нет.
б) Если окно видимо и неактивно - сделать его активным.
в) Если окно видимо и только что было активно - сделать его невидимым.
Вот с идентификацией пунктов б) и в) имеются большие проблемы ввиду пункта 2). У кого какие мысли?
0
 Аватар для Kukuxumushu
1624 / 806 / 146
Регистрация: 13.06.2015
Сообщений: 3,266
11.03.2017, 22:12  [ТС]
Решение найдено!
Пусть и не совсем точно соответствующее ТЗ, но полностью меня устраивающее.
Оно настолько шедеврально, что заслуживает премии "Золотой Костыль".
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
// Функция по клику на значке в трее
procedure TForm1.IconMouse(var Msg: TMessage);
begin
if (Msg.LParam=WM_LBUTTONDOWN)         // Если нажата ЛКМ
or (Msg.LParam=WM_LBUTTONDBLCLK) then  // или даблклик
 begin
 if not IsWindowVisible(Handle) then   // Если окно вообще невидимо
  begin
  ShowWindow(Handle,SW_SHOW);          // то сделать его видимым
  SetForegroundWindow(Handle);         // и активировать
  end
 else                                  // Если окно типа "видимо"
  if IsIconic(Handle) then             // но в состоянии Iconic
   begin
   ShowWindow(Handle,SW_RESTORE);      // то развернуть его
   SetForegroundWindow(Handle);        // и активировать
   end
  else                                 // Если окно видимо и не свёрнуто
   if CrossWindow(Handle) then         // то проверить его перекрытость
    SetForegroundWindow(Handle)        // Если перекрыто - активировать
   else ShowWindow(Handle,SW_HIDE);    // Если не перекрыто - скрыть его
 end;
end;
 
// Проверка, перекрыто ли окно
function TForm1.CrossWindow(hw:HWND):boolean;
var R,Rhw,Cross:TRect;
begin
Result:=false;            // По дефолту - перекрыто
GetWindowRect(hw,Rhw);    // Запоминаем прямоугольник окна
while IsWindow(hw) do     // Проверяем все окна перед нашим
 begin
 hw:=GetWindow(hw,GW_HWNDPREV);   // Получаем очередное окно
 If IsWindowVisible(hw) and not IsIconic(hw) then // Если оно отображается
  begin
  GetWindowRect(hw,R);                 // то получаем его прямоугольник
  if IntersectRect(Cross,R,Rhw) then   // и проверяем на пересечение с нашим
   begin
   Result:=true;      // Пересекаются - выйти
   exit;
   end;
  end;
 end;
end;
0
 Аватар для BOGG ART
592 / 459 / 147
Регистрация: 09.12.2013
Сообщений: 2,385
Записей в блоге: 2
12.03.2017, 11:33
Цитата Сообщение от Kukuxumushu Посмотреть сообщение
function TForm1.CrossWindow(hw:HWND):boolean;
А чего будет если "у вашей программы есть несколько окон, и они перекрывают друг-друга"? Функция будет вечно выдавать исключительно неверный результат.

Добавлено через 55 секунд
XE10 это Seattle штоле? Там уже должно быть встроенным TTrayIcon - есть смысл использовать его, нежели голый API:
  • На нужное окно кладём невизуальный контрол TTrayIcon;
  • При создании окна как-то так:
    Delphi
    1
    2
    3
    4
    5
    6
    7
    8
    
    procedure TForm1.FormCreate(Sender: TObject);
    begin
    TrayIcon1.Icon:=Application.Icon;
    TrayIcon1.BalloonTitle:='Заголовок';
    TrayIcon1.BalloonHint:='бла-бла-бла';
    TrayIcon1.Visible:=True;
    TrayIcon1.ShowBalloonHint();
    end;
  • Создать события одиночное или двойное нажатия:
    Delphi
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    
    procedure TForm1.TrayIcon1Click(Sender: TObject);
    begin
    ...
    end;
     
    procedure TForm1.TrayIcon1DblClick(Sender: TObject);
    begin
    if mrYes=MessageDlg('Close Application?', mtWarning, [mbYes, mbNo], 0) then
      Close();
    end;

Добавлено через 3 минуты
вот... Далее я потестил как убирать приложение с ПанелиЗадач - что-то большинство способов из её величества Гугла кривые до чёртиков...
И то работают, то не работают, то приводят окно в неработоспособное состояние - в зависимости от способа и версии ОС...
Скорее всего наиболее предпочтительно работать с ITaskbarList:

Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
Uses ... , Winapi.ShlObj, System.Win.ComObj, ...
 
...
 
type
  TForm1 = class(TForm)
    ...
  private
    Taskbar: ITaskbarList;
    ...
 
...
 
procedure TForm1.FormCreate(Sender: TObject);
begin
Taskbar:=CreateComObject(CLSID_TaskbarList) as ITaskbarList;
Taskbar.HrInit();
end;
 
...
 
... // ??
begin
Taskbar.DeleteTab(Handle);
Taskbar.DeleteTab(Application.Handle);
end;
Осталось понять при каком событии(ях) это вызывать... Ибо вот вроде всё нормально работает под Win7, но выяснилось что косячит на XP...

Добавлено через 3 минуты
И у меня "хитросвёрнутое" окно вполне себе появляется при:
Delphi
1
2
Winapi.Windows.ShowWindow(Handle, SW_SHOWNORMAL);
Winapi.Windows.SetForegroundWindow(Handle);
Добавлено через 1 минуту
В остальных случаях считаю вполне разумно пользоваться методами VCL.
1
 Аватар для Kukuxumushu
1624 / 806 / 146
Регистрация: 13.06.2015
Сообщений: 3,266
12.03.2017, 13:08  [ТС]
Цитата Сообщение от BOGG ART Посмотреть сообщение
А чего будет если "у вашей программы есть несколько окон, и они перекрывают друг-друга"?
У неё всегда только одно окно. И даже в этом случае не очень понятно, почему же результат то неверный будет?
Цитата Сообщение от BOGG ART Посмотреть сообщение
XE10 это Seattle штоле? Там уже должно быть встроенным TTrayIcon
Спасибо, я гляну/попробую. Ещё я хотел реализовать событие по прокрутки мыши, но событие WM_MOUSEWHEEL на иконке почему-то не обрабатывается (хотя плеер AIMP, например, прекрасно меняет громкость прокруткой по иконке).
Цитата Сообщение от BOGG ART Посмотреть сообщение
Далее я потестил как убирать приложение с ПанелиЗадач - что-то большинство способов из её величества Гугла кривые до чёртиков...
А тестировали
Delphi
1
2
3
4
procedure TForm1.FormShow(Sender: TObject);
begin
ShowWindow(Application.Handle,SW_HIDE);
end;
при
Delphi
1
Application.MainFormOnTaskbar := False;
?
На ХР вроде всё работает. Но у меня в Win7 стандартная панель задач на Classic Shell заменена, так что не знаю, что там в родной семёрочной творится.
0
 Аватар для BOGG ART
592 / 459 / 147
Регистрация: 09.12.2013
Сообщений: 2,385
Записей в блоге: 2
12.03.2017, 16:06
Да можно цельную таблицу составляти, по версиям ОС (а то и хуже): где заработало, где спустя время само появляется обратно, где вообще без эффектов, а где окно изуродовалось до безумия.

Добавлено через 1 час 50 минут
Как верно сказали:
Цитата Сообщение от GoodWeather Посмотреть сообщение
Оно работает хитро. И походу в разных версиях ОС по-разному.
В некоторых случаях Win+D (оно же Свернуть все окна) на самом деле делает сворачивание, я проверял: приходят соответствующие сообщения, добавляются соответствующие стили, это можно отловить... Но не на всех ОС. Сейчас у меня "семёрка" - окну при Win+D не приходит практически вообще ничего.

А ещё такое мнение имеется:
Цитата Сообщение от Anatoly Podgoretsky
Win+D это не сворачивание, а вывод другого дектопа, потом обратное его появление
Цитата Сообщение от Anatoly Podgoretsky
Я говоряю об Desktop как об системном объекте Виндоус, справка по Win API - Desktops
Мне кажется такое утверждение несколько странным. Откуда информация? Это где-то в документации описано? Как вы это проверяли? Как это вообще проверить-то? Полазил я по справке, не понял даже как определить текущий десктоп, тока какие-то списки получил, одинаковые (и чаще всего из одного элемента).
И думаю это всё равно не объясняет полного отсутствия сообщений...
0
пофигист широкого профиля
4770 / 3205 / 862
Регистрация: 15.07.2013
Сообщений: 18,613
13.03.2017, 03:56
Цитата Сообщение от BOGG ART Посмотреть сообщение
Мне кажется такое утверждение несколько странным.
2 BOGG ART. Анатолий, царствие ему внеземное, увы уже не сможет вам ответить.
Я могу ответить вам. Команда "свернуть все окна", дурацкая команда (имхо), просто выводит на передний план (на верх Z-order) окно рабочего стола.
0
 Аватар для BOGG ART
592 / 459 / 147
Регистрация: 09.12.2013
Сообщений: 2,385
Записей в блоге: 2
13.03.2017, 15:35

Не по теме:

ой... Я не знал... Искренне жаль, хороший был человек.



Добавлено через 4 минуты
И такое слышал, говорившие доказывали это тем что окно десктопа становится активным/верхним/передним или как-то так. Но вот незадача...
Если свернуть все окна (хоть по Win+D на той ОС где тот реально сворачивает, хоть руками всё свернуть) - рабочий стол правда становится верхним и активным. Но не потому что его "подняли", а потому что всё остальное "опустили" и кроме него просто больше ничего не осталось - разумеется он активный/верхний/передний.
Ладно, предположим что на некоторых ОС это правда работает так. Как достоверно проверить? Как это сделать не по Win+D, а программно из своего кода (чтоб сравнить получаемый эффект с Win+D)? И как это событие хотя бы отловить/отследить?
0
 Аватар для Kukuxumushu
1624 / 806 / 146
Регистрация: 13.06.2015
Сообщений: 3,266
13.03.2017, 15:51  [ТС]
Цитата Сообщение от BOGG ART Посмотреть сообщение
Как достоверно проверить?
По моему вышеописанному коду можно пройтись дебагером (как я и делал) и узнать много интересного на этот счёт.
Цитата Сообщение от BOGG ART Посмотреть сообщение
Как это сделать не по Win+D, а программно из своего кода (чтоб сравнить получаемый эффект с Win+D)?
Через ShellExecute выполнится оригинальный Win+D.
Цитата Сообщение от BOGG ART Посмотреть сообщение
И как это событие хотя бы отловить/отследить?
А вот это очень хороший вопрос! По логике, должен срабатывать хук на активацию, но у меня он так и не заработал, и я плюнул на эту затею (ибо всё равно удалось обойтись без него).
0
 Аватар для BOGG ART
592 / 459 / 147
Регистрация: 09.12.2013
Сообщений: 2,385
Записей в блоге: 2
13.03.2017, 17:58
Как удалось обойтись? На версии ОС где нет (почти) никаких сообщений окну работать же не станет...

Ставить хук это странно и подозрительно. Да и вообще как костыль какой-то.

Насчёт проверки есть ли "вывод другого дектопа" я застрял на "как определить что за десктоп активен в данный момент", если вдруг кто знает - просветите пожалуйста.
Смог только получить список "WindowStations" и список "Desktops", на семёрке в списках по два элемента, и списки почему-то одинаковые. Ну или я что-то не так сделал.
0
 Аватар для Kukuxumushu
1624 / 806 / 146
Регистрация: 13.06.2015
Сообщений: 3,266
13.03.2017, 18:27  [ТС]
Цитата Сообщение от BOGG ART Посмотреть сообщение
Как удалось обойтись?
Ну я же привёл код, как мне удалось сделать для своей программы - ничего отслеживать там не надо, достаточно по факту проверить в каком состоянии окно. Меня сейчас другая проблема мучает.
0
 Аватар для BOGG ART
592 / 459 / 147
Регистрация: 09.12.2013
Сообщений: 2,385
Записей в блоге: 2
13.03.2017, 20:38
Забавно... В том-то и дело что окно в "состоянии" будто ничего не происходило.
Но зато срабатывает ваша CrossWindow()! Видимо все окна правда просто перекрываются...
Правда не самим десктопом... ...а той штукой с иконками рабочего стола... как там её...

А у меня задача как раз как отловить! Была когда-то. Я тогда корячился-корячился и плюнул, но теперь раз уж начали изучать хорошо бы разобраться.
0
 Аватар для Kukuxumushu
1624 / 806 / 146
Регистрация: 13.06.2015
Сообщений: 3,266
13.03.2017, 21:51  [ТС]
Цитата Сообщение от BOGG ART Посмотреть сообщение
В том-то и дело что окно в "состоянии" будто ничего не происходило.
Когда я дебажил, при Win+D окно переходило в состояние IsIconic, при этом его Visible не изменялось, а координаты верхнего левого угла устанавливались в -32000.
0
 Аватар для BOGG ART
592 / 459 / 147
Регистрация: 09.12.2013
Сообщений: 2,385
Записей в блоге: 2
13.03.2017, 22:17
Да, на некоторых версиях ОС делается так. Как раз например на XP такое наблюдаю.

А вот на семёрке нажимаю Win+D и:
  • WS_VISIBLE не меняется (окно видимое)
  • WS_ICONIC не меняется (окно не свёрнуто)
  • WindowRect не меняется (окно на своём месте, где было там и осталось, не двигалось, не перемещалось)
И только ваша функция CrossWindow() сообщает что мы перекрыты окном #00010472 (при том что GetDesktopWindow выдаёт #00010010).

Добавлено через 2 минуты
И эффект такой любопытный - нажатие мышкой по обоям рабочего стола (между значков, или даже на значке) скрывает открытое нами окно.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
13.03.2017, 22:17
Помогаю со студенческими работами здесь

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

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

После нажатия 'WIN+D' или "свернуть все окна" программа зависает
Здравствуйте, такая проблема. После нажатия WIN+D или "свернуть все окна" моя программа уходит в "астрал" она будет висеть в...

Свернуть окна
Нужно свернуть окно игры, именно когда играет, а не когда в меню. Есть несколько кодов ,но игры не сворачивают. Может есть у кого?

Заменить кнопки окна 'свернуть', 'закрыть'
Подскажите каким образом можно изменить иконки окна на свои ? и добавить новые


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
Хочу заставить корпорации вкладываться в здоровье сотрудников: делаю мат модель здравосохранения
anaschu 22.03.2026
e7EYtONaj8Y Z4Tv2zpXVVo https:/ / github. com/ shumilovas/ med2. git
1С: Программный отбор элементов справочника по группе
Maks 22.03.2026
Установка программного отбора элементов справочника "Номенклатура" из модуля формы документа. В качестве фильтра для отбора справочника служит группа номенклатуры. Отбор по наименованию группы. . .
Как я обхитрил таблицу Word
Alexander-7 21.03.2026
Когда мигает курсор у внешнего края таблицы, и нам надо перейти на новую строку, а при нажатии Enter создается новый ряд таблицы с ячейками, то мы вместо нервных нажатий Энтеров мы пишем любые буквы. . .
Krabik - рыболовный бот для WoW 3.3.5a
AmbA 21.03.2026
без регистрации и смс. Это не торговля, приложение не содержит рекламы. Выполняет свою непосредственную задачу - автоматизацию рыбалки в WoW - и ничего более. Однако если админы будут против -. . .
1С: Программный отбор элементов справочника по значению перечисления
Maks 21.03.2026
Установка программного отбора элементов справочника "Сотрудники" из модуля формы документа. В качестве фильтра для отбора служит значение перечислений. / / Событие "НачалоВыбора" реквизита на форме. . .
Переходник USB-CAN-GPIO
Eddy_Em 20.03.2026
Достаточно давно на работе возникла необходимость в переходнике CAN-USB с гальваноразвязкой, оный и был разработан. Однако, все меня терзала совесть, что аж 48-ногий МК используется так тупо: просто. . .
Оттенки серого
Argus19 18.03.2026
Оттенки серого Нашёл в интернете 3 прекрасных модуля: Модуль класса открытия диалога открытия/ сохранения файла на Win32 API; Модуль класса быстрого перекодирования цветного изображения в оттенки. . .
SDL3 для Desktop (MinGW): Рисуем цветные прямоугольники с помощью рисовальщика SDL3 на Си и C++
8Observer8 17.03.2026
Содержание блога Финальные проекты на Си и на C++: finish-rectangles-sdl3-c. zip finish-rectangles-sdl3-cpp. zip
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru