![]() |
Модераторы: Snowy, bartram, MetalFan, bems, Poseidon, Riply |
![]() ![]() ![]() |
|
Poseidon |
|
||||||||||||||||||||||
![]() Delphi developer ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 5273 Регистрация: 4.2.2005 Где: Гомель, Беларусь Репутация: 10 Всего: 133 |
Я заметил, что вопросы о иконки в трее возникают довольно часто, поэтому решил выложить на форум эту статью
----------------------------------------------------------------------------------------------- Наверняка многие, кто начинает программировать на Delphi нередко задавались такими вопросами как: 1. А как можно поместить иконки приложения в системный трей Windows возле часов? 2. Как скрыть главную форму приложения при запуске и показывать ее по команде всплывающего меню иконки приложения в системной трее, и как затем скрыть ее обратно? Знакомо да? Что ж, сам я тоже когда-то был начинающим программистом, и потратил уйму времени и нервов за изучение и поиска решений для всех вышеизложенных вопросов. И именно сейчас я готов изложить Вам все свои знания по части работы с иконкой приложения в системной трее. Статью я решил разделить на две части. Что содержит каждая из них догадаться не трудно - вопросов, о решении которых я расскажу тоже две. Итак, это часть 1: "Добавление иконки в системный трей". В этой части мы научимся: - добавлять, изменять и удалять иконку. - отлавливать события мыши на иконке (наведение, клик, двойной клик и т.д.) - менять иконку во время работы приложения, а также текст всплывающей подсказки. Начать статью я решил не с описания всевозможных компонентов для данной сферы программинга (которых полным полно в интернете), а с описания азов - WinAPI функций, предназначенных для работы с system tray. Хотя, "функции", как то больно громко получилось. На самом деле она всего одна:
(я привожу Вам упрощенное представление функции сделанное лично мной, т.к. если взять описание функции из WinAPI SDK - понять его будет намного труднее) подробнее о параметрах: dwMessage: Параметр, а точнее команда, которая указывает этой функции что именно она должна делать. Может принимать следующие значения констант: NIM_ADD - добавляет иконку в трей NIM_DELETE - удаляет иконку из системного трея NIM_MODIFY - меняет (обновляет) иконку в системном трее. lpData: Сей параметр есть запись, которая содержит всю информацию об добавляемой, удаляемой или изменяемой иконке. Данная запись имеет вид: _NOTIFYICONDATAA = record cbSize: DWORD; Wnd: HWND; uID: UINT; uFlags: UINT; uCallbackMessage: UINT; hIcon: HICON; szTip: array [0..63] of AnsiChar; end; (указатель PNotifyIconData является указателем именно на эту запись) Давайте рассмотрим, какие именно данные содержит данная запись: cbSize: Размер данной записи; Wnd: Handle того окна, которое будет получать сообщения от иконки; uID: Идентификатор иконки; uFlags: Здесь содержатся константы, означающие, какие данные верны в записи: NIF_ICON - hIcon содержит верную информацию. NIF_MESSAGE - uCallbackMessage содержит верную информацию. NIF_TIP -szTip содержит верную информацию. (Подробнее об этом я расскажу ниже) uCallbackMessage: Назначенный Вами идентификатор сообщения, которое будет получать приложение от иконки. hIcon: Собственно Handle иконки (TIcon.Handle). szTip: Текст всплывающей подсказки (не более 64 символов). Мда, наверняка ничего не понятно, да? ..особенно новичкам. Ничего! Далее я приведу код небольшой программы, написанной лично мной. Весь код программы имеет очень богатые комментарии. С их помощью понять смысл каждого шага Вам будет нетрудно ![]() Ниже привожу листинг файла main.pas (файл основной и единственной формы приложения): Внимание!: в тексте программы прошу не путать два понятия: "иконка" - это то, что собственно находится в системно трее, и "иконка (изображение)" - это то, что содержит то само изображение иконочки.
Итак, это вторая часть моей небольшой "эпопеи", посвященное иконке в системной трее. В этой части мы рассмотрим и научимся решать следующие вопросы: 1. Как добавить всплывающее меню к иконке? 2. Как скрывать главную форму приложения при запуске, и показываеть его по команде всплывающего меню. Для изучения данных вопросов, мы воспользуемся все тем же примером, который использовали в первой части, и немного модернизируем его. Откройте в Delphi исходник от первой части статьи и внесите в него следующие изменения: 1. Найдите на форме кнопку с именем "Exit". Теперь, измените ее свойство "Caption" на "Скрыть", а свойство "Name" на "BHide"; 2. Добавьте на форму компонент PupopMenu и измените его свойство "Name" на "PopupMenu". 3. Теперь два раза щелкните на нем, чтобы открылся редактор меню, и создайте точно такое меню: Пункту "О программе" дайте имя "PAbout", пункту "Настройки" дайте имя "PSettings", пункту "Выход" имя "PExit". У пункта "Настройки" свойство "Default" установите в "True" (этим мы делаем данный пункт меню основным, т.е. данное действие будет выполняться при двойном нажатии левой кнопки мыши на иконке приложения в системном трее. Как это сделать Вы узнаете чуть ниже). После чего закройте редактор меню. Теперь, давайте приступим к решению вопросов, заданных в начале статьи. Начнем мы с того, что научимся скрывать главную форму при запуске приложения. Для этого вам необходимо зайти в пункт меню самой Delphi: Project -> View Source (Проект -> Просм. источник). После чего Вашим глазам откроется содержание файла tray.dpr. Текста там немного, так что ничего страшного в этом файле нет ![]()
которая создает главную форму приложения, и, сразу после нее, на следующей строке напишите:
Вот и все! Этой строкой вы запретили показ главной формы приложения при запуске. Чтобы проверить, сохраните все изменения, и запустите программу. Теперь, при запуске, Вы увидите только иконку в системном трее. Да, кстати, закрыть программу теперь возможно только в Delphi при помощи меню Run -> Program Reset, или при помощи горячих клавиш Ctrl-F2. Но это только временно, ниже мы решим эту проблему. Далее, давайте напишем нужные коды в обработчиках событий нажатия кнопки мыши в каждом из пунктов меню: Пункт "О программе":
Пункт "Настройки":
Пункт "Выход":
По моему комментарии излишне ![]() А сейчас мы сделаем самое главное и самое интересное: заставим наше меню "всплывать" на иконке во время нажатия правой кнопки мыши, а нашу главную форму "показываться" при двойной нажатии левой кнопки мыши. В исходном коде программы найдите процедуру IconCallBackMessage и модернизируйте ее так, чтобы она выглядела так, как показано ниже:
С первым событием двойного нажатия левой кнопки мыши наверняка все понятно - мы выполняем вызываем обработчик события нажатия кнопки мыши на пункте меню "Настройки". Но, с нажатием правой кнопки мыши наверное потруднее да? Чтож, все по порядку: В самом начале процедуры мы объявляем объект Mouse типа TMouse. Для того, чтобы позднее при помощи него узнать координаты мыши на экране. Далее мы пишем следующую строчку:
Смысл ее простой. Метод Popup используется для показа меню в заданной точке экрана. Именно здесь нам пригодился объект Mouse, при помощи свойств которого, мы узнаем координаты мыши на экране, во время нажатия правой кнопки мыши. Но, в "всплывании" меню есть еще одни нюанс. Если сейчас все оставить все как есть, оно будет "зависать" при потери фокуса - т.е. просто не будет исчезать. Для устранения данного бага в обработчике события OnPopup нашего меню впишите нижеследующее:
Этим мы указываем, что активным является главная форма нашего приложения (даже если он невидима). И, при переключении между приложения оно теряет свою активность, и, соответственно, всплывающее меню исчезает из виду, т.к. оно является дочерним объектом, по отношению к форме. Вот и в принципе и все ![]()
А вот теперь все! Надеюсь, по мере чтения статей этой серии Вам становится все легче и легче понять азы работы с иконкой приложения в системной трее ![]() -------------------- Если хочешь, что бы что-то работало - используй написанное, если хочешь что-то понять - пиши сам... |
||||||||||||||||||||||
|
|||||||||||||||||||||||
SoWa |
|
|||
![]() Харекришна ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2422 Регистрация: 18.10.2004 Репутация: 2 Всего: 74 |
Молодец! Это конечно не компонент, который я всегда юзаю, но написано понятно! Твой [+]
-------------------- Всем добра ![]() |
|||
|
||||
Poseidon |
|
|||
![]() Delphi developer ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 5273 Регистрация: 4.2.2005 Где: Гомель, Беларусь Репутация: 10 Всего: 133 |
![]() -------------------- Если хочешь, что бы что-то работало - используй написанное, если хочешь что-то понять - пиши сам... |
|||
|
||||
Palladin |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 932 Регистрация: 15.5.2007 Где: Беларусь г.Гомель Репутация: нет Всего: 17 |
Спасибо огромное тебе за эту статью, еслиб у меня было уже 100 сообщений, я б тебе [+] полюбому бы повесил, молодец!!!!!!!!!
![]() Добавлено @ 18:58 Короче вот моя прога(весь код) мне ненадо чтобы когда на трей наводиш всплывали подсказки и прочее, мне надо только чтоб когда прога запускалась она не сворачивалась при загрузке проги, а делала это при нажатии на кнопку Button5, а когда прога уже в трее и её надо снова развернуть, то поней надо просто клинуть было чтобы она снова разворачивалась в нормальное состояние и всё, больше ничего, плиззз поправьте что там не так, а то я уже пол дня убил чё-то не выходит(опыт нулёвый две недели делфи учу) ![]()
плиззз помогите ![]() ![]() Это сообщение отредактировал(а) RooR - 28.2.2006, 19:01 -------------------- Глуп тот кто полагается на истину авторитета, а не на авторитет истины [color=red]KAV&KIS==Evil[/color] |
|||
|
||||
Romikgy |
|
|||
![]() Любитель-программер ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7326 Регистрация: 11.5.2005 Где: Porto Franco Odes sa Репутация: 13 Всего: 146 |
-------------------- Владение русской орфографией это как владение кунг-фу — истинные мастера не применяют его без надобности. ![]() |
|||
|
||||
Palladin |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 932 Регистрация: 15.5.2007 Где: Беларусь г.Гомель Репутация: нет Всего: 17 |
спасибо, но что-то не так, вот такие ошибки
[Error] Unit1.pas(140): Undeclared identifier: 'IconFile' [Error] Unit1.pas(143): Undeclared identifier: 'Picture' [Error] Unit1.pas(148): Undeclared identifier: 'IconCallBackMessage' [Error] Unit1.pas(148): ';' expected but '(' found [Error] Unit1.pas(148): ';' expected but ')' found ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() 6 час пошёл как я пытаюсь что-то исправить, хелп ме ![]() Это сообщение отредактировал(а) RooR - 1.3.2006, 01:25 -------------------- Глуп тот кто полагается на истину авторитета, а не на авторитет истины [color=red]KAV&KIS==Evil[/color] |
|||
|
||||
Palladin |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 932 Регистрация: 15.5.2007 Где: Беларусь г.Гомель Репутация: нет Всего: 17 |
Ура, я разобрался, всё пашет, сорри за офтоп
![]() -------------------- Глуп тот кто полагается на истину авторитета, а не на авторитет истины [color=red]KAV&KIS==Evil[/color] |
|||
|
||||
Демо |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1278 Регистрация: 3.11.2005 Репутация: 6 Всего: 50 |
Сейчас исчело такое понятие, как "System tray", к сожалению. Microsoft зачем-то избавилась от него. Теперь это "Область сообщений/уведомлений"
-------------------- |
|||
|
||||
Palladin |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 932 Регистрация: 15.5.2007 Где: Беларусь г.Гомель Репутация: нет Всего: 17 |
Мда, я к сожалению не совсм разобрался, прога сворачивается но значка внизу никакого нет
![]() поправьте плиззз
-------------------- Глуп тот кто полагается на истину авторитета, а не на авторитет истины [color=red]KAV&KIS==Evil[/color] |
|||
|
||||
Poseidon |
|
|||
![]() Delphi developer ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 5273 Регистрация: 4.2.2005 Где: Гомель, Беларусь Репутация: 10 Всего: 133 |
Код твой пока не изучал, но на ходу появился один вопрос: ты назначил событие OnCreate = FormCreate???
-------------------- Если хочешь, что бы что-то работало - используй написанное, если хочешь что-то понять - пиши сам... |
|||
|
||||
Palladin |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 932 Регистрация: 15.5.2007 Где: Беларусь г.Гомель Репутация: нет Всего: 17 |
Короче поизменял тут всякое вроде запахало, но вот при запуске откомпелированной проги, на старте выскакивает ошибка
Access violation at address 00456FCC9 in module 'Project1.exe'. read of addres 00000168 Нажимаеш ОК и прога начинает работать нормально, но всётаки это же не дело чтоб при каждом запуске прога выдавала ошибку ![]() По поводу OnCreate = FormCreate то небыло выставлено, поставил и я ещё убрал функцию кнопки на форме procedure BrowseClick(Sender: TObject); вообщем что за ошибка незнаете???? Соорри это я сморозил, сам разобрался спасибо что помагали!!!! Спасибо ВСЕМ, прога работает и трей тоже!!!11 Вообщем сенкс! Это сообщение отредактировал(а) RooR - 1.3.2006, 22:11 -------------------- Глуп тот кто полагается на истину авторитета, а не на авторитет истины [color=red]KAV&KIS==Evil[/color] |
|||
|
||||
bems |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 3400 Регистрация: 5.1.2006 Репутация: 21 Всего: 88 |
![]()
Это всегда была область уведомлений. В сдк от Д2005 видел что-то типа "область уведомлений, которую иногда ошибочно называют треем". Если порыться в дереве окон, то видим, что слово трей есть в окне другой части таскбара (помоему, там где кнопочки...) -------------------- Обижено школьников: 8 |
|||
|
||||
skinny |
|
|||
![]() Новичок Профиль Группа: Участник Сообщений: 7 Регистрация: 2.12.2007 Репутация: нет Всего: нет |
здрасте всем
у меня проблема вот какова характера при наведении курсора на иконку в трее возникает событие WM_MOUSEMOVE это понятно когда я пытаюсь при этом што то сделать выскакивает исключение и описано оно так: "окно не имеет полос прокрутки" вот и всё и получается што подёргать курсором над иконкой не плучатся |
|||
|
||||
Scandium |
|
|||
![]() Новичок Профиль Группа: Участник Сообщений: 5 Регистрация: 3.12.2007 Репутация: нет Всего: нет |
![]() Я уже нашёл один пример работы с треем...списал его и [censored 6]...он работал, ![]() Потом решил ещё поискать...и вот увидел вашу статью..написал...всё работает ![]() ![]() |
|||
|
||||
СЭНСЭЙ |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 432 Регистрация: 20.3.2006 Репутация: нет Всего: нет |
Проверил лично - рабатАет.
причем Я - чайник. Другим чайникам могу сказать - если копируете текст программы она работать не будет. События нажатия на кнопки и пункты меню нужно создавать в проекте, например двойным щелчком по кнопке, а в созданную при этом процедуру уже вписывать предложенный хаспадином - хорошим, код. Жаль только неясно засем там групбоксы. |
|||
|
||||
![]() ![]() ![]() |
Правила форума "Delphi: WinAPI и системное программирование" | |
|
Запрещено: 1. Публиковать ссылки на вскрытые компоненты 2. Обсуждать взлом компонентов и делиться вскрытыми компонентами
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, bartram, MetalFan, bems, Poseidon, Rrader, Riply. |
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | Delphi: WinAPI и системное программирование | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |