自绘关闭按钮

本文介绍如何实现自绘窗体的关闭按钮,涉及图标资源插入、鼠标操作处理、使用CDC类绘制图标以及设置鼠标形状等功能。通过添加鼠标移动和左键按下消息响应,结合不同状态的图标资源,改变鼠标形状,完成自定义关闭按钮的交互体验。

自绘关闭按钮涉及到插入图标资源、鼠标操作、绘制图标的类CDC、设置鼠标形状等操作。

一、至于鼠标操作,必须添加鼠标移动、鼠标左键按下的消息

BEGIN_MESSAGE_MAP(CShowDlg, CDialog)
    //{{AFX_MSG_MAP(CShowDlg)
    ON_WM_SYSCOMMAND()
    ON_WM_PAINT()
    ON_WM_QUERYDRAGICON()
    ON_WM_MOUSEMOVE()
    ON_WM_LBUTTONDOWN()
    //}}AFX_MSG_MAP
END_MESSAGE_MAP()

二、插入图标资源,资源一IDI_ICON1是鼠标在关闭区要显示的形状,资源二IDI_ICON1为鼠标不在关闭区要显示的形状。


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

    HICON hIcon1=AfxGetApp()->LoadIcon(IDI_ICON1);
    CDC *pDC = GetDC();
    CBrush br1;
    br1.CreateSolidBrush(RGB(0,20,20));
    CRect ctrlRct;
    ctrlRct.SetRect(50,150,90,190);
    /* 为图标添加底色 */
    pDC->FillRect(&ctrlRct,&br1);
    ctrlRct.SetRect(50,150,90,190);
    CPoint pt;
    /* 获取当前鼠标在电脑屏幕中的位置 */
    GetCursorPos(&pt);
    /* 将鼠标在电脑屏幕中的位置转换为窗口位置 */
    ScreenToClient(&pt);//此时pt == point都为鼠标在窗口中的相对位置

    if(ctrlRct.PtInRect(pt))
    {
    /* 鼠标在关闭图标按钮内移动 */


        #ifndef IDC_HAND
        #define IDC_HAND            MAKEINTRESOURCE(32649)
        #endif /* WINVER >= 0x0500 */
        HCURSOR hCur  =  LoadCursor( NULL  , IDC_HAND ) ;
        ::SetCursor(hCur);
    }
    else
    {
        /* 当鼠标不再关闭按钮区域内时,加载显示另一个资源 */
        hIcon1=AfxGetApp()->LoadIcon(IDI_ICON2);
    }
    pDC->DrawIcon(50,150,hIcon1);
    DestroyIcon(hIcon1);
    DeleteObject(br1);
    CDialog::OnMouseMove(nFlags, point);
}

void CShowDlg::OnLButtonDown(UINT nFlags, CPoint point) 
{
    // TODO: Add your message handler code here and/or call default
    CRect ctrlRct;
    /* 设置关闭窗口图标的位置 */
    ctrlRct.SetRect(50,150,90,190);
    if(ctrlRct.PtInRect(point))
    {
        AfxMessageBox("关闭窗口");
    }
    CDialog::OnLButtonDown(nFlags, point);
}

三、设置鼠标形状函数

/* 设置的鼠标形状在本窗口中永久生效 */
SetClassLong(this->GetSafeHwnd(),
                             GCL_HCURSOR , 
                             (LONG)LoadCursor(NULL , IDC_ARROW));

    /* SetCursor设置的鼠标形状只是临时生效,当鼠标移动时没有进行设置则会显示默认鼠标形状 */
        #ifndef IDC_HAND
        #define IDC_HAND            MAKEINTRESOURCE(32649)
        #endif /* WINVER >= 0x0500 */
        HCURSOR hCur  =  LoadCursor( NULL  , IDC_HAND ) ;
        ::SetCursor(hCur);

四、鼠标移动函数的MSDN定义

afx_msg void OnMouseMove(
            UINT nFlags,
            CPoint point
            );

当鼠标移动时调用此函数 。
参数:
    nFlags
指示各种虚拟按键是否按下 ,此参数可以是任何下列值的组合:
    MK_CONTROL当CTRL键按下时。
    MK_LBUTTON当鼠标左键按下时。
    MK_MBUTTON当鼠标中键按下时。
    MK_RBUTTON当鼠标右键按下时.
    MK_SHIFT当SHIFT按下时。
point:鼠标的X,Y坐标:该坐标为 鼠标距离截获该消息的窗口左上角的位置 是一个相对位置而不是在屏幕像素上的绝对位置。

例如:当窗口的左上角坐标为(10,10)那么当鼠标在屏幕的(10,10)像素点的时候,OnMouseMove函数point值为(0,0)因为是相对窗口左上角的相对位置。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值