?? wtl for mfc programmers, part v - advanced dialog ui classes - wtl.htm
字號:
LPNMCUSTOMDRAW lpNMCD)
{
<SPAN class=cpp-keyword>return</SPAN> CDRF_NOTIFYITEMDRAW;
}
DWORD CBuffyTreeCtrl::OnItemPrePaint(<SPAN class=cpp-keyword>int</SPAN> idCtrl,
LPNMCUSTOMDRAW lpNMCD)
{
<SPAN class=cpp-keyword>if</SPAN> ( <SPAN class=cpp-literal>1</SPAN> == lpNMCD->lItemlParam )
pnmtv->clrText = RGB(<SPAN class=cpp-literal>0</SPAN>,<SPAN class=cpp-literal>128</SPAN>,<SPAN class=cpp-literal>0</SPAN>);
<SPAN class=cpp-keyword>return</SPAN> CDRF_DODEFAULT;
}</font></PRE>
<P>CCustomDraw類也有SetMsgHandled()函數,你可以像在COwnerDraw類那樣使用這個函數。</P>
<H2><A name=newwtlctrls></A><font color="#FFFF66">WTL的新控件</font></H2>
<P>WTL有幾個新控件,它們要么是其他封裝類的擴展(像 CTreeViewCtrlEx),要么是提供windows標準控件沒有的新功能(像 CHyperLink)。</P>
<H3><A name=newcbitmapbutton></A><font color="#FFFF66">CBitmapButton</font></H3>
<P>WTL的CBitmapButton類聲明在atlctrlx.h中,它比MFC的同名類使用起來要簡單的多。WTL的CBitmapButton類使用image
list而不是單個的位圖資源,你可以將多個按鈕的圖像放到一個位圖文件中,減少GDI資源的占用。這對于使用很多圖片并需要在Windows 9X系統上運行的程序很有好處,因為使用太多的單個位圖將會很快耗盡GDI資源并導致系統崩潰。</P>
<p>CBitmapButton是一個CWindowImpl派生類,它又很多特色:自動調整控件的大小,自動生成3D邊框,支持hot-tracking,每個按鈕可以使用多個圖像分別表示按鈕的不同狀態。</p>
<p>在ControlMania2中,我們對前面的例子創建的自畫按鈕使用CBitmapButton類?,F在CMainDlg對話框類中添加CBitmapButton類型的變量m_wndBmpBtn,調用SubclassWindow()函數或使用DDX將其和控件聯系起來,將位圖裝載到image
list并告訴按鈕使用這個image list,還要告訴按鈕每個圖像分別對應按鈕的什么狀態。下面是OnInitDialog()函數中建立和使用這個按鈕的代碼段:</p>
<PRE> <font color="#0033FF"><SPAN class=cpp-comment>// Set up the bitmap button</SPAN>
CImageList iml;
iml.CreateFromImage ( IDB_ALYSON_IMGLIST, <SPAN class=cpp-literal>81</SPAN>, <SPAN class=cpp-literal>1</SPAN>, CLR_NONE,
IMAGE_BITMAP, LR_CREATEDIBSECTION );
m_wndBmpBtn.SubclassWindow ( GetDlgItem(IDC_ALYSON_BMPBTN) );
m_wndBmpBtn.SetToolTipText ( _T(<SPAN class=cpp-string>"Alyson"</SPAN>) );
m_wndBmpBtn.SetImageList ( iml );
m_wndBmpBtn.SetImages ( <SPAN class=cpp-literal>0</SPAN>, <SPAN class=cpp-literal>1</SPAN>, <SPAN class=cpp-literal>2</SPAN>, <SPAN class=cpp-literal>3</SPAN> );</font></PRE>
<P>默認情況下,按鈕只是引用image list,所以OnInitDialog()不能delete它所創建的image list。下面顯示的是新按鈕的一般狀態,注意控件是如何根據圖像的大小來調整自己的大小。</P>
<P><IMG height=324 alt=" [WTL bitmap button - 12K] "
src="images/cm2_bb15.png"
width=305 align=bottom border=0></P>
<P>因為CBitmapButton是一個非常有用的類,我想介紹一下它的公有方法。</P>
<H4><font color="#990000">CBitmapButton methods</font></H4>
<P>CBitmapButtonImpl類包含了實現一個按鈕的所有代碼,除非你想重載某個方法或消息處理,你可以對控件直接使用CBitmapButton類。</P>
<H5><font color="#990000">CBitmapButtonImpl constructor</font></H5>
<PRE><font color="#0033FF">CBitmapButtonImpl(DWORD dwExtendedStyle = BMPBTN_AUTOSIZE,HIMAGELIST hImageList = NULL)</font></PRE>
<P>構造函數可以指定按鈕的擴展樣式(這與窗口的樣式不沖突)和圖像列表,通常使用默認參數就足夠了,因為可以使用其他的方法設定這些屬性。</P>
<H5><font color="#990000">SubclassWindow()</font></H5>
<PRE><font color="#0033FF">BOOL SubclassWindow(HWND hWnd)</font></PRE>
<P>SubclassWindow()是個重載函數,主要完成控件的子類化和初始化控件類保有的內部數據。</P>
<H5><font color="#990000">Bitmap button extended styles</font></H5>
<PRE><font color="#0033FF">DWORD GetBitmapButtonExtendedStyle()
DWORD SetBitmapButtonExtendedStyle(DWORD dwExtendedStyle, DWORD dwMask = <SPAN class=cpp-literal>0</SPAN>)</font></PRE>
<P>CBitmapButton支持一些擴展樣式,這些擴展樣式會對按鈕的外觀和操作方式產生影響:</P>
<DL>
<DT>BMPBTN_HOVER
<DD>使用hot-tracking,當鼠標移到按鈕上時按鈕被畫成焦點狀態。
<DT>BMPBTN_AUTO3D_SINGLE, BMPBTN_AUTO3D_DOUBLE
<DD>在按鈕圖像周圍自動產生一個三維邊框,當按鈕擁有焦點時會顯示一個表示焦點的虛線矩形框。另外如果你沒有指定按鈕按下狀態的圖像,將會自動生成一個。BMPBTN_AUTO3D_DOUBLE樣式生成的邊框稍微粗一些,其他特征和BMPBTN_AUTO3D_SINGLE一樣。
<DT>BMPBTN_AUTOSIZE
<DD>按鈕調整自己的大小以適應圖像大小,這是默認樣式。
<DT>BMPBTN_SHAREIMAGELISTS
<DD>如果指定這個樣式,按鈕不負責銷毀按鈕使用的image list,如果不使用這個樣式,CBitmapButton的析構函數會銷毀按鈕使用的image
list。
<DT>BMPBTN_AUTOFIRE
<DD>如果設置這個樣式,在按鈕上按住鼠標左鍵不放將會產生連續的WM_COMMAND消息。</DD>
</DL>
<P>調用SetBitmapButtonExtendedStyle()時,dwMask參數控制著那個樣式將被改變,默認值是0,意味著用新樣式完全替換舊的樣式。</P>
<H5><font color="#990000">Image list management</font></H5>
<PRE><font color="#0033FF">HIMAGELIST GetImageList()
HIMAGELIST SetImageList(HIMAGELIST hImageList)</font></PRE>
<P>調用SetImageList()設置按鈕使用的image list。</P>
<H5><font color="#990000">Tooltip management</font></H5>
<PRE><SPAN class=cpp-keyword><font color="#0033FF">int</font></SPAN><font color="#0033FF"> GetToolTipTextLength()
<SPAN class=cpp-keyword>bool</SPAN> GetToolTipText(LPTSTR lpstrText, <SPAN class=cpp-keyword>int</SPAN> nLength)
<SPAN class=cpp-keyword>bool</SPAN> SetToolTipText(LPCTSTR lpstrText)</font></PRE>
<P>CBitmapButton支持顯示工具提示(tooltip),調用SetToolTipText()指定顯示的文字。</P>
<H5><font color="#990000">Setting the images to use</font></H5>
<PRE><SPAN class=cpp-keyword><font color="#0033FF">void</font></SPAN><font color="#0033FF"> SetImages(<SPAN class=cpp-keyword>int</SPAN> nNormal, <SPAN class=cpp-keyword>int</SPAN> nPushed = -<SPAN class=cpp-literal>1</SPAN>,<SPAN class=cpp-keyword>int</SPAN> nFocusOrHover = -<SPAN class=cpp-literal>1</SPAN>, <SPAN class=cpp-keyword>int</SPAN> nDisabled = -<SPAN class=cpp-literal>1</SPAN>)</font></PRE>
<P>調用SetImages()函數告訴按鈕分別使用image list的拿一個圖像表示那個狀態。nNormal是必須的,其它是可選的,使用-1表示對應的狀態沒有圖像。</P>
<H3><A name=cchecklist></A><font color="#FFFF66">CCheckListViewCtrl</font></H3>
<P>CCheckListViewCtrl類在atlctrlx.h中定義,它是一個CWindowImpl派生類,實現了一個帶檢查框的list view控件。它和MFC的CCheckListBox不同,CCheckListBox只是一個list
box,不是list view。CCheckListViewCtrl類非常簡單,只添加了很少的函數,當然,它使用了一個新的輔助類CCheckListViewCtrlImplTraits,它和CWinTraits類的作用類似,只是第三個參數是list
view控件的擴展樣式屬性,如果你沒有定義自己的CCheckListViewCtrlImplTraits,它將使用沒默認的樣式:LVS_EX_CHECKBOXES
| LVS_EX_FULLROWSELECT。</P>
<p>下面是一個定義list view擴展樣式屬性的例子,加入了一個使用這個樣式的新類。(注意,擴展屬性必須包含LVS_EX_CHECKBOXES,否則會因起斷言錯誤消息。)</p>
<PRE><SPAN class=cpp-keyword><font color="#0033FF">typedef</font></SPAN><font color="#0033FF"> CCheckListViewCtrlImplTraits<
WS_CHILD | WS_VISIBLE | LVS_REPORT,
WS_EX_CLIENTEDGE,
LVS_EX_CHECKBOXES | LVS_EX_GRIDLINES | LVS_EX_UNDERLINEHOT |
LVS_EX_ONECLICKACTIVATE> CMyCheckListTraits;
<SPAN class=cpp-keyword>class</SPAN> CMyCheckListCtrl :
<SPAN class=cpp-keyword>public</SPAN> CCheckListViewCtrlImpl<CMyCheckListCtrl, CListViewCtrl,
CMyCheckListTraits>
{
<SPAN class=cpp-keyword>private</SPAN>:
<SPAN class=cpp-keyword>typedef</SPAN> CCheckListViewCtrlImpl<CMyCheckListCtrl, CListViewCtrl,
CMyCheckListTraits> baseClass;
<SPAN class=cpp-keyword>public</SPAN>:
BEGIN_MSG_MAP(CMyCheckListCtrl)
CHAIN_MSG_MAP(baseClass)
END_MSG_MAP()
};</font></PRE>
<H4><font color="#990000">CCheckListViewCtrl methods</font></H4>
<H5><font color="#990000">SubclassWindow()</font></H5>
<P>當子類化一個已經存在的list view控件時,SubclassWindow()查看CCheckListViewCtrlImplTraits的擴展樣式屬性并將之應用到控件上。未用到前兩個參數(窗口樣式和擴展窗口樣式)。</P>
<H5><font color="#990000">SetCheckState() and GetCheckState()</font></H5>
<P>這些方法實際上是在CListViewCtrl中,SetCheckState()使用行的索引和一個布爾類型參數,該布爾參數的值表示是否check這一行。GetCheckState()以行索引未參數,返回改行的checked狀態。</P>
<H5><font color="#990000">CheckSelectedItems()</font></H5>
<P>這個方法使用item的索引作為參數,它翻轉這個item的check狀態,這個item必須是被選定的,同時還將其他所有被選擇的item設置成相應狀態(譯者加:多選狀態下)。你大概不會用到這個方法,因為CCheckListViewCtrl會在check
box被單擊或用戶按下了空格鍵時設置相應的item的狀態。</P>
<p>下面是ControlMania2中的CCheckListViewCtrl的樣子:</p>
<P><IMG height=429 alt=" [Check list ctrl - 12K] "
src="images/cm2_lv5.png"
width=305 align=bottom border=0></P>
<H3><A name=treeex></A><font color="#FFFF66">CTreeViewCtrlEx and CTreeItem</font></H3>
<P>有兩個類使得樹控件的使用簡化了很多:CTreeItem類封裝了HTREEITEM,一個CTreeItem對象含有一個HTREEITEM和一個指向包含這個HTREEITEM的樹控件的指針,使你不必每次調用都引用樹控件;CTreeViewCtrlEx和CTreeViewCtrl一樣,只是它的方法操作CTreeItem而不是HTREEITEM。例如,InsertItem()函數返回一個CTreeItem而不是HTREEITEM,你可以使用CTreeItem操作新添加的item。下面是一個例子:</P>
<PRE><SPAN class=cpp-comment><font color="#0033FF">// Using plain HTREEITEMs:</font></SPAN><font color="#0033FF">
HTREEITEM hti, hti2;
hti = m_wndTree.InsertItem ( <SPAN class=cpp-string>"foo"</SPAN>, TVI_ROOT, TVI_LAST );
hti2 = m_wndTree.InsertItem ( <SPAN class=cpp-string>"bar"</SPAN>, hti, TVI_LAST );
m_wndTree.SetItemData ( hti2, <SPAN class=cpp-literal>100</SPAN> );
<SPAN class=cpp-comment>// Using CTreeItems:</SPAN>
CTreeItem ti, ti2;
ti = m_wndTreeEx.InsertItem ( <SPAN class=cpp-string>"foo"</SPAN>, TVI_ROOT, TVI_LAST );
ti2 = ti.AddTail ( <SPAN class=cpp-string>"bar"</SPAN>, <SPAN class=cpp-literal>0</SPAN> );
ti2.SetData ( <SPAN class=cpp-literal>100</SPAN> );</font></PRE>
<P>CTreeViewCtrl對HTREEITEM的每一個操作,CTreeItem都有與之對應的方法,正像每一個關于HWND的API都有一個CWindow方法與之對應一樣。查看ControlMania2的代碼可以看到更多的CTreeViewCtrlEx和CTreeItem類的方法的演示。</P>
<H3><A name=chyperlink></A><font color="#FFFF66">CHyperLink</font></H3>
<P>CHyperLink是一個CWindowImpl派生類,它子類化一個static text控件,使之變成可點擊的超鏈接。CHyperLink根據用戶的IE使用的顏色畫鏈接對象,還支持鍵盤導航。CHyperLink類的構造函數沒有參數,下面是其它的公有方法。</P>
<H4><font color="#990000">CHyperLink methods</font></H4>
<P>CHyperLinkImpl類內含實現一個超鏈接的全部代碼,如果不需要重載它的方法或處理消息的話,你可以直接使用CHyperLink類。</P>
<H5><font color="#990000">SubclassWindow()</font></H5>
<PRE><font color="#0033FF">BOOL SubclassWindow(HWND hWnd)</font></PRE>
<P>重載函數SubclassWindow()完成控件子類化,然后初始化該類保有的內部數據。</P>
<H5><font color="#990000">Text label management</font></H5>
<PRE><SPAN class=cpp-keyword><font color="#0033FF">bool</font></SPAN><font color="#0033FF"> GetLabel(LPTSTR lpstrBuffer, <SPAN class=cpp-keyword>int</SPAN> nLength)
<SPAN class=cpp-keyword>bool</SPAN> SetLabel(LPCTSTR lpstrLabel)</font></PRE>
<P>獲得或設置控件顯示的文字,如果不指定顯示文字,控件會顯示資源編輯器指定給控件的靜態字符串。</P>
<H5><font color="#990000">Hyperlink management</font></H5>
<PRE><SPAN class=cpp-keyword><font color="#0033FF">bool</font></SPAN><font color="#0033FF"> GetHyperLink(LPTSTR lpstrBuffer, <SPAN class=cpp-keyword>int</SPAN> nLength)
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -