大雀软件园

首页 软件下载 安卓市场 苹果市场 电脑游戏 安卓游戏 文章资讯 驱动下载
技术开发 网页设计 图形图象 数据库 网络媒体 网络安全 站长CLUB 操作系统 媒体动画 安卓相关
当前位置: 首页 -> 技术开发 -> 程序开发 -> 在VC中透明浮动按键的实现

在VC中透明浮动按键的实现

时间: 2021-07-31 作者:daque

    有一种按键,看上去是一幅完备的图片,当鼠标移到按键地区时,图片的一局部凸现,产生一个按键,当鼠标移走时又回复从来状况。      迩来,看了少许对于浮动按键的代码,其道理大概上跟cbitmapbutton差不离,用数幅位图代办按键的各个状况,相应鼠目标百般动静来树立按键的状况,实行按键的浮动表露,然而如许的按键却不许和范围的后台混和成一幅图片。      为了实行“通明”按键,不妨大略地做个考查:先在对话框中介入一个button,经过属性框选“owner draw”作风,再介入一个picture,并介入图片,将button移到picture上。运转截止创造,按键没有表露出来,但在按键地区按下鼠标时,该按键仍旧能发出wm_command动静,如许一个纯通明的按键创造了。明显,这个按键是毫无运用意旨的,由于用户不领会按键的场所,必需让用户简单察觉到按键的场所,不妨把这个按键变革一下:      (开始从cbutton派生出一个新类cdrawbutton)      ·把按键的题目表露出来      这个实行起来比拟大略,咱们不妨重载cbutton类的分子因变量drawitem(), void cdrawbutton::drawitem(lpdrawitemstruct lpdrawitemstruct){cdc dc;crect rect=lpdrawitemstruct- >rcitem;//获得按键地区cstring scaption;dc.attach(lpdrawitemstruct- >hdc); //获得摆设情况cdcverify(lpdrawitemstruct- >ctltype==odt_button);getwindowtext(scaption);//获得按键的题目dc.setbkmode(transparent);//透鲜明示cfont* m_poldfont=dc.selectobject(m_pfont);dc.drawtext(scaption,&rect,dt_center|dt_vcenter|dt_singleline);dc.selectobject(m_poldfont);}     个中的m_pfont是分子变量,它生存了对话框的字体南针,为了按键的题目作风与对话框的字体作风普遍,在初始化时挪用对话框的分子因变量getfont()即可获得指向对话框字体的cfont类南针。      ·使按键浮动表露     要经过自绘来表白按键的百般状况,可填写drawitemstruct来报告drawitem()因变量须要做什么,咱们先领会一下drawitemstruct: typedef struct tagdrawitemstruct{    uint ctltype; // 控件典型    uint ctlid;// 控件的id号    unit itemid;//菜单项的索引    uint itemaction;// 画图操纵    uint itemstate; // 状况    hwnd hwnditem; // 控件的窗口句柄    hdc hdc; // 关系的摆设情况    rect rcitem;//控件的范畴    dword itemdata;//指定与菜单项相接洽的运用步调设置的32位值}drawitemstruct;    运用这个构造先做一个按键状况树立因变量: void cdrawbutton::setbuttonmode(uint action, uint mode){ // todo: add your message handler code here and/or call default    drawitemstruct dis;     dis.ctltype = odt_button;     dis.ctlid = getdlgctrlid();     dis.itemaction = action;     dis.itemstate = mode;     dis.hwnditem = getsafehwnd();     dis.hdc = getdc()- >getsafehdc();     getclientrect(&(dis.rcitem));     sendmessage(wm_drawitem,(wparam)getsafehwnd(),(lparam)&dis);    releasedc(cdc::fromhandle(dis.hdc));}    如许,咱们不妨相应鼠目标百般动静来树立按键的百般状况: void cdrawbutton::onmousemove(uint nflags, cpoint point) {    // todo: add your message handler code here and/or call default    crect rect;    getclientrect(&rect);    if(rect.ptinrect(point)){        if (mbtnstats==btn_normal){    setbuttonmode(oda_select, ods_focus);             setcapture();        }    }    else{//autoload(getdlgctrlid(),getparent());setbuttonmode(oda_drawentire,ods_default);        releasecapture();    }    cbutton::onmousemove(nflags, point);}    这边,mbtnstats是个uint典型的分子变量,它不妨有三种自设置状况: btn_normal    平常状况btn_up        鼠标移入按键地区或开释鼠标btn_down    按下鼠标(不妨再加一种disable状况)    当在按键地区开释鼠标时,必需发送wm_command动静:void cdrawbutton::onlbuttonup(uint nflags, cpoint point) {    // todo: add your message handler code here and/or call default    crect rect;    getclientrect(&rect);    if(rect.ptinrect(point)){        if (mbtnstats==btn_down)            getparent()- >sendmessage(wm_command,        makelparam(getdlgctrlid(),bn_clicked),        (lparam)getsafehwnd());        setcapture();    }    else{    setbuttonmode(oda_drawentire,ods_default);        releasecapture();    }    cbutton::onlbuttonup(nflags, point);}    接着即是绘制按键的百般状况:因为按键必需“通明”,以是在按下和开释时只在按键地区的边际加上一个3d边框就行了。而在平常状况下,则必需去掉边框回复后台。但怎样回复后台图象呢?我是如许做的:在按键初始化时,先把被按键掩盖了的地区生存在一个cbitmap类中,此后须要重绘按键时就把这个cbitmap画在按键上就行了。 void cdrawbutton::drawitem(lpdrawitemstruct lpdrawitemstruct) {    // todo: add your code to draw the specified item    cdc dc;    crect rect=lpdrawitemstruct- >rcitem;    cstring scaption;    dc.attach(lpdrawitemstruct->hdc); //获得绘制的摆设情况cdc    verify(lpdrawitemstruct- >ctltype==odt_button);    if (lpdrawitemstruct- >itemaction & oda_drawentire){        //重绘控件(平常状况)        mbtnstats=btn_normal;        if (m_pbitmap!=0){            cdc memdc;             memdc.createcompatibledc(&dc);            memdc.selectobject(m_pbitmap);    dc.bitblt(0, 0, rect.width(), rect.height(),                &memdc, 0, 0, srccopy);             memdc.deletedc();        }        //表露按键题目        getwindowtext(scaption);        dc.setbkmode(transparent);        if (m_pfont!=0){        cfont* m_poldfont=dc.selectobject(m_pfont);        dc.drawtext(scaption,&rect,    dt_center|dt_vcenter|dt_singleline);            dc.selectobject(m_poldfont);        }    }if ((lpdrawitemstruct- >itemstate & ods_selected) && (lpdrawitemstruct- >itemaction & oda_select)){//按下鼠标mbtnstats=btn_down;dc.draw3drect(&rect,rgb(128,128,128),rgb(192,192,192));rect.top=rect.top+1;rect.bottom=rect.bottom-1;rect.left=rect.left+1;rect.right=rect.right-1;dc.draw3drect(&rect,rgb(0,0,0),rgb(255,255,255));    }if(!(lpdrawitemstruct- >itemstate & ods_selected) && (lpdrawitemstruct- >itemaction & oda_select)){//开释鼠标或鼠标加入按键地区mbtnstats=btn_up;dc.draw3drect(&rect,rgb(255,255,255),rgb(0,0,0));rect.top=rect.top+1;rect.bottom=rect.bottom-1;rect.left=rect.left+1;rect.right=rect.right-1;dc.draw3drect(&rect,rgb(192,192,192),rgb(128,128,128));    }    dc.detach();}    接着就必需少许初始化处事,个中最要害即是把被按键掩盖了的地区生存进cbitmap类中,咱们领会cdc::stretchblt()因变量不妨把位图的指定地区从一个摆设正片到另一个摆设中,如许不妨很简单地把窗口或对话框的某个地区生存,前提是赢得其dc: void cdrawbutton::loadback(cwnd *pparent){    assert(getstyle() & bs_ownerdraw);     if (m_pbitmap!=0) return;    crect rect;    getwindowrect(&rect);    pparent- >screentoclient(&rect);//赢得按键地区    cpaintdc dc(pparent);    if (m_pbitmap==0) m_pbitmap=new cbitmap;//初始化位图    m_pbitmap- >createcompatiblebitmap (&dc,rect.width(),rect.height());    cdc memdc;    memdc.createcompatibledc(&dc);    memdc.selectobject(m_pbitmap);memdc.stretchblt(0, 0, rect.width(),rect.height(), &dc,    rect.left, rect.top, rect.width(),rect.height(), srccopy);//生存    memdc.deletedc();m_pfont=pparent- >getfont();//赢得窗口或对话框的字体    modifystyle(0,ws_visible);//表露按键    setbitmapmode(oda_drawentire,0);//绘制按键}    而使这个类和对话框上的按键爆发接洽还必需挪用一下subclassdlgitem(): bool cdrawbutton::autoload(uint nid, cwnd *pparent){ // first attach the cdrawbutton to the dialog control     if (m_pbitmap!=0) return false;    if (!subclassdlgitem(nid, pparent)) return false;    loadback(pparent);    return true;}    这个类还必需具备三个分子变量:     cfont* m_pfont;    cbitmap* m_pbitmap;    uint mbtnstats;在结构因变量中初始化那些变量    m_pbitmap=0;    m_pfont=0;    //付与0是不妨的    mbtnstats=btn_normal;在折构因变量中废除位图    if(m_pbitmap!=0) delete m_pbitmap;    如许,一个通明的浮动式按键类就做好了,简直实行本领以次:     1.接收对话框的button,开始在对话框上画一个button,再加一个picture图片,button的作风必需介入owner draw及去掉visible,把button移到picture上符合的场所,在对话框类介入cdrawbutton类分子m_mybutton,因为按键初始化时必需生存对话框的图象,而对话框在运转initdialog()或第一次运转onpaint()时对话框的控件还没有真实表露出来,咱们只幸亏onmousemove()中举行初始化: m_mybutton.autoload(idc_button1,this);autoload()只运转一次。    2.动静创造cdrawbutton,在对话框类或cxxxview类介入cdrawbutton类分子m_mybutton,不妨在对话框的initdialog()或cxxxview类的initialupdate()中介入:m_mybutton.create()因变量,必需包括bs_ownerdraw而不许有ws_visible作风,而后在onmousemove()或ondraw()中举行初始化:m_mybutton.loadback(this);提防应加在ondraw()的结果。     同样地,loadback()只运转一次。     (即使按键比后台的图片迟创造而具备看来(visible)属性,则会把图片抹掉,以是必需去掉visible属性或不许介入ws_visible作风)     ·当鼠标移到按键地区时,变换鼠标    这个很简单实行,不在这边多说了。

热门阅览

最新排行

Copyright © 2019-2021 大雀软件园(www.daque.cn) All Rights Reserved.