• 一个自动重复按钮类


    介绍 我需要一个自动重复按钮。当用户按下按钮时,它会发出多个BN_CLICKED 通知。我搜索了一下,发现了Joseph M. Newcomer的文章“自动重复按钮类”。虽然文章中的代码和广告中的完全一样,但它有一个主要的缺陷。当用户按下空格键时,它不工作,它只与鼠标左键工作。文章后附的评论提供了一些如何修复它的想法,但没有一个是理想的。我采纳了这篇文章中提出的想法和一些评论,编写了我在这里分享的代码。 使用的代码 让按钮控件做我需要它做的事情的最好方法是子类化cbuttoncontrol并覆盖它的OnLButtonDown、OnLButtonUp、OnKeyDown和onkeyupmessage处理器。我添加了4个bool 成员变量,作为标志来控制在使用控件时发生了什么以及接下来必须发生什么。前两个变量是keypress&和mousepress&which控制是鼠标按钮还是空格键启动计时器。下一个是TimerActive 防止计时器被重新启动时,按键自动重复。最后一个是控制按钮被释放时是否发送消息的messagesent。 隐藏,收缩,复制Code

    void CAutoRepeatButton::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
    {
        if (!MousePress)    // Only if not already activated by the mouse
        {
            if (VK_SPACE == nChar && !TimerActive)
            {
                SetTimer(TIMERID, InitialTime, NULL);
                TimerActive = true;
                KeyPress = true;
            }
    
            CButton::OnKeyDown(nChar, nRepCnt, nFlags);
        }
    }
    
    void CAutoRepeatButton::OnLButtonDown(UINT nFlags, CPoint point)
    {
        if (!KeyPress)  // Only if not already activated with the space bar
        {
            if (!TimerActive)
            {
                SetTimer(TIMERID, InitialTime, NULL);
                TimerActive = true;
                MousePress = true;
            }
    
            CButton::OnLButtonDown(nFlags, point);
        }
    }

    当用鼠标左键或空格键按下按钮时,我们首先检查该按钮是否已被另一个按钮激活。然后我们检查计时器是否还没有启动,如果没有启动,则用初始延迟时间启动它。最后,调用基类处理程序来执行默认处理程序,该处理程序捕获鼠标并将按钮绘制为按下按钮。 隐藏,复制Code

    void CAutoRepeatButton::OnTimer(UINT_PTR nIDEvent)
    {
        if (nIDEvent == TIMERID)
        {
            if (BST_PUSHED == (BST_PUSHED & GetState()))
            {
                if (!MessageSent)
                {
                    SetTimer(TIMERID, RepeatTime, NULL);
                    MessageSent = true;
                }
                Parent->SendMessage(WM_COMMAND, MAKELPARAM(GetDlgCtrlID(), BN_CLICKED), (WPARAM)m_hWnd);
            }
        }
        else
        {
            CButton::OnTimer(nIDEvent);
        }
    }

    当定时器触发时,我们首先检查按钮的状态。如果鼠标被用来开始定时器,然后它被移离按钮,按钮将不再被按下,所以我们将不希望消息被发送。但我们希望当鼠标移动到按钮上时它们继续。在初始时间延迟之后,定时器被重置为重复时间,a 被发送消息。 隐藏,收缩,复制Code

    void CAutoRepeatButton::OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags)
    {
        if (VK_SPACE == nChar && KeyPress)
        {
            KillTimer(TIMERID);
            if (MessageSent)
            {
                ReleaseCapture();   // CButton::OnKeyDown captures the mouse
                SetState(0);        // Redraw button as not pushed
            }
            else
            {
                CButton::OnKeyUp(nChar, nRepCnt, nFlags);
            }
            TimerActive = false;
            KeyPress = false;
            MessageSent = false;
        }
    }
    
    void CAutoRepeatButton::OnLButtonUp(UINT nFlags, CPoint point)
    {
        if (MousePress)
        {
            KillTimer(TIMERID);
            if (MessageSent)
            {
                ReleaseCapture();
                SetState(0);
            }
            else
            {
                CButton::OnLButtonUp(nFlags, point);
            }
            TimerActive = false;
            MousePress = false;
            MessageSent = false;
        }
    } 

    当按钮被释放时,计时器停止。然后,根据按钮是否被长时间按住以生成BN_CLICKED 消息,我们要么简单地释放鼠标捕获并绘制按钮作为未按下,或者我们调用基类处理程序来发射BN_CLICKED 消息。然后在下一次按下按钮时重新设置标志。 隐藏,复制Code

    void CAutoRepeatButton::OnLButtonDblClk(UINT nFlags, CPoint point)
    {
        OnLButtonDown(nFlags, point);
    }

    最后要处理的是用户双击按钮后按住按钮。我只是调用onlbuttondown来将双击视为第二次单击。如果不这样做,则计时器不会启动。 隐藏,复制Code

    void CAutoRepeatButton::SetTimes(UINT Initial, UINT Repeat)
    {
        InitialTime = Initial;
        RepeatTime = Repeat;
    }

    最后,作为一个方便的函数,我添加了设置初始和重复延迟时间间隔的功能。 历史 2017年4月13日——发表在CodeProject上 本文转载于:http://www.diyabc.com/frontweb/news359.html

  • 相关阅读:
    基础面试
    三级联动
    数据库分裤分表操作
    缓存的三种方式
    php部分--session的三种用法
    css
    数组
    生成中国地区随机IP
    xml的读取
    React入门
  • 原文地址:https://www.cnblogs.com/Dincat/p/13443794.html
Copyright © 2020-2023  润新知