Как узнать есть ли форма.
TMyForm *MyForm;
...Button1Click(TObject *Sender)
{
if(/*здесь должна быть проверка на существование*/)
MyForm = new TMyForm(this);
MyForm->Show();
}
MyForm - дочерняя форма MDI-приложения. На OnClose у неё Action = caFree, т.е. при закрытии форма уничтожается. Надо как то проверить перед созданием формы, а не создана ли она уже? А то получается несколько одинаковых форм. FindWindow не подходит. Делать по созданию недоступной кнопку, а при уничтожении открывать к ней доступ тоже нельзя. Может есть у кого мысли?
if(!MyForm)
MyForm = new TMyForm(Application);
else
MyForm->Show();
я в подобных ситуациях после Action = caFree пишу еще MyForm = NULL, а при попытке повторного создания:
if(!MyForm)
MyForm = new TMyForm(Application);
else
MyForm->Show();
Да, я так тоже сделал. Но хотелось знать нельзя ли по другому отловить?
Да, я так тоже сделал. Но хотелось знать нельзя ли по другому отловить?
Хех, ну если MDI приложение то что мешает тебе создавать в меню "Окно" пункт меню с названием совпадающим с Caption данной MDI формы, и перед ее созданием проверять на наличие сего пункта???
Или другой вариант. Более экстремальный но и более правильный чтоли - Mutex.
еще у формы есть такие свойства:
MDIChildCount
MDIChildren
может они тебе помогут...
А как сделать так, чтобы дополнительная форма создавалась один раз через (MyForm = new TMyForm(Application)), а потом просто показывалась (MyForm->Show()) или скрывалась(???), при этом не удаляя ее через delete ?
Я меню гружу из БД. А формы из dll. из главной проги для создания соответстующего окна вызываю функцию:
void __fastcall TfrmMain::DllMenuClick(TObject * Sender)
{
AnsiString A,S = ((TMenuItem*)Sender)->Name;
typedef AnsiString (__import *Prop)();
typedef HWND (__import *Sh)(AnsiString &Capt, void *Conn);
Prop MyProp;
Sh ShowMy;
HINSTANCE Dll;
for (int i = 0; i < Dlls->Count; i++)
{
Dll = LoadLibrary(Dlls->Strings.c_str());
if(Dll != NULL)
{
MyProp = (Prop)GetProcAddress(Dll,"_ReturnProperty");
A = MyProp();
}
if (S != A)
{
FreeLibrary(Dll);
}
else
{
ShowMy = (Sh)GetProcAddress(Dll,"_ShowDllForm");
AnsiString B = ((TMenuItem*)Sender)->Caption;
HWND in;
ShowMy(B,MTODm->ADOConnection1);
break;
}
}
}
А в dll у меня соответственно написано:
AnsiString ReturnProperty()
{
return Name;
}
//---------------------------------------------------------------------------
HWND ShowDllForm(AnsiString &Capt, void *AC)
{
if(Application->MainForm->Menu->Items->Find("Окна")->Find(Capt))
{
ShowWindow(FindWindow("TfrmProjectMTO",Capt.c_str()),SW_SHOW);
SetForegroundWindow(FindWindow("TfrmProjectMTO",Capt.c_str()));
return 0;
}
else{
TfrmProjectMTO *ProjectMTO = new TfrmProjectMTO(Application, AC, Capt);
ProjectMTO->Show();
return ProjectMTO->Handle;
}
}
Ну и при создании основного окна плугина(dll) естественно делаю:
1) в конструкторе:
__fastcall TfrmProjectMTO::TfrmProjectMTO(TComponent* Owner, void *AC, AnsiString &Capt)
: TForm(Owner)
{
this->Caption = Capt;
DM = new TDMod(this, AC);
}
2) При создании формы:
void __fastcall TfrmProjectMTO::FormCreate(TObject *Sender)
{
DataSource1->DataSet = ((TDMod*)DM)->aspReturnProj;
((TDMod*)DM)->aspReturnProj->Open();
void* AddrProc = Application->MainForm->MethodAddress("OnWindClick");
TMethod Method;
Method.Data = this;
Method.Code = AddrProc;
AnsiString S = this->Caption;
TMenuItem *Item = NewItem(S,NULL,true,true,*(TNotifyEvent*)&Method,0,ClassName(this->ClassType()));
TMenuItem *Wind = new TMenuItem(0);
Wind = Application->MainForm->Menu->Items->Find("Окна");
for(int i = 0; i < Wind->Count; i++)
{
Wind->Items->Checked = false;
}
Wind->Add(Item);
Wind = NULL;
Item = NULL;
delete Wind;
delete Item;
}
3) При закрытии формы:
void __fastcall TfrmProjectMTO::FormClose(TObject *Sender,
TCloseAction &Action)
{
((TDMod*)DM)->aspReturnProj->Close();
AnsiString String;
String = this->Caption;
((TDMod*)DM)->aspRetZayaMTO->Close();
TMenuItem *Wind = new TMenuItem(0);
Wind = Application->MainForm->Menu->Items->Find("Окна")->Find(this->Caption);
delete Wind;
this->Release();
}
И так для всех dll. если заметили то при добавлении пункта в меню окна (В создании формы) для OnClick назначаю метод OnWindClick главной формы приложения который выглядит как:
void __fastcall TfrmMain::OnWindClick(TObject * Sender)
{
ShowWindow(FindWindow(((TMenuItem*)Sender)->Name.c_str(),((TMenuItem*)Sender)->Caption.c_str()),SW_SHOW);
SetForegroundWindow(FindWindow(((TMenuItem*)Sender)->Name.c_str(),((TMenuItem*)Sender)->Caption.c_str()));
}
Ну вот собсно и все.
можно и попроще - в событии OnClose прописать Action = caHide
У меня способ универсальнее. То есть в главной проге я всего лишь провожу авторизацию и гружу меню из БД. а также подгружаю плугины по требованию.
А дальше пишу плугин с указанными двумя функциями для его вызова. Плюс в БД добавляю новый пункт меню.
Потому главный модуль я уже забыл когда трогал. он у всех юзеров стоит и пашет. Если что-то надо новое то просто пишу плугин, выкладываю его на сервер и все. А главный модуль уже сам заморачивается с проверкой версий плугинов их подгрузкой и так далее.
Естественно что в главном модуле еще реализованно добавление юзеров и расстановка их прав. А так же добавление новых пунктов меню.