65.9K
CodeProject 正在变化。 阅读更多。
Home

CInputEvent 类

starIconstarIconstarIconstarIconemptyStarIcon

4.00/5 (3投票s)

2003年3月7日

2分钟阅读

viewsIcon

46117

downloadIcon

679

为您的自绘控件提供更简单的鼠标事件管理。

引言

CInputEvent 类管理鼠标事件。它更新一个数据结构,该结构在 DrawItem 或 OnPaint 方法中可用,以便您可以以正确的视觉状态绘制控件。

使用代码

该类避免了使用通常用于获取按钮状态的所有方法。Button 类不再需要所有 OnLButtonDownOnMouseMove 等方法。此外,所有通常的 m_OverTracking、m_ButtonDownTrackMouseEvent 等都不需要在派生的 CWnd 类(按钮、静态控件等)中。

数据结构会针对收到的每个消息进行更新。当需要绘制按钮时,例如在 DrawItem() 方法中,您只需要获取按钮状态,然后绘制相应的位图、文本或您想要的任何内容。

使用方法

声明一个指向 CInputEvent 数据的指针

CInputEvent* m_pInputEvent;
在 CWnd 按钮创建后,在 PreSubclassWindow 中初始化此数据。
void CMyButton::PreSubclassWindow() 
{
    //--------------------------------------------------
    // Init InputEvents
    //--------------------------------------------------
    m_pInputEvent = new CInputEvent(this);
    CButton::PreSubclassWindow();
}

PreTranslateMessage(MSG* pMsg) 中过滤 Windows 消息。这将填充一个数据结构,该结构会更新按钮状态。

CInputEvent 类将过滤消息

WM_MOUSEMOVE
WM_MOUSELEAVE
WM_LBUTTONDOWN
WM_LBUTTONUP
WM_LBUTTONDBLCLK
BOOL CMyButton::PreTranslateMessage(MSG* pMsg) 
{
    //--------------------------------------------------
    // Pass message to CInputEvent and relay it or not to mother class
    //--------------------------------------------------
    m_pInputEvent->RelayMsg(pMsg);
    return CButton::PreTranslateMessage(pMsg);
}

DrawItem 方法中,获取 InputStatus 结构。该结构包含按钮状态、客户端矩形 (CRect)、鼠标坐标、Ctrl 和 Shift 键的状态以及其他鼠标按钮。

这是演示代码

void CMyButton::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct) 
{
    // Gets Button status
    CInputEvent::INPUTSTATUS ips;
    m_pInputEvent->GetStatus(&ips);
    CString    str;

    // Gets DC
    CDC* pDC=CDC::FromHandle(lpDrawItemStruct->hDC);

    // Button is disabled
    if (lpDrawItemStruct->itemState & ODS_DISABLED)
    {
        str="Disabled";
    }
    else
    {
        switch (ips.drawPosition)
        {
        case 1:     //CInputEvent::DRAW_NORMAL:
            str="Normal";
            break;
        case 2:     //CInputEvent::DRAW_OVER:
            str="Over";
            break;
        case 3:     //CInputEvent::DRAW_PUSHED:
            str="Pushed";
            break;
        }
    }
    
    pDC->FillSolidRect(&ips.rect, RGB(100,200,255));
    pDC->DrawText(str, &ips.rect, DT_CENTER|DT_VCENTER|DT_SINGLELINE);
}
请注意,禁用状态未被管理,因为按钮在接收 WM_ENABLE 消息之前已被禁用。因此,我使用 DrawItem 结构来获取此信息。我可以使用 WindowProc 方法,但它会接收来自其他控件的消息。

在按钮析构函数中删除 CInputEvent 数据。

CMyButton::~CMyButton()
{
    // free memory
    delete m_pInputEvent;
}

关注点

使用此类可以避免重载 Ownerdraw 按钮类或响应鼠标的图形静态控件。

另一个重点是 Windows 消息过滤。该类可以管理收到的任何消息。很容易添加鼠标滚轮、右键单击、键盘输入等,以管理任何控件的绘制。

© . All rights reserved.