自定義控制項實現訊號燈

2021-06-19 12:13:28 字數 2069 閱讀 5819

**

總是會在論壇裡看到類似這樣的問題,「如何通過按鈕更換一幅」,「怎樣將顯示在對話方塊中」,「mfc的picturectrl怎樣操作」等等,不一而足。面對這類問題我一般都會建議通過cwnd派生乙個自定義控制項來自行處理,不過這話說起來容易,可是這個控制項要如何實現呢?所以經常會想不妨做個例子和大家分享一下,當然如果大家有什麼更好的辦法我也可以從中學習借鑑。但問題又來了,這類例子簡單實現其實就是乙個函式的問題——onpaint,但要做的精緻些要處理的方面又太多,容易喧賓奪主。怎麼才能找個折中的方案呢,什麼樣題材的例子更具代表性呢?這兩天逛論壇乙個帖子給了我啟示,做個訊號燈的控制,即可以說明問題又簡單實用,大家還可以舉一反三,這應該是個不錯的主意,於是做了乙個

demo

,寫了這篇文章。

這回做了乙個gif的效果圖,我做了乙個三態的狀態燈,分別實現的正常(綠色)、警告(紅色)和不可用(灰色)的狀態表示。狀態切換是通過單選按鈕實現的,當然這個可以通過任何我們想要的方式控制。大家可以看得出來,這個例子做的比較粗糙,其實就是更換三張不同的,為了突出主要功能我沒有新增不必要的修飾,比如鏤空的處理等。

落實到具體實現,正如前文所說我是通過cwnd派生出了乙個csignallampctrl來實現自定義控制項,然後就是在這個類的onpaint裡繪製點陣圖了。說到這我插一句,起初我剛做介面程式設計的時候每每遇到問題就會把需求往mfc的標準控制項上靠,找乙個最接近的過載自繪一下,如果沒有接近的就統統過載cstatic實現。可後來發現,靜態控制項也有很多的特殊處理,為了實現「靜態」static有很多處理是我們做一般控制項時不需要的,所以在使用這種控制項的時候就會產生很多不必要的麻煩。所以後來我開始嘗試通過自定義控制項解決問題,而且越來越適應這種方式。自定義控制項雖然沒有一些現成可用的訊息,但是它給了我們最大的控制權和自由度,使我們可以做到隨心所欲沒有束縛。

使用自定義控制項只需要注意乙個小細節,控制項的屬性編輯器裡可以看到class項,這裡要填寫控制項的類名。同時這個類名要進行註冊,所以在我的類中可以找到registerctrlclass,它的具體實現**為

[cpp]view plain

copy

print?

void csignallampctrl::registerctrlclass()     

我通常將它放到控制項的建構函式中以便使用時自動進行註冊。

關於這個例子其實也沒有什麼需要特別說明的,onpaint函式很簡單,就是繪製一張位圖,我的點陣圖都是放到資源中的,當然通過檔案讀進來顯示也沒有問題。而且通過cimage或gdi+我們也可以顯示非位圖的影象,這個有興趣的讀者可以自行嘗試。onpaint的**如下

[cpp]view plain

copy

print?

void csignallampctrl::onpaint()     

可以注意到載入點陣圖的時候是通過乙個變數nidbitmap實現的,這裡存放欲顯示的點陣圖的資源id,切換位圖就是切換這個id,我做了乙個函式setstate來實現

[cpp]view plain

copy

print?

void csignallampctrl::setstate(statetype nstate)   

invalidate();   

}  

而在radio訊息中對它的呼叫也很簡單

[cpp]view plain

copy

print?

void csignallampdlg::onbnclickedradionormal()     

這裡大家可以使用任何一種自己認為合理的切換的方式,如果通過ontimer訊息控制訊號燈的狀態切換就可以實現訊號燈閃爍的動畫效果。最後要提的一點是我在presubclasswindow中我對控制項的大小做了限制,使其與的大小相同,具體**為

[cpp]view plain

copy

print?

void csignallampctrl::presubclasswindow()     

看看,希望大家提出寶貴意見。由於水平有限例子功能過於簡單,讓大家見笑了。

VS2010自定義控制項實現訊號燈

總是會在論壇裡看到類似這樣的問題,如何通過按鈕更換一幅 怎樣將顯示在對話方塊中 mfc的picturectrl怎樣操作 等等,不一而足。面對這類問題我一般都會建議通過cwnd派生乙個自定義控制項來自行處理,不過這話說起來容易,可是這個控制項要如何實現呢?所以經常會想不妨做個例子和大家分享一下,當然如...

訊號燈和共享記憶體機制實現程序通訊

父程序建立子程序互相通訊,父程序從指定檔案中每次讀取一行放入共享記憶體中,子程序將共享記憶體的內容寫入另乙個檔案末尾。由於子程序是無限迴圈,父程序結束前必須殺死子程序,程序結束時會釋放掉等待的訊號量,否則再次執行程式時會直接在建立子程序之前阻塞。include include include inc...

DuiLib實現自定義控制項

在duilib中實現自定義控制項,和qt過載類似,也是繼承原有的控制項只不過是要將這個控制項也能在xml中進行使用。當作xml中的乙個節點。下面就看一下我寫的乙個小例子,這個例子是過載了乙個按鈕 cbuttonui 過載cbuttonui的標頭檔案 subcontrol.h ifndef subco...