写了个button自绘,不是很懂这方面,效果是出来了,现在的问题是,如果我点中了按钮,然后不去点其他的控件,这样按钮显示的就是保持住了点中状态,但是如果触碰了其他的按钮,则变了,想实现360那样的tab,有经验的帮我看看,谢了void CUIButton::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{
CRect rect = lpDrawItemStruct->rcItem;
CDC  *mydc = CDC::FromHandle(lpDrawItemStruct->hDC);
CDC *pMemDC = new CDC;
pMemDC->CreateCompatibleDC(mydc);
UINT state = lpDrawItemStruct->itemState;
CString msg;
//保存旧对象
CBitmap *pOldBitmap;
pOldBitmap = pMemDC->SelectObject(&mybitmap); //获取按钮的状态
if (state & ODS_FOCUS)
{
m_bFocus = TRUE;
m_bSelected = TRUE;
}
else
{
m_bFocus = FALSE;
m_bSelected = FALSE;
}
if (state & ODS_SELECTED || state & ODS_DEFAULT)
{
m_bFocus = TRUE;
} if(m_bOver) //鼠标移上时
{
msg = "鼠标移上时";
::SendMessage(hWnd,WM_SHOWSTATE_MESSAGE,0,(LPARAM)msg.AllocSysString());
mydc->BitBlt(0,0,m_ButtonSize.cx,m_ButtonSize.cy,pMemDC,m_ButtonSize.cx*2,0,SRCCOPY);
}
else
{
msg = "鼠标没有移上时";
::SendMessage(hWnd,WM_SHOWSTATE_MESSAGE,0,(LPARAM)msg.AllocSysString());
mydc->BitBlt(0,0,m_ButtonSize.cx,m_ButtonSize.cy,pMemDC,0,0,SRCCOPY);
} if (m_bOver || m_bSelected) //鼠标移至上面且选中
{
msg = "鼠标移上且选中";
::SendMessage(hWnd,WM_SHOWSTATE_MESSAGE,0,(LPARAM)msg.AllocSysString());
mydc->BitBlt(0,0,m_ButtonSize.cx,m_ButtonSize.cy,pMemDC,m_ButtonSize.cx,0,SRCCOPY);
}
pMemDC->SelectObject(pOldBitmap);
delete pMemDC;
}void CUIButton::OnMouseMove(UINT nFlags, CPoint point)
{
if (!m_bTracking)
{
TRACKMOUSEEVENT tme;
tme.cbSize = sizeof(tme);
tme.hwndTrack = m_hWnd;
tme.dwFlags = TME_LEAVE | TME_HOVER;
tme.dwHoverTime = 1;
m_bTracking = _TrackMouseEvent(&tme);
} CButton::OnMouseMove(nFlags, point);
}BOOL CUIButton::OnEraseBkgnd(CDC* pDC)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值 return true;
}LRESULT CUIButton::OnMouseLeave(WPARAM wParam, LPARAM lParam)
{
m_bOver = FALSE;
m_bTracking = FALSE;
InvalidateRect(NULL, FALSE);
return 0;
}LRESULT CUIButton::OnMouseHover(WPARAM wParam, LPARAM lParam)
{
m_bOver = TRUE;
InvalidateRect(NULL);
return 0;
}
void CUIButton::PreSubclassWindow()
{
// TODO: 在此添加专用代码和/或调用基类 CButton::PreSubclassWindow();
ModifyStyle(0, BS_OWNERDRAW);
//设置按钮的有效区域
CRgn rgn;
CRect rc;
GetClientRect(&rc);
//有效区域为一个角半径为5的圆角矩形
rgn.CreateRoundRectRgn(rc.left,rc.top,rc.right,rc.bottom,5,5);
SetWindowRgn(rgn,TRUE);
rgn.DeleteObject();
}bool CUIButton::LoadBitmap(UINT bitmapid)
{
//载入图片
mybitmap.Attach(::LoadImage(::AfxGetInstanceHandle(),MAKEINTRESOURCE(bitmapid),IMAGE_BITMAP,0,0,LR_LOADMAP3DCOLORS));
BITMAP bitmapbits; //获取位图信息并保存入bitmapbits结构中
mybitmap.GetBitmap(&bitmapbits); //取位图相应的高度和1/3宽度
m_ButtonSize.cy = bitmapbits.bmHeight;
m_ButtonSize.cx = bitmapbits.bmWidth/3; SetWindowPos(NULL,0,0,m_ButtonSize.cx,m_ButtonSize.cy,SWP_NOMOVE|SWP_NOOWNERZORDER); return true;
}

解决方案 »

  1.   

    设置下按钮的类型 BS_AUTORADIOBOX 应该是这个吧 就是单选按钮的类型
      

  2.   

    设置一个变量替换 m_bSelected。通过主窗口控制,
      

  3.   

    你要控件嘛,哥可以给你做一个
    你要用按钮仿出360的效果嘛,比较......
    呵呵,哈哈,嘿嘿嘿嘿好好学自绘吧,从CWnd自绘一个,搞啥子拼凑哦
      

  4.   

    看了楼主写的程序
    很好的风范遗憾啊,这么好的底子
    咋就总和这些控件纠缠呢?特别是Tab,是最简单的了,你真的可以通过用CWnd来做个Tab
    从而学习比较彻底一点的自绘
    从而彻底解决从垃圾派生垃圾的历史有你那么多代码,十个漂亮Tab都弄出来了
    走绕路了,兄弟你看
    鼠标响应你会
    图片装载绘制你会
    消息发送接受你会
    区域操作你会我确实想不通你们是怎么想的
    难道拿张凳子 改张桌子 真的真的要比直接拿木料做简单
    郁闷,相当郁闷................
      

  5.   

    很好的建议,虽然我自己现在把这个问题解决了,不过还是决定去研究下从CWnd继承,对界面的了解比较少,现在打算深入下,谢了
      

  6.   

    曾经用CButtonST,然后换图片样式来解决楼主的这个情况。
      

  7.   


    你来晚了老虎兄,我也用了CButtonST,但是就是做不出美工给的图片效果,所以才决定采用自绘,恨自己没研究过自绘
      

  8.   

    继承过来,然后自己设置一个BOOL值控制,设置不同的图片,然后再逻辑上作个互斥就行了。