在VC中透明浮動按鍵的實現

2021-08-26 06:17:41 字數 3362 閱讀 7695

有一種按鍵,看起來是一幅完整的,當

滑鼠移到按鍵區域時,的一部分凸現,形成乙個按鍵,當滑鼠移走時又恢復原來狀態。

最近,看了一些關於浮動按鍵的**,其原理大致上跟cbitma

pbutton差不多,用數幅位圖代表按鍵的各個狀態,響應滑鼠的各種訊息來設定按鍵的狀態,實現按鍵的浮動顯示,但是這樣的按鍵卻不能和周圍的背景混和成一幅。

為了實現「透明」按鍵,可以簡單地做個試驗:先在對話方塊中加入乙個button,通過屬性框選「owner draw」風格,再加入乙個picture,並加入,將button移到picture上。執行結果發現,按鍵沒有顯示出來,但在按鍵區域按下滑鼠時,該按鍵仍然能發出wm_command訊息,這樣乙個純透明的按鍵建立了。顯然,這個按鍵是毫無使用意義的,因為使用者不知道按鍵的位置,必須讓使用者容易覺察到按鍵的位置,可以把這個按鍵改造一下:

(首先從cbutton派生出乙個新類cdrawbutton)

·把按鍵的標題顯示出來

這個實現起來比較簡單,我們可以過載cbutton類的成員函式drawitem(),

void cdrawbutton::drawitem

(lpdrawitemstruct lpdrawitemstruct)

其中的m_pfont是成員變數,它儲存了對話方塊的字型指標,為了按鍵的標題風格與對話方塊的字型風格一致,在初始化時呼叫對話方塊的成員函式getfont()即可得到指向對話方塊字型的cfont類指標。

·使按鍵浮動顯示

要通過自繪來表示按鍵的各種狀態,可填寫drawitemstruct來通知drawitem()函式需要做什麼,我們先了解一下drawitemstruct:

typedef struct tagdrawitemstructdrawitemstruct;

利用這個結構先做乙個按鍵狀態設定函式:

void cdrawbutton::setbuttonmode(uint action, uint mode)

這樣,我們可以響應滑鼠的各種訊息來設定按鍵的各種狀態:

void cdrawbutton::onmousemove

(uint nflags, cpoint point) }

else

cbutton::onmousemove(nflags, point);

} 這裡,mbtnstats是個uint型別的成員變數,它可以有三種自定義狀態:

btn_normal正常狀態

btn_up滑鼠移入按鍵區域或釋放滑鼠

btn_down按下滑鼠

(可以再加一種disable狀態)

當在按鍵區域釋放滑鼠時,必須傳送wm_command訊息:

void cdrawbutton::onlbuttonup(uint nflags, cpoint point)

else

cbutton::onlbuttonup(nflags, point);

} 接著就是繪製按鍵的各種狀態:由於按鍵必須「透明」,所以在按下和釋放時只在按鍵區域的四周加上乙個3d邊框就行了。而在正常狀態下,則必須去掉邊框恢復背景。但如何恢復背景圖象呢?我是這樣做的:在按鍵初始化時,先把被按鍵覆蓋了的區域儲存在乙個cbitmap類中,以後需要重繪按鍵時就把這個cbitmap畫在按鍵上就行了。

void cdrawbutton::drawitem

(lpdrawitemstruct lpdrawitemstruct)

//顯示按鍵標題

getwindowtext(scaption);

dc.setbkmode(transparent);

if (m_pfont!=0)

} if ((lpdrawitemstruct- >itemstate & ods_selected) &&

(lpdrawitemstruct- >itemaction & oda_select))

if(!(lpdrawitemstruct- >itemstate & ods_selected) &&

(lpdrawitemstruct- >itemaction & oda_select))

dc.detach();

} 接著就必須一些初始化工作,其中最關鍵就是把被按鍵覆蓋了的區域儲存進cbitmap類中,我們知道cdc::stretchblt()函式可以把點陣圖的指定區域從乙個裝置拷貝到另乙個裝置中,這樣可以很方便地把視窗或對話方塊的某個區域儲存,條件是獲得其dc:

void cdrawbutton::loadback(cwnd *pparent)

而使這個類和對話方塊上的按鍵產生聯絡還必須呼叫一下subclassdlgitem():

bool cdrawbutton::autoload(uint nid, cwnd *pparent)

這個類還必須具有三個成員變數:

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,在對話方塊類或c***view類加入cdrawbutton類成員m_mybutton,可以在對話方塊的initdialog()或c***view類的initialupdate()中加入:m_mybutton.create()函式,必須包含bs_ownerdraw而不能有ws_visible風格,然後在onmousemove()或ondraw()中進行初始化:m_mybutton.loadback(this);注意應加在ondraw()的最後。

同樣地,loadback()只執行一次。

(如果按鍵比背景的遲建立而具有可見(visible)屬性,則會把抹掉,所以必須去掉visible屬性或不能加入ws_visible風格)

·當滑鼠移到按鍵區域時,改變滑鼠

這個很容易實現,不在這裡多說了。

vc中透明窗體的實現!!

向對話方塊初始化函式中新增 如下 向對話方塊中新增乙個滑動條和編譯框。並利用classwizard新增變數m slide m edit,新增乙個滑動條響應函式,如下 todo add extra initialization here setwindowpos m hwnd,hwnd topmost...

VC 透明編輯框的實現

本方法對於背景為位圖的對話方塊有效,其實也就是換了一種方式讓編輯框相對於對話方塊是透明的,把編輯框在當前對話方塊的點陣圖給擷取一部分出來用於填充編輯框 實現如下 派生乙個cedit的類,新增 cbitmap m bmp cbrush m brhollow 新增wm ctlcolor,wm lbutt...

VC 透明編輯框的實現

本方法對於背景為位圖的對話方塊有效,其實也就是換了一種方式讓編輯框相對於對話方塊是透明的,把編輯框在當前對話方塊的點陣圖給擷取一部分出來用於填充編輯框 實現如下 派生乙個cedit的類,新增 cbitmap m bmp cbrush m brhollow 新增wm ctlcolor,wm lbutt...