Форум: "Начинающим";
Текущий архив: 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