Модераторы: Snowy, bartram, MetalFan, bems, Poseidon, Riply

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Иконка в системном трее, статья 
:(
    Опции темы
Scandium
  Дата 7.12.2007, 01:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 5
Регистрация: 3.12.2007

Репутация: нет
Всего: нет



Цитата

Жаль только неясно засем там групбоксы.


Групбоксы не несут там никакого функционала, а нужны тока для графического отделения компонетов, исключение составляет групбокс "AboutGroupBox". Он нужен для работы с контактоной информации, расположенной на ней (ссылка на мыло и сайт)...Вот текст показа этого групбокса при нажатии на кнопку "About":
Код

procedure TForm1.AboutClick(Sender: TObject);
begin
    if Form1.Width=250 then
  begin
    Form1.Width:=430;
    About.Caption:='О Программе <<';
  end
  else begin
    Form1.Width:=250;
    About.Caption:='О Программе >>';
  end;
  AboutGroupBox.Visible:=not AboutGroupBox.Visible;
end;


Если я не прав, то пусть автор меня поправит smile 

Это сообщение отредактировал(а) Scandium - 7.12.2007, 01:09
PM MAIL   Вверх
skinny
Дата 13.12.2007, 21:07 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 7
Регистрация: 2.12.2007

Репутация: нет
Всего: нет



В этой статье пожалуй не хватает одного пункта
при сворачивании приложения в трей как правило его главное окно становиться недоступным, т.е. вызвать его можно только если клацнуть по иконке в трее, а если она исчезла. Да. Именно исчезла.
Такое бывает при перезагрузке Explorer'а што тогда делать.
Вызывать диспетчер задач и завершать приложение аварийно?
Непрфессионально да и неудобно, кроме того, многие программы, как-то же, с этим борятся, например, винамп или ICQ. Их значки появляються даже после сбоя. Так што вот некоторый код, который нужно добавить дабы наше приложение тоже могло в случае чего востановить свой значёк:

для этого:

1. Объявляем глобальную переменную для хранения дискриптора трея:
Код

...
private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;
  lastH:THandle;         // для работы с дискриптором трея

implementation

{$R *.dfm}
...


2. Помещаем в тело программы две функции:
Код


// две следующих процедуры комментировать не буду
// они не мои
// их задача просто определить дискриптьор трея
// необходимо скопировать их в тело программы непомредственно в это место 

function EnumChildProc(hWindow: HWND; lParam: Pointer): BOOL; stdcall; 
var 
    pszBuff: array [0..255] of char; 
    sClass, sCaption: string; 
begin 
    Result := True; 
    GetClassName(hWindow, pszBuff, SizeOf(pszBuff)); 
    sClass := pszBuff; 
    GetWindowText(hWindow, pszBuff, SizeOf(pszBuff)); 
    sCaption := pszBuff; 
    if (sClass   = 'ToolbarWindow32') and
       (sCaption = 'Notification Area') then
    begin 
        CopyMemory(lParam, @hWindow, SizeOf(HWND)); 
        Result := False; 
    end;
end;


function GetTrayToolBarHandle: HWND;
begin
    EnumChildWindows(FindWindow('Shell_TrayWnd', nil), 
                        @EnumChildProc, Integer(@Result)); 
end;



3. Добавляем на форму компонент таймер с интервалом скажем 2-3 секунды (2000-3000) 
и в его событие OnTimer
вставляем следующий код:
Код

procedure TForm1.Timer2Timer(Sender: TObject);

begin
       if lastH<>GetTrayToolBarHandle then
       begin
              with trData do
              begin
                  cbSize := SizeOf( TNotifyIconData );
                  Wnd := Form1.Handle;
                  uFlags := NIF_ICON or NIF_MESSAGE or NIF_TIP;
                  uCallbackMessage := WM_USER + 100;
                  hIcon := LoadIcon(hInstance, 'MAINICON');
                  StrPCopy(szTip,
                                'Любой текст'#10#13+
                                'Разделённый символами'#10#13+
                                'Переноса строки');
              end;
        Shell_NotifyIcon( NIM_ADD, @trData);
        // присвоение переменной lastH нового значения
        // дискриптора трея
        lastH:=GetTrayToolBarHandle;
        end;
end;


Данный код расчитан на то что вы уже умеете добавлять иконку в трей 
и знаете все стороны работы с треем и теми функциями которые приведены в примере.
Если же нет, то выкладываю исходники и екзешник
всё писано на 7 делфе со стандартными компонентами, т.е. запуститься у всех smile
С КОМЕНТАРИЯМИ
БЕЗ КОМЕНТАРИЕВ
ЭКЗЕШНИК

Это маленькая статейка на щёт работы с треем вскором времени собираюсь написать большую статью по практически всему што только можно придумать с треем
а именно там будет и то как можно заставить иконку мигать или просто менятся 
как запустить программу только в 1 экземпляре (в таких приложениях обычно это важно)
PM MAIL   Вверх
bems
Дата 13.12.2007, 21:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 3400
Регистрация: 5.1.2006

Репутация: 21
Всего: 88



skinny, перечислять окна в таймере это не способ, тк для этой цели есть предусмотренная API возможность.
В инициализации модуля сделать так:
Код

WM_TASKBARCREATED:=RegisterWindowMessage('TaskbarCreated')

где WM_TASKBARCREATED - глобальная переменная типа DWORD

В обработчике OnMessage компонента ApplicationEvents проверять код сообщения на совпадение с WM_TASKBARCREATED и если совпадает - восстанавливать иконки


--------------------
Обижено школьников: 8
PM MAIL   Вверх
skinny
Дата 14.12.2007, 08:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 7
Регистрация: 2.12.2007

Репутация: нет
Всего: нет



это философия и рассуждения
докажи што оно работает
желательно исходником
а то из-за таких умников новички бьются сутками а им тока тыкают што они тупые.
PM MAIL   Вверх
Mephisto
Дата 14.12.2007, 10:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Волкъ
***


Профиль
Группа: Завсегдатай
Сообщений: 1818
Регистрация: 27.8.2003
Где: Питер

Репутация: нет
Всего: 34



И еще один момент. Чет не могу понять, когда выключается компьютер, а в трее сидит иконка созданная по вышеописанной технологии, то выключение/перезагрузка прерывается. Т.е. сначала нужно закрыть приложение, потом перезапускать комп, иначе никак. Сам пока не разбирался, но может кто-то встречал такую фигню? 
PM   Вверх
Poseidon
Дата 14.12.2007, 11:31 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Delphi developer
****


Профиль
Группа: Комодератор
Сообщений: 5273
Регистрация: 4.2.2005
Где: Гомель, Беларусь

Репутация: 10
Всего: 133



Цитата(skinny @  13.12.2007,  21:07 Найти цитируемый пост)
т.е. вызвать его можно только если клацнуть по иконке в трее, а если она исчезла. Да. Именно исчезла.
Не разу с таким не встречался. Но даже если так, то восстанавливать иконку через таймер в 2-3 секунды тоже не профессионально, т.к. если все в порядке с иконкой, то этот таймер крутится в холостую и производит не нужную нагрузку. Из двух зол выбирают меншее, а меншее - это перезагрузить программу рас в n лет ( ведь не каждый день иконки пропадают с трея), чем каждые 2-3 секунды сканить трей на наличие иконки.

Добавлено через 4 минуты и 38 секунд
Цитата(Mephisto @  14.12.2007,  10:45 Найти цитируемый пост)
Чет не могу понять, когда выключается компьютер, а в трее сидит иконка созданная по вышеописанной технологии, то выключение/перезагрузка прерывается
Ничего не прерывется. При выключении программа получает WM_QUERYENDSESSION и завершается штатно smile



--------------------
Если хочешь, что бы что-то работало - используй написанное, 
если хочешь что-то понять - пиши сам...
PM MAIL ICQ   Вверх
Mephisto
Дата 14.12.2007, 12:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Волкъ
***


Профиль
Группа: Завсегдатай
Сообщений: 1818
Регистрация: 27.8.2003
Где: Питер

Репутация: нет
Всего: 34



Цитата(Poseidon @  14.12.2007,  12:31 Найти цитируемый пост)
Ничего не прерывется. При выключении программа получает WM_QUERYENDSESSION и завершается штатно

Не буду голословным. Как нить вынесу свой код в более-менее простенькую утилитку и выолжу сюда. Убедишьси что это не правда.  smile 
Я сам не могу понять что происходит. 
PM   Вверх
Poseidon
Дата 14.12.2007, 12:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Delphi developer
****


Профиль
Группа: Комодератор
Сообщений: 5273
Регистрация: 4.2.2005
Где: Гомель, Беларусь

Репутация: 10
Всего: 133



Цитата(Mephisto @  14.12.2007,  12:09 Найти цитируемый пост)
Убедишьси что это не правда.
В таком случае отлавливай в ручную WM_QUERYENDSESSION и завершай приложение сам smile



--------------------
Если хочешь, что бы что-то работало - используй написанное, 
если хочешь что-то понять - пиши сам...
PM MAIL ICQ   Вверх
Mephisto
Дата 14.12.2007, 14:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Волкъ
***


Профиль
Группа: Завсегдатай
Сообщений: 1818
Регистрация: 27.8.2003
Где: Питер

Репутация: нет
Всего: 34



Цитата(Poseidon @  14.12.2007,  13:14 Найти цитируемый пост)
В таком случае отлавливай в ручную WM_QUERYENDSESSION и завершай приложение сам

хм. Можно попробовать. ;)
PM   Вверх
bems
Дата 14.12.2007, 18:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 3400
Регистрация: 5.1.2006

Репутация: 21
Всего: 88



Цитата(skinny @  14.12.2007,  08:00 Найти цитируемый пост)
это философия и рассуждения
докажи што оно работает

Цитата(skinny @  14.12.2007,  08:00 Найти цитируемый пост)
а то из-за таких умников новички бьются сутками а им тока тыкают што они тупые. 

это значит "сделай за новичка"?
сам попробуй
могу немного пожевать для понятности:
Цитата(bems @  13.12.2007,  21:46 Найти цитируемый пост)
WM_TASKBARCREATED:=RegisterWindowMessage('TaskbarCreated')

функция RegisterWindowMessage регистрирует в системе новое сообщение впридачу к константам начинающимся с WM_
При этом если при двух вызовах функции (не обязательно из контекста одного процесса) переданы разные строковые аргументы - возвращается гарантировано разное значение кода сообщения. Если одинаковые строковые аргументы - гарантировано одинаковые коды сообщения. Значение нового сообщения сохраняется на интервал времени от первого вызова с такой строкой до конца сеанса. Это можно прочитать в хелпе по Win32 API который есть в Дельфи даже старых версий (в 5-ке уже есть).
А в хелпе который идет в комплекте Дельфи (200x) можно прочитать что при создании панели задач explorer вызывает RegisterWindowMessage с аргументом 'TaskbarCreated' и рассылает полученый код сообщения всем окнам верхнего уровня (не имеющим владельца).
Последняя фраза в скобках это то что я помню приблизительно и возможно это не так (лень сейчас проверять).
Если действительно нужно "без владельца" то в проге на Дельфи (где используется VCL) таким окном будет только окно с дескриптором Application.Handle. 
Если наличие владельца не важно, то сообщение получат все формы плюс Application.Handle

То есть в обоих случаях Application.Handle имеет возможyость обработать сообщение о создании панели задач. 
Для того чтобы сделать свою обработку сообщений, получаемых окном Application.Handle можно
положить на форму компонент ApplicationEvents и в обработчике его события OnMessage сделать так
Код

procedure TForm1.ApplicationEvents1Message(var Msg: tagMSG;
  var Handled: Boolean);
begin
if msg=WM_TASKBARCREATED then SetTrayIcons
end;

в этом фрагменте предполагается, что WM_TASKBARCREATED это твоя переменная (константы нет такой), что ей когда-то уже было присвоено значение, которое вернул вызов RegisterWindowMessage('TaskbarCreated') ("когда-то" означает до первого сообщения пришедшего в ApplicationEvents1Message, например в секции initialization) и что SetTrayIcons это твоя функция, создающая иконку(иконки) в трее так, как это описано в обсуждаемой статье.

Если и после этого новичку нужен какой-то код, то значит ему нужно учить синтаксис языка и учиться читать хелпы. С этим уж не ко мне.

Цитата(skinny @  14.12.2007,  08:00 Найти цитируемый пост)
докажи што оно работает


Я это видел. 
Даже в суде такая фраза считается доказательством.


--------------------
Обижено школьников: 8
PM MAIL   Вверх
skinny
Дата 15.12.2007, 08:08 (ссылка)   | (голосов:4) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 7
Регистрация: 2.12.2007

Репутация: нет
Всего: нет



именно об этом я и говорю
читать хелпы и знать синтаксисы
всегда хотел убивать тех кто так говорит
во первых хелпы на аглицком, даже знание оного не спасает меня ибо понять порой технические слова я не могу
а на щёт синтаксисов, то не все программисты закончили вузы, некоторые ваще нигде программированию не учились - это я и про себя

поэтому я почти не знаком с теорией и мне намного легче понять и осознать работающий код, а не придумать новый

когда я начализучать работу с треем в 2003 году везде была только функция и её флаги
понять "што это всё ваще значит" я никак не мог
а после того как нашол работающий пример - всё сразу стало на свои места и сейчас я пожалуй закрытыми глазамит напишу этот код
если послушать вас то выходит што подобные форумы и вообще примеры и исходники никому не нужны - пусть сами каждый раз новую функцию придумывают
я всегда когда читаю всякую философию не могу понять зачем люди сие пишут - только наверно шобы паказать собственное величие штоли над другими

форум не для филосовских рассуждений а для помощи
PM MAIL   Вверх
Scandium
Дата 16.12.2007, 13:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 5
Регистрация: 3.12.2007

Репутация: нет
Всего: нет



Цитата(skinny @ 15.12.2007,  08:08)
именно об этом я и говорю
читать хелпы и знать синтаксисы
всегда хотел убивать тех кто так говорит
во первых хелпы на аглицком, даже знание оного не спасает меня ибо понять порой технические слова я не могу
а на щёт синтаксисов, то не все программисты закончили вузы, некоторые ваще нигде программированию не учились - это я и про себя

поэтому я почти не знаком с теорией и мне намного легче понять и осознать работающий код, а не придумать новый

когда я начализучать работу с треем в 2003 году везде была только функция и её флаги
понять "што это всё ваще значит" я никак не мог
а после того как нашол работающий пример - всё сразу стало на свои места и сейчас я пожалуй закрытыми глазамит напишу этот код
если послушать вас то выходит што подобные форумы и вообще примеры и исходники никому не нужны - пусть сами каждый раз новую функцию придумывают
я всегда когда читаю всякую философию не могу понять зачем люди сие пишут - только наверно шобы паказать собственное величие штоли над другими

форум не для филосовских рассуждений а для помощи

Я тоже не оканчивал ничего по програмироанию...а чисто сам разбирался по примерам. Поэтому реально научиться по примерам с коментариями, чем по фразам типо "читай хелп и мануалы". smile 
PM MAIL   Вверх
bems
Дата 17.12.2007, 17:45 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 3400
Регистрация: 5.1.2006

Репутация: 21
Всего: 88



Цитата(skinny @  15.12.2007,  08:08 Найти цитируемый пост)
читать хелпы и знать синтаксисы
всегда хотел убивать тех кто так говорит
...
а на щёт синтаксисов, то не все программисты закончили вузы, некоторые ваще нигде программированию не учились - это я и про себя

в моем посте не хватало кода для этого:


Цитата(bems @  13.12.2007,  21:46 Найти цитируемый пост)
где WM_TASKBARCREATED - глобальная переменная типа DWORD

В обработчике OnMessage компонента ApplicationEvents проверять код сообщения на совпадение с WM_TASKBARCREATED и если совпадает - восстанавливать иконки 

это значит: чтобы написать рабочий код нужно уметь объявить глобальную переменную и создать обработчик события (имя события и имя компонента я дал).
Создание обработчика и объявления переменных это настолько начальный уровень, что объяснять это на форуме просто неприлично.

Чтобы знать как в паскале объявить переменную не нужно заканчивать ВУЗ



--------------------
Обижено школьников: 8
PM MAIL   Вверх
~FoX~
Дата 20.12.2007, 12:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


НЕ рыжий!!!
****


Профиль
Группа: Участник Клуба
Сообщений: 2819
Регистрация: 8.10.2003
Где: Зеленоград

Репутация: 0
Всего: 68



Нафиг комапненты, просто перегружаем ВинПрок и все  smile 

Код

type
  TForm1 = class(TForm)
    procedure FormCreate(Sender: TObject);
    procedure WndProc(var M: TMessage); override;
  end;

var
  Form1: TForm1;
  WM_TASKBARCREATED: cardinal;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
  WM_TASKBARCREATED:=RegisterWindowMessage('TaskbarCreated');
end;

procedure TForm1.WndProc(var M: TMessage);
begin
  if (M.Msg=WM_TASKBARCREATED) then ShowMessage('Tray created')
  else inherited WndProc(M);
end;


Это сообщение отредактировал(а) ~FoX~ - 20.12.2007, 12:24


--------------------
user posted image
…множественность никогда не следует полагать без необходимости…
PM MAIL WWW ICQ Jabber   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: WinAPI и системное программирование"
Snowybartram
MetalFanbems
PoseidonRrader
Riply

Запрещено:

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по Delphi обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи
  • 99% ответов по WinAPI можно найти в MSDN Library, оставшиеся 1% здесь

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, bartram, MetalFan, bems, Poseidon, Rrader, Riply.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: WinAPI и системное программирование | Следующая тема »


 




[ Время генерации скрипта: 0.1378 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.