Форум программистов, компьютерный форум, киберфорум
Delphi: WinAPI
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.50/8: Рейтинг темы: голосов - 8, средняя оценка - 4.50
0 / 0 / 0
Регистрация: 29.10.2013
Сообщений: 14

Как проигнорировать ToogleDesktop для своего приложения

29.10.2013, 23:23. Показов 1590. Ответов 13
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Пишу что-то на подобии виджета
Столкнулся с такой проблемой:
При нажатии на Win+D или кнопки "Свернуть все окна" приложение "сворачивается"
Известно что приложение на самом деле приложения не сворачиваются а меняют положение по оси Z
Как можно отловить ToogleDesktop или же его проигнорировать?
Испробовал всё что мог, гуглил, ничего не помогло
Знаю что виджет от программы OpenHardWareMonitor справляется с этой проблемой, полазил в исходниках и мало что понял так как программа на C# написана.
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
29.10.2013, 23:23
Ответы с готовыми решениями:

Как создать установщик для своего приложения
давно хочу написать установкщик,но весь гугл перерыв не нашел.вот все совреемнные установщики сжимают твой exe,кучу мусора что там ты...

Как установить иконку для своего приложения
Добрый день! Подскажите пожалуйста как приложению задать иконку. Оно ставиться но сверху но в паке Debug все равно само приложение иконка...

Как создать лицензионный ключ для своего приложения?
Здравствуйте Уважаемые форумчане. как составить лицензионный ключ для своей программы? Как и куда сохраняется ключ для активации? ...

13
0 / 0 / 0
Регистрация: 29.10.2013
Сообщений: 14
31.10.2013, 22:11  [ТС]
Тему закрыть
Ответ найдет
Если кому и надо то:
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
procedure TForm1.Timer1Timer(Sender: TObject);
var
S: PWideChar;
hw,hw2 : HWND;
buff: array[0..127] of Char;
aName: array [0..255] of Char;
ShellWnd,WorkerID,Wind,DesktopWindow,WorW: HWND;
begin
ShellWnd:=GetWindowThreadProcessId(ShellWindow);
hw:=GetNextWindow(GetForegroundWindow,GW_HWNDPREV);
hw2:=GetNextWindow(GetDesktopWindow,GW_HWNDNEXT);
GetClassName(GetForegroundWindow,aName,256);
WorkerID:=GetWindowThreadProcessId(GetForegroundWindow);
WorW:=FindWindowEx(0, 0, 'WorkerW', nil);
Wind:=FindWindowEx(WorW, 0, 'SHELLDLL_DefView', nil);
DesktopWindow:=FindWindowEx(Wind, 0, 'SysListView32', nil);
if (DesktopWindow<>0) then//if WorkerID=ShellWnd then //if  then
SetWindowPos(Handle, hw, 0, 0, 0, 0, SWP_NOMOVE or SWP_NOSIZE or SWP_NOACTIVATE)
else
if GetForegroundWindow<>Handle then
SetWindowPos(Handle, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOMOVE or SWP_NOSIZE or SWP_NOACTIVATE);
end;
0
2 / 2 / 1
Регистрация: 21.04.2013
Сообщений: 14
21.11.2013, 14:23
ShellWnd:=GetWindowThreadProcessId(Shell Window)

ShellWindow - это что?

если это

Pascal
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
function ShellWindow: HWND;
 type
   TGetShellWindow = function(): HWND; stdcall;
 var
   hUser32: THandle;
   GetShellWindow: TGetShellWindow;
 begin
   Result := 0;
   hUser32 := GetModuleHandle('user32.dll');
   if (hUser32 > 0) then
   begin
     @GetShellWindow := GetProcAddress(hUser32, 'GetShellWindow');
     if Assigned(GetShellWindow) then
     begin
       Result := GetShellWindow;
     end;
   end;
 end;
то не работает
0
0 / 0 / 0
Регистрация: 29.10.2013
Сообщений: 14
21.11.2013, 22:21  [ТС]
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
function ShellWindow: HWND;
 type
   TGetShellWindow = function(): HWND; stdcall;
 var
   hUser32: THandle;
   GetShellWindow: TGetShellWindow;
 begin
   Result := 0;
   hUser32 := GetModuleHandle('user32.dll');
   if (hUser32 > 0) then
   begin
     @GetShellWindow := GetProcAddress(hUser32, 'GetShellWindow');
     if Assigned(GetShellWindow) then
     begin
       Result := GetShellWindow;
     end;
   end;
 end;
С ним, родимым
Всё работает хорошо, могу продемонстрировать
Среда: Delphi XE5
0
2 / 2 / 1
Регистрация: 21.04.2013
Сообщений: 14
21.11.2013, 22:36
Пожалуйста, продемонстрируй.
Выложи исходник, или на почту кинь (hash-md5@yandex.ru)

Я попробовал в XE, окно ведет себя как StayOnTop, но при нажатии Win+D пропадает (Win7 x64).
0
0 / 0 / 0
Регистрация: 29.10.2013
Сообщений: 14
21.11.2013, 23:46  [ТС]
Забыл ещё сказать что форма прячется с панели задач и не видна при "Alt+Tab"

Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
ShlObj, ActiveX, ComObj
 
procedure CreateWnd; override;
 
procedure TForm1.CreateWnd;
var
  Taskbar: ITaskbarList;
begin
  inherited;
  Taskbar := CreateComObject(CLSID_TaskbarList) as ITaskbarList;
  Taskbar.HrInit;
  Taskbar.DeleteTab(Handle);
end;
Пример с исходником
0
2 / 2 / 1
Регистрация: 21.04.2013
Сообщений: 14
22.11.2013, 11:56
Цитата Сообщение от Surikalex007456 Посмотреть сообщение
Говнокод, хотя и рабочий.

1. Саму процедуру можно (и нужно) почистить.

Pascal
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
var
  hw: HWND;
  ShellWnd, WorkerID, Wind, DesktopWindow, WorW: HWND;
begin
   ShellWnd := GetWindowThreadProcessId(ShellWindow);
   hw := GetNextWindow( GetForegroundWindow, GW_HWNDPREV );
   WorkerID:=GetWindowThreadProcessId(GetForegroundWindow);
   WorW:=FindWindowEx(0, 0, 'WorkerW', nil);
   Wind:=FindWindowEx(WorW, 0, 'SHELLDLL_DefView', nil);
   DesktopWindow:=FindWindowEx(Wind, 0, 'SysListView32', nil);
   if (DesktopWindow<>0) then//if WorkerID=ShellWnd then //if  then
      SetWindowPos(Handle, hw, 0, 0, 0, 0, SWP_NOMOVE or SWP_NOSIZE )
   else
     if GetForegroundWindow<>Handle then
        SetWindowPos(Handle, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOMOVE or SWP_NOSIZE );
end;
2. ОБЯЗАТЕЛЬНО нужно убрать значок программы с таскбара (без этого не работает)!

3. Таймер здесь совершенно излишен, достаточно отслеживать когда окно становится неактивным.

А в целом спасибо за пример, сейчас его причешу и добавлю в свою "копилку", может и пригодится

Добавлено через 20 минут
Хотя возможно я немного поторопился с выводами.

При нажатии Win+D форма в любом случае прячется. Таймер однозначно вернет ее на место, а мот через отслеживание деактивации окна не всегда срабатывает. Если часто нажимать Win+D, иногда сообщение WM_ACTIVATE "пропадает", и обработчик просто не выполняется... Надо подумать, ибо от таймера все таки хочется избавиться.
0
0 / 0 / 0
Регистрация: 29.10.2013
Сообщений: 14
22.11.2013, 19:24  [ТС]
"Говно"код образовался в следствии множественных (2х недельных) экспериментов c различными методами в поисках решения проблем
Оригинальный код был взят из исходников OpenHardwaremonitor, которая в свою очередь написана на C#
Затем двухчасовой перевод её на делфи без знаний C#
По этому прошу не называть говнокодом)
А То что процедуру нужно почистить само-собой

Ещё скажу что при "Свернуть все окна" или Win+D окна вообще не сворачиваются и никак не изменяют свои позиции кроме как по оси Z т.е. по непосредственно рабочий стол выходит на передний план
Как без таймера обойтись даже не имею представления, начинающий ведь)
Отловить это самое "ShowDesktop" другими средствами так же не удалось
0
2 / 2 / 1
Регистрация: 21.04.2013
Сообщений: 14
22.11.2013, 23:57
Цитата Сообщение от Surikalex007456 Посмотреть сообщение
Ещё скажу что при "Свернуть все окна" или Win+D окна вообще не сворачиваются и никак не изменяют свои позиции кроме как по оси Z т.е. по непосредственно рабочий стол выходит на передний план
В Vista и выше так и есть, в XP меняет (проверено лично). Прога получает сообщение WM_MOVE с координатами x=-32000 и y=-32000. Но там немного другой путь решения этой проблемы. Возможно перед тобой не стоит задачи поддерживать эту ось, мне же хочется получить универсальное решение...

Цитата Сообщение от Surikalex007456 Посмотреть сообщение
"Говно"код образовался в следствии множественных (2х недельных) экспериментов c различными методами в поисках решения проблем
Молодец! 2 недели усилий достойны уважения... Но все же после получения рабочего варианта неплохо бы его проанализировать и понять, что там вообще происходит.

От таймера я избавиться не смог, но зато почистил хорошенько, в итоге вот что получилось

Pascal
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
45
46
47
48
49
50
51
52
53
unit MainFrm;
 
interface
 
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ExtCtrls, ShlObj, ComObj;
 
type
  TForm1 = class(TForm)
    Timer1: TTimer;
    procedure CreateWnd; override;
    procedure Timer1Timer(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;
 
var
  Form1: TForm1;
 
implementation
 
{$R *.dfm}
 
{ TForm1 }
 
procedure TForm1.CreateWnd;
var
  Taskbar: ITaskbarList;
begin
   inherited;
   Taskbar := CreateComObject( CLSID_TaskbarList ) as ITaskbarList;
   Taskbar.HrInit;
   Taskbar.DeleteTab( Handle );
end;
 
procedure TForm1.Timer1Timer(Sender: TObject);
var
  hw: HWND;
  aName: array [0..255] of Char;
begin
   inherited;
   GetClassName( GetForegroundWindow, aName, 256 );
   if aName = 'WorkerW' then
   begin
      hw := GetNextWindow( GetForegroundWindow, GW_HWNDPREV );
      SetWindowPos(Handle, hw, 0, 0, 0, 0, SWP_NOMOVE or SWP_NOSIZE );
   end;
end;
 
end.
0
0 / 0 / 0
Регистрация: 29.10.2013
Сообщений: 14
23.11.2013, 06:35  [ТС]
Не спешите чистить процедуру
Думаю не зря проверяется наследование у WorkerW
Сейчас не упомню точно но баги программка ловила, не зря допиливал проверку наследования
Иначе и так очевидно что строчки лишние, но всё же лишними их не считаю
0
2 / 2 / 1
Регистрация: 21.04.2013
Сообщений: 14
23.11.2013, 09:54
Цитата Сообщение от Surikalex007456 Посмотреть сообщение
Не спешите чистить процедуру
Думаю не зря проверяется наследование у WorkerW
Сейчас не упомню точно но баги программка ловила, не зря допиливал проверку наследования
Иначе и так очевидно что строчки лишние, но всё же лишними их не считаю
Можно конечно и оставить, хотя я проверял, ничего страшного не обнаружил...
Будут лишние срабатывания в случае, если вдруг активным будет приложение с классом окна 'WorkerW', но ничего критичного в этом нет.

Если ты ловил баги, постарайся припомнить какие и при каких обстоятельствах...
0
0 / 0 / 0
Регистрация: 29.10.2013
Сообщений: 14
23.11.2013, 10:48  [ТС]
Если вспомню то сообщу
Решались они теми строчками проверки наследования, дальше разбираться не стал
0
2 / 2 / 1
Регистрация: 21.04.2013
Сообщений: 14
25.11.2013, 14:09
Как вариант

Pascal
1
2
3
4
5
6
7
8
9
10
11
12
13
type
  TForm1 = class(TForm)
    {...}
    procedure CreateWnd; override;
    {...}
  end;
 
procedure TForm1.CreateWnd;
begin
   inherited;
   BorderStyle := bsToolWindow;
   FormStyle := fsStayOnTop;
end;
0
0 / 0 / 0
Регистрация: 29.10.2013
Сообщений: 14
25.11.2013, 16:03  [ТС]
Всегда поверх всех окон
Много вариантов таких было перепробовано но, мне такой вариант не подходит
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
25.11.2013, 16:03
Помогаю со студенческими работами здесь

Как создать окно справки для своего приложения?
подскажите, пожалуйста, леплю интерфейс, как подключить при нажатии f1 справку, или вообще как писать справку?

Как задать строгое расположение иконок в трее для своего приложения?
Воспользовавшись предложенным в теме https://www.cyberforum.ru/lazarus/thread2350414.html решением для вывода в систрее числа минут и...

Как программно нажать клавишу F5 для обновления рабочего стола из своего приложения?
Есть ли метод или функция эмулирующая нажатие клавиши F5 для обновления рабочего стола? Или примерно такой способ, только кодом C#

Красивый UI для своего приложения
Доброго времени суток форумчане. Подскажите, что можете посоветовать максимально красивого для приложений выполняющихся в среде...

Плагин для своего приложения
нужно написать плагин для своего приложения (приложение и плагин на делфе 7). Подскажите статейку по теме. Надо просто в приложении...


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

Или воспользуйтесь поиском по форуму:
14
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): Обработчик клика мыши в браузере ПК и касания экрана в браузере на мобильном устройстве
8Observer8 02.02.2026
Содержание блога Для начала пошагово создадим рабочий пример для подготовки к экспериментам в браузере ПК и в браузере мобильного устройства. Потом напишем обработчик клика мыши и обработчик. . .
Философия технологии
iceja 01.02.2026
На мой взгляд у человека в технических проектах остается роль генерального директора. Все остальное нейронки делают уже лучше человека. Они не могут нести предпринимательские риски, не могут. . .
SDL3 для Web (WebAssembly): Вывод текста со шрифтом TTF с помощью SDL3_ttf
8Observer8 01.02.2026
Содержание блога В этой пошаговой инструкции создадим с нуля веб-приложение, которое выводит текст в окне браузера. Запустим на Android на локальном сервере. Загрузим Release на бесплатный. . .
SDL3 для Web (WebAssembly): Сборка C/C++ проекта из консоли
8Observer8 30.01.2026
Содержание блога Если вы откроете примеры для начинающих на официальном репозитории SDL3 в папке: examples, то вы увидите, что все примеры используют следующие четыре обязательные функции, а. . .
SDL3 для Web (WebAssembly): Установка Emscripten SDK (emsdk) и CMake для сборки C и C++ приложений в Wasm
8Observer8 30.01.2026
Содержание блога Для того чтобы скачать Emscripten SDK (emsdk) необходимо сначало скачать и уставить Git: Install for Windows. Следуйте стандартной процедуре установки Git через установщик. . . .
SDL3 для Android: Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 29.01.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами. Версия v3 была полностью переписана на Си, в. . .
Инструменты COM: Сохранение данный из VARIANT в файл и загрузка из файла в VARIANT
bedvit 28.01.2026
Сохранение базовых типов COM и массивов (одномерных или двухмерных) любой вложенности (деревья) в файл, с возможностью выбора алгоритмов сжатия и шифрования. Часть библиотеки BedvitCOM Использованы. . .
SDL3 для Android: Загрузка PNG с альфа-каналом с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 28.01.2026
Содержание блога SDL3 имеет собственные средства для загрузки и отображения PNG-файлов с альфа-каналом и базовой работы с ними. В этой инструкции используется функция SDL_LoadPNG(), которая. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru