// Copyright (c) 2002
// Sergey Klimov (kidd@ukr.net)
// WTL Docking windows
//
// This code is provided "as is", with absolutely no warranty expressed
// or implied. Any use is at your own risk.
//
// This code may be used in compiled form in any way you desire. This
// file may be redistributed unmodified by any means PROVIDING it is
// not sold for profit without the authors written consent, and
// providing that this notice and the authors name is included. If
// the source code in this file is used in any commercial application
// then a simple email woulod be nice.
#if !defined(AFX_DBSTATE_H__05B4C486_973C_4275_97A3_AE6F5A20107A__INCLUDED_)
#define AFX_DBSTATE_H__05B4C486_973C_4275_97A3_AE6F5A20107A__INCLUDED_
#include <dwstate.h>
#include <TabDockingBox.h>
namespace sstate{
class CDockWndMgrEx: public CDockWndMgr
{
protected:
struct CImpl : CDockWndMgr::CImpl
{
class CQLoader
{
public:
CQLoader(CRestQueue& q,IMainState* pMState,CRegKey& keyTop)
:m_queue(q),m_pMState(pMState),m_keyTop(keyTop)
{
}
void operator() (std::pair<const ID,CItem>& x) const
{
CRestPos dpos;
std::basic_stringstream<TCHAR> sstrKey;
sstrKey.flags(std::ios::hex | std::ios::showbase );
sstrKey<<x.first;
DWORD dwType;
DWORD cbData=sizeof(dockwins::DFDOCKPOSEX);
dockwins::DFDOCKPOSEX* ptr=static_cast<dockwins::DFDOCKPOSEX*>(&dpos);
if((::RegQueryValueEx(m_keyTop,sstrKey.str().c_str(),NULL,&dwType,
reinterpret_cast<LPBYTE>(ptr),&cbData)==ERROR_SUCCESS)
&&(dwType==REG_BINARY))
{
if(dpos.bDocking)
{
dpos.id=x.first;
dockwins::CDockingSide dside(dpos.dockPos.dwDockSide);
if(dside.IsValid())
{
/////////////////////////////3<<30+0x3f8<<20+0x3fff<<9+0x1ff
assert(dpos.bDocking);
// dpos.weight=0;
dpos.weight=dpos.dockPos.nIndex&0x1ff;
dpos.weight|=(DWORD(dpos.dockPos.fPctPos*0x3fff)&0x3fff)<<9;
dpos.weight|=(dpos.dockPos.nBar&0x7f)<<20;
dpos.weight|=((~dpos.dockPos.dwDockSide)&3)<<30;
///////////////////////////////////////////////////
}
else
dpos.weight=reinterpret_cast<DWORD>(dpos.dockPos.hdr.hBar) | 0xe0000000;
m_queue.push(dpos);
}
else
x.second->Restore(m_pMState,&dpos);
}
else
x.second->RestoreDefault();
}
protected:
CRestQueue& m_queue;
IMainState* m_pMState;
CRegKey& m_keyTop;
};
virtual bool Restore(IMainState* pMState,CRegKey& key)
{
//bad style, probably I'll fix it later
std::for_each(m_bunch.begin(),m_bunch.end(),CQLoader(m_queue,pMState,key));
DWORD weight=0;
HDOCKBAR hBar=HNONDOCKBAR;
BOOL bVisible=TRUE;
HWND hActiveWnd=NULL;
while(!m_queue.empty())
{
// CRestPos& dpos=const_cast<CRestPos&>(m_queue.top());
CRestPos dpos=m_queue.top();
assert(m_bunch.find(dpos.id)!=m_bunch.end());
// dpos.dockPos.hdr.hBar=((dpos.weight&0xfffffe00)==weight) ? hBar : HNONDOCKBAR;
/////////////////
//very ugly :(
if((dpos.weight&0xfffffe00)!=weight)
{
if(hBar!=HNONDOCKBAR)
{
if(dockwins::CDockingBox::IsWindowBox(hBar) && (hActiveWnd!=NULL))
{
dockwins::CDockingBox box(hBar);
box.Activate(hActiveWnd);
}
if(!bVisible )
::SendMessage(::GetParent(hBar),WM_CLOSE,0,0);
}
hActiveWnd=NULL;
hBar=HNONDOCKBAR;
}
bVisible=dpos.bVisible;
dpos.bVisible=TRUE;
dpos.dockPos.hdr.hBar=hBar;
m_bunch[dpos.id]->Restore(pMState,&dpos);
if((bVisible&2)!=0)
hActiveWnd=dpos.dockPos.hdr.hWnd;
hBar=dpos.dockPos.hdr.hWnd;
weight=dpos.weight&0xfffffe00;
m_queue.pop();
}
if(hBar!=HNONDOCKBAR)
{
if(dockwins::CDockingBox::IsWindowBox(hBar) && (hActiveWnd!=NULL))
{
dockwins::CDockingBox box(hBar);
box.Activate(hActiveWnd);
}
if(!bVisible )
::SendMessage(::GetParent(hBar),WM_CLOSE,0,0);
}
return true;
}
};
public:
CDockWndMgrEx():CDockWndMgr(new CImpl())
{
}
};
template<class T>
class CDockingWindowStateAdapterEx
: public CDockingWindowStateAdapter<T>
{
typedef CDockingWindowStateAdapter<T> baseClass ;
protected:
template<class T>
class CImplExT : public baseClass::CImplT<T>
{
typedef baseClass::CImplT<T> baseClass;
public:
CImplExT(T& x,int nDefCmdShow=SW_SHOWNOACTIVATE)
:baseClass(x,nDefCmdShow)
{
}
virtual bool Store(IMainState* pMState,dockwins::DFDOCKPOSEX* pDocPos)
{
bool bRet=baseClass::Store(pMState,pDocPos);
if(pDocPos->bDocking)
{
pDocPos->dockPos.hdr.hBar=::GetParent(pDocPos->dockPos.hdr.hWnd);
if(dockwins::CDockingBox::IsWindowBox(pDocPos->dockPos.hdr.hBar))
pDocPos->bVisible|=(::IsWindowVisible(pDocPos->dockPos.hdr.hWnd)&1)<<1;
}
return bRet;
}
};
typedef CImplExT<T> CImpl;
public:
CDockingWindowStateAdapterEx(T& x,int nDefCmdShow=SW_SHOWNOACTIVATE)
: baseClass(new CImpl(x,nDefCmdShow))
{
}
};
}//namespace sstate
#endif // !defined(AFX_DBSTATE_H__05B4C486_973C_4275_97A3_AE6F5A20107A__INCLUDED_)