Мое приложение работает так, как вы описываете. Вот подход, который я выбрал. Я хотел бы найти более простой подход, но никогда не делал.
Я начал с чтения этих статей. Это первая отличная статья Питера Белоу:
http://groups -beta.google.com / группа / borland.public.delphi.winapi / сообщ / e9f75ff48ce960eb? Гектолитров = еп
Другая информация также была найдена здесь, однако это не оказалось правильным решением: для моего использования:
http://blogs.teamb.com/DeepakShenoy/archive/2005/04/26/4050.aspx
В конце концов вот что я закончил.
Мой экран-заставка используется в качестве основной формы приложения. Основная форма имеет особую привязку к объекту приложения. Использование всех вторичных форм дает мне то поведение, которое я искал.
В каждой форме на панели задач я перезаписываю CreateParams. Я делаю это в моих формах редактирования и в том, что пользователи видят как «основную форму»
procedure TUaarSalesMain.CreateParams(var Params: TCreateParams);
begin
inherited CreateParams(Params);
Params.ExStyle := Params.ExStyle or WS_EX_APPWINDOW;
Params.WndParent := GetDesktopWindow;
end;
Моя «Основная» форма, если говорить о Delphi, загружает истинную основную форму в свою функцию Activitate. Я использую переменную-член, чтобы отслеживать первую активацию. Затем в конце функции я скрываю форму всплеска, но не закрываю ее. Это было важно для меня, потому что, если пользователь редактировал документ и закрывал основную форму, я не хотел, чтобы экраны редактирования закрывались одновременно. Таким образом, все видимые формы обрабатываются одинаково.
if FFirstActivate = false then
exit;
FFristActivate := false;
/*
Main Load code here
Update Splash label, repaint
Application.CreateForm
etc.
*/
// I can't change visible here but I can change the size of the window
Self.Height := 0;
Self.Width := 0;
Self.Enabled := false;
// It is tempting to set Self.Visible := false here but that is not
// possible because you can't change the Visible status inside this
// function. So we need to send a message instead.
ShowWindow(Self.Handle, SW_HIDE);
end;
Но есть еще проблема. Вам нужно закрыть главное окно / заставку, когда все остальные формы закрыты. У меня есть дополнительная проверка в моих процедурах закрытия для Parent <> nil, потому что я использую формы как плагины (в моих целях они работают лучше, чем фреймы).
Мне не очень понравилось использовать событие Idle, но я не замечаю, что это перетаскивание процессора.
{
TApplicationManager.ApplicationEventsIdle
---------------------------------------------------------------------------
}
procedure TApplicationManager.ApplicationEventsIdle(Sender: TObject;
var Done: Boolean);
begin
if Screen.FormCount < 2 then
Close;
end;
{
TApplicationManager.FormCloseQuery
---------------------------------------------------------------------------
}
procedure TApplicationManager.FormCloseQuery(Sender: TObject;
var CanClose: Boolean);
var
i: integer;
begin
for i := 0 to Screen.FormCount - 1 do
begin
if Screen.Forms[i] <> self then
begin
// Forms that have a parent will be cleaned up by that parent so
// ignore them here and only attempt to close the parent forms
if Screen.Forms[i].Parent = nil then
begin
if Screen.Forms[i].CloseQuery = false then
begin
CanClose := false;
break;
end;
end;
end;
end;
end;
{
TApplicationManager.FormClose
---------------------------------------------------------------------------
}
procedure TApplicationManager.FormClose(Sender: TObject;
var Action: TCloseAction);
var
i: integer;
begin
for i := Screen.FormCount - 1 downto 0 do
begin
if Screen.Forms[i] <> self then
begin
// Forms that have a parent will be cleaned up by that parent so
// ignore them here and only attempt to close the parent forms
if Screen.Forms[i].Parent = nil then
begin
Screen.Forms[i].Close;
end;
end;
end;
end;
Это до сих пор хорошо мне служило. Я сделал небольшое изменение для Vista, потому что значок для моего экрана «Main / Splash» все еще показывался. Я не помню, что это было, хотя. Возможно, мне не нужно устанавливать ширину, высоту, включать и отправлять сообщение о скрытии на заставке. Я просто хотел убедиться, что он не появился: -).
Необходимо иметь дело с событиями закрытия. Если я правильно помню, это было необходимо, когда Windows отправил сообщение о выключении. Я думаю, что только основная форма получает это сообщение.