WEB开发网
开发学院软件开发VC MFC程序员WTL指南(8)分隔窗口 阅读

MFC程序员WTL指南(8)分隔窗口

 2008-01-19 20:26:47 来源:WEB开发网   
核心提示:在分隔窗口的窗格中使用ActiveX控件与在对话框中使用ActiveX控件类似,使用CAxWindow类的方法在运行是创建控件,MFC程序员WTL指南(8)分隔窗口(7),然后将这个CAxWindow指定给分隔窗口的窗格,下面演示了如何在水平分隔窗口下面的窗格中使用浏览器控件:// Create the bottom

在分隔窗口的窗格中使用ActiveX控件与在对话框中使用ActiveX控件类似,使用CAxWindow类的方法在运行是创建控件,然后将这个CAxWindow指定给分隔窗口的窗格。下面演示了如何在水平分隔窗口下面的窗格中使用浏览器控件:

// Create the bottom pane (browser)
CAxWindow wndIE;
const DWORD dwIEStyle = WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN |
             WS_HSCROLL | WS_VSCROLL;
   wndIE.Create ( m_wndHorzSplit, rcDefault,
          _T("http://www.codeproject.com"), dwIEStyle );
   // Set the horizontal splitter as the client area window.
   m_hWndClient = m_wndHorzSplit;
   // Set up the splitter panes
   m_wndPaneContainer.SetClient ( m_wndFormatList );
   m_wndHorzSplit.SetSplitterPanes ( m_wndVertSplit, wndIE );
   m_wndVertSplit.SetSplitterPanes ( m_wndPaneContainer, m_wndDataViewer );

特殊绘制

如果你想改变分隔条的外观,例如在上面使用一些材质,你可以从CSplitterWindowImpl派生新类并重载DrawSplitterBar()函数。如果你只是想调整一下分隔条的外观,可以复制CSplitterWindowImpl类的函数,然后稍做修改。下面的例子就在分隔条中使用了斜交叉线图案。

template <bool t_bVertical = true>
class CMySplitterWindowT :
   public CSplitterWindowImpl<CMySplitterWindowT<t_bVertical>, t_bVertical>
{
public:
   DECLARE_WND_CLASS_EX(_T("My_SplitterWindow"),
             CS_DBLCLKS, COLOR_WINDOW)
   // Overrideables
   void DrawSplitterBar(CDCHandle dc)
   {
   RECT rect;
     if ( m_br.IsNull() )
       m_br.CreateHatchBrush ( HS_DIAGCROSS,
                   t_bVertical ? RGB(255,0,0)
                         : RGB(0,0,255) );
     if ( GetSplitterBarRect ( &rect ) )
     {
       dc.FillRect ( &rect, m_br );
       // draw 3D edge if needed
       if ( (GetExStyle() & WS_EX_CLIENTEDGE) != 0)
         dc.DrawEdge(&rect, EDGE_RAISED,
               t_bVertical ? (BF_LEFT | BF_RIGHT)
                     : (BF_TOP | BF_BOTTOM));
     }
   }
protected:
   CBrush m_br;
};
typedef CMySplitterWindowT<true>  CMySplitterWindow;
typedef CMySplitterWindowT<false>  CMyHorSplitterWindow;

这就是结果(将分隔条变宽是为了更容易看到效果):

窗格容器内的特殊绘制

CPaneContainer也有几个函数可以重载,用来改变窗格容器的外观。你可以从CPaneContainerImpl派生新类并重载你需要的方法,例如:

class CMyPaneContainer :
   public CPaneContainerImpl<CMyPaneContainer>
{
public:
   DECLARE_WND_CLASS_EX(_T("My_PaneContainer"), 0, -1)
//... overrides here ...
};

一些更有意思的方法是:

void CalcSize()

调用CalcSize()函数只是为了设置m_cxyHeader,这个变量控制着窗格容器的顶部区域的宽度和高度。不过SetPaneContainerExtendedStyle()函数中有一个BUG,导致窗格从水平切换到垂直时没有调用派生类的CalcSize()方法,你可以将CalcSize()调用改为pT->CalcSize()来修补这个BUG。

HFONT GetTitleFont()

这个方法返回一个HFONT,它被用来画顶部区域的文字,默认的值是调用GetStockObject(DEFAULT_GUI_FONT)得到的字体,也就是MS Sans Serif。如果你想改称更现代的Tahoma字体,你可以重载GetTitleFont()方法,返回你创建的Tahoma字体。

BOOL GetToolTipText(LPNMHDR lpnmh)

重载这个方法提供鼠标移到Close按钮时弹出的提示信息,这个函数实际上是TTN_GETDISPINFO的相应函数,你可以将lpnmh转换成NMTTDISPINFO*,并设置这个数据结构内相应的成员变量。记住一点,你必须检查通知代码,它可能是TTN_GETDISPINFO或TTN_GETDISPINFOW,你需要有区别的访问这两个数据结构。

void DrawPaneTitle(CDCHandle dc)

你可以重载这个方法自己画顶部区域,你可以用GetClientRect()和m_cxyHeader来计算顶部区域的范围。下面的例子演示了在水平容器的顶部区域画一个渐变填充的背景:

void CMyPaneContainer::DrawPaneTitle ( CDCHandle dc )
{
RECT rect;
   GetClientRect(&rect);
TRIVERTEX tv[] = {
   { rect.left, rect.top, 0xff00 },
   { rect.right, rect.top + m_cxyHeader, 0, 0xff00 }
};
GRADIENT_RECT gr = { 0, 1 };
   dc.GradientFill ( tv, 2, &gr, 1, GRADIENT_FILL_RECT_H );
}

例子工程代码中演示了对这几个方法的重载,使得结果看起来是这个样子的:

从上面的图中可以看到,这个演示程序有一个Splitters菜单,通过它可以在各种风格的分隔条(包括自画风格)和窗格容器之间切换,比较它们之间的异同。你还可以锁定分隔条的位置,这是通过设置和取消SPLIT_NONINTERACTIVE扩展风格来实现的。

在状态栏显示进度条

正如我在前几篇文章中做得保证那样,新的ClipSpy也演示了如何在状态条上创建进展条,它和MFC版本得功能一样,几个相关得步骤是:

  1. 得到状态条第一个窗格得坐标范围RECT
  2. 创建一个进展条作为状态条得子窗口,窗口大小就是哪个状态条窗格得大小
  3. 随着edit控件被填充的同时更新进展条的位置

这些代码在CMainFrame::CreateProgressCtrlInStatusBar()函数中。

继续

在第八章我将介绍属性页和向导对话框的用法

参考

WTL Splitters and Pane Containers by Ed Gadziemski

修改记录

July 9, 2003: 文章第一次发布。

上一页  2 3 4 5 6 7 

Tags:MFC 程序员 WTL

编辑录入:爽爽 [复制链接] [打 印]
赞助商链接