当前位置:C++技术网 > 资讯 > 按钮控件怎么自绘

按钮控件怎么自绘

更新时间:2015-06-25 16:28:13浏览次数:1+次

控件自绘的方式有两种:

1.直接在父窗口进行自绘(本文所讲述的)

2.将控件的自绘封装成一个类,控件类中自己绘制(本文不讲,参考其他文章)

-----------------------------------------------------------------
实现过程:

1.在主窗口中放置一个按钮

2.设置按钮的行为为:Owner Draw (控件自绘)
设置此行为后,控件需要自己绘制,否则显示不了控件。默认没有设置,系统会绘制此控件。
如图:


3.对父窗口的WM_DRAWITEM消息进行处理
在父窗口资源对话框中,右击,查看属性,如下图:


找到WM_DRAWITEM,添加处理函数。如图:


添加消息处理后,如下图:


4.消息处理函数OnDrawItem(int nIDCtl, LPDRAWITEMSTRUCT lpDrawItemStruct)
第一个参数int nIDCtl是控件ID,可以通过IF语句对ID进行判断,然后对不同的ID的控件进行自绘。上图中可以看出,有两个按钮,判断后调用相应的函数进行自绘处理。当然,我都使用了相同的方式自绘。注意,调用函数要将第二个参数LPDRAWITEMSTRUCT lpDrawItemStruct传给自绘函数。这个参数是自绘结构体,有自绘需要的各种信息。

5.自绘函数编写。
具体的每一句就不详细解释了。代码中有注释。

void C自绘按钮Dlg::draw(LPDRAWITEMSTRUCT lpDrawItemStruct)
{
    CDC ButtonDC;
    CBitmap bitmapTrans;
    BITMAP bmp;
    CDC mem;
    CRect rc;
    //得到用于绘制按钮的DC
    ButtonDC.Attach(lpDrawItemStruct->hDC);
    //准备用于向按钮区域传输位图
    mem.CreateCompatibleDC(&ButtonDC);
    //获取按钮所占的矩形大小
    rc=lpDrawItemStruct->rcItem;
    //获取按钮目前所处的状态,根据不同的状态绘制不同的按钮
    UINT state = lpDrawItemStruct->itemState;
    //如果按钮已经得到焦点,绘制选中状态下的按钮
    if(state&ODS_FOCUS)
    {
        bitmapTrans.LoadBitmap(IDB_BITMAP2);
        bitmapTrans.GetBitmap(&bmp);
        CBitmap *old=mem.SelectObject(&bitmapTrans);
        //向按钮所在位置传输位图
        //使用StretcnBlt的目的是为了让位图随按钮的大小而改变
        ButtonDC.StretchBlt(rc.left,rc.top,rc.right,rc.bottom,&mem,0,0,bmp.bmWidth,bmp.bmHeight,SRCCOPY);
        mem.SelectObject(old);
        bitmapTrans.DeleteObject();
    }
    else
    {
        bitmapTrans.LoadBitmap(IDB_BITMAP1);
        CBitmap *old2 = mem.SelectObject(&bitmapTrans);
        bitmapTrans.GetBitmap(&bmp);
        CBitmap *old=mem.SelectObject(&bitmapTrans);
        ButtonDC.StretchBlt(rc.left,rc.top,rc.right,rc.bottom,&mem,0,0,bmp.bmWidth,bmp.bmHeight,SRCCOPY);
        mem.SelectObject(old2);
        bitmapTrans.DeleteObject();
    }
}

IDB_BITMAP1IDB_BITMAP2是两个Bitmap资源,需要提前添加以下。

6.运行的结果就是:
单击按钮(得到焦点)会更换按钮显示的图片,单击另外的按钮(失去焦点)后又会恢复之前的图片。


另外实现的截图:
单击前:

单击后: