如何实现当一个按钮按下后,如果不松开它,就会一直向窗口发送按下的消息?10/s,
就向键盘一样?我在:onTimer()中不知道如何向窗口发送click消息?

解决方案 »

  1.   

    你的程序逻辑有问题哦。onTimer里干嘛要向窗口发送click消息?你的按钮不断地收到click消息,就不断地创建timer,然后再不断地收到click消息……如此下去,岂不是没完了?
        你要干什么事,直接在ontimer里做就是了。
      

  2.   

    是的。
    是SendMessage(WM_COMMAND,id,0) 到Parent吗?
      

  3.   

    OnLButtonDown 时设置一个 10/s Timer, 同时设置一个标志使 Timer 不被重复设置,OnLButtonUp 清除标志并 KillTimer.然后 OnTimer 中发送 Command 消息到父窗口
      

  4.   

    有什么事在OnTimer里做就是了,干嘛一定要发送click消息呢?
      

  5.   

    In355Hz(好象一条狗) 的方法是不行的。因为在同一个主线程中会阻塞。
    启用另一个线程是一个选择。
      

  6.   

    阻塞 ?向同一线程的窗口 SendMessage(WM_COMMAND,...) 不会阻塞吧,这个 SendMessage 会直接调用目标 WindowProc 。此外的确如 webber84(***闭关修炼中***) 所说,尽量少用 Timer 这种系统资源, 并可能造成 message queue 负担过重。
      

  7.   

         主线程正在处理wm_lbuttondown, 在这个消息处理函数返回之前,不会读消息队列。
         但是,如果你自己调用PEEKMESSAGE,也可以解决。
      

  8.   

    SendMessage, from MSDN:If the specified window was created by the calling thread, the window procedure is called immediately as a subroutine. If the specified window was created by a different thread, the system switches to that thread and calls the appropriate window procedure.
      

  9.   

    我试过,前提是父窗口和子窗口是由同一线程创建:RepeatBtn.h :省略了所有 MFC 头文件都有的代码/////////////////////////////////////////////////////////////////////////////
    // CRepeatBtn windowclass CRepeatBtn : public CButton
    {
    // Construction
    public:
    CRepeatBtn();// Attributes
    public:
    DWORD m_dwRepeatTimer;// Operations
    public:// Overrides
    // ClassWizard generated virtual function overrides
    //{{AFX_VIRTUAL(CRepeatBtn)
    //}}AFX_VIRTUAL// Implementation
    public:
    virtual ~CRepeatBtn(); // Generated message map functions
    protected:
    //{{AFX_MSG(CRepeatBtn)
    afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
    afx_msg void OnLButtonUp(UINT nFlags, CPoint point);
    afx_msg void OnTimer(UINT nIDEvent);
    //}}AFX_MSG DECLARE_MESSAGE_MAP()
    };RepeatBnt.cpp :省略了所有 MFC 源文件都有的代码#define ID_TIMER_REPEATBTN 1024/////////////////////////////////////////////////////////////////////////////
    // CRepeatBtnCRepeatBtn::CRepeatBtn()
    {
    m_dwRepeatTimer = 0;
    }CRepeatBtn::~CRepeatBtn()
    {
    if (m_dwRepeatTimer)
    {
    KillTimer(m_dwRepeatTimer);
    }
    }BEGIN_MESSAGE_MAP(CRepeatBtn, CButton)
    //{{AFX_MSG_MAP(CRepeatBtn)
    ON_WM_LBUTTONDOWN()
    ON_WM_LBUTTONUP()
    ON_WM_TIMER()
    //}}AFX_MSG_MAP
    END_MESSAGE_MAP()/////////////////////////////////////////////////////////////////////////////
    // CRepeatBtn message handlersvoid CRepeatBtn::OnLButtonDown(UINT nFlags, CPoint point) 
    {
    m_dwRepeatTimer = SetTimer(ID_TIMER_REPEATBTN, 100, NULL);

    CButton::OnLButtonDown(nFlags, point);
    }void CRepeatBtn::OnLButtonUp(UINT nFlags, CPoint point) 
    {
    if (m_dwRepeatTimer)
    {
    KillTimer(m_dwRepeatTimer);
    m_dwRepeatTimer = 0;
    }

    CButton::OnLButtonUp(nFlags, point);
    }void CRepeatBtn::OnTimer(UINT nIDEvent) 
    {
    CWnd *pParent = GetParent(); if (ID_TIMER_REPEATBTN == nIDEvent && pParent)
    {
    pParent->SendMessage(WM_COMMAND, 
    MAKEWPARAM(GetDlgCtrlID(), BN_CLICKED), (LPARAM)GetSafeHwnd());
    }
    }
      

  10.   

    谢谢In355Hz(好象一条狗),问题解决了。
    给分啦!!