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

Вниз

Показ формы-оповещения без фокуса   Найти похожие ветки 

 
shmelina ©   (2007-09-14 12:23) [0]

Есть такая задача.
Работает программа. В фоновом режиме она проверяет наличие некоторых событий. Если событие есть, то показывается специальная форма-оповещение. Но форма эта должна отображаться в панели задач и не должна забирать на себя фокус. Кроме того:
- если форма на заднем фоне (на главным окном), то при наступлении события она должна показываться (не беря на себя фокус опять же)
- если форма оповещения свернута, то при наступлении события она должна показываться (не беря на себя фокус)
- если форма оповещения закрыта (но висит в памяти), то при наступлении события она должна показываться (не беря на себя фокус)
- если пользователь работает в другом приложении, то при наступлении события она должна показываться (не беря на себя фокус)
- форма не должна быть модальной или иметь признак "всегда сверху"

Что пока получилось:
- В панели задачи мы сидим.
- Первый показ окна оповещения срабатывает (после Create).

Не получилось:
- Второй и следующие показы не хотят показывать окно. Оно остается на заднем фоне.

Как в панель задач пихал окно писать не буду, оно вроде понятно.

Окно оповещения создается так:
 Form.Create(nil);
Причем создается один раз и не уничтожается, пока не закроют программу. Так надо!

Показывается окно так:
 ShowWindow(Form.Handle, SW_SHOWNOACTIVATE);
 Form.Visible := True;

Первый показ происходит правильно, остальные - нет. Эксперименты с использование метода тыка не помогли.

Помогите пожалуйста.


 
Lacmus ©   (2007-09-14 13:40) [1]

Как форма скрывается ?


 
shmelina ©   (2007-09-14 14:35) [2]

Close;


 
Lacmus ©   (2007-09-14 14:44) [3]



procedure TForm57.Button1Click(Sender: TObject);
begin
 ShowWindow(Form58.Handle, SW_SHOWNOACTIVATE);
 Form58.Visible := True
end;

procedure TForm57.Button2Click(Sender: TObject);
begin
 Form58.Close
end;



Проблем нет


 
shmelina ©   (2007-09-14 14:53) [4]

Ты показываешь окно по кнопке ИЗ СВОЕГО ПРИЛОЖЕНИЯ. А ты подцепи таймер - пусть само показывается. И не забудь в другое приложение переключиться.

Окно оповещения должно появляться в какой программе вы бы не находились!


 
Lacmus ©   (2007-09-14 16:05) [5]



procedure TForm57.Timer1Timer(Sender: TObject);
begin
 AttachThreadInput(GetWindowThreadProcessId(GetForegroundWindow, nil),
                            GetWindowThreadProcessId(Form58.Handle, nil), True);
 SetWindowPos(Form58.Handle, HWND_TOP, 0, 0, 0, 0,
      SWP_NOMOVE or SWP_NOSIZE or SWP_SHOWWINDOW or SWP_NOACTIVATE);
 Form58.Visible := True;
end;

{ unit Unit58 }

...
   procedure CreateParams(var aParams: TCreateParams); override;
 end;

var
 Form58: TForm58;

implementation

{$R *.dfm}

procedure TForm58.CreateParams(var aParams: TCreateParams);
begin
 inherited;
 aParams.WndParent := GetDesktopWindow
end;



Хотя тоже есть некоторые проблемы, но условия shmelina ©   (14.09.07 12:23)  вроде выполняются.


 
shmelina ©   (2007-09-14 16:41) [6]

Спасибо! У меня тоже получилось, но несколько по другому сделано:


 SetWindowPos(Form.Handle, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE or SWP_NOSIZE or SWP_NOACTIVATE or SWP_SHOWWINDOW or SWP_NOOWNERZORDER);
 SetWindowPos(Form.Handle, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE or SWP_NOSIZE or SWP_NOACTIVATE or SWP_SHOWWINDOW or SWP_NOOWNERZORDER);
 AlarmForm.Visible := True;


Однако есть еще проблема (у тебя и у меня):
Находясь в другом приложение появляется (без фокуса) форма оповещения. Но при закрытии ее крестиком всплывает приложение от оповещения.

Как быть?


 
Котик Б   (2007-09-14 16:53) [7]

А не проще ли сделать tray + hint ?


 
Anatoly Podgoretsky ©   (2007-09-14 16:57) [8]

> Котик Б  (14.09.2007 16:53:07)  [7]

> А не проще ли сделать tray + hint ?

BallonHint


 
shmelina ©   (2007-09-14 17:02) [9]

Может и проще. Но переделок много.
В принципе полученного результата по минимуму хватает. Можно не нажимать крестик, а сворачивать оповещение. Так вроде все работает как надо. Если с крестиком не победим, то оставлю как есть =(.


 
Lacmus ©   (2007-09-14 17:07) [10]


procedure WMMouseActivate(var aMessage: TMessage); message WM_MOUSEACTIVATE;

procedure TForm58.WMMouseActivate(var aMessage: TMessage);
begin
 aMessage.Result := MA_NOACTIVATE
end;



 
shmelina ©   (2007-09-14 17:38) [11]

Теперь при клике на заготовок формы58 рамка не отображает фокус.
А если кликнуть на саму форму, то фокус ловится, но при закрытии крестиком опять приложение оповещения появляется.


 
Lacmus ©   (2007-09-14 17:58) [12]

Еще вариант

{ unit58 }

implementation

{$R *.dfm}

procedure TForm58.FormCreate(Sender: TObject);
begin
 ParentWindow := GetDesktopWindow
end;

end.


 
shmelina ©   (2007-09-17 14:21) [13]

Спасибо, осталось совсем чуть-чуть. =)
При клике на форму оповещения (не на заголовок, а на саму форму!) она не ловит фокус.


 
shmelina ©   (2007-09-17 14:44) [14]

Кстати, на тестовом приложении с пустыми формами после закрытия оповещения фокус возвращается приложению, в котором я работал. А в реальной программе - нет =(. Но все равно спасибо за помощь. В любом случае лучше стало, чем было.


 
Lacmus ©   (2007-09-17 14:52) [15]

Считаем, что фокус все-таки нужен



   FSaveForeground: THandle;
 public
   { Public declarations }
   procedure CreateParams(var aParams: TCreateParams); override;
   procedure ShowByEvent;
 end;

var
 Form58: TForm58;

implementation

{$R *.dfm}

procedure TForm58.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
begin
 if IsWindow(FSaveForeground) then begin
   AttachThreadInput(GetWindowThreadProcessId(Handle, nil),
                     GetWindowThreadProcessId(FSaveForeground, nil), True);
   SetForegroundWindow(FSaveForeground)
 end
end;

procedure TForm58.CreateParams(var aParams: TCreateParams);
begin
 inherited;
 aParams.WndParent := GetDesktopWindow
end;

procedure TForm58.ShowByEvent;
begin
 FSaveForeground := GetForegroundWindow;
 AttachThreadInput(GetWindowThreadProcessId(FSaveForeground, nil),
                            GetWindowThreadProcessId(Handle, nil), True);
 SetWindowPos(Handle, HWND_TOP, 0, 0, 0, 0,
      SWP_NOMOVE or SWP_NOSIZE or SWP_SHOWWINDOW or SWP_NOACTIVATE);
 Visible := True;
end;



 
shmelina ©   (2007-09-17 14:58) [16]

Хотя нет, торможу. Все работает почти как надо. Только при сворачивании оповещения появляется приложение оповещения.


 
shmelina ©   (2007-09-17 15:15) [17]

Все, разобрался. Спасибо!


 
shmelina ©   (2007-09-17 15:29) [18]

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

 if IsWindow(FSaveForeground) then
 begin
{    AttachThreadInput(
     GetWindowThreadProcessId(Handle, nil),
     GetWindowThreadProcessId(FSaveForeground, nil),
     True); }

   SetForegroundWindow(FSaveForeground)
 end;



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

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

Наверх




Память: 0.49 MB
Время: 0.128 c
2-1190098194
artem779
2007-09-18 10:49
2007.10.14
проблема с *.INI


2-1190004580
GeLLeR
2007-09-17 08:49
2007.10.14
Сообщение нажатия кнопки


15-1189892059
me
2007-09-16 01:34
2007.10.14
Неустойчивость пузырьковой сортировки


4-1176455742
Серге И
2007-04-13 13:15
2007.10.14
Как получить список административных ресурсов компьютера в сети.


3-1180362429
makvell
2007-05-28 18:27
2007.10.14
Какие компоненты использовать





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский