基于CDialogBar的IE多标签栏的实现
来源:优易学  2010-1-14 11:42:41   【优易学:中国教育考试门户网】   资料下载   IT书店

  IE浏览器的多标签模式已日趋占据浏览器市场的主流模式。回忆IE6.0时代的单文档多实例年代,那浏览多网页是何等的痛苦。原本有限的空间就要被那些烦琐的网页所占据,要从这些烦琐的网页中切换到自己目的网页更是何等的不便。现在很多第三方IE浏览器对IE浏览器所显示出来的弊病虎视眈眈许久,多标签浏览器也应运而生。遨游、世界之窗、TT等如今都是拜多标签浏览器之福,早早占领了市场,占据了一席之地。而如今微软也知道自己浏览器帝国的根基也岌岌可危,其怎可示弱,IE7.0也就相继问世。
  IE多标签栏的主要特点是:单实例多文档模式,文档间的切换是通过标签实现。一个实例就可以包容多个文档,察看网页是何其的方便。
  构成IE多标签栏的界面要素包括工具栏和标签。工具栏采用CDialogBar做为标签的容器,标签采用自绘按钮来实现,CtabCtrl做标签不容易实现自绘(自绘的时候有灰色的border出现)。
  在CDialogBar的宽度发生改变的时候,其上面的按钮标签应做适当的调整。当然在足够容纳按钮标签的时,可以给一个设定值。若空间有限的话,则就适当缩小标签的大小,其上的内容通过提示框提示。所以只要响应CdialogBar的WM_SIZE来调整标签的摆放方式。至于标签栏的自绘通过响应WM_PAINT消息就可以做到。
  void CTabBar::OnSize(UINT nType, int cx, int cy)
  {
  CDialogBar::OnSize(nType, cx, cy);
  CRect rcClient;
  GetClientRect(rcClient);
  int nBarWidth = rcClient.Width();
  int nTabWidth = nBarWidth-120;
  int nCount = m_ptrArray.GetCount();
  if(nCount*m_nWidth>nTabWidth)
  {
  //平均分配位置
  int nAveWidth = nTabWidth*1.0/nCount;
  for(int i=0; i<nCount; i++)
  {
  CRect rcBtn;
  TABINFO* pTabInfo = (TABINFO*)m_ptrArray.GetAt(i);
  pTabInfo->pTabButton->GetClientRect(&rcBtn);
  pTabInfo->pTabButton->MoveWindow(nAveWidth*i,
  (rcClient.Height()-rcBtn.Height())/2,
  nAveWidth,
  m_nHeight,
  FALSE);
  }
  }
  else
  {
  //固定大小
  for(int i=0; i<nCount; i++)
  {
  CRect rcBtn;
  TABINFO* pTabInfo = (TABINFO*)m_ptrArray.GetAt(i);
  pTabInfo->pTabButton->GetClientRect(&rcBtn);
  pTabInfo->pTabButton->MoveWindow(m_nWidth*i,
  (rcClient.Height()-rcBtn.Height())/2,
  m_nWidth, m_nHeight, FALSE);
  }
  }
  Invalidate();
  }当选中标签后,鼠标移动到标签右边的时候,则会出现一个关闭按钮,用来关闭文档。所以这个里面涉及到按钮的自绘原理,这样的文章比较多,这里就不多做说明。不过俺想提个问题,对于按钮的0nDrawItem与DrawItem,是否有什么区别,如果将下面换成OnDrawItem消息响应函数是否可以?实在不懂得的话可以去跟踪CButton的源代码,就知道了。void CTabButton::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
  {
  ASSERT(lpDrawItemStruct->CtlType == ODT_BUTTON);
  CRect rcItem=lpDrawItemStruct->rcItem;
  HWND hWnd=lpDrawItemStruct->hwndItem;
  UINT nState=lpDrawItemStruct->itemState;
  HDC hDC=lpDrawItemStruct->hDC;
  CDC dc;
  dc.Attach(hDC);
  dc.SetBkMode(TRANSPARENT);
  CString strTitle;
  GetWindowText(strTitle);
  if (m_bSel)
  {
  if(!m_bmpBmpBkgnd.IsNull())
  {
  m_bmpBmpBkgnd.Draw(dc.m_hDC, CRect(0,0,10, m_bmpBmpBkgnd.GetHeight()),
  CRect(m_bmpBmpBkgnd.GetWidth()/4*2, 0, m_bmpBmpBkgnd.GetWidth()/4*2+10, m_bmpBmpBkgnd.GetHeight()));
  m_bmpBmpBkgnd.Draw(dc.m_hDC, CRect(4,0,rcItem.right-10, m_bmpBmpBkgnd.GetHeight()),
  CRect(m_bmpBmpBkgnd.GetWidth()/4*2+10, 0, m_bmpBmpBkgnd.GetWidth()/4*3-10, m_bmpBmpBkgnd.GetHeight()));
  m_bmpBmpBkgnd.Draw(dc.m_hDC, CRect(rcItem.right-10,0,rcItem.right, m_bmpBmpBkgnd.GetHeight()),
  CRect(m_bmpBmpBkgnd.GetWidth()/4*3-10, 0, m_bmpBmpBkgnd.GetWidth()/4*3, m_bmpBmpBkgnd.GetHeight()));
  }
  if(!m_bmpIcon.IsNull())
  {
  m_bmpIcon.Draw(dc.m_hDC, CRect(4, 4, 4+m_bmpIcon.GetWidth(), 4+m_bmpIcon.GetHeight()),  CRect(0,0,m_bmpIcon.GetWidth(), m_bmpIcon.GetHeight()));
  }
  CRect rcLabel;
  rcLabel.left = rcItem.left+4*2+16;
  rcLabel.top = rcItem.top;
  rcLabel.right = rcItem.right - (4*2+16);
  rcLabel.bottom = rcItem.bottom;
  dc.SetTextColor(RGB(0xff,0xff,0xff));
  dc.DrawText(strTitle, &rcLabel, DT_SINGLELINE | DT_VCENTER | DT_WORD_ELLIPSIS);
  if(m_bOverCloseButton)
  {
  if(!m_bmpClose.IsNull())
  {
  m_bmpClose.Draw(dc.m_hDC,
  CRect(rcItem.Width()-m_bmpClose.GetWidth()/3-5,
  (rcItem.Height()-m_bmpClose.GetHeight())/2,rcItem.Width()-2,
  (rcItem.Height()-m_bmpClose.GetHeight())/2+m_bmpClose.GetHeight()),
  CRect(m_bmpClose.GetWidth()/3, 0, m_bmpClose.GetWidth()/3*2, m_bmpClose.GetHeight()));
  }
  }
  else
  {
  if(!m_bmpClose.IsNull())
  {
  m_bmpClose.Draw(dc.m_hDC, CRect(rcItem.Width()-m_bmpClose.GetWidth()/3-5,
  (rcItem.Height()-m_bmpClose.GetHeight())/2,rcItem.Width()-2,
  (rcItem.Height()-m_bmpClose.GetHeight())/2+m_bmpClose.GetHeight()),
  CRect(0, 0, m_bmpClose.GetWidth()/3, m_bmpClose.GetHeight()));
  }
  }
  }

[1] [2] 下一页

责任编辑:cyth

文章搜索:
 相关文章
热点资讯
资讯快报
热门课程培训