📄 dwautohide.h
字号:
{
return Orientation().IsTop();
}
void Initialize(CSide side)
{
m_side=side;
}
bool CalculateRect(CDC& dc,CRect& rc,long width,long leftPadding,long rightPadding)
{
if(IsVisible())
{
CopyRect(rc);
if(IsHorizontal())
{
if(IsTop())
rc.top=bottom=top+width;
else
rc.bottom=top=bottom-width;
left+=leftPadding;
right-=rightPadding;
}
else
{
if(IsTop())
rc.left=right=left+width;
else
rc.right=left=right-width;
top+=leftPadding;
bottom-=rightPadding;
}
UpdateLayout(dc);
}
return true;
}
void UpdateLayout(CDC& dc) const
{
bool bHorizontal=IsHorizontal();
HFONT hPrevFont;
long availableWidth;
// long availableWidth=bHorizontal ? Width() : Height();
CDWSettings settings;
if(bHorizontal)
{
availableWidth=Width();
hPrevFont=dc.SelectFont(settings.HSysFont());
}
else
{
availableWidth=Height();
hPrevFont=dc.SelectFont(settings.VSysFont());
}
availableWidth+=IPinnedLabel::labelPadding-IPinnedLabel::leftBorder-IPinnedLabel::rightBorder;
typedef std::priority_queue<long,std::deque<long>,std::greater<long> > CQWidth;
CQWidth widths;
long width = 0;
for(const_iterator i=m_bunch.begin();i!=m_bunch.end();++i)
{
int labelWidth=(*i)->DesiredWidth(dc);
(*i)->Width(labelWidth);
labelWidth+=IPinnedLabel::labelPadding;
widths.push(labelWidth);
width+=labelWidth;
}
long averageLableWidth=width;
long n=m_bunch.size();
if(n>0 && (width>availableWidth) )
{
width=availableWidth;
long itemsLeft=n;
averageLableWidth=width/itemsLeft;
long diffrence=width%itemsLeft;
while(!widths.empty())
{
long itemWidth=widths.top();
long diff=averageLableWidth-itemWidth;
if(diff>0)
{
diffrence+=diff;
--itemsLeft;
widths.pop();
}
else
{
if(diffrence<itemsLeft)
break;
averageLableWidth+=diffrence/itemsLeft;
diffrence=diffrence%itemsLeft;
}
}
averageLableWidth-=IPinnedLabel::labelPadding;
if(averageLableWidth<IPinnedLabel::labelPadding)
averageLableWidth=0;
for(const_iterator i=m_bunch.begin();i!=m_bunch.end();++i)
{
long labelWidth=(*i)->Width();
if( labelWidth>averageLableWidth )
labelWidth=averageLableWidth;
(*i)->Width(labelWidth);
}
}
dc.SelectFont(hPrevFont);
}
void Draw(CDC& dc,bool bEraseBackground=true)
{
if(IsVisible())
{
if(bEraseBackground)
{
CDWSettings settings;
CBrush bgrBrush;
bgrBrush.CreateSolidBrush(settings.CoolCtrlBackgroundColor());
HBRUSH hOldBrush=dc.SelectBrush(bgrBrush);
dc.PatBlt(left, top, Width(), Height(), PATCOPY);
dc.SelectBrush(hOldBrush);
}
CDWSettings settings;
CPen pen;
pen.CreatePen(PS_SOLID,1,::GetSysColor(COLOR_BTNSHADOW));
HPEN hOldPen=dc.SelectPen(pen);
CPen penEraser;
penEraser.CreatePen(PS_SOLID,1,::GetSysColor(COLOR_BTNFACE));
COLORREF oldColor=dc.SetTextColor(settings.AutoHideBarTextColor());
CBrush brush;
brush.CreateSolidBrush(::GetSysColor(COLOR_BTNFACE));
HBRUSH hOldBrush=dc.SelectBrush(brush);
int oldBkMode=dc.SetBkMode(TRANSPARENT);
HFONT hOldFont;
long* pLeft;
long* pRight;
CRect rcLabel(this);
long *xELine,*yELine;
long tmp;
if(IsHorizontal())
{
xELine=&rcLabel.right;
if(IsTop())
{
rcLabel.bottom-=IPinnedLabel::labelEdge;
yELine=&rcLabel.top;
}
else
{
rcLabel.top+=IPinnedLabel::labelEdge;
tmp=rcLabel.bottom-1;
yELine=&tmp;
}
hOldFont=dc.SelectFont(settings.HSysFont());
pLeft=&rcLabel.left;
pRight=&rcLabel.right;
}
else
{
yELine=&rcLabel.bottom;
if(IsTop())
{
rcLabel.right-=IPinnedLabel::labelEdge;
xELine=&rcLabel.left;
}
else
{
rcLabel.left+=IPinnedLabel::labelEdge;
tmp=rcLabel.right-1;
xELine=&tmp;
}
hOldFont=dc.SelectFont(settings.VSysFont());
pLeft=&rcLabel.top;
pRight=&rcLabel.bottom;
}
*pLeft+=IPinnedLabel::leftBorder;
*pRight-=IPinnedLabel::rightBorder;
long minSize=m_bunch.size()*IPinnedLabel::labelPadding-IPinnedLabel::labelPadding;
if(minSize<(*pRight-*pLeft))
{
*pRight=*pLeft+1;
CPoint ptELine;
for(const_iterator i=m_bunch.begin();i!=m_bunch.end();++i)
{
ptELine.x=*xELine;
ptELine.y=*yELine;
*pRight=*pLeft+(*i)->Width();
assert( m_side.IsHorizontal() ? *pRight<=right : *pRight<=bottom);
(*i)->Draw(dc,rcLabel,m_side);
*pLeft=*pRight+IPinnedLabel::labelPadding;
--*pRight;
HPEN hPrevPen=dc.SelectPen(penEraser);
dc.MoveTo(ptELine);
dc.LineTo(*xELine,*yELine);
dc.SelectPen(hPrevPen);
*pRight=*pLeft+1;
assert( m_side.IsHorizontal()
? (*pLeft>=left && (*pLeft<=right+IPinnedLabel::labelPadding) )
: (*pLeft>=top && (*pLeft<=bottom+IPinnedLabel::labelPadding) ) );
}
}
dc.SelectFont(hOldFont);
dc.SelectPen(hOldPen);
dc.SetTextColor(oldColor);
dc.SelectBrush(hOldBrush);
dc.SetBkMode(oldBkMode);
}
}
IPinnedLabel::CPinnedWindow* MouseEnter(const CPoint& pt,bool bActivate=false) const
{
IPinnedLabel::CPinnedWindow* ptr=0;
if(IsVisible() && IsPtIn(pt))
{
int x;
int vRight;
if(IsHorizontal())
{
x=pt.x;
vRight=left;
}
else
{
x=pt.y;
vRight=top;
}
for(const_iterator i=m_bunch.begin();i!=m_bunch.end();++i)
{
unsigned long vLeft=vRight;
vRight+=(*i)->Width();
if(vRight>x)
{
ptr=(*i)->FromPoint(x-vLeft,bActivate);
break;
}
vRight+=IPinnedLabel::labelPadding;
if(vRight>x)
break;
}
}
return ptr;
}
CPinnedLabelPtr Insert(DFPINUP* pHdr)
{
assert(m_side.Side()==CSide(pHdr->dwDockSide).Side());
CPinnedLabelPtr ptr=0;
try{
if(pHdr->n>1)
ptr=new CMultyPinnedLabel(pHdr,IsHorizontal());
else
ptr=new CSinglePinnedLabel(pHdr,IsHorizontal());
m_bunch.push_back(ptr);
}
catch(std::bad_alloc& /*e*/)
{
}
return ptr;
}
bool Remove(HWND hWnd,HDOCKBAR hBar,DFDOCKPOS* pHdr)
{
CBunch::iterator i=std::find_if(m_bunch.begin(),m_bunch.end(),
IPinnedLabel::CCmp(hWnd));
bool bRes=(i!=m_bunch.end());
if(bRes)
{
CPinnedLabelPtr ptr=*i;
if(pHdr==0)
(*i)=ptr->Remove(hWnd,hBar);
else
{
pHdr->dwDockSide=m_side.Side() | CDockingSide::sSingle | CSide::sPinned;
ptr->UnPin(hWnd,hBar,pHdr);
(*i)=0;
}
if((*i)!=ptr)
delete ptr;
if((*i)==0)
m_bunch.erase(i);
if(!IsVisible())
SetRectEmpty();
}
return bRes;
}
bool GetDockingPosition(DFDOCKPOS* pHdr) const
{
CBunch::const_iterator i=std::find_if(m_bunch.begin(),m_bunch.end(),
IPinnedLabel::CCmp(pHdr->hdr.hWnd));
bool bRes=(i!=m_bunch.end());
if(bRes)
{
pHdr->dwDockSide=m_side.Side() | CDockingSide::sSingle | CSide::sPinned;
(*i)->GetDockingPosition(pHdr);
pHdr->nBar=std::distance(m_bunch.begin(),i);
}
return bRes;
}
protected:
CSide m_side;
CBunch m_bunch;
};
#define HTSPLITTERH HTLEFT
#define HTSPLITTERV HTTOP
template <class T,
class TBase,
class TAutoHidePaneTraits>
class ATL_NO_VTABLE CAutoHidePaneImpl :
public CWindowImpl< T, TBase, TAutoHidePaneTraits >
{
typedef CWindowImpl< T, TBase, TAutoHidePaneTraits > baseClass;
typedef CAutoHidePaneImpl< T, TBase, TAutoHidePaneTraits > thisClass;
protected:
typedef typename TAutoHidePaneTraits::CCaption CCaption;
typedef typename CAutoHideBar::CSide CSide;
struct CSplitterBar : CSimpleSplitterBarEx<>
{
CSplitterBar(bool bHorizontal=true):CSimpleSplitterBarEx<>(bHorizontal)
{
}
void CalculateRect(CRect& rc,DWORD side)
{
CopyRect(rc);
switch(side)
{
case CSide::sTop:
rc.bottom=top=bottom-GetThickness();
break;
case CSide::sBottom:
rc.top=bottom=top+GetThickness();
break;
case CSide::sRight:
rc.left=right=left+GetThickness();
break;
case CSide::sLeft:
rc.right=left=right-GetThickness();
break;
};
}
};
public:
CAutoHidePaneImpl()
{
m_caption.SetPinButtonState(CPinIcons::sUnPinned);
}
protected:
CSide Orientation() const
{
return m_side;
}
void Orientation(const CSide& side)
{
m_side=side;
m_splitter.SetOrientation(IsHorizontal());
m_caption.SetOrientation(IsHorizontal());
}
bool IsHorizontal() const
{
return m_side.IsHorizontal();
}
bool IsTop() const
{
return m_side.IsTop();
}
public:
void GetMinMaxInfo(LPMINMAXINFO pMinMaxInfo) const
{
pMinMaxInfo->ptMinTrackSize.x=0;
pMinMaxInfo->ptMinTrackSize.y=0;
}
LRESULT NcHitTest(const CPoint& pt)
{
LRESULT lRes=HTNOWHERE;
if(m_splitter.PtInRect(pt))
lRes=(IsHorizontal()) ? HTSPLITTERV : HTSPLITTERH;
else
{
lRes=m_caption.HitTest(pt);
if(lRes==HTNOWHERE)
lRes=HTCLIENT;
else
{
if(GetCapture()==NULL)
m_caption.HotTrack(m_hWnd,lRes);
}
}
return lRes;
}
void NcCalcSize(CRect* pRc)
{
m_splitter.CalculateRect(*pRc,m_side.Side());
DWORD style = GetWindowLong(GWL_STYLE);
if((style&WS_CAPTION)==0)
m_caption.SetRectEmpty();
else
m_caption.CalculateRect(*pRc,true);
}
void NcDraw(CDC& dc)
{
DWORD style = GetWindowLong(GWL_STYLE);
if((style&WS_CAPTION)!=0)
m_caption.Draw(m_hWnd,dc);
m_splitter.Draw(dc);
}
bool CloseBtnPress()
{
PostMessage(WM_CLOSE);
return false;
}
bool PinBtnPress()
{
return true;
}
void StartResizing(const CPoint& pt)
{
assert(false);
}
bool OnClosing()
{
return false;
}
bool AnimateWindow(long time,bool bShow)
{
const int n=10;
CRect rc;
GetWindowRect(&rc);
CWindow parent(GetParent());
if(parent.m_hWnd!=NULL)
parent.ScreenToClient(&rc);
long* ppoint;
long step;
CRect rcInvalidate(rc);
long* pipoint;
if(m_side.IsHorizontal())
{
step=rc.Height()/n;
if(m_side.IsTop())
{
ppoint=&rc.bottom;
pipoint=&rc.bottom;
rcInvalidate.bottom=rcInvalidate.top;
}
else
{
ppoint=&rc.top;
pipoint=&rc.top;
rcInvalidate.top=rcInvalidate.bottom;
step=-step;
}
}
else
{
step=rc.Width()/n;
if(m_side.IsTop())
{
ppoint=&rc.right;
pipoint=&rc.right;
rcInvalidate.left=rcInvalidate.right;
}
else
{
ppoint=&rc.left;
pipoint=&rc.left;
rcInvalidate.right=rcInvalidate.left;
step=-step;
}
}
if(!bShow)
step=-step;
else
{
parent.RedrawWindow(&rc,NULL,RDW_INVALIDATE | RDW_UPDATENOW);
*ppoint-=step*n;
SetWindowPos(HWND_TOP,&rc,SWP_FRAMECHANGED|SWP_SHOWWINDOW);
}
bool bRes=true;
for(int i=0;i<n;i++)
{
*ppoint+=step;
bRes=(SetWindowPos(HWND_TOP,&rc,NULL)!=FALSE);
if(!bShow)
{
*pipoint+=step;
parent.RedrawWindow(&rcInvalidate,NULL,RDW_INVALIDATE | RDW_UPDATENOW);
}
else
{
CRect rcInvalidateClient(rc);
parent.MapWindowPoints(m_hWnd,&rcInvalidateClient);
RedrawWindow(&rcInvalidateClient,NULL,RDW_INVALIDATE | RDW_UPDATENOW);
}
Sleep(time/n);
}
return bRes;
}
protected:
BEGIN_MSG_MAP(thisClass)
MESSAGE_HANDLER(WM_GETMINMAXINFO,OnGetMinMaxInfo)
MESSAGE_HANDLER(WM_NCCALCSIZE, OnNcCalcSize)
MESSAGE_HANDLER(WM_NCACTIVATE, OnNcActivate)
MESSAGE_HANDLER(WM_NCHITTEST,OnNcHitTest)
MESSAGE_HANDLER(WM_NCPAINT,OnNcPaint)
MESSAGE_HANDLER(WM_SETTEXT,OnCaptionChange)
MESSAGE_HANDLER(WM_SETICON,OnCaptionChange)
MESSAGE_HANDLER(WM_NCLBUTTONDOWN, OnNcLButtonDown)
MESSAGE_HANDLER(WM_NCLBUTTONUP,OnNcLButtonUp)
MESSAGE_HANDLER(WM_NCLBUTTONDBLCLK,OnNcLButtonDblClk)
MESSAGE_HANDLER(WM_CLOSE, OnClose)
MESSAGE_HANDLER(WM_SETTINGCHANGE, OnSettingChange)
MESSAGE_HANDLER(WM_SYSCOLORCHANGE, OnSettingChange /*OnSysColorChange*/)
END_MSG_MAP()
LRESULT OnGetMinMaxInfo(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/)
{
T* pThis=static_cast<T*>(this);
LRESULT lRes=pThis->DefWindowProc(uMsg,wParam,lParam);
pThis->GetMinMaxInfo(reinterpret_cast<LPMINMAXINFO>(lParam));
return lRes;
}
LRESULT OnNcActivate(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled)
{
bHandled=IsWindowEnabled();
return TRUE;
}
LRESULT OnNcCalcSize(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& /*bHandled*/)
{
T* pThis=static_cast<T*>(this);
CRect* pRc=reinterpret_cast<CRect*>(lParam);
CPoint ptTop(pRc->TopLeft());
(*pRc)-=ptTop;
pThis->NcCalcSize(pRc);
(*pRc)+=ptTop;
return NULL;
}
LRESULT OnNcHitTest(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& /*bHandled*/)
{
CPoint pt(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
T* pThis=static_cast<T*>(this);
CRect rcWnd;
GetWindowRect(&rcWnd);
pt.x-=rcWnd.TopLeft().x;
pt.y-=rcWnd.TopLeft().y;
return pThis->NcHitTest(pt);
}
//OnSetIcon
//OnSetText
LRESULT OnCaptionChange(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/)
{
// LockWindowUpdate();
DWORD style = ::GetWindowLong(m_hWnd,GWL_STYLE);
::SetWindowLong(m_hWnd, GWL_STYLE, style&(~WS_CAPTION));
LRESULT lRes=DefWindowProc(uMsg,wParam,lParam);
::SetWindowLong(m_hWnd, GWL_STYLE, style);
T* pThis=static_cast<T*>(this);
pThis->SetWindowPos(NULL,0,0,0,0,SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED);
// CWindowDC dc(m_hWnd);
// pThis->NcDraw(dc);
// LockWindowUpdate(FALSE);
return lRes;
}
LRESULT OnNcPaint(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
{
CWindowDC dc(m_hWnd);
T* pThis=static_cast<T*>(this);
pThis->NcDraw(dc);
return NULL;
}
LRESULT OnNcLButtonDown(UINT /*uMsg*/, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/)
{
if( (wParam==HTSPLITTERH) || (wParam==HTSPLITTERV) )
static_cast<T*>(this)->StartResizing(CPoint(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)));
else
m_caption.OnAction(m_hWnd,wParam);
return 0;
}
LRESULT OnNcLButtonUp(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& bHandled)
{
T* pThis=static_cast<T*>(this);
switch(wParam)
{
case HTCLOSE:
bHandled=pThis->CloseBtnPress();
break;
case HTPIN:
bHandled=pThis->PinBtnPress();
break;
default:
bHandled=FALSE;
}
return 0;
}
LRESULT OnNcLButtonDblClk(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
{
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -