Мечты вуайериста - чужие окна 2Delphi , Программа и Интерфейс , Приложения чужиеМечты вуайериста - чужие окна 2Теперь, попробуем менять, что-то в чужих окнах. И вообще попробуем сделать с ними то же, что мы делаем со своими окнами. Сразу скажу, что тема эта неисчерпаема. Ей можно посвятить не одно скромное обозрение, а детальное многотомное издание. Я не ставлю св оей задачей. Несколько предварительных сурьезных слов. Вынужден сказать, что многое изложенное ниже может привести к неприятным последствиям. Например, к тому, что программа или система будет зависать. Поэтому будем считать, что читатель находиться в трезвом уме и здравой памяти и не будет совершать необдуман ные действия. Прежде чем убить или закрыть чужое окно, подумайте, а зачем это окно вообще висит. Помните, что если окна висят в системе значит это кому то нужно ?! (почти Маяковский). Ну а теперь немного попугав для проформы перейдем к делу. Содержание:
Несколько предварительных сурьезных слов. Итак… Режимы отображение окон верхнего уровня. Давайте попробуем для начала сделать чужое окно активным (мы уже это делали, когда спасали чужое окно в картинку). Для этого можно использовать одну из следующих функций: Функция SetForegroundWindow Синтаксис:
Описание: Показывает верхние окно системы. Параметры:
Wnd: Идентификатор окна. Процедура BringWindowToTop Синтаксис:
Описание: Активизирует и перемещает Wnd в вершину стека перекрывающихся окон. параметры:
Wnd: Всплывающее или дочернее окно. Теперь попробуем проделать с неким окном, имеющим идентификатор окна HD:HWnd некие стандартные действия:
1) Свернуть данное окно; Все данные действия могут быть проделаны с окном при помощи стандартной функции SendMessage или PostMessage, с различными параметрами:
1) SendMessage(HD,WM_SYSCOMMAND,SC_MINIMIZE,0); Существуют и другие константы, для сообщений вида WM_SYSCOMMAND:
SC_CLOSE Закрывает окно. Первый параметр - описатель искомого окна, второй сообщение (в нашем случае WM_SYSCOMMAND) третий одна из констант приведенных выше, четвертый параметр - координаты (x- младшее слово y - старшее). Можно, так же, показать или скрыть окно, используя функцию API: Процедура ShowWindow Синтаксис:
Описание: отображает или прячет окно образом, указанным параметром CmdShow. параметры:
Wnd: Всплывающее или дочернее окно.
SW_HIDE Возвращаемое значение: Не нуль, если окно было ранее видимым; нуль - если оно было ранее спрятанным. Константы позволяют скрыть/показать окно с различными типами (распахнутым, свернутым, неактивным и пр.) Давайте теперь попробуем решить ряд наиболее часто встречающихся проблем: 1) Как свернуть все окна системы ??? (как свернуть все окна системы кроме окна программы)
Для того чтобы окно программы тоже сворачивалось достаточно убрать строку If Wd<>Form1.Handle then в EnumMiniProc Конечно, можно поставить еще массу условий, по которым будут минимизироваться окна, но это уже дело конкретной задачи. Еще один пример, который бывает зачастую нужен: 2) Как закрыть (или постоянно закрывать) окна, например содержащие в заголовке подстроку «Реклама» Закрыть все окна, содержащие определенную подстроку в заголовке.
Понятно, что настоящая реклама не дает себе таких заголовков, но общий принцип останется тем же, а так попробуйте поискать общее в заголовках окна, названии классов окна и т.п. Кроме того, использование таймера чревато тем, что окон в системе очень много и за установленный интервал времени все окна не будут отработаны, это приведет к замедлению работы системы. Но решение данной подзадачки автор оставляет за читателем, благо особых сложностей с этим нет (увеличения интервала времени, установка логического условия о том, что проверка уже идет, вставка оператора Application.ProcessMessages и проч.) На этом все возможности этих функций API не исчерпываются, но общий принцип отображения чужих окон, закрытия, перемещения и прокрутки изложен, дальше нужно от конкретной задачи. Системное меню и кнопки заголовка. Системное меню, отображает обычно ряд доступных стандартных функций применимых к окнам. Обычно к таким функциям относятся следующие команды (применительно к локализованным Windows, в англоязычных названия будут другие, есть подозрения, что английские J):
Восстановить - восстанавливает размер окна. Все эти команды, а так же ряд других (например, добавленных пользователем) доступны при нажатии на иконку, расположенную в левой части заголовка окна. Ряд команд имеет кнопку, расположенную в правой части заголовка. Обычно таких кнопок три: свернуть, восстановить, закрыть. Иногда добавляется кнопка помощь. Зачем манипулировать доступными командами системного окна ??? Ну, например, есть окошко, у которого кнопка закрыть - недоступна, а в системном меню пункта закрыть нет, да и на Alt+F4 она не откликается. А убрать программку ужас как хочется. Процедура GetSystemMenu Синтаксис:
Описание: Считывает системное меню окна для копирования и модификации. параметры:
Wnd: Всплывающее или дочернее окно. Для начала надо получить идентификатор системного меню. При помощи приведенной выше функции. Далее попробуем определить, что именно содержится в системном меню (надо сказать, что приведенные ниже функции API справедливы для любых меню, а не только системных, но об этом несколько позже): Процедура GetMenuString Синтаксис:
Описание: копирует метку элемента меню в Str. параметры:
Menu: идентификатор меню.
mf_ByPosition - определять пункт меню по порядковому номеру Возвращаемое значение: Количество реально скопированных байт. Как видно из описания функции возможно два варианта определения списка по номеру или по выполняемой команде. Если Flag = mf_ByCommand тогда в качестве IDItem передаются стандартные команды (см. константы в WM_SYSCOMMAND. Предыдущий раздел). Например
Возвращает название пункта системного меню, отвечающего за закрытие окна. I=0 указывает, что такого пункта в системном меню нет. Если Flag = mf_ByPosition тогда в качестве IDItem передается порядковый номер искомого пункта меню, начиная с 0 Например
Возвращает название самого первого по порядку пункта системного меню (обычно это восстановить). I=0 указывает, что такого пункта в системном меню нет. ИМХО первый вариант более пригоден для получения списка строк системного меню, в то время как второй - д ля определения присутствует ли данная команда в системном меню. Количество элементов меню можно получить при помощи функции Процедура GetMenuItemCount Синтаксис:
Описание: определяет число меню и элементов меню верхнего уровня в указанном меню. параметры:
Menu: идентификатор меню. Вот как приблизительно может выглядеть функция, которая определяет системное меню окна: Получение списка системного меню окна.
Итак, мы получили список пунктов системного меню. Пустые строки, скорее всего, означают разделители. Так же используются акселераторы (&) Следующим шагом будет определение состояния того или иного пункта меню. Процедура GetMenuState Синтаксис:
Описание: Считывает инфоpмацию состояния для указанного элемента меню. параметры:
Menu: идентификатор меню.
mf_ByPosition - определять пункт меню по порядковому номеру Возвращаемое значение: Маски флагов из следующих значений:
mf_Checked - отмеченное галочкой в случае всплывающего меню старший байт содержит число элементов; -1 в случае неверного идентификатора. Давайте слегка улучшим наш предыдущий текст, будем отображать, кроме названия пунктов меню, еще и такую насущную информацию как является ли данный пункт разделителем и доступен ли данный пункт для пользователя : Получение списка состояния системного меню окна.
Точно так же можно определять и многие другие параметры пунктов меню. Для получения большего количества информации о пункте меню можно использовать Пpоцедуpа GetMenuItemInfo Синтаксис:
Описание: Выдает информацию о пункте меню. параметры:
Menu: идентификатор меню.
Возвращаемое значение: В случае успешного завершения возвращается 1; 0 - в противном случае. Эта функция является упрощенным вариантом монстроподобной GetMenuInfo, которая, к сожалению, поддерживается не везде (Делфа 3 не поддерживает), поэтому описывать и привязываться к этой функции не буду. Итак, мы получили список пунктов системного меню окна . Теперь можно
1) Изменять статус пунктов меню (и соответствующих им кнопок заголовка) Будем решать эти вопросы по порядку. процедура EnableMenuItem Синтаксис:
Описание: разрешает, блокирует или затеняет элемент меню в соответствии со значением параметра Enable.
Menu: Идентификатор меню.
mf_ByCommand - пункты меню по команде совмещенные с константами
mf_Disabled, - недоступный Возвращаемое значение: Пpедыдущее состояние элемента меню; -1, если элемент не существует.. Следует заметить, что некоторые пункты системного меню связаны с состоянием окна (такие которые задают положение окна и возможность перемещать и изменять его размеры) и даже если удается формально запретить некий пункт (например развернуться) это не значи т, что он будет действительно недоступен. Включение/выключение пункта меню
Как уже было сказано, это процедура будет работать далеко не для всех пунктов меню, например кнопку и пункт меню закрыть она будет запрещать очень даже хорошо, а вот например пункт развернуть далеко не всегда. Для того, чтобы сделать это наверняка нужно п росто удалить такую возможность. Т.е. удалить соответствующий пункт системного меню. Пpоцедуpа DeleteMenu Синтаксис:
Описание: Удаляет элемент из Menu. Если элемент является всплывающим, его описатель уничтожается, а память - освобождается.
Menu: Идентификатор меню. Описание стандартное, поэтому никаких сложностей при использовании данной функции возникнуть не должно. ИМХО использование как раз этой функции - тот случай, когда в качестве параметра flags лучше передавать значение mf_ByCommand явно указывая какую коман ду Вы собираетесь удалить из меню. Так же следует заметить, что удаление пункта меню, которому соответствует кнопка заголовка приведет не к исчезновению кнопки из заголовка, а только к ее затенению. Добавить пункт меню можно двумя способами: просто добавить пункт в конец меню: Пpоцедуpа AppendMenu Синтаксис:
Описание: Пpисоединяет в конец меню новый элемент, состояние котоpого опpеделяется Flags.
Menu: Идентификатор меню. Или вставить пункт меню настроив все необходимые параметры Пpоцедуpа InsertMenuItem Синтаксис:
Описание: Вставляет пункт меню.
Menu: Идентификатор меню. Ну и как результат всех наших стараний напишем процедуру, которая разрешает или запрещает кнопку, строку системного меню «закрыть» (а так же комбинацию клавиш Alt+F4): Удаление или восстановление кнопки закрыть окно.
Конечно, куда правильнее было бы использовать функцию InserMenuItem вместо AppendMenu, тогда можно было бы поставить слева значек «закрыть». Но это уже для любителей самим повозиться с API, очень уж не хочется лишать их этого удовольствия J. Ну, и, наконец, для развлечения тех, кто продрался сквозь все эти кошмары работы с системным меню, предлагаю маленькое развлечение. Иногда появляется необходимость нарисовать, что-нибудь (например, кнопку) в заголовке чужого окна (а возможно и своего). Это можно сделать очень и очень просто. Пpоцедуpа DrawFrameControl Синтаксис:
Описание: Рисует один из элементов в заголовке окна.
DFC_BUTTON Кнопка Для кнопок
DFCS_BUTTON3STATE Кнопка с тремя состояниями Для заголовков
DFCS_CAPTIONCLOSE Кнопка закрыть Для меню
DFCS_MENUARROW Стрелка подменю Для полос прокрутки DFCS_SCROLLCOMBOBOX Линейка прокрутки выпадаюшего списка DFCS_SCROLLDOWN Кнопка вниз DFCS_SCROLLLEFT Кнопка влево DFCS_SCROLLRIGHT Кнопка вправо DFCS_SCROLLSIZEGRIP Размерная ручка DFCS_SCROLLUP Кнопка вверх Возвращаемое значение: В случае успешного завеpшения - не нуль; в пpотивном случае - 0. Заметьте, что это функция только рисует элемент заголовка. 14 Отрисовка «фальшивой» кнопки закрыть в заголовке окна.
Некоторые дополнительные возможности С приложениями (и окнами верхнего уровня в частности) можно делать огромное количество вещей. Если быть честным, то останавливаться подробно на этих возможностях я не собирался. Но оказалось, что решение этих задач интересует достаточно многих. В этом раз деле попробуем привести некоторые, на мой взгляд, наиболее полезные из них. Самым простым, и наиболее часто используемой является возможность изменять заголовок чужих окон. И действительно, почему в заголовке Дельфы пишется например Delphi ? J Непорядок ! Пpоцедуpа SetWindowText Синтаксис:
Описание: Устанавливает название заголовка для окна или текст оpгана упpавления с помощью стpоки, указанной в Str. И текст, который иллюстрирует работу данной функции, например, находит окно Дельфы и меняет ее заголовок с «Delphi» на любой другой Замена текста в заголовке окна.
Зачастую необходимо выяснить, не зависло ли окно (или вернее насколько живо оно откликается на попытки системы достучаться до него) Для этих целей можно использовать следующий текст 16 Определение не является ли данное окно зависшим.
Теперь поговорим о, так называемом, подсвечивание окон. Например, при установке точки останова в программе главное окно начинает мерцать. И делает это до тех пор, пока пользователь не переключится в это окно. Как это делается ??? Существует пара функций: Пpоцедуpа FlashWindow Синтаксис:
Описание: Делает окно или пиктогpамму мигающими. Активное состояние откpытого окна инвеpтиpуется. И вторая функция, которая описана для Delphi 5 а для 3 нет, что обидно, но мы это исправим. Пpоцедуpа FlashWindowEx Синтаксис:
Описание: Делает окно или пиктогpамму мигающими. Активное состояние откpытого окна инвеpтиpуется.
Возвращаемое значение: Не нуль, если окно до вызова было активным; 0 - в пpотивном случае.
А теперь сама программа, не забудьте подключить модуль кому нужно: 17 Мигающий заголовок окна
Итоги Итак, мы научились управлять чужими окнами верхнего уровня:
1. Изменять их положение, размеры Статья Мечты вуайериста - чужие окна 2 раздела Программа и Интерфейс Приложения чужие может быть полезна для разработчиков на Delphi и FreePascal. Комментарии и вопросыМатериалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта. :: Главная :: Приложения чужие ::
|
|||||||||||||||||||||||||||||||||||
©KANSoftWare (разработка программного обеспечения, создание программ, создание интерактивных сайтов), 2007 |