#include <common/mdifrm.hpp>
#include <common/mdiwin.hpp>
#include <common/instance.hpp>
#include <common/dde.hpp>
#include <common/mmsystem.hpp>
#include <common/string.hpp>
#include <common/rect.hpp>

FrameWindow::FrameWindow(void)
{
  mDestroyHandler.setCallback(this,&FrameWindow::destroyHandler);
	mMDIActivateHandler.setCallback(this,&FrameWindow::mdiActivateHandler);
	mCommandHandler.setCallback(this,&FrameWindow::commandHandler);
	insertHandler(VectorHandler::MDIActivateHandler,&mMDIActivateHandler);
	insertHandler(VectorHandler::CommandHandler,&mCommandHandler);
}

FrameWindow::FrameWindow(const FrameWindow &frameWindow)
{ // private implementation
  *this=frameWindow;
	mDestroyHandler.setCallback(this,&FrameWindow::destroyHandler);
	mMDIActivateHandler.setCallback(this,&FrameWindow::mdiActivateHandler);
	mCommandHandler.setCallback(this,&FrameWindow::commandHandler);
	insertHandler(VectorHandler::MDIActivateHandler,&mMDIActivateHandler);
	insertHandler(VectorHandler::CommandHandler,&mCommandHandler);
}

FrameWindow::~FrameWindow()
{
  removeHandler(VectorHandler::MDIActivateHandler,&mMDIActivateHandler);
	removeHandler(VectorHandler::CommandHandler,&mCommandHandler);
}

FrameWindow &FrameWindow::operator=(const FrameWindow &/*frameWindow*/)
{ // private implentation
  return *this;
}

void FrameWindow::createWindow(const String &className,const String &windowName,const String &menuName,const String &iconName)
{
  HINSTANCE hInstance(processInstance());
	mFrameMenu=menuName;
  registerClass(hInstance,className,iconName);
//	GUIWindow::createWindow(className,windowName,WS_OVERLAPPEDWINDOW|WS_CLIPCHILDREN,Rect(CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT),0,mFrameMenu,hInstance,(LPSTR)this);
	GUIWindow::createWindow(className,windowName,WS_OVERLAPPEDWINDOW,Rect(CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT),0,mFrameMenu,hInstance,(LPSTR)this);
	show(SW_SHOW);
	update();
}

void FrameWindow::registerClass(HINSTANCE hInstance,const String &className,const String &iconName)
{
  WNDCLASS wndClass;

  if(::GetClassInfo(hInstance,(char*)(String&)className,&wndClass))return;
  wndClass.style         =CS_HREDRAW|CS_VREDRAW;
  wndClass.lpfnWndProc   =(WNDPROC)FrameWindow::FrameProc;
  wndClass.cbClsExtra    =0;
  wndClass.cbWndExtra    =sizeof(FrameWindow*);
  wndClass.hInstance     =hInstance;
  wndClass.hIcon         =::LoadIcon(hInstance,iconName);
  wndClass.hCursor       =::LoadCursor(NULL,IDC_ARROW);
  wndClass.hbrBackground =(HBRUSH)(COLOR_WINDOWFRAME);
  wndClass.lpszMenuName  =0;
  wndClass.lpszClassName =(char*)(String&)className;
	preRegister(wndClass);
  ::RegisterClass(&wndClass);
}

void FrameWindow::createMDIClientWindow(void)
{
  CLIENTCREATESTRUCT clientCreate;
	PureMenu subMenu;

  clientCreate.hWindowMenu=(HMENU)subMenu;
  clientCreate.idFirstChild=IDFirstMDIChild;
	mClientWnd.createWindow("MDICLIENT",String(),WS_CHILD|WS_CLIPCHILDREN|WS_VISIBLE|MDIS_ALLCHILDSTYLES,Rect(0,0,0,0),*this,(HMENU)0,processInstance(),(CLIENTCREATESTRUCT *)&clientCreate);
}

void FrameWindow::insert(MDIWindow &mdiWindow)
{
  mDocuments.insert(&SmartPointer<MDIWindow>(&mdiWindow));
	mDocuments[mDocuments.size()-1].disposition(PointerDisposition::Delete);
	mDocuments[mDocuments.size()-1]->insertHandler(VectorHandler::DestroyHandler,&mDestroyHandler);
}

MDIWindow &FrameWindow::operator[](int itemIndex)
{
  return *(mDocuments[itemIndex]);
}

int FrameWindow::size(void)const
{
  return mDocuments.size();
}

int FrameWindow::windowProcedure(HWND hWnd,WORD message,WPARAM wParam,LPARAM lParam)
{
  watchDocumentWindows();
  if(message>=WM_USER&&message<=0x7FFF)
	{
    if(!installedHandlers(VectorHandler::UserHandler))return ::DefWindowProc(hWnd,message,wParam,lParam);
		return callHandlers(VectorHandler::UserHandler,CallbackData(message,lParam,hWnd));
	}
	switch(message)
	{
    case WM_CLOSE :
			if(!installedHandlers(VectorHandler::CloseHandler))return ::DefFrameProc(hWnd,mClientWnd,message,wParam,lParam);
			return callHandlers(VectorHandler::CloseHandler,CallbackData(wParam,lParam,hWnd));
		case WM_NCCREATE :
			if(!installedHandlers(VectorHandler::NCCreateHandler))return ::DefFrameProc(hWnd,mClientWnd,message,wParam,lParam);
			return callHandlers(VectorHandler::NCCreateHandler,CallbackData(wParam,lParam,hWnd));
		case WM_CHANGECBCHAIN :
			if(!installedHandlers(VectorHandler::ChangeCBChainHandler))return ::DefFrameProc(hWnd,mClientWnd,message,wParam,lParam);
			return callHandlers(VectorHandler::ChangeCBChainHandler,CallbackData(wParam,lParam,hWnd));
		case WM_DRAWCLIPBOARD :
			if(!installedHandlers(VectorHandler::DrawClipboardHandler))return ::DefFrameProc(hWnd,mClientWnd,message,wParam,lParam);
			return callHandlers(VectorHandler::DrawClipboardHandler,CallbackData(wParam,lParam,hWnd));
		case WM_CREATE :
		  createMDIClientWindow();
			if(!installedHandlers(VectorHandler::CreateHandler))return ::DefFrameProc(hWnd,mClientWnd,message,wParam,lParam);
			return callHandlers(VectorHandler::CreateHandler,CallbackData(wParam,lParam,hWnd));
		case WM_PAINT :
			if(!installedHandlers(VectorHandler::PaintHandler))return ::DefFrameProc(hWnd,mClientWnd,message,wParam,lParam);
			return handlePaintMessage(hWnd,message,wParam,lParam);
		case WM_ERASEBKGND :
		  if(!installedHandlers(VectorHandler::EraseBackgroundHandler))return ::DefFrameProc(hWnd,mClientWnd,message,wParam,lParam);
			return callHandlers(VectorHandler::EraseBackgroundHandler,CallbackData(wParam,lParam,hWnd));
		case WM_PALETTECHANGED :
		  if(!installedHandlers(VectorHandler::PaletteChangedHandler))return ::DefFrameProc(hWnd,mClientWnd,message,wParam,lParam);
			return callHandlers(VectorHandler::PaletteChangedHandler,CallbackData(wParam,lParam,hWnd));
		case WM_DRAWITEM :
			if(!installedHandlers(VectorHandler::DrawItemHandler))return ::DefFrameProc(hWnd,mClientWnd,message,wParam,lParam);
			return callHandlers(VectorHandler::DrawItemHandler,CallbackData(wParam,lParam,hWnd));
		case WM_TIMER :
			if(!installedHandlers(VectorHandler::TimerHandler))return ::DefFrameProc(hWnd,mClientWnd,message,wParam,lParam);
			return callHandlers(VectorHandler::TimerHandler,CallbackData(wParam,lParam,hWnd));
		case WM_CHAR :
			if(!installedHandlers(VectorHandler::CharHandler))return ::DefFrameProc(hWnd,mClientWnd,message,wParam,lParam);
			return callHandlers(VectorHandler::CharHandler,CallbackData(wParam,lParam,hWnd));
		case WM_COMMAND :
			if(!installedHandlers(VectorHandler::CommandHandler))return ::DefFrameProc(hWnd,mClientWnd,message,wParam,lParam);
			callHandlers(VectorHandler::CommandHandler,CallbackData(wParam,lParam,hWnd));
			return ::DefFrameProc(hWnd,mClientWnd,message,wParam,lParam);
		case WM_COMPACTING :
			if(!installedHandlers(VectorHandler::CompactingHandler))return ::DefFrameProc(hWnd,mClientWnd,message,wParam,lParam);
			return callHandlers(VectorHandler::CompactingHandler,CallbackData(wParam,lParam,hWnd));
		case WM_WININICHANGE :
			if(!installedHandlers(VectorHandler::WinIniChangeHandler))return ::DefFrameProc(hWnd,mClientWnd,message,wParam,lParam);
			return callHandlers(VectorHandler::WinIniChangeHandler,CallbackData(wParam,lParam,hWnd));
		case WM_SYSCOLORCHANGE :
			if(!installedHandlers(VectorHandler::SysColorChangeHandler))return ::DefFrameProc(hWnd,mClientWnd,message,wParam,lParam);
			return callHandlers(VectorHandler::SysColorChangeHandler,CallbackData(wParam,lParam,hWnd));
		case WM_CTLCOLOR :
			if(!installedHandlers(VectorHandler::ControlColorHandler))return ::DefFrameProc(hWnd,mClientWnd,message,wParam,lParam);
			return callHandlers(VectorHandler::ControlColorHandler,CallbackData(wParam,lParam,hWnd));
		case WM_CTLCOLORMSGBOX :
			if(!installedHandlers(VectorHandler::ControlColorHandler))return ::DefFrameProc(hWnd,mClientWnd,message,wParam,lParam);
			return callHandlers(VectorHandler::ControlColorHandler,CallbackData(wParam,lParam,hWnd));
		case WM_CTLCOLOREDIT :
			if(!installedHandlers(VectorHandler::ControlColorHandler))return ::DefFrameProc(hWnd,mClientWnd,message,wParam,lParam);
			return callHandlers(VectorHandler::ControlColorHandler,CallbackData(wParam,lParam,hWnd));
		case WM_CTLCOLORLISTBOX :
			if(!installedHandlers(VectorHandler::ControlColorHandler))return ::DefFrameProc(hWnd,mClientWnd,message,wParam,lParam);
			return callHandlers(VectorHandler::ControlColorHandler,CallbackData(wParam,lParam,hWnd));
		case WM_CTLCOLORBTN :
			if(!installedHandlers(VectorHandler::ControlColorHandler))return ::DefFrameProc(hWnd,mClientWnd,message,wParam,lParam);
			return callHandlers(VectorHandler::ControlColorHandler,CallbackData(wParam,lParam,hWnd));
		case WM_CTLCOLORDLG :
			if(!installedHandlers(VectorHandler::ControlColorHandler))return ::DefFrameProc(hWnd,mClientWnd,message,wParam,lParam);
			return callHandlers(VectorHandler::ControlColorHandler,CallbackData(wParam,lParam,hWnd));
		case WM_CTLCOLORSCROLLBAR :
			if(!installedHandlers(VectorHandler::ControlColorHandler))return ::DefFrameProc(hWnd,mClientWnd,message,wParam,lParam);
			return callHandlers(VectorHandler::ControlColorHandler,CallbackData(wParam,lParam,hWnd));
		case WM_CTLCOLORSTATIC :
			if(!installedHandlers(VectorHandler::ControlColorHandler))return ::DefFrameProc(hWnd,mClientWnd,message,wParam,lParam);
			return callHandlers(VectorHandler::ControlColorHandler,CallbackData(wParam,lParam,hWnd));
		case WM_DDE_INITIATE :
			if(!installedHandlers(VectorHandler::DDEInitiateHandler))return ::DefFrameProc(hWnd,mClientWnd,message,wParam,lParam);
			return callHandlers(VectorHandler::DDEInitiateHandler,CallbackData(wParam,lParam,hWnd));
		case WM_DDE_ACK :
			if(!installedHandlers(VectorHandler::DDEAckHandler))return ::DefFrameProc(hWnd,mClientWnd,message,wParam,lParam);
			return callHandlers(VectorHandler::DDEAckHandler,CallbackData(wParam,lParam,hWnd));
		case WM_DDE_REQUEST :
			if(!installedHandlers(VectorHandler::DDERequestHandler))return ::DefFrameProc(hWnd,mClientWnd,message,wParam,lParam);
			return callHandlers(VectorHandler::DDERequestHandler,CallbackData(wParam,lParam,hWnd));
		case WM_DDE_TERMINATE :
			if(!installedHandlers(VectorHandler::DDETerminateHandler))return ::DefFrameProc(hWnd,mClientWnd,message,wParam,lParam);
			return callHandlers(VectorHandler::DDETerminateHandler,CallbackData(wParam,lParam,hWnd));
		case WM_DDE_DATA :
			if(!installedHandlers(VectorHandler::DDEDataHandler))return ::DefFrameProc(hWnd,mClientWnd,message,wParam,lParam);
			return callHandlers(VectorHandler::DDEDataHandler,CallbackData(wParam,lParam,hWnd));
		case MM_WOM_OPEN :
			if(!installedHandlers(VectorHandler::MMOpenHandler))return ::DefFrameProc(hWnd,mClientWnd,message,wParam,lParam);
			return callHandlers(VectorHandler::MMOpenHandler,CallbackData(wParam,lParam,hWnd));
		case MM_WOM_CLOSE :
			if(!installedHandlers(VectorHandler::MMCloseHandler))return ::DefFrameProc(hWnd,mClientWnd,message,wParam,lParam);
			return callHandlers(VectorHandler::MMCloseHandler,CallbackData(wParam,lParam,hWnd));
		case MM_WOM_DONE :
			if(!installedHandlers(VectorHandler::MMDoneHandler))return ::DefFrameProc(hWnd,mClientWnd,message,wParam,lParam);
			return callHandlers(VectorHandler::MMDoneHandler,CallbackData(wParam,lParam,hWnd));
		case WM_LBUTTONDBLCLK :
			if(!installedHandlers(VectorHandler::LeftButtonDoubleHandler))return ::DefFrameProc(hWnd,mClientWnd,message,wParam,lParam);
			return callHandlers(VectorHandler::LeftButtonDoubleHandler,CallbackData(wParam,lParam,hWnd));
		case WM_LBUTTONDOWN :
			if(!installedHandlers(VectorHandler::LeftButtonDownHandler))return ::DefFrameProc(hWnd,mClientWnd,message,wParam,lParam);
			return callHandlers(VectorHandler::LeftButtonDownHandler,CallbackData(wParam,lParam,hWnd));
		case WM_LBUTTONUP :
			if(!installedHandlers(VectorHandler::LeftButtonUpHandler))return ::DefFrameProc(hWnd,mClientWnd,message,wParam,lParam);
			return callHandlers(VectorHandler::LeftButtonUpHandler,CallbackData(wParam,lParam,hWnd));
		case WM_RBUTTONDBLCLK :
			if(!installedHandlers(VectorHandler::RightButtonDoubleHandler))return ::DefFrameProc(hWnd,mClientWnd,message,wParam,lParam);
			return callHandlers(VectorHandler::RightButtonDoubleHandler,CallbackData(wParam,lParam,hWnd));
		case WM_RBUTTONDOWN :
			if(!installedHandlers(VectorHandler::RightButtonDownHandler))return ::DefFrameProc(hWnd,mClientWnd,message,wParam,lParam);
			return callHandlers(VectorHandler::RightButtonDownHandler,CallbackData(wParam,lParam,hWnd));
		case WM_RBUTTONUP :
			if(!installedHandlers(VectorHandler::RightButtonUpHandler))return ::DefFrameProc(hWnd,mClientWnd,message,wParam,lParam);
			return callHandlers(VectorHandler::RightButtonUpHandler,CallbackData(wParam,lParam,hWnd));
		case WM_NCLBUTTONUP :
			if(!installedHandlers(VectorHandler::NCLeftButtonUpHandler))return ::DefFrameProc(hWnd,mClientWnd,message,wParam,lParam);
			return callHandlers(VectorHandler::NCLeftButtonUpHandler,CallbackData(wParam,lParam,hWnd));
		case WM_NCLBUTTONDOWN :
			if(!installedHandlers(VectorHandler::NCLeftButtonDownHandler))return ::DefFrameProc(hWnd,mClientWnd,message,wParam,lParam);
			return callHandlers(VectorHandler::NCLeftButtonDownHandler,CallbackData(wParam,lParam,hWnd));
		case WM_NCRBUTTONUP :
			if(!installedHandlers(VectorHandler::NCRightButtonUpHandler))return ::DefFrameProc(hWnd,mClientWnd,message,wParam,lParam);
			return callHandlers(VectorHandler::NCRightButtonUpHandler,CallbackData(wParam,lParam,hWnd));
		case WM_NCRBUTTONDOWN :
			if(!installedHandlers(VectorHandler::NCRightButtonDownHandler))return ::DefFrameProc(hWnd,mClientWnd,message,wParam,lParam);
			return callHandlers(VectorHandler::NCRightButtonDownHandler,CallbackData(wParam,lParam,hWnd));
		case WM_MOUSEMOVE :
			if(!installedHandlers(VectorHandler::MouseMoveHandler))return ::DefFrameProc(hWnd,mClientWnd,message,wParam,lParam);
			return callHandlers(VectorHandler::MouseMoveHandler,CallbackData(wParam,lParam,hWnd));
		case WM_SETFOCUS :
			if(!installedHandlers(VectorHandler::SetFocusHandler))return ::DefFrameProc(hWnd,mClientWnd,message,wParam,lParam);
			return callHandlers(VectorHandler::SetFocusHandler,CallbackData(wParam,lParam,hWnd));
		case WM_SETFONT :
			if(!installedHandlers(VectorHandler::SetFontHandler))return ::DefFrameProc(hWnd,mClientWnd,message,wParam,lParam);
			return callHandlers(VectorHandler::SetFontHandler,CallbackData(wParam,lParam,hWnd));
		case WM_KILLFOCUS :
			if(!installedHandlers(VectorHandler::KillFocusHandler))return ::DefFrameProc(hWnd,mClientWnd,message,wParam,lParam);
			return callHandlers(VectorHandler::KillFocusHandler,CallbackData(wParam,lParam,hWnd));
		case WM_KEYUP :
			if(!installedHandlers(VectorHandler::KeyUpHandler))return ::DefFrameProc(hWnd,mClientWnd,message,wParam,lParam);
			return callHandlers(VectorHandler::KeyUpHandler,CallbackData(wParam,lParam,hWnd));
		case WM_KEYDOWN :
			if(!installedHandlers(VectorHandler::KeyDownHandler))return ::DefFrameProc(hWnd,mClientWnd,message,wParam,lParam);
			return callHandlers(VectorHandler::KeyDownHandler,CallbackData(wParam,lParam,hWnd));
		case WM_GETMINMAXINFO :
			if(!installedHandlers(VectorHandler::MinMaxHandler))return ::DefFrameProc(hWnd,mClientWnd,message,wParam,lParam);
			return callHandlers(VectorHandler::MinMaxHandler,CallbackData(wParam,lParam,hWnd));
		case WM_ENTERIDLE :
			if(!installedHandlers(VectorHandler::EnterIdleHandler))return ::DefFrameProc(hWnd,mClientWnd,message,wParam,lParam);
			return callHandlers(VectorHandler::EnterIdleHandler,CallbackData(wParam,lParam,hWnd));
		case WM_MENUSELECT :
			if(!installedHandlers(VectorHandler::MenuSelectHandler))return ::DefFrameProc(hWnd,mClientWnd,message,wParam,lParam);
			return callHandlers(VectorHandler::MenuSelectHandler,CallbackData(wParam,lParam,hWnd));
		case WM_GETDLGCODE :
			if(!installedHandlers(VectorHandler::DialogCodeHandler))return ::DefFrameProc(hWnd,mClientWnd,message,wParam,lParam);
			return callHandlers(VectorHandler::DialogCodeHandler,CallbackData(wParam,lParam,hWnd));
		case WM_MEASUREITEM :
			if(!installedHandlers(VectorHandler::MeasureItemHandler))return ::DefFrameProc(hWnd,mClientWnd,message,wParam,lParam);
			return callHandlers(VectorHandler::MeasureItemHandler,CallbackData(wParam,lParam,hWnd));
		case WM_VSCROLL :
		  if(!installedHandlers(VectorHandler::VerticalScrollHandler))return ::DefFrameProc(hWnd,mClientWnd,message,wParam,lParam);
			return callHandlers(VectorHandler::VerticalScrollHandler,CallbackData(wParam,lParam,hWnd));
		case WM_HSCROLL :
		  if(!installedHandlers(VectorHandler::HorizontalScrollHandler))return ::DefFrameProc(hWnd,mClientWnd,message,wParam,lParam);
			return callHandlers(VectorHandler::HorizontalScrollHandler,CallbackData(wParam,lParam,hWnd));
#if defined(__FLAT__)
		case WM_NOTIFY :
			if(!installedHandlers(VectorHandler::NotifyHandler))return ::DefFrameProc(hWnd,mClientWnd,message,wParam,lParam);
			return callHandlers(VectorHandler::NotifyHandler,CallbackData(wParam,lParam,hWnd));
#endif
		case WM_SIZE :
			if(!installedHandlers(VectorHandler::SizeHandler))return ::DefFrameProc(hWnd,mClientWnd,message,wParam,lParam);
			return callHandlers(VectorHandler::SizeHandler,CallbackData(wParam,lParam,hWnd));
		case WM_DROPFILES :
		  if(!installedHandlers(VectorHandler::DropFilesHandler))return ::DefFrameProc(hWnd,mClientWnd,message,wParam,lParam);
			return callHandlers(VectorHandler::DropFilesHandler,CallbackData(wParam,lParam,hWnd));
		case WM_DESTROY :
		  if(!installedHandlers(VectorHandler::DestroyHandler))postQuitMessage();
			callHandlers(VectorHandler::DestroyHandler,CallbackData(wParam,lParam,hWnd));
			InstanceData::removeInstanceData(hWnd);
			setHandle(0);
			if(!installedHandlers(VectorHandler::SizeHandler))return ::DefFrameProc(hWnd,mClientWnd,message,wParam,lParam);
			return FALSE;
		case WM_MDIACTIVATE :
		  if(!installedHandlers(VectorHandler::MDIActivateHandler))return ::DefFrameProc(hWnd,mClientWnd,message,wParam,lParam);
			return callHandlers(VectorHandler::MDIActivateHandler,CallbackData(wParam,lParam,hWnd));
		case WM_ACTIVATEAPP :
		  if(!installedHandlers(VectorHandler::ActivateAppHandler))return ::DefFrameProc(hWnd,mClientWnd,message,wParam,lParam);
			return callHandlers(VectorHandler::ActivateAppHandler,CallbackData(wParam,lParam,hWnd));
		case WM_DISPLAYCHANGE :
		  if(!installedHandlers(VectorHandler::DisplayChangeHandler))return ::DefFrameProc(hWnd,mClientWnd,message,wParam,lParam);
			return callHandlers(VectorHandler::DisplayChangeHandler,CallbackData(wParam,lParam,hWnd));
		case WM_SHOWWINDOW :
		  if(!installedHandlers(VectorHandler::ShowWindowHandler))return ::DefFrameProc(hWnd,mClientWnd,message,wParam,lParam);
			return callHandlers(VectorHandler::ShowWindowHandler,CallbackData(wParam,lParam,hWnd));
		case WM_MDIDESTROY :
			return FALSE;
		case WM_NCDESTROY :
		default :
			return ::DefFrameProc(hWnd,mClientWnd,message,wParam,lParam);
	}
}

#if defined(_MSC_VER)
int FAR PASCAL FrameWindow::enumerateProcedure(HWND hWnd,LPARAM lParam)
#else
int FAR PASCAL _export FrameWindow::enumerateProcedure(HWND hWnd,LPARAM lParam)
#endif
{
	if(::GetWindow(hWnd,GW_OWNER))return 1;
	switch(LOWORD(lParam))
	{
	  case MDICloseAll :
      if(!::SendMessage(hWnd,WM_QUERYENDSESSION,0,0L))return 1;
			::SendMessage(::GetParent(hWnd),WM_MDIDESTROY,(WPARAM)hWnd,0L);
			break;
		case MDIRestoreAll :
		  if(::IsIconic(hWnd)||::IsZoomed(hWnd))
			  ::SendMessage(::GetParent(hWnd),WM_MDIRESTORE,(WPARAM)hWnd,0L);
			break;
		case MDIMinimizeAll :
			if(!::IsIconic(hWnd))::ShowWindow(hWnd,SW_SHOWMINNOACTIVE);
			break;
	}
  return 1;
}

void FrameWindow::watchDocumentWindows(void)
{
  WORD size(mDocuments.size());
  for(int itemIndex=0;itemIndex<size;itemIndex++)
	{
	  if(!mDocuments[itemIndex]->isValid())
		{
		  mDocuments.remove(itemIndex);
			size=mDocuments.size();
			itemIndex=-1;
		}
	}
}

bool FrameWindow::getActive(SmartPointer<MDIWindow> &mdiWindow)
{
  HWND hMDIChild(0);

  if(!mClientWnd.isValid())return false;
	if((HWND)0==(hMDIChild=(HWND)mClientWnd.sendMessage(WM_MDIGETACTIVE,0,0L)))return false;
	for(int itemIndex=0;itemIndex<mDocuments.size();itemIndex++)
	  if(hMDIChild==(HWND)*(mDocuments[itemIndex]))return mdiWindow=mDocuments[itemIndex],true;
	return false;
}

bool FrameWindow::getDocument(const String &strWindowName,SmartPointer<MDIWindow> &mdiWindow)
{
  HWND hMDIChild;

  if(!mClientWnd.isValid())return false;
	if((HWND)0==(hMDIChild=mClientWnd.findWindow(strWindowName)))return false;
	for(int itemIndex=0;itemIndex<mDocuments.size();itemIndex++)
	  if(hMDIChild==(HWND)*(mDocuments[itemIndex]))return mdiWindow=mDocuments[itemIndex],true;
  return false;
}

bool FrameWindow::getDocuments(Array<SmartPointer<MDIWindow> > &mdiWindows)
{
  mdiWindows.size(mDocuments.size());
	if(!mdiWindows.size())return false;
	for(int index=0;index<mdiWindows.size();index++)
	  mdiWindows[index]=mDocuments[index];
	return true;
}

bool FrameWindow::getDocumentClass(const String &strClassName,SmartPointer<MDIWindow> &mdiWindow)
{
  Array<SmartPointer<MDIWindow> > mdiWindows;
	if(!getDocuments(mdiWindows))return false;
	for(int index=0;index<mdiWindows.size();index++)
	{
	  if(mdiWindows[index]->className()==strClassName)
		{
		  mdiWindow=mdiWindows[index];
		  return true;
		}
	}
	return false;
}

void FrameWindow::enableMenuItems(UINT menuIndex,UINT itemID,PureMenu::PositionFlags positionFlags,PureMenu::InsertFlags insertFlags)
{
  SmartPointer<MDIWindow> mdiWindow;
	Array<SmartPointer<MDIWindow> > mdiWindows;
  PureMenu subMenu;

	if(!getDocuments(mdiWindows))return;
	getFrameMenu().getSubMenu(menuIndex,subMenu);
  subMenu.enableMenuItem(itemID,positionFlags,insertFlags);
	drawMenuBar();
	for(int index=0;index<mdiWindows.size();index++)
	{
	  mdiWindow=mdiWindows[index];
		mdiWindow->getMenu().getSubMenu(menuIndex,subMenu);
    subMenu.enableMenuItem(itemID,positionFlags,insertFlags);
		mdiWindow->drawMenuBar();
	}
}

CallbackData::ReturnType FrameWindow::destroyHandler(CallbackData &someCallbackData)
{
	for(int itemIndex=0;itemIndex<mDocuments.size();itemIndex++)
	  if(someCallbackData.hwndFrom()==(HWND)*(mDocuments[itemIndex]))mdiDestroy(*(mDocuments[itemIndex]));
	return (CallbackData::ReturnType)FALSE;
}

CallbackData::ReturnType FrameWindow::mdiActivateHandler(CallbackData &someCallbackData)
{
  MDIWindow *pMDIWndActivate=0;
	MDIWindow *pMDIWndDeactivate=0;

	for(int itemIndex=0;itemIndex<mDocuments.size();itemIndex++)
	{
	  if((HWND)someCallbackData.wParam()==(HWND)*(mDocuments[itemIndex]))pMDIWndDeactivate=(MDIWindow*)mDocuments[itemIndex];
	  if((HWND)someCallbackData.lParam()==(HWND)*(mDocuments[itemIndex]))pMDIWndActivate=(MDIWindow*)mDocuments[itemIndex];
	}
	if(pMDIWndDeactivate)mdiDeactivate(*pMDIWndDeactivate);
	if(pMDIWndActivate)mdiActivate(*pMDIWndActivate);
  return FALSE;
}

CallbackData::ReturnType FrameWindow::commandHandler(CallbackData &someCallbackData)
{
  PureMenu pureMenu(::GetMenu(someCallbackData.hwndFrom()));
	String strItem(pureMenu.menuItemString(someCallbackData.wParam(),PureMenu::ByCommand));
	if(!strItem.isNull()&&strItem==String("More Windows..."))return moreWindows(),FALSE;
  for(UINT chIndex=0,menuID=IDFirstMDIChild;chIndex<mDocuments.size();chIndex++,menuID++)
	  if(menuID==someCallbackData.wmCommandID())activate(chIndex);
  return FALSE;
}

BOOL FrameWindow::activate(UINT childIndex)
{
  if(childIndex>=mDocuments.size())return FALSE;
  mClientWnd.sendMessage(WM_MDIACTIVATE,(WPARAM)(HWND)*mDocuments[childIndex],0L);
	mDocuments[childIndex]->show(SW_SHOWNORMAL);
	return TRUE;
}

void FrameWindow::destroy(void)
{
  SmartPointer<MDIWindow> mdiWindow;
	Array<SmartPointer<MDIWindow> > mdiWindows;

	getDocuments(mdiWindows);
	for(int index=0;index<mdiWindows.size();index++)
	{
	  mdiWindow=mdiWindows[index];
		if(preDestroy(*mdiWindow))return;
	}
	closeAll();
  GUIWindow::destroy();
}

// *** virtuals

bool FrameWindow::preDestroy(MDIWindow &/*mdiWindow*/)
{
  return false;
}

void FrameWindow::moreWindows(void)
{
}

void FrameWindow::mdiDeactivate(MDIWindow &/*mdiWindow*/)
{
}

void FrameWindow::mdiActivate(MDIWindow &/*mdiWindow*/)
{
}

void FrameWindow::mdiDestroy(MDIWindow &/*mdiWindow*/)
{
}

void FrameWindow::preRegister(WNDCLASS &/*wndClass*/)
{
}
