我现在在做一个自定义控件 CMyButton::CButton 。要实现的需求大概是这样的:
1、单击会弹出一个窗口 
2、鼠标放在上边时会有浮动提示窗口显示按钮属性
3、按“delete”键可把按钮删除每个单独的响应我都做好了,都没有问题,但是同时放在一个程序里时就有响应冲突。
1、2同时存在时可以正常响应。
1、3同时存在,或2、3同时存在时,3就不会响应。我的响应代码如下:
void CMyButton::OnLButtonDown(UINT nFlags, CPoint point)
{
    dlg1 dlg;
    dlg.DoModal();
}
BOOL CMyButton::PreTranslateMessage(MSG* pMsg)
{

if(pMsg->message   ==   WM_KEYDOWN)  
{  
if(pMsg->wParam   ==  VK_DELETE)  
{  
DestroyWindow();
        delete this;
return   TRUE;  
}  
} tip.RelayEvent(pMsg);  //CMyButton类成员  CToolTipCtrl  CMyButton::tip
return CButton::PreTranslateMessage(pMsg);
}
需要怎么改才能让这些事件可以同时响应呢?

解决方案 »

  1.   

    已经解决了,只要把所有的消息都放在PreTranslateMessage中处理就可以了。
    是个很笨的办法,写出来也很丑,一大堆switch-case,不过确实有效。暂时不结贴,如果谁有更好的办法请告诉我。
      

  2.   

    MFC的ONKEWDOWN和ONCHAR从来没写通过,好像只能用PreTranslateMessage才能实现,和你怎么组合没关系
      

  3.   

    MFC的ONKEWDOWN和ONCHAR从来没写通过,好像只能用PreTranslateMessage才能实现,和你怎么组合没关系————————————————我还是第一次知道这个啊。谢谢你告诉我。其实我之前有做实验,直接拖了一个按钮控件到对话框上,然后加入OnClick事件、ONKEWDOWN事件和ONCHAR事件。
    ONCHAR事件确实好像没有相应。
    但是ONKEWDOWN事件单独存在的时候是可以响应的,不过一加入其它的事件,它就不会响应了,一定要用PreTranslateMessage。
    我再去找找其它资料吧。
      

  4.   

    多加一个判断WM_MOUSEMOVE,在里面 tip.RelayEvent(pMsg); 
    其余的事件直接 return CButton::PreTranslateMessage(pMsg);
    应该就行了,别的事件该写哪儿写哪儿
      

  5.   


    意思是这样么?
    BOOL CMyButton::PreTranslateMessage(MSG* pMsg)
    {
        
        if(pMsg->message   ==   WM_KEYDOWN )  
        {  
            if(pMsg->wParam   ==  VK_DELETE)  
            {  
                DestroyWindow();
                delete this;
                return   TRUE;  
            }  
        }
        if(pMsg->message == WM_MOUSEMOVE)
       {
            tip.RelayEvent(pMsg);
       } 
        return CButton::PreTranslateMessage(pMsg);
    }我试了一下,还是不能响应键盘事件。
    而且,我的OnMouseMove是有自己的处理代码的,我为了简化问题所以就把它省略掉了。
    所以,这个方法好像不能用啊。
    还是说我的理解有问题?
      

  6.   

    那就是这里了 BOOL CMyButton::PreTranslateMessage(MSG* pMsg)
    {
        
        if(pMsg->message   ==   WM_KEYDOWN )  
        {  
            if(pMsg->wParam   ==  VK_DELETE)  
            {  
                DestroyWindow();
                delete this;
                return   TRUE;  // 这里有VK_LBUTTON之类的键
                 //改为 return CButton::PreTranslateMessage(pMsg); 或者不RETRUN        }  
        }
        if(pMsg->message == WM_MOUSEMOVE)
       {
            tip.RelayEvent(pMsg);
       } 
        return CButton::PreTranslateMessage(pMsg);
    }
      

  7.   

    不是不是,上面的不算,你本来就没return...
    怪 再看看
      

  8.   

    刚才又试了一下,其实问题还是没有解决以单击事件为例。
    第一次单击控件之前,在对话框的其他部分单击鼠标,是正常的(这里没有响应事件,所以就应该是什么也没有)。
    单击了控件之后,控件也正常响应了单击事件。
    然后,再单击对话框的其它部分,也只会响应控件的单击事件,而不会响应窗口的事件或者窗口上其它控件的事件。我加了判断: if( ID_BN == GetDlgCtrlID()) , ID_BN是我的控件的ID。
    但在单击控件后再单击对话框其它部分时,GetDlgCtrlID()返回的仍是ID_BN。这个可能就是出现问题的原因。
    这时它不是应该返回对话框的ID么? 谁能帮我解释一下?或者提供一个解决方法?
      

  9.   

    自己解决了一点。上边的问题只要在PreTranslateMessage中加一个判断是否在自己的控件里的语句就可以了:
    if ( this->WindowFromPoint(pMsg->pt) == this )就算这个问题最后全部是我自己解决的,但是给我帮助或者提出建议的人的分还是不会少的。
    写出了解决过程应该也可以对别人有点帮助吧。