随笔-59  评论-36  文章-0  trackbacks-0

这两天遇见了如何让CListBox的内容响应鼠标右键的问题,没有头绪,Google了半天,基本上都是清一色的答复:从clistbox派生一个类,且响应WM_RBUTTONDOWN消息。但起初的实践发现,这种方法只是让整个控件响应右键,而我想要的是让其内容响应。
后来才发现是我没有领悟“答复”的真谛。

为让CListBox类响应鼠标右键,需要从CListBox类派生出一个新类,且在该派生类中添加一个WM_RBUTTONDOWN消息的响应函数,例如如下代码:

void newlist::OnRButtonDown(UINT nFlags, CPoint point) 
{
    
// TODO: Add your message handler code here and/or call default

    MessageBox(_T(
"Ok,响应鼠标右键!"));

    CListBox::OnRButtonDown(nFlags, point);
}

以上这段代码是让整个listbox空间响应右键,为了只让listbox中的条目响应右击则需要更改为:
void newlist::OnRButtonDown(UINT nFlags, CPoint point) 
{
    
// TODO: Add your message handler code here and/or call default
    int i = GetCurSel();
    
if(LB_ERR != i)
    {
        MessageBox(
"ok");
    }

    CListBox::OnRButtonDown(nFlags, point);
}

因为当listbox没有选中内容或多选时,GetCurSel函数返回LB_ERR,于是可以借由GetCurSel函数来实现只让listbox中的条目响应鼠标右击,而非整个控件。
P.S: 一旦能够让listbox的内容响应右键,那么就可以对listbox的内容实现右键弹出菜单了,这正我想要的。下附右击listbox中的内容弹出菜单
void newlist::OnRButtonDown(UINT nFlags, CPoint point)
{
    
// TODO: 在此添加消息处理程序代码和/或调用默认值

    POINT curpoint;
    GetCursorPos(
&curpoint);
    ScreenToClient(
&curpoint);

    RECT test;
    
int i = 0;

    
while(i<= GetCount())
    {
        GetItemRect(i, 
&test);

        
if (curpoint.y < test.bottom)
        {
            
// 将当前右击项选中
            SetCurSel(i);

            
// 加载弹出菜单
            CMenu temp,*ptr;
            temp.LoadMenu(IDR_MENU1);
            ptr 
= temp.GetSubMenu(0);
            ClientToScreen(
&point);
            ptr
->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON,point.x,point.y,GetParent());

            
break;
        }
        
else
            
// 若之前选中了某项,而现在的右击又没有击中选项,则取消之前的选项
            SetCurSel(-1);

        i
++;
    }

    CListBox::OnRButtonDown(nFlags, point);
}
posted on 2009-11-30 02:54 zhaoyg 阅读(3024) 评论(0)  编辑 收藏 引用 所属分类: MFC学习笔记

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   博问   Chat2DB   管理