在前一篇文章中
)中,我將乙個公共視窗控制項進行了之類劃分,目的是為了修飾其行為或者說是擴充套件其功能。有時候,你只能將公共視窗控制項擴充套件到這樣的底部。我遇到的乙個例子是乙個比較普遍的話題即需要乙個格網控制項並且編輯tabular資料。我對clistctrl進行了之類劃分,並擴充套件使其能夠進行子項編輯、多行元素、按首字母排序以及很多其他的功能。但是,深究起來,它仍然是乙個列表控制項,重點是看起來我需要寫更多的**去停止控制項的表現而不是如我實際所做的為其加上功能。
我需要從亂寫開始,從基類開始開始工作,從而提供我需要的功能別且不需要任何我不需要的特徵和不利條件。所以從自定義控制項開始吧。
建立乙個自定義控制項同對普通視窗控制項進行之類劃分非常類似。你需要從已存在的類中繼承乙個新類並且過載基類的函式以達到你想要的功能。
本例中我們將從cwnd類中繼承乙個類,因為該類提供了我們需要的最少功能,沒有多餘的無用函式。
第一步是從選擇的generic cwnd基類中繼承乙個新類。本例中我們將建立乙個顯示點陣圖的自定義控制項,並命名為cbitmapviewer。顯然,已經有乙個cstatic型別的類可用於顯示位圖,但是本例的目的是將可能多的方法展示給「不守本分」的程式設計師。如下圖:
為了在控制項中顯示位圖,新增了乙個名為setbitmap的函式。我們不僅僅是天才的美國程式設計師同時富有想象力(雷人)。
對於本文來說,內部的實現**並不重要但是為了完整性也包括在下面了:
在類中新增乙個cbitmap的例項以及函式setbitmap宣告。
classcbitmapviewer :
public
cwnd
;在實現檔案中新增setbitmap的實現函式,並且新增wm_paint和wm_erasebkgnd訊息控制代碼:
void cbitmapviewer::onpaint()
// do not call cwnd::onpaint() for painting messages
}
bool cbitmapviewer::onerasebkgnd(cdc* pdc)
bool cbitmapviewer::setbitmap(uint nidresource)
現在已有乙個類允許我們載入並顯示乙個位圖,但是實際上我們還沒有辦法使用這個類。在建立控制項時有兩種選擇:動態方式條用create函式或者用visual studio的資源編輯器建立對話方塊模板。
由於我們的類是繼承自cwnd類所以我們可以使用cwnd::create來動態的建立控制項。例如,在對話方塊的oninitdialog函式中新增一下的**:
// cbitmapviewer m_viewer; - declared in dialog class header
m_viewer.create(null, _t(""), ws_visible, crect(0,0,100,100), this, 1);
m_viewer.setbitmap(idb_bitmap1);其中,m_viewer是cbitmapviewer類的例項物件,定義在對話方塊的標頭檔案中。idb_bitmap1是點陣圖資源的id號。這兩句**的作用是建立控制項並顯示位圖。
但是,如果想要把控制項放在乙個用visual studio資源編輯器建立的對話方塊模板中又該如何做呢?對於這種情況,我們需要使用afxregisterclass函式註冊乙個視窗類。註冊乙個類的好處是我們能夠指定背景顏色,游標型別和類型別。具體請查閱afxregisterwndclass。
在本例中,我們將註冊乙個簡單的類「mfcbitmapviewerctrl」。我們只需要註冊該類一次,為了簡便我們只需在類的建構函式中寫這幾行**即可:
#define bitmapviewer_classname_t("mfcbitmapviewerctrl")// window class name
cbitmapviewer::cbitmapviewer()
bool cbitmapviewer::registerwindowclass()
}
return true;
}在我們的例子中,動態建立有所不同:
m_viewer.create(_t("mfcbitmapviewerctrl"), _t(""), ws_visible, crect(0,0,100,100), this, 1);這樣將能確保正確的視窗風格、游標和顏色。當然為了自定義控制項寫乙個新的create函式也是值得的這樣使用者將不必要記住視窗類的名稱。例如:
bool cbitmapviewer::create(cwnd* pparentwnd, const rect& rect, uint nid, dword dwstyle /*=ws_visible*/)
為了在對話方塊資源中定製控制項,只需要在對話方塊中拉出乙個自定義控制項即可。如下圖:
接著在控制項屬性對話方塊中,將類名稱改為「mfcbitmapviewerctrl」。
最後一步就是將乙個變數同控制項連線起來。在對話方塊類中簡單定義乙個cbitmapviewer型別的變數(如,m_viewer)並且在dodataexchange函式中加入一下**:
void ccustomcontroldemodlg::dodataexchange(cdataexchange* pdx)
}afx_data_map
}通過呼叫subclasswindow函式,ddx_control連線類變數m_viewer與控制項ididc_custom1。在對話方塊「mfcbitmapviewerctrl」資源中通過自定義控制項能夠建立由cbitmapviewer::registerwindowclass所展示的功能。ddx_control函式能將cbitmapviewer和預先的視窗連線在一起。
編譯並執行,你會看到你已經建立了乙個自定義控制項。
本文及說附帶的**與檔案,執行cpol許可。
chris maunder是codeproject的合作創辦者,管理者及首席編輯。從2023年來就開始程式設計,他的角色多種多樣。同時他還是微軟vc的全球及加拿大mvp。
他的程式語言包括c/c++、c#、sql、mfc、asp、asp.net,更多的是fortran。
chris出生在澳大利亞。
職位:創業者
公司:the code project
出生地:加拿大
建立自定義控制項
引入布局可以使布局統一,但如果布局中有控制項要能夠響應事件,我們還是需要在每個活動中對控制項進行事件的註冊。我們可以使用自定義控制項的方式解決 新建titlelayout 類並繼承linearlayout,package com.example.layouttest import android.c...
建立web自定義控制項
建立asp.net web自定義控制項 例程1 web自定義控制項程式設計是asp.net程式設計裡面比較難的一部分,尤其是複雜的控制項需要用到平常不常用的一些技術技巧。下面根據一些我自己的實踐經驗,向讀者介紹一下這方面的技術。簡單的繼承控制項 confirmbutton 我們在用asp.net編寫...
建立Web自定義控制項
控制項中方法的實現與任何其他元件中方法的實現方式相同。在 visual basic 中,如果要求方法返回乙個值,則方法以public function形式實現 如果不要求返回值,則以public sub形式實現。使用下列語法宣告方法 visual basic public function conv...