С++ Builder/Delphi Несколько верхних (top) окон в приложении (и на панели задач)

Чтобы окно показывалось в панели задач (task panel) необходимо поставить ему соответствующие аттрибуты и назначить родителем десктоп: (Написано по мотивам примера для Delphi http://blogs.teamb.com/deepakshenoy/archive/2005/04/26/4050.aspx) Для каждой формы верхнего уровня перегружаем виртуальую функцию

void __fastcall CreateParams(TCreateParams &Params);

...

В реализации функции добавляем атрибут WS_EX_APPWINDOW и родительское окно - десктоп

void __fastcall TForm1::CreateParams(TCreateParams &Params){

TCustomForm::CreateParams(Params);

Params.ExStyle = Params.ExStyle | WS_EX_APPWINDOW;

Params.WndParent = GetDesktopWindow();

}

Чтобы в панели задач не показывалось фективное окно приложения до в файле проекта до стандартного вызова

Application->Initialize();

убираем у приложения флаг WS_EX_APPWINDOW

WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int) {

try {

long exStyle = GetWindowLong(Application->Handle,GWL_EXSTYLE);

exStyle = exStyle &~WS_EX_APPWINDOW| WS_EX_TOOLWINDOW;

SetWindowLong(Application->Handle, GWL_EXSTYLE, exStyle);

Application->Initialize();

...

}

В таком режиме (в отличие от варианта с одним гавным окном) откроются сразу все окна верхнего уровня. Чтобы этого не произошло достаточно создавать вторичные формы динамически либо выключить атрибут Visible = false для форм, которые не нужны при запуске (потом можно показывать их --Form2->Show();)

С главной формой возникает одна проблема - TApplication обрабатывает ее сообщения минимизации WM_MINIMIZE,WM_RESTORE, WM_MAXIMIZE.

При стиле WS_EX_TOOLWINDOW обработки этих сообщений не происходит. Чтобы главное (первое) окно обрабатывало такие сообщение необходимо реализовать и зарегистрировать соответствующюю функцию:

TMainForm: public TForm {

...

void __fastcall OnSysCommand(TWMSysCommand &Message);

BEGIN_MESSAGE_MAP

VCL_MESSAGE_HANDLER(WM_SYSCOMMAND, TWMSysCommand, OnSysCommand)

END_MESSAGE_MAP(TForm)

}

//Внимание END_MESSAGE_MAP(TForm) - должен быть указан именно родительский класс

void __fastcall TFormStart::OnSysCommand(Messages::TWMSysCommand &Message) {

switch(Message.CmdType) {

case 0xF093: //SysMenu

Message.Result = 0; break;

case SC_CLOSE:

case 0xF063: //Close on double click

Close();

Message.Result = 0;

Application->Terminate();

break;

case SC_MINIMIZE:

::ShowWindow(this->Handle, SW_MINIMIZE);

Message.Result = 0;

break;

case 0xF122: //Double click on cation

case SC_RESTORE:

::ShowWindow(this->Handle, SW_RESTORE);

Message.Result = 0;

break;

case 0xF032://Double click on cation

case SC_MAXIMIZE:

::ShowWindow(this->Handle, SW_MAXIMIZE);

Message.Result = 0;

break;

case 0xF012: //click on caption

Message.Result = 0;

break;

default:

Message.Result = 0;

break;

}

}