• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            c++初學(xué)者

            專注技術(shù)開(kāi)發(fā)

            自繪按鈕補(bǔ)遺【轉(zhuǎn)】

            《自繪按鈕的實(shí)現(xiàn)》一文中所示范的CXPButton按鈕從形狀上看可以說(shuō)是一個(gè)不規(guī)則按鈕。我們把MFC中提供的控件成為標(biāo)準(zhǔn)控件,而其中的按鈕控件則可稱為規(guī)則按鈕,因?yàn)樗堑男螤钍且粋€(gè)規(guī)則的矩形。但是隨著流線型設(shè)計(jì)在界面設(shè)計(jì)中被廣泛采用,越來(lái)越多的程序設(shè)計(jì)者都樂(lè)意在自己的作品中加入一些非規(guī)則形狀的控件。以按鈕為例,最簡(jiǎn)單的就到有圓形按鈕,三角按鈕等。下圖是一組定義好的圓形按鈕:



            但是這些在我們眼中似乎呈現(xiàn)出不規(guī)則形狀的按鈕,有時(shí)候的表現(xiàn)卻不近乎人意。以之前設(shè)計(jì)的CXPButton為例,下面我們就來(lái)找找它的缺陷。我們把對(duì)話框的背景色改為其它顏色,看看會(huì)有什么效果。修改背景色的方法如下:為對(duì)話框類添加WM_ERASEBKGND消息,如果你在類向?qū)е姓也坏皆撓ⅲ?qǐng)參考《自繪按鈕的實(shí)現(xiàn)》中介紹的方法,注意在添加對(duì)話框中要把Filter for messages available to設(shè)為Child Window才能在列表中看到WM_ERASEBKGND消息。我們?cè)诤瘮?shù)中添加繪制背景色的代碼:
            BOOL CXPButtonDemoDlg::OnEraseBkgnd(CDC* pDC)
            {
            BOOL retValue= CDialog::OnEraseBkgnd(pDC);
            CRect rc;
            GetClientRect(&rc);
            pDC->FillSolidRect(&rc,RGB(0,0,255));
            return retValue;
            }
            編譯后運(yùn)行程序,可以看到下面的效果,在按鈕的四個(gè)角上出現(xiàn)了難看的邊角,這就是我所說(shuō)的缺陷了:



            既然發(fā)現(xiàn)了問(wèn)題,下面當(dāng)然就是動(dòng)手來(lái)解決問(wèn)題的時(shí)間了。在《自繪按鈕的實(shí)現(xiàn)》一文中曾經(jīng)講過(guò),按鈕的繪制主要在DrawItem()函數(shù)中完成。這里要補(bǔ)充一點(diǎn)就是DrawItem()是MFC所提供的系統(tǒng)函數(shù),所以可以通過(guò)下圖的方法添加。選擇Add Virtual Function…之后在彈出對(duì)話框左邊的列表中找到DrawItem,選擇Add and Edit即可。



            好了,我們接著上面的話題。要解決按鈕顯示的“殘角”問(wèn)題,在這里需要使用一個(gè)叫做CRgn的類,這個(gè)類在創(chuàng)建不規(guī)則控件的時(shí)候經(jīng)常要用到,我們可以通過(guò)CRgn類來(lái)設(shè)置控件的有效區(qū)域。那么什么是有效區(qū)域呢?以圓形按鈕為例,MFC默認(rèn)的按鈕形狀是矩形的,為了實(shí)現(xiàn)圓形按鈕的效果,我們希望能夠把原來(lái)矩形的四角裁剪掉,只保留中間的圓形區(qū)域。這種關(guān)系可以用下圖來(lái)表示:



            圖中的A是原來(lái)的矩形區(qū)域,B是需要裁剪的區(qū)域,而C是有效區(qū)域。我們希望程序不要把B看作按鈕的一部分,當(dāng)鼠標(biāo)在B上面點(diǎn)擊的時(shí)候不要產(chǎn)生任何效果。設(shè)置按鈕的有效區(qū)域一般是在PreSubclassWindow()函數(shù)里面實(shí)現(xiàn)的:
            void CXPButton::PreSubclassWindow()
            {
            CButton::PreSubclassWindow();
            ModifyStyle(0, BS_OWNERDRAW);
            //設(shè)置按鈕的有效區(qū)域
            CRgn rgn;
            CRect rc;
            GetClientRect(&rc);
            //有效區(qū)域?yàn)橐粋€(gè)角半徑為5的圓角矩形
            rgn.CreateRoundRectRgn(rc.left,rc.top,rc.right,rc.bottom,5,5);
            SetWindowRgn(rgn,TRUE);
            rgn.DeleteObject();
            }
            
            編譯后運(yùn)行程序,我們發(fā)現(xiàn)盡管已經(jīng)設(shè)置了按鈕的有效區(qū)域,但是問(wèn)題還是沒(méi)有解決,這是為什么呢?前面我們?cè)?jīng)通過(guò)對(duì)話框的WM_ERASEBKGND消息函數(shù)來(lái)改變對(duì)話框的底色,其實(shí)按鈕也有它的WM_ERASEBKGND消息函數(shù),它會(huì)使用系統(tǒng)顏色根據(jù)控件的默認(rèn)形狀來(lái)繪制控件的底色。所以我們要重載按鈕的WM_ERASEBKGND消息函數(shù),讓它什么都不做:
            BOOL CXPButton::OnEraseBkgnd(CDC* pDC)
            {
            //禁止繪制底色
            return TRUE;
            }
            
            再編譯一次,運(yùn)行后發(fā)現(xiàn),難看的"殘角"不見(jiàn)了:

             



            《自繪按鈕的實(shí)現(xiàn)》一文中還講過(guò)在DrawItem()函數(shù)中應(yīng)該先畫底色,其實(shí)這是有前提的,前提就是你已經(jīng)知道了按鈕所在對(duì)話框所使用的背景色,你可以使用這個(gè)顏色作為按鈕的底色來(lái)進(jìn)行填充。這樣即使程序會(huì)在WM_ERASEBKGND消息函數(shù)中使用系統(tǒng)顏色來(lái)繪制控件的底色,但是等到它執(zhí)行DrawItem()的時(shí)候,馬上又會(huì)把之前的矩形底色覆蓋,從而不留痕跡地把“殘角”掩蓋掉。
            在本篇開(kāi)頭列舉的圓形按鈕中也有類似的問(wèn)題,大家不防把它作為練習(xí),看看是否能夠解決圓形按鈕中的“殘角”問(wèn)題。我在本篇提供的練習(xí)程序中需要修改的地方會(huì)表明“提示”的字眼,大家可以先把源程序中有“提示”字眼的地方找出來(lái),再根據(jù)提示的內(nèi)容進(jìn)行修改。



            最后還要補(bǔ)充的是各位對(duì)CRgn類的關(guān)注。在VC中,要?jiǎng)?chuàng)建出各種復(fù)雜形狀的控件、窗口經(jīng)常要依靠CRgn類的強(qiáng)大功能來(lái)實(shí)現(xiàn)。如果你想在界面設(shè)計(jì)這個(gè)環(huán)節(jié)更進(jìn)一步的話,建議你抽點(diǎn)時(shí)間仔細(xì)研究一下Msdn中關(guān)于CRgn類的使用說(shuō)明。如果你有什么好的使用經(jīng)驗(yàn)和心得,不防把相關(guān)資料發(fā)到我的郵箱。以后有機(jī)會(huì)的話我會(huì)專門寫一篇文章探討一下CRgn類的使用技巧的。

            posted on 2008-09-25 20:19 大海 閱讀(559) 評(píng)論(0)  編輯 收藏 引用 所屬分類: VC++圖像

            久久久久久毛片免费看| 精品免费久久久久久久| 人妻系列无码专区久久五月天| 久久久青草青青国产亚洲免观| 中文字幕无码av激情不卡久久| 亚洲熟妇无码另类久久久| 日韩人妻无码一区二区三区久久| 久久亚洲国产中v天仙www| 91精品观看91久久久久久| 久久亚洲2019中文字幕| 国产韩国精品一区二区三区久久| 欧美久久一区二区三区| 97久久超碰国产精品旧版| 久久国产AVJUST麻豆| 欧美久久综合性欧美| 欧美亚洲色综久久精品国产 | 99久久精品国产综合一区| 一极黄色视频久久网站| 丁香五月综合久久激情| 久久婷婷国产综合精品| 国内精品久久久久影院薰衣草 | 伊人久久大香线蕉亚洲| 国产免费久久精品丫丫| 97久久超碰国产精品2021| 亚洲国产美女精品久久久久∴ | 色欲久久久天天天综合网 | 久久久噜噜噜久久中文字幕色伊伊| 久久99精品久久久久久久不卡| 狠狠色丁香婷婷久久综合五月| 日本精品久久久中文字幕| 国产成人综合久久综合| 精品乱码久久久久久久| 久久精品麻豆日日躁夜夜躁| 亚洲AV无码一区东京热久久| 久久妇女高潮几次MBA| 伊人久久大香线蕉av不卡| 77777亚洲午夜久久多人| 麻豆亚洲AV永久无码精品久久| 中文国产成人精品久久不卡| 亚洲综合伊人久久综合| 精品乱码久久久久久久|