CRegionButton -一个多向按钮

介绍 本文简要讨论了如何创建充当多向按钮的button类。大多数按钮在单击时执行任务。无论你在哪里点击这个按钮,任务都是一样的。如果任务碰巧是像在视窗的某个方向移动一个对象(例如,左),你需要每个方向一个按钮。可行,但有点笨拙。 稍微的改进可能是使用两个旋转按钮控件,一个是UDS_HORZ样式,另一个是UDS_VERT样式。这两个控件可以放在一起,产生类似: 虽然不是不正确,但这种方法有几个缺点。第一个是控件没有干净地重叠。很明显,一个控件实际上遮蔽了另一个控件。这可能被认为是一个小烦恼。 其次,每个控件都需要自己的CSpinButtonCtrl变量,这也意味着需要两个UDN_DELTAPOS处理程序。这些处理程序可能看起来像:复制Code

void CRegionButtonTestDlg::OnDeltaposHorz(NMHDR* pNMHDR, LRESULT* pResult) 
{
    NM_UPDOWN *pNMUpDown = (NM_UPDOWN *) pNMHDR;

    if (0 < pNMUpDown->iDelta)
        ; // left
    else
        ; // right
 
    *pResult = 0;
}

void CRegionButtonTestDlg::OnDeltaposVert(NMHDR* pNMHDR, LRESULT* pResult) 
{
    NM_UPDOWN *pNMUpDown = (NM_UPDOWN *) pNMHDR;

    if (0 < pNMUpDown->iDelta)
        ; // down
    else
        ; // up

    *pResult = 0;
}

如果您需要在一个处理程序中进行更改,那么您可能也需要在另一个处理程序中进行更改。复制代码很少有乐趣。 更好的解决方案是使用一个根据单击位置而表现不同的控件。一个按钮很好地满足了这一需求。 我创建的类CRegionButton派生自CBitmapButton,非常容易使用。它有两个私有成员变量和一个公共方法。这两个成员变量用于跟踪按钮上的不同区域。它目前适用于4或9个区域,但其他数字只要是完全平方的就可以使用(例如,16,25)。 公共方法CalculateRegions()实际上是所有“魔法”发生的地方。它应该在LoadBitmaps()之后调用。这个方法将创建一个代表位图不同区域的CRect对象数组。 在4区域按钮的情况下,该按钮将被平均划分为4个区域,编号从0到3。 因此,如果用于按钮的位图是80x80像素,按钮的区域0将是l=0, t=0, r=39,和b=39。 一旦计算了区域,现在只需使用BN_CLICKED处理程序检测鼠标点击即可。其代码如下:Hide  收缩,复制Code

void CRegionButton::OnClicked() 
{
    CPoint  pt;
    DWORD   dwPos;
    
    // where was the mouse clicked
    dwPos = GetMessagePos();

    // get the X/Y screen coordinates
    pt.x = LOWORD(dwPos);
    pt.y = HIWORD(dwPos);

    // convert them to client coordinates
    ScreenToClient(&pt);

    // see if the mouse click is within any of the regions
    for (UINT x = 0; x < m_uRegionCount; x++)
    {
        // if so, send a message to the parent
        // including the region that was clicked
        if (m_pRegion[x].PtInRect(pt) != FALSE)
        {
            GetParent()->SendMessage(UDM_REGION_CLICKED, x);
            break;
        }
    }
}

发送到父节点的消息是通过调用RegisterWindowMessage()创建的注册消息。您可以在类的.h文件中看到此消息的实现。请注意,所单击的区域是作为WPARAM参数发送的。 此时,剩下要做的惟一事情就是响应消息。需要将ON_REGISTERED_MESSAGE()条目添加到对话框的消息映射中。其代码如下:Hide  复制Code

LRESULT CRegionButtonTestDlg::OnRegionClicked( WPARAM wParam, LPARAM lParam )
{
    CString     str;

    str.Format("You clicked in region %u", wParam);

    return (0);
}

现在,我们只有一个方法,不管我们点击按钮在哪里都会被调用,而且还会告诉我们点击了按钮的哪里。当使用时,这个按钮可能看起来像: 享受吧! 本文转载于:http://www.diyabc.com/frontweb/news526.html

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