所有者绘制按钮助手类

介绍 这只是一个类的表示,它可以用作所有者绘制按钮的中间类。 使用的代码 当创建一个owner draw按钮时,我们像这样开始… 隐藏,复制Code

class CMyButton : public CButton
{
    // class content related custom drawing
};

我所做的是从CButton派生了一个名为CODBaseBtn的类,它与绘图没有任何关系。相反,调用一些虚函数。这使得它成为所有者绘制按钮的中间类。 隐藏,复制Code

class CODBaseBtn : public CButton
{
    // Basic handling of events and virtual functions for drawing
}

提供了两种虚函数: 画relatedAction相关 图中相关虚函数如下… 隐藏,复制Code

virtual void OnDrawNormal( CDC& dc, CRect rect ) = 0;
virtual void OnDrawHovered( CDC& dc, CRect rect ) { OnDrawNormal( dc, rect ); }
virtual void OnDrawPressed( CDC& dc, CRect rect ) { OnDrawNormal( dc, rect ); }
virtual void OnDrawDisabled( CDC& dc, CRect rect ) { OnDrawNormal( dc, rect ); }

第一个函数是纯虚函数,它必须由派生类实现。顾名思义,这些函数在相应的条件下调用。因此派生类可以处理它们并绘制适当的按钮图像。 与动作相关的虚函数如下… 隐藏,复制Code

virtual void OnBeginHover() { }
virtual void OnEndHover() { }
virtual void OnPressed() { }
virtual void OnReleased() { }

它们分别在鼠标悬停、鼠标离开、按下和释放等操作上被调用。可以明智地使用它们来扩展普通按钮的功能。它们不是纯虚拟的,所以如果不需要,可以避免使用。 从CODBaseBtn派生一个类如下所示… 隐藏,复制Code

class CMyBtn : public CODBaseBtn
{
    // Implementation of custom drawings and actions.
}

样例应用程序 示例测试应用程序有两个派生类。一种是使用相关函数的绘图。而另一种则同时使用绘图和动作相关的功能。由此,可以理解这样一个类的可能性。 绘图非常简单,因为测试应用程序只是为了演示CODBaseBtn的使用。 内部CODBaseBtn CODBaseBtn内部的主要代码描述如下: 隐藏,复制Code

void CODBaseBtn::PreSubclassWindow()
{
    // Some code...


    // Update the style to owner draw
    ModifyStyle( 0, BS_OWNERDRAW );

    // Some code...
}

样式设置为BS_OWNERDRAW以启用按钮所有者绘制。这有助于避免在对话框资源编辑器中或在运行时使用Create(或CreateWindow)创建按钮时设置此样式。 隐藏,复制Code

void CODBaseBtn::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{
    // The virtual functions are called from here
}

DrawItem是CButton的一个虚拟函数。当需要绘制按钮时调用它。lpDrawItemStruct将包含绘制所需的内容,如hDC、客户端矩形、按钮状态等。使用这些函数,可以调用用于绘制和操作的适当虚函数。 隐藏,复制Code

void CODBaseBtn::OnMouseMove(UINT nFlags, CPoint point)
{
    if( !m_bMouseHover )
    {
        // Set the flag so that next mouse move message will be neglected
        m_bMouseHover = true;

        // Some code to register the mouse leave message
    }
}

这是鼠标悬停处理。当鼠标在按钮内部时,m_bMouseHover将为false(最初设置为false)。在函数内部,它被设为真。因此,当鼠标再次移动到按钮内时,可以忽略它。第一次,调用相应的绘图和操作函数,并使用_TrackMouseEvent注册鼠标留言请求。当鼠标离开按钮(客户端)区域时,将调用以下函数。 隐藏,复制Code

LRESULT CODBaseBtn::OnMouseLeave( WPARAM, LPARAM )
{
    // Reset the flag
    m_bMouseHover = false;

    // Some code...

    return 0;
}

这里,m_bMouseHover被重置为false。调用绘制和动作函数的必要调用: 隐藏,复制Code

void CODBaseBtn::OnLButtonDblClk(UINT nFlags, CPoint point)
{
    // Convert the double click to single click
    const MSG* pstMSG = GetCurrentMessage();
    DefWindowProc( WM_LBUTTONDOWN, pstMSG->wParam, pstMSG->lParam );
}

这是一个棘手的问题。具有BS_OWNERDRAW样式的按钮不会像普通按钮那样对双击作出响应。解如上所述。当双击发生时,用WM_LBUTTONDOWN调用按钮的默认窗口过程,而不是实际的WM_LBUTTONDBLCLK。 结论 提供的类可以用作CButton和所有者绘制按钮的派生类之间的层。它将有助于避免大量代码,而且非常有用。 历史 一个也没有。 本文转载于:http://www.diyabc.com/frontweb/news443.html

posted @ 2020-08-07 02:03  Dincat  阅读(136)  评论(0编辑  收藏  举报