Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 2002.10.28;
Скачать: [xml.tar.bz2];

Вниз

Окошко, не желающее становиться активным   Найти похожие ветки 

 
Jel   (2002-10-15 17:24) [0]

Проблема проста до идиотизма. Сворачиваю программку в трей, обрабатывая WM_SysCommand. То бишь прячу форму и кнопку на таскбаре. Потом из обработчика NotifyIcon пытаюсь развернуть обратно. Результат - окошко восстанавливается но не на переднем плане а за остальными окнами. Нужно вытащить его наверх. Пишу


if a.LParam = 514 then begin // знаю - константа в тексте некрасиво (это отпускание левой кнопки мыши)
TrayHideIcon; // здесь убираю иконку из трея
ShowWindow(Application.Handle, SW_SHOWNORMAL);
ShowWindow(handle, SW_SHOWNORMAL);
SetForegroundWindow(handle); // а вот тут - только начинает мигать кнопка на таскбаре - окно не всплывает!
// SetWindowPos(Handle, HWND_TOP, 0,0,0,0, SWP_NOSIZE + SWP_NOMOVE); // пробовал еще так
// BringWindowToTop(handle); // и вот так
// SendMessage(handle, WM_SYSCOMMAND, SC_RESTORE, 0); // и сяк - результат нулевой
end;
a.Result := 0;


Где грабли-то? Чего я не сделал или сделал не так?
Заранее спасибо.


 
Song   (2002-10-15 19:48) [1]

WM_NULL надо передавать. Смотри подробней здесь: http://pascal.sources.ru/cgi-bin/forum/YaBB.cgi?board=delphi;action=display;num=1020241631;start=11


 
Kibitzer   (2002-10-16 00:09) [2]

Ещё посмотри здесь: http://delphibase.endimus.ru/?action=viewfunc&topic=appctrl&id=10031


 
Jel   (2002-10-16 10:06) [3]


> WM_NULL надо передавать. (C) Song.


Куда передавать? Можно поподробнее? В указанном Вами источнике ссылки на эту константу отсутствуют.

В дополнение - выяснил что приведенный мной кусок кода не работает в обработчике сообщения, но прекрасно работает будучи повешенным на пункт pop-up-а (который вызывается из того же обработчика сообщения.) Кто-нибудь может это прокоментировать?


 
Song   (2002-10-16 10:07) [4]

В том топике что я привёл WM_NULL передаётся после нажатия на значок в трее. Плохо искали.


 
Jel   (2002-10-16 10:16) [5]

Да, Вы правы. Извините за излишнюю поспешность, однако проблемы это не решает. И, кстати, если не затруднит, объясните пожалуйста почему недостаточно просто присвоить

msg.result := 0;

для индикации завершения обработки сообщения. И что даст вызов

PostMessage(Handle,WM_NULL,0,0)?


 
Song   (2002-10-16 10:22) [6]

Вы сделайте всё как там написано и у_Вас_всё_будет_работать


 
Zemal   (2002-10-16 10:22) [7]



procedure TfmMain.AppMinimize(Sender: TObject);
begin
ShowWindow(Application.Handle, SW_HIDE);
end;

procedure TfmMain.AppRestore(Sender: TObject);
begin
ShowWindow(Application.Handle, SW_SHOW);
SetForegroundWindow(Application.Handle);
end;

procedure TfmMain.TrayIconClick(Sender:TObject;
Button:TMouseButton; Shift:TShiftState; X,Y:Integer);
begin
Application.Restore;
end;



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


 
Song   (2002-10-16 10:30) [8]

Потому что Вы используете компонент, а в нём это уже реализовано.


 
Jel   (2002-10-16 10:35) [9]

Спасибо всем за ответы.

Попробую воспользоваться советом и перепишу код, как советует Song.


 
Zemal   (2002-10-16 10:47) [10]

>>Song
Спасибо. Действительно, чтобы не мучаться с размещением иконки в трее и неписать лишкего кода, от лени своей просто бросил RxTrayIcon на форму и обработал события сворачивания-разворачивания... в общем-то и так заработало... а щас слазию посмотрю в исходники где этот WM_NULL посылается :). Спасибо, что натолкнул :).


 
Zemal   (2002-10-16 10:59) [11]

>>Song
Я чего-то непойму...

TRxTrayIcon = class(TComponent)
private
...
FOnClick: TMouseEvent;
...
published
...
property OnClick: TMouseEvent read FOnClick write FOnClick;
...
end;

Где он посылает сообщения окну?! В этом коде видно только обработчик события мышиного клика по иконке, которое я использую для востановления окна (Application.Restore). Нифига он ничего непосылает! И без WM_NULL всё работает без заморочек и глюков. В чём дело? Кто тогда посылает этот "нуль" окну?


 
Zemal   (2002-10-16 11:02) [12]

Могу выложить всё описание класса TRxTrayIcon... оно небольшое... в одной месаге поместится... и во всей реализации класса нет ниодной функции, шлющей сообщение окну.


 
Song   (2002-10-16 11:10) [13]

Пошлите мне на почту исходник, я гляну, Вам отпишу


 
Zemal   (2002-10-16 11:16) [14]

ок


 
Separator   (2002-10-16 11:25) [15]

Он и не посылает, сам по себе RxTrayIcon на событие OnClick ничего не делат. Но ты ведь сначала бросаешь компонент на форму, а потом сам и создаешь обрабочик события


 
Zemal   (2002-10-16 11:31) [16]

>>Separator
Вот о чём я и говорю!!! Я же привожу код из своей прилаги, которая сворачивается в трей и прячет кнопаню в таскбаре. Причём я непосылаю форме никаких WM_NULL и всё прекрасно и без глюков работает. Вот в чём фишка-то! Сворачивается... и разворачивается... сворачивается... и выходит... входит... и выходит... :)


 
Jel   (2002-10-16 11:43) [17]

>> Song

Реализовал все как Вы описали. Результат такой же как у моего кода - из менюшки - пожалуйста, а вот по левому клику - восстанавливается, но НЕ поверх других окон.

Хотелось бы уточнить, вы тестировали приведенный код или работать он должен теоретически? Или же такое странное поведене окна наблюдается только на моей версии Delphi 6.0 (Build 6.163)?



 
Song   (2002-10-16 11:46) [18]

2Jel © (16.10.02 11:43)
У Вас w2k ?


 
Jel   (2002-10-16 11:47) [19]

>> Song

Пробовал на 2к и на 98se


 
Zemal   (2002-10-16 11:53) [20]

У меня, кстати, тоже Delphi 6.0 (Build 6.163) и Win 2000 Server sp2.
>>Jel
Смотри мой код:

procedure TfmMain.FormCreate(Sender: TObject);
begin
Application.OnMessage := AppMessage;
Application.OnMinimize := AppMinimize;
Application.OnRestore := AppRestore;
end;

procedure TfmMain.AppMinimize(Sender: TObject);
begin
ShowWindow(Application.Handle, SW_HIDE);
end;

procedure TfmMain.AppRestore(Sender: TObject);
begin
ShowWindow(Application.Handle, SW_SHOW);
SetForegroundWindow(Application.Handle);
end;

procedure TfmMain.RxTrayIcon1Click(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
Application.Restore;
end;

Этот код работает корректно. Как часики :). Правда я использовал трейикон из RX, но в исходниках класса TRxTrayIcon я ненашол ниодной функции работы с окном... она вообще неработает с окном (просто вешает иконку в трей и предоставляет различные события мышки). Всё работает безо всяких посылок WM_NULL. Почему? А сам незнаю... просто работает :).


 
Song   (2002-10-16 11:54) [21]

У меня в W98se работает отлично, по крайней мере у меня.
Начиная с w2k проблема начинается из-за выделенной строчки.
...
WM_RBUTTONUP: {Действия, выполняемый по одинарному щелчку правой кнопки мыши}
Begin
SetForegroundWindow(Handle);
PopupMenu1.Popup(p.X,p.Y);
...


Дело в том, что MS изменило работу SetForeGroundWindow(), чтобы не мешать программе, имеющий фокус ввода тем что на передний план выведется программа из трея. Например, представьте, что Вы что-то набираете в ворде и вдруг чего-то выплывает на передний план и, если Вы не смотрели на экран (так некоторые делают), когда набирали, Вы нажали много кнопок впустую. Такое поведение было введено специально.
Изменить эту фишку можно несколькими способами. Один из них есть в UBPFD. А вообще Вы можете кое-что почитать об этом здесь: http://delphi.mastak.ru/cgi-bin/forum.pl?look=1&id=1034681936&n=5


 
Jel   (2002-10-16 11:56) [22]

Видимо придется пойти по этому пути и использовать RXLib. А казалось все так просто, зачем вешать еще один компонент... :)


 
Zemal   (2002-10-16 12:07) [23]

>>Jel
Зачем тебе RxLib? Ты можешь вешать значёк в трей и ручками! Я же написал, что RxTrayIcon никак с окном неработает!!! Единственно, что тебе надо, так это обработать клик мышки по иконке в трее. И всё будет работать, но как пишет Song, будет работать только под Win2k. Теперь понятно?


 
Jel   (2002-10-16 12:19) [24]

Нашел!!!!

Все не просто, а очень просто

ShowWindow(Application.Handle, SW_SHOW);
ShowWindow(handle, SW_SHOW);

Причем именно SW_SHOW, а не SW_SHOWNORMAL !!!

Вот они, грабли-то!!!
И никаких вызовов WinApi не нужно.


 
Zemal   (2002-10-16 12:20) [25]

Только прошу обратить внимание, что я мессагу шлю не окну (Handle), а объекту Application.


 
Zemal   (2002-10-16 12:23) [26]

>>Jel
Поздравляю! :)


 
Song   (2002-10-16 12:42) [27]

>>Все не просто, а очень просто
Вы имеет ввиду SW_SHOW на событиий WM_LBUTTONUP ?


 
Zemal   (2002-10-16 13:08) [28]

>>Song
Именно так :). По этому событию и надо делать Application.Restore, а в событиях Application.OnMinimize и Application.OnRestore делать так:

Application.OnMinimize >>
ShowWindow(Application.Handle, SW_HIDE);

Application.OnRestore >>
ShowWindow(Application.Handle, SW_SHOW);
SetForegroundWindow(Application.Handle);

И всё работает, под Win2k по крайней мере работает :). Под 98 незнаю... возможно и небудет :(.


 
Zemal   (2002-10-16 13:15) [29]

Application.OnMinimize >>
ShowWindow(Application.Handle, SW_HIDE); {сворачивается окно самостоятельно и нечего в это вмешиваться, а эта процедура скрывает кнопаню в таскбаре :) }

Application.OnRestore >>
ShowWindow(Application.Handle, SW_SHOW); {при разворачивании окна, показываем кнопаню в таскбаре}
SetForegroundWindow(Application.Handle); {а эта процедура делает приложение активным и показывает его :) }


 
Song   (2002-10-16 13:18) [30]

Просто у нас разные методики. Вы прячете в таскбар (т.е. минимизируете попросту говоря), а потом скрываете саму кнопку. А я ничего не мимизирую, а просто прячу и окно и кнопку. Кстати, спасибо, нашёл, ошибку в той "статейке" благодаря этому обсуждению.


 
Zemal   (2002-10-16 13:25) [31]

>>Song
Рад был посодействовать! :)



Страницы: 1 вся ветка

Форум: "Основная";
Текущий архив: 2002.10.28;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.52 MB
Время: 0.008 c
14-92655
Cr@sh
2002-10-06 10:44
2002.10.28
Где можно найти хороший бесплатный форум?


7-92760
Metallica
2002-08-05 19:32
2002.10.28
Как заблокировать клавиатуру.


4-92803
Alek Aaz
2002-09-17 08:19
2002.10.28
Ресурс занят


14-92718
mifi
2002-10-08 19:30
2002.10.28
как получить список всех накопителей


1-92607
mafiya
2002-10-17 10:43
2002.10.28
Информация о CD-ROM диске





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский