📄 wndfrmpkg.h
字号:
typedef typename CTraits::CSplitterBar CSplitterBar;
typedef CSubWndFramesPackage<TPackageFrame,TTraits> thisClass;
typedef CWndFramesPackageBase<CFrame,TTraits > baseClass;
typedef typename TPackageFrame CPackageFrame;
enum {controlledLen=(15+CSplitterBar::sbThickness)};
struct CDockOrientationFlag
{
enum{low=0,high=1};
static void SetHigh(DWORD& flag)
{
flag=high;
}
static void SetLow(DWORD& flag)
{
flag=low;
}
static bool IsLow(DWORD flag)
{
return (flag&high)==0;
}
};
protected:
class CFrameWrapper : public IFrame
{
public:
CFrameWrapper(thisClass* ptr):m_ptr(ptr)
{
}
virtual ~CFrameWrapper()
{
}
virtual HWND hwnd() const
{
return NULL;
}
/*
virtual bool AcceptDock(DFDOCKRECT* pHdr) const
{
return m_ptr->AcceptDock(pHdr);
}
*/
virtual bool AcceptDock(DFDOCKRECT* /*pHdr*/) const
{
assert(false);
return true;
}
virtual HDWP DeferFramePos(HDWP hdwp,long x1,long y1,long x2,long y2) const
{
m_ptr->UpdateLayout(CRect(x1,y1,x2,y2));
return hdwp;
}
virtual void GetMinMaxInfo(LPMINMAXINFO pMinMaxInfo) const
{
m_ptr->GetMinMaxInfo(pMinMaxInfo);
}
virtual distance MinDistance() const
{
MINMAXINFO mmInfo;
ZeroMemory(&mmInfo,sizeof(MINMAXINFO));
GetMinMaxInfo(&mmInfo);
return m_ptr->IsHorizontal() ? mmInfo.ptMinTrackSize.y : mmInfo.ptMinTrackSize.x;
}
protected:
thisClass* m_ptr;
};
public:
CSubWndFramesPackage(bool bHorizontal)
:baseClass(bHorizontal),m_pDecl(0)
{
SetRectEmpty();
}
HCURSOR GetCursor(const CPoint& pt) const
{
return baseClass::GetCursor(pt,*this);
}
bool StartSliding(HWND hWnd,const CPoint& pt,bool bGhostMove)
{
return baseClass::StartSliding(hWnd,pt,*this,bGhostMove);
}
#ifndef DW_PROPORTIONAL_RESIZE
bool UpdateLayout(const CRect& rc)
{
bool bRes=EqualRect(&rc)!=FALSE;
if(!bRes)
{
CopyRect(rc);
CBounds bounds;
if(IsHorizontal())
{
bounds.low=rc.left;
bounds.hi=rc.right;
}
else
{
bounds.low=rc.top;
bounds.hi=rc.bottom;
}
bounds.low-=splitterSize;
CBounds::distance_t limit=m_frames.distance_limit();
if(bounds.distance()<limit)
bounds.hi=bounds.low+limit;
if(m_pDecl!=0)
m_frames.set_bounds(bounds,CFrame::CCmp(m_pDecl->hwnd()));
else
m_frames.set_bounds(bounds);
bRes=Arrange(rc);
}
return bRes;
}
#else
bool UpdateLayout(const CRect& rc)
{
bool bRes=EqualRect(&rc)!=FALSE;
if(!bRes)
{
CopyRect(rc);
bRes=baseClass::UpdateLayout(*this);
}
return bRes;
}
#endif //DW_PROPORTIONAL_RESIZE
void Draw(CDC& dc)
{
baseClass::Draw(dc,*this);
}
bool AcceptDock(DFDOCKRECT* pHdr)
{
CPoint pt(pHdr->rect.left,pHdr->rect.top);
CSize sz(0,0);
position pos;
if(IsHorizontal())
{
pos=pt.x;
sz.cx=controlledLen;
}
else
{
pos=pt.y;
sz.cy=controlledLen;
}
bool bRes=PtInRect(pt)==TRUE;
if(bRes)
{
// position pos=IsHorizontal() ? pHdr->rect.left :pHdr->rect.top;
const_iterator i=m_frames.locate(pos);
if( m_frames.get_frame_low(i)+controlledLen>pos)
bRes=AcceptDock(i,pHdr,*this);
else
{
if( m_frames.get_frame_hi(i)-controlledLen<pos)
bRes=AcceptDock(++i,pHdr,*this);
else
{
bRes=i->hwnd()!=m_pDecl->hwnd();
if(bRes)
bRes=(*i)->AcceptDock(pHdr);
}
}
}
else
{
CRect rc(this);
rc.InflateRect(sz);
bRes=rc.PtInRect(pt)==TRUE;
if(bRes)
{
if(pos<m_frames.hi())
bRes=AcceptDock(m_frames.begin(),pHdr,rc);
else
bRes=AcceptDock(m_frames.end(),pHdr,rc);
}
}
return bRes;
}
bool AcceptDock(const_iterator i,DFDOCKRECT* pHdr,const CRect& rc)
{
assert(std::find_if(m_frames.begin(),m_frames.end(),CFrame::CCmp(m_pDecl->hwnd()))!=m_frames.end());
const_iterator begin=m_frames.begin();
if(std::find_if(begin,i,CFrame::CCmp(m_pDecl->hwnd()))==i)
CDockOrientationFlag::SetLow(pHdr->flag);
else
CDockOrientationFlag::SetHigh(pHdr->flag);
bool bRes=baseClass::AcceptDock(pHdr,rc);
if(bRes)
{
if(IsHorizontal())
{
long len=(pHdr->rect.right-pHdr->rect.left);
if(CDockOrientationFlag::IsLow(pHdr->flag))
{
assert(i!=m_frames.end());
pHdr->rect.left=(*i)+CSplitterBar::GetThickness();
pHdr->rect.right=pHdr->rect.left+len;
}
else
{
pHdr->rect.right=(i==m_frames.end()) ? m_frames.hi() : (*i);
pHdr->rect.left=pHdr->rect.right-len;
}
}
else
{
long len=(pHdr->rect.bottom-pHdr->rect.top);
if(CDockOrientationFlag::IsLow(pHdr->flag))
{
assert(i!=m_frames.end());
pHdr->rect.top=(*i)+CSplitterBar::GetThickness();
pHdr->rect.bottom=pHdr->rect.top+len;
}
else
{
pHdr->rect.bottom=(i==m_frames.end()) ? m_frames.hi() : (*i);
pHdr->rect.top=pHdr->rect.bottom-len;
}
}
}
return bRes;
}
bool Dock(CFrame& frame,const DFDOCKRECT* pHdr,const CRect& rc)
{
position pos;
CFrames::distance len;
if(IsHorizontal())
{
pos=pHdr->rect.left;
len=pHdr->rect.right-pHdr->rect.left;
}
else
{
pos=pHdr->rect.top;
len=pHdr->rect.bottom-pHdr->rect.top;
}
frame=pos;
if(!CDockOrientationFlag::IsLow(pHdr->flag))
pos+=len;
iterator i;
if(pos!=m_frames.hi())
i=m_frames.locate(pos);
else
i=m_frames.end();
m_frames.insert(i,CFrame::CCmp(m_pDecl->hwnd()),frame,len);
return Arrange(rc);
}
bool Dock(DFDOCKRECT* pHdr)
{
CPackageFrame* ptr=CPackageFrame::CreateInstance(pHdr->hdr.hBar,!IsHorizontal());
bool bRes=(ptr!=0);
if(bRes)
{
HWND hDockWnd=pHdr->hdr.hWnd;
pHdr->hdr.hWnd=ptr->hwnd();
CFrame frame(0,ptr);
bRes=Dock(frame,pHdr,*this);
assert(bRes);
if(bRes)
{
pHdr->hdr.hWnd=hDockWnd;
pHdr->hdr.hBar=ptr->hwnd();
CWindow bar(pHdr->hdr.hBar);
bar.GetWindowRect(&(pHdr->rect));
bRes=::SendMessage(ptr->hwnd(),WMDF_DOCK,NULL,reinterpret_cast<LPARAM>(pHdr))!=FALSE;
}
}
return bRes;
}
bool Undock(const DFMHDR* pHdr)
{
iterator i=std::find_if(m_frames.begin(),m_frames.end(),CFrame::CCmp(pHdr->hWnd));
bool bRes=(i!=m_frames.end());
if(bRes)
{
m_frames.erase(i,CFrame::CCmp(m_pDecl->hwnd()));
bRes=Arrange(*this);
}
return bRes;
}
bool GetDockingPosition(DFDOCKPOS* pHdr) const
{
const_iterator i=std::find_if(m_frames.begin(),m_frames.end(),CFrame::CCmp(pHdr->hdr.hBar));
bool bRes=(i!=m_frames.end());
if(bRes)
{
pHdr->nWidth=m_frames.get_frame_size(i)-CSplitterBar::GetThickness();
CFrames::size_type dWnd=std::distance(m_frames.begin(),i);
i=std::find_if(m_frames.begin(),m_frames.end(),CFrame::CCmp(m_pDecl->hwnd()));
assert(i!=m_frames.end());
CFrames::size_type dBWnd=std::distance(m_frames.begin(),i);
if(dBWnd>dWnd)
{
pHdr->nBar=dWnd;
pHdr->dwDockSide|=CDockingSide::sTop;
}
else
{
pHdr->nBar=m_frames.size()-dWnd-1;
// pHdr->dwDockSide|=0;
}
bRes=(::SendMessage(pHdr->hdr.hBar,WMDF_DOCK,NULL,reinterpret_cast<LPARAM>(pHdr))!=FALSE);
}
return bRes;
}
// bool SetDockingPosition(DFDOCKPOS* pHdr)
// {
// bool bRes=true;
// unsigned long limit=GetMinFrameDist(&(pHdr->hdr));
// if(pHdr->nWidth<limit)
// pHdr->nWidth=limit;
// CDockingSide side(pHdr->dwDockSide);
// if(side.IsTop())
// {
// iterator i=ssec::search_n(m_frames.begin(),m_frames.end(),CFrame::CCmp(m_pDecl->hwnd()),pHdr->nBar);
// assert(i!=m_frames.end());
// if(i->hwnd()==m_pDecl->hwnd() || side.IsSingle())
// {
// CPackageFrame* ptr=CPackageFrame::CreateInstance(pHdr->hdr.hBar,!IsHorizontal());
// bRes=(ptr!=0);
// if(bRes)
// {
//// i=m_frames.insert(i,CFrame(*i,ptr),pHdr->nWidth);
// i=m_frames.insert(i,CFrame::CCmp(m_pDecl->hwnd()),CFrame(*i,ptr),pHdr->nWidth+splitterSize);
// }
// }
// else
// m_frames.set_frame_size(i,pHdr->nWidth+splitterSize);
// pHdr->hdr.hBar=i->hwnd();
// }
// else
// {
// reverse_iterator ri=ssec::search_n(m_frames.rbegin(),m_frames.rend(),CFrame::CCmp(m_pDecl->hwnd()),pHdr->nBar);
// assert(ri!=m_frames.rend());
// iterator i=ri.base();
// if(/*ri->hwnd()*/(*ri).hwnd()==m_pDecl->hwnd() || side.IsSingle())
// {
// CPackageFrame* ptr=CPackageFrame::CreateInstance(pHdr->hdr.hBar,!IsHorizontal());
// bRes=(ptr!=0);
// if(bRes)
// {
// position pos=(i==m_frames.end())? m_frames.hi():*i;
// pos-=pHdr->nWidth+CSplitterBar::GetThickness();
// if(pos<m_frames.low())
// pos=m_frames.low();
//// i=m_frames.insert(i,CFrame(pos,ptr),pHdr->nWidth);
// i=m_frames.insert(i,CFrame::CCmp(m_pDecl->hwnd()),CFrame(pos,ptr),pHdr->nWidth+splitterSize);
// }
// }
// else
// {
// assert(i!=m_frames.begin());
// m_frames.set_frame_size(--i,pHdr->nWidth+splitterSize);
// }
// pHdr->hdr.hBar=i->hwnd();
// }
// bRes=Arrange(*this);
// assert(bRes);
// if(bRes)
// {
// bRes=(::SendMessage(pHdr->hdr.hBar,WMDF_DOCK,NULL,reinterpret_cast<LPARAM>(pHdr))!=FALSE);
// assert(bRes);
// }
// return bRes;
// }
bool SetDockingPosition(DFDOCKPOS* pHdr)
{
bool bRes=true;
unsigned long limit=GetMinFrameDist(&(pHdr->hdr));
if(pHdr->nWidth<limit)
pHdr->nWidth=limit;
CDockingSide side(pHdr->dwDockSide);
if(side.IsTop())
{
iterator i=ssec::search_n(m_frames.begin(),m_frames.end(),CFrame::CCmp(m_pDecl->hwnd()),pHdr->nBar);
assert(i!=m_frames.end());
if(i->hwnd()==m_pDecl->hwnd() || side.IsSingle())
{
CPackageFrame* ptr=CPackageFrame::CreateInstance(pHdr->hdr.hBar,!IsHorizontal());
bRes=(ptr!=0);
if(bRes)
{
// i=m_frames.insert(i,CFrame(*i,ptr),pHdr->nWidth);
i=m_frames.insert(i,CFrame::CCmp(m_pDecl->hwnd()),CFrame(*i,ptr),pHdr->nWidth+splitterSize);
bRes=Arrange(*this);
assert(bRes);
}
}
pHdr->hdr.hBar=i->hwnd();
}
else
{
reverse_iterator ri=ssec::search_n(m_frames.rbegin(),m_frames.rend(),CFrame::CCmp(m_pDecl->hwnd()),pHdr->nBar);
assert(ri!=m_frames.rend());
iterator i=ri.base();
if(/*ri->hwnd()*/(*ri).hwnd()==m_pDecl->hwnd() || side.IsSingle())
{
CPackageFrame* ptr=CPackageFrame::CreateInstance(pHdr->hdr.hBar,!IsHorizontal());
bRes=(ptr!=0);
if(bRes)
{
position pos=(i==m_frames.end())? m_frames.hi():*i;
pos-=pHdr->nWidth+CSplitterBar::GetThickness();
if(pos<m_frames.low())
pos=m_frames.low();
// i=m_frames.insert(i,CFrame(pos,ptr),pHdr->nWidth);
i=m_frames.insert(i,CFrame::CCmp(m_pDecl->hwnd()),CFrame(pos,ptr),pHdr->nWidth+splitterSize);
bRes=Arrange(*this);
assert(bRes);
pHdr->hdr.hBar=i->hwnd();
}
}
else
pHdr->hdr.hBar=/*ri->hwnd()*/(*ri).hwnd();
}
if(bRes)
{
bRes=(::SendMessage(pHdr->hdr.hBar,WMDF_DOCK,NULL,reinterpret_cast<LPARAM>(pHdr))!=FALSE);
assert(bRes);
}
return bRes;
}
bool Insert(HWND* ptr, const CRect& rc)
{
DFDOCKRECT dockHdr;
::CopyRect(&dockHdr.rect,&rc);
assert(m_pDecl==0);
m_pDecl=new CWindowPtrWrapper(ptr);
CFrame frame(0,m_pDecl);
return baseClass::Dock(frame,&dockHdr,*this);
}
bool Insert(thisClass* ptr, const CRect& rc)
{
DFDOCKRECT dockHdr;
::CopyRect(&dockHdr.rect,&rc);
assert(m_pDecl==0);
m_pDecl=new CFrameWrapper(ptr);
CFrame frame(0,m_pDecl);
return baseClass::Dock(frame,&dockHdr,*this);
}
protected:
IFrame* m_pDecl;
};
}//namespace dockwins
#endif // __WTL_DW__WNDFRMPKG_H__
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -