天天看點

VC++通用控件程式設計

滑動條控制(Slider Control)也叫軌道條控制,其主要是用一個帶有軌道和滑标的小視窗以及視窗上的刻度,來讓使用者選擇一個離散資料或一個連續的數值區間。通過滑鼠或鍵盤來進行資料的選擇操作,這在WIN98/95中的很多應用程式中都可以看到,如控制台中的滑鼠等,滑動條既可以是水準方式的也可以是垂直方式的。滑動條控制的風格如下:

TBS_HORZ 滑動條是水準方向的      TBS_VERT 滑動條是垂直方向的

TBS_LEFT 滑動條位于視窗左側      TBS_RIGHT 滑動條位于視窗右側

TBS_TOP 滑動條位于視窗頂部       TBS_BOTTOM 滑動條位于視窗底部

TBS_BOTH 滑動條位于視窗兩側      TBS_AUTOTICKS滑動條具有刻度,預設

TBS_NOTICKS 滑動條不具有刻度

  滑動條的刻度條在每一個數值位置顯示一個刻度标記,如果在滑動條上顯示某一數值選擇區間,則應使用風格TBS_ENABLESELRANGE,此時選擇區間兩個不再是刻度标記,而是一個小的三角形符号。另外,使用風格TBS_NOTHUMB會使滑标消隐起來。

  滑動條控制在MFC類庫中被封裝為CSliderCtrl控制,其主要操作是設定刻度範圍、繪制刻度标記、設定選擇範圍和目前滑标位置等。當使用者進行互動操作時,滑動條控制将向其父視窗發送消息WM_HSCROLL,是以在應用程式中應重載父視窗的OnHScroll()成員函數,以便對消息進行正确處理系統發送的通知代碼、滑标位置和指向CSliderCtrl對象的指針等。由于考慮到和水準卷動杆公用同一個成員函數,OnHScroll()函數參數表中的指針變量被定義為CScrollBar*類型,由于實際上消息是由滑動條産生的,是以在程式中必須把這個指針變量強制轉換為CSliderCtrl*類型。滑動條和卷動杆的消息代碼和含義都非常類似如TB_BOTTOM等,是以這種處理方法比較合理。SetRange()函數用來設定範圍,SetPos()函數用來設定目前位置。

(二)滑動條控制的對象結構

  滑動條控制的建立方法

   CsliderCtrl &SliderCtrl 建立滑動條控制對象結構;Create 建立滑動條控制對象并綁定對象

   滑動條控制類CSliderCtrl::Create的調用格式如下:

  BOOL Create( DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID );

  其中參數dwStyle用來确定滑動條控制風格;參數rect用來确定滑動條控制的大小和位置;參數pParentWnd用來确定滑動條控制的父視窗指針;參數nID用來确定滑動條控制的控制符ID值。

  2、滑動條控制的類屬性

  滑動條控制對象的類屬性包括取得滑動條大小GetLineSize、設定滑動條大小SetLineSize、取得滑動條頁大小GetPageSize、設定滑動條頁大小SetPageSize、取得滑動條最大位置GetRangeMax、取得滑動條最小位置GetRangeMin、取得滑動條範圍GetRange、設定滑塊最小位置SetRangeMin、設定滑塊最大位置SetRangeMax、設定滑動條範圍SetRange、取得滑塊目前位置GetSelection、設定滑塊目前位置SetSelection、取得滑動條目前位置GetPos和設定滑動條目前位置SetPos等。

  3、滑動條控制的操作方法

  滑動條控制的操作方法包括清除滑動條目前選擇ClearSel、驗證滑動條目前位置是否在最大最小位置之間VerifyPos和清除目前刻度标志ClearTics。

  滑動條控制的應用技巧示例

  1、利用應用程式向導AppWizard生成基于對象框的應用程式CSlidDlg;

  2、在對話框中設定滑動條控制,其ID為IDC_SLIDER;

  3、在對話框初始代碼中增加控制的範圍和位置:

  (1)在SlidDlg.h中設定資料成員,用來表示滑動條的目前值:

//SlidDlg.h

class CSlidDlg:public Cdialog

{    ......//其它代碼

    public:

        int m_nCur;

    ......//其它代碼

}

(2)在SlidDlg.cpp中設定初始狀态

BOOL CSlidDlg::OnInitDialog()

{    Cdialog::OnInitDialog();

     ......//其它代碼

    //TODO:Add extra initialization here

    CSliderCtrl *pSlidCtrl=(CSliderCtrl*)GetDlgItem(IDC_SLLIDER);

    pSlidCtrl->SetRange(1,5,TRUE);//設定滑動條範圍

    pSlidCtrl->SetPos(2);//設定滑動條位置

     return TRUE;

(3)完善滑動條的消息處理,利用類向導ClassWizard增加對話框視窗的WM_HSCROLL消息處理函數,并取得滑标所指位置值:

void CSlidDlg::OnHScroll(UINT nSBCode,UINT nPos,CScrollBar *pScrollBar)

{ //TODO:Add your message handler?

    Cdialog::OnHScroll(nSBCode,nPos,pScrollBar);

    m_nCur=pSlidCtrl->GetPos();//取得目前位置值

VC通用控件程式設計之CStatusBar控件

(一)狀态條控制的主要功能

(二)狀态條控制的對象結構

1、狀态條控制的建立方法

CStatusBarCtrl &StatusBarCtrl 建立狀态條控制對象結構;Create 建立狀态條控制對象并綁定狀态條控制類CstatusBarCtrl::Create的調用格式如下:

BOOL Create( DWORD dwStyle,const RECT& rect,CWnd* pParentWnd,UINT nID);

其中參數dwStyle用來确定狀态條的控制風格;參數rect用來确定狀态條視窗的大小和位置;參數pParentWnd用來确定狀态條父視窗的指針;nID用來确定狀态條控制的辨別符。

狀态條控制風格可以是下列值的組合:CCS_BOTTOM、CCS_NODIVIDER、CCS_NOHILITE、CCS_NOMOVEY、CCS_NOPARENTALIGN、CCS_NORESIZE和CCS_TOP等,具體内容和含義請見工具條控制中的有關部分。

2、狀态條控制的類屬性

狀态條控制類屬性包括設定給定部分顯示文本SetText、取得給定部分的文本GetText、設定狀态條區域劃分數及其每部分的右邊坐标SetParts、取得狀态條區域劃分數量GetParts、取得狀态條的水準和垂直寬度GetBorders和取得狀态條矩形區域GetRect。

(三)狀态條控制的應用技巧

狀态條控制除可以顯示一定的幫助和提示資訊外,還可以實作響應滑鼠輸入等功能。這裡以在狀态條上顯示滑鼠移動坐标為例,具體說明其應用技巧。

利用應用程式向導生成的程式代碼中,狀态條作為主視窗的子視窗,其具有一個AFX_IDW_STATUS _BAR辨別符,通過它調用函數GetDescendantWindow()和AfxGetMainWnd(),就可以取得狀态條視窗的指針。由于基于文檔的應用程式在建立時就具有狀态條區域,是以隻要利用類向導簡單地加入滑鼠移動消息處理功能函數和下述函數代碼,就可以實作這一功能:

Void CTestView::OnMouseMove(UINT nFlags,Cpoint point)

{

CclientDC dc(this);//建立裝置文本

OnPrepareDC(&dc,NULL);//裝置映射處理

dc.DPtoLP(&point);//滑鼠指針轉換

char text[128];

CstatusBar *pStatus=(CstatusBar *)AfxGetApp()->m_pMainWnd->

GetDescendanWindow(AFX_IDW_STATUS_BAR);//取得視窗指針

If(pStatus){//如果存在顯示滑鼠坐标

Sprintf(text,”X坐标=%4d,Y坐标=%4d”,point.x,point.y);

pStatus->SetPaneText(0,text);}

CscrollView::OnMouseMove(nFlags,point);

VC通用控件程式設計之CProgress控件

(一)進度條的主要功能

  進度條控制(Progress Control)主要用來進行資料讀寫、檔案拷貝和磁盤格式等操作時的工作進度提示情況,如安裝程式等,伴随工作進度的進展,進度條的矩形區域從左到右利用目前活動視窗标題條的顔色來不斷填充。

進度條控制在MFC類庫中的封裝類為CProgressCtrl,通常僅作為輸出類控制,是以其操作主要是設定進度條的範圍和目前位置,并不斷地更新目前位置。進度條的範圍用來表示整個操作過程的時間長度,目前位置表示完成情況的目前時刻。SetRange()函數用來設定範圍,初始範圍為0-100,SetPos()函數用來設定目前位置,初始值為0,SetStep()函數用來設定步長,初始步長為10,StepIt()函數用來按照目前步長更新位置,OffsetPos()函數用來直接将目前位置移動一段距離。如果範圍或位置發生變化,那麼進度條将自動重繪進度區域來及時反映目前工作的進展情況。

進度條的對象結構

  進度條控制的建立方法

  CProgressCtrl &ProgressCtrl 建立進度條控制對象結構

  Create 建立進度條控制對象并綁定對象

  進度條控制類CprogressCtrl::Create的調用格式如下:

  其中參數dwStyle用來确定進度條控制的控制風格;參數rect用來确定進度條控制的大小和位置;參數pParentWnd用來确定進度條父視窗指針;參數nID用來确定進度條控制的控制符ID值。

  2、進度條控制的類屬性

  進度條控制的類屬性包括設定進度條最大最小控制範圍SetRange、設定進度條目前位置 SetPos、設定進度條目前位置偏移值OffsetPos和設定進度條控制增量值SetStep。

 3、進度條控制的操作方法

  進度條控制的操作方法主要是使進度條控制并重繪進度條的StepIt函數。

  進度條控制的應用技巧示例

  1、利用應用程式向導AppWizard生成基于對象框的應用程式CProgDlg;

  2、在對話框中設定進度條和靜态文本控制,其ID分别為IDC_PROG和IDCPERCENT;

在對話框初始代碼中增加控制的範圍和位置:

  在ProgDlg.h中設定兩個資料成員,用來表示進度條的最大值和步長:

//ProgDlg.h

class CProgDlg:public Cdialog

{   ......//其它代碼

   public:

        int m_nMax,m_nStep;

   ...... //其它代碼

(2)在ProgDlg.cpp中設定初始狀态

BOOL CProgDlg::OnInitDialog()

(3)完善WM_TIMER消息處理,使進度條按照目前步長進行更新,同時完成進度條的百分比顯示:

void CProgDlg::OnTimer(UINT nIDEvent)

{     //TODO:Add your message handler?

     CProgressCtrl *pProgCtrl=(CProgressCtrl*)GetDlgItem(IDC_PROG);

     int nPrePos=pProgCtrl->StepIt();//取得更新前位置

     char test[10];

     int nPercent=(int)(((nPrePos+m_nStep)/m_nMax*100+0.5);

     wsprintf(test,?%d%%?,nPercent);

     GetDlgItem(IDC_PERCENT)->SetWindowText(text);

     Cdialog::OnTimer(nIDEvent);

VC通用控件程式設計之CList控件

(一)清單控制的主要功能

  清單控制和視(List Control&View)主要用來以各種方式顯示一組資料記錄供使用者進行各種操作,Windows98/95中資料總管中的“檢視”标簽下的“大圖示|小圖示|清單|詳細資源”就是一個非常好的典型應用。清單中的記錄可以包括多個資料項,也可以包括表示資料内容的大小圖示,用來表示資料記錄的 清單控制提供了對Windows清單功能操作的基本方法,而使用清單視的視函數可以對清單視進行各種操作,通過調用視成員GetListCtrl擷取嵌在清單視内清單控制的引用(GetListCtrl& ctrlList = GetListCtrl()),就可以和清單控制一樣進行各種操作。操作一個清單控制和視的基本方法為:建立清單控制;建立清單控制所需要的圖像清單;向清單控制添加表列和表項;對清單進行各種控制,主要包括查找、排序、删除、顯示方式、排列方式以及各種消息處理功能等;最後撤消清單控制。

對于一個清單控制,其最典型最常用的顯示控制方式為:大圖示方式(LVS_ICON)、小圖示方式(LVS_SMALLICON)、清單顯示方式(LVS_LIST)和詳細資料(即報告LVS_REPORT)顯示方式。這可以通過設定其顯示方式屬性來實作。要控制清單所在視窗的風格,可通過功能函數GetWindowLong和SetWindowLong來實作,要控制清單圖示的對齊方式,可通過設定清單視窗的風格LVS_ALIGNTOP或LVS_ALIGNLEFT來實作,

(二)清單控制的對象結構

1、清單控制的建立方法

CListCtrl&listCtrl 定義清單對象的結構

Create 建立清單控制并綁定對象

清單控制CListCtrl::Create的調用格式如下:

BOOL Create( DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID );

其中參數dwStyle用來确定清單控制的風格;rect用來确定清單控制的大小和位置;pParentWnd用來确定清單控制的父視窗,通常是一個對話框;nID用來确定清單控制的辨別。其中清單控制的風格可以是下列值的組合:

LVS_ALIGNLEFT 用來确定表項的大小圖示以左對齊方式顯示;

LVS_ALIGNTOP 用來确定表項的大小圖示以頂對齊方式顯示;

LVS_AUTOARRANGE 用來确定表項的大小圖示以自動排列方式顯示;

LVS_EDITLABELS 設定表項文本可以編輯,父視窗必須設有LVN_ENDLABELEDIT風格;

LVS_ICON 用來确定大圖示的顯示方式;

LVS_LIST 用來确定清單方式顯示;

LVS_NOCOLUMNHEADER 用來确定在詳細資料方式時不顯示清單頭;

LVS_NOLABELWRAP 用來确定以單行方式顯示圖示的文本項;

LVS_NOSCROLL 用來屏蔽滾動條;

LVS_NOSORTHEADER 用來确定清單頭不能用作按鈕功能;

LVS_OWNERDRAWFIXED 在詳細清單方式時允許自繪視窗;

LVS_REPORT 用來确定以詳細資料即報告方式顯示;

LVS_SHAREIMAGELISTS用來确定共享圖像清單方式;

LVS_SHOWSELALWAYS 用來确定一直顯示被選中表項方式;

LVS_SINGLESEL 用來确定在某一時刻隻能有一項被選中;

LVS_SMALLICON 用來确定小圖示顯示方式;

LVS_SORTASCENDING 用來确定表項排序時是基于表項文本的升序方式;

LVS_SORTDESCENDING 用來确定表項排序時是基于表項文本的降序方式;

2、清單控制的屬性類

清單控制的屬性類包括取得清單控制的背景色GetBkColor、設定清單控制的背景色SetBkColor、取得清單控制的圖像清單GetImageList、設定清單控制的圖像清單SetImageList、取得清單項數目GetItemCount、取得清單控制的屬性GetItem、取得與表項相關的資料GetItemData、設定表項的屬性SetItem、設定與表項相關的數值SetItemData、取得相關聯的下一個表項GetNextItem、設定清單控制的文本顔色SetTextColor、取得清單控制的文本背景顔色GetTextBkColor、設定表項的最大數目SetItemCount和取得被選中表項的數目GetSelectedCount等。

3、清單控制的操作方法

清單控制的操作方法包括插入一個新的表項InsertItem、删除一個表項DeleteItem、排序表項SortItems、測試清單的位置HitTest、重繪表項RedrawItems、插入一個表列InsertColumn、删除一個表列DeleteColumn、編輯一個表項文本EditLabel和重繪一個表項DrawItem等。

(三)清單控制的資料結構

清單控制中包含兩個非常重要的資料結構LV_ITEM和LV_COLUMN。LV_ITEM用于定義清單控制的一個表項,LV_COLUMN用于定義清單控制的一個表列,其定義格式分别為:

typedef struct _LV_ITEM {

UINT mask; //結構成員屏蔽位

int iItem; //表項索引号

int iSubItem; //子表項索引号

UINT state; //表項狀态

UINT stateMask; //狀态有效性屏蔽位

LPTSTR pszText; //表項名文本

int cchTextMax; //表項名最大長度

int iImage; // 表項圖示的索引号

LPARAM lParam; // 與表項相關的32位數

} LV_ITEM;

typedef struct _LV_COLUMN {

UINT mask; //結構成員有效性屏蔽位

int fmt; //表列對齊方式

int cx; //表列的象素寬度

LPTSTR pszText; //表列的表頭名

int cchTextMax; //表列名的文本長度

int iSubItem; //與表列關聯的子表項索引号

} LV_COLUMN;

  其中fmt可以取如下值:

LVCFMT_CENTER 表列居中對齊

LVCFMT_LEFT 表列左對齊

(四)清單控制的應用技巧示例

本文給出具體執行個體示範清單控制及前面的表頭控制和圖像清單的應用技巧。步驟如下:

1、   通過“FILE->NEW->PROJECTS->MFC AppWizard(EXE)”建立名為VCLIST的工程,在建立過程中選擇基于對話框(Dialog based)的應用;将對話框中的預設控件删除,并将所有對話框屬性中的Language域設定為Chinese(P.R.C.),以使應用程式支援中文;

2、   建立兩個圖示IDI_GJ和IDI_XS,用來表示圖示的選中和非選中狀态,對于每個圖示都應建立32X32和16X16兩種大小,以保證程式的需要;

3、   在對話框視窗中設計組合框(Group Box),組合框中設定四個無線按鈕(Radio)“大圖示|小圖示|清單|資料”,同時設定排序、删除和關閉三個控制按鈕(Button),并在對話框中設定大小合适的清單控制(List Ctrl),其對應辨別分别如下:

--------------------------------------------------------------------------------

控制名稱 标題名稱辨別符号

清單控制 IDC_LISTCTRL

組合框 方式 IDC_STATIC

無線按鈕 大圖示 IDC_STDICON

小圖示 IDC_SMLICON

列 表 IDC_LIST

資 料 IDC_REPORT

按鈕 排 序 IDC_SORT

删 除 IDC_DEL

關 閉 IDOK

4、在設定無線按鈕時,需要注意的是隻有大圖示的Group屬性為選中狀态,而其它無線按鈕的狀态均為預設值。

5、選中清單控制控件,選擇“VIEW->ClassWizard->Memory Variables”,并利用IDC_ LISTCTRL引入成員變量,其變量類型為:

變量名 種類 變量類型

m_ListCtrl Control ClistCtrl

同時利用“MESSAGES MAP”為各無線按鈕和指令按鈕增加控制功能

6、然後在包含檔案和代碼檔案中分别加入如下代碼:

(1)在VCLISTDlg.h中增加資料結構和定義

typedef struct tagSPS { //定義結構

char szPm[10]; //品名

int Lx; //0-GJ 1-XS

char szSl[10]; //數量

char szDj[10]; //單價

char szJe[10]; //金額

} SPS;

int CALLBACK CompareFunc(LPARAM lParam1,LPARAM lParam2,LPARAM lParamSort);

(2)在VCLISTDlg.CPP中的起始處增加初始化資料和程式定義

//在檔案開始處增加資料結構初始化

SPS Sps[]={//資訊

{"紅梅",0,"1000","30","30000"},

{"黃梅",0,"1000","29","29000"},

{"綠梅",0,"1000","28","28000"},

{"青梅",0,"1000","27","27000"},

{"白梅",0,"1000","31","31000"},

{"紅梅",1,"1000","30","30000"},

{"黃梅",1,"1000","29","29000"},

{"綠梅",1,"1000","28","28000"},

{"青梅",1,"1000","27","27000"},

{"白梅",1,"1000","31","31000"}};

CImageList Cil1,Cil2;//大小圖像清單

(3)在程式初始化處增加表頭、圖像和清單控制建立代碼

BOOL CVCLISTDlg::OnInitDialog()

{   CDialog::OnInitDialog();

//......//其它代碼

// TODO: Add extra initialization here此處增加代碼

LV_ITEM lvitem;

LV_COLUMN lvcol;

int i,iPos,iItemNum;

CVCLISTApp *pApp=(CVCLISTApp *)AfxGetApp();//建立圖象清單

Cil1.Create(32,32,TRUE,2,2);

Cil1.Add(pApp->LoadIcon(IDI_GJ));

Cil1.Add(pApp->LoadIcon(IDI_XS));

Cil2.Create(16,16,TRUE,2,2);

Cil2.Add(pApp->LoadIcon(IDI_GJ));

Cil2.Add(pApp->LoadIcon(IDI_XS));//設定圖象清單

m_ListCtrl.SetImageList(&Cil1,LVSIL_NORMAL);

m_ListCtrl.SetImageList(&Cil2,LVSIL_SMALL);//向清單控制中添加表列

lvcol.mask=LVCF_FMT|LVCF_SUBITEM|LVCF_TEXT|LVCF_WIDTH;

lvcol.fmt=LVCFMT_CENTER;//居中

i=0;

lvcol.pszText="品 名";

lvcol.iSubItem=i;

lvcol.cx=70;

m_ListCtrl.InsertColumn(i++,&lvcol);

lvcol.pszText="數 量";

lvcol.pszText="單 價";

lvcol.pszText="金 額";

//向清單控制中添加表項

iItemNum=sizeof(Sps)/sizeof(SPS);

for(i=0;i<iItemNum;i++){

lvitem.mask=LVIF_TEXT|LVIF_IMAGE|LVIF_PARAM;

lvitem.iItem=i;

lvitem.iSubItem=0;

lvitem.pszText=Sps[i].szPm;

lvitem.iImage=Sps[i].Lx;

lvitem.lParam=i;

iPos=m_ListCtrl.InsertItem(&lvitem);//傳回表項插入後的索引号

lvitem.mask=LVIF_TEXT;

lvitem.iItem=iPos;

lvitem.iSubItem=1;

lvitem.pszText=Sps[i].szSl;

m_ListCtrl.SetItem(&lvitem);

lvitem.iSubItem=2;

lvitem.pszText=Sps[i].szDj;

lvitem.iSubItem=3;

lvitem.pszText=Sps[i].szJe;

CheckRadioButton(IDC_STDICON,IDC_REPORT,IDC_STDICON);

return TRUE; // return TRUE unless you set the focus to a control

(4)完善清單顯示方式代碼

在利用Classwizard類向導建立各功能按鈕顯示功能函數之後,必須依次完善這些功能函數的代碼,這些功能函數如下:

void CVCLISTDlg::OnStdicon()//設定大圖示顯示方式

{ // TODO: Add your control notification handler code here

LONG lStyle;

lStyle=GetWindowLong(m_ListCtrl.m_hWnd,GWL_STYLE);//擷取目前視窗類型

lStyle&=~LVS_TYPEMASK; //清除顯示方式位

lStyle|=LVS_ICON; //設定顯示方式

SetWindowLong(m_ListCtrl.m_hWnd,GWL_STYLE,lStyle);//設定視窗類型

void CVCLISTDlg::OnSmlicon() //設定小圖示顯示方式

lStyle|=LVS_SMALLICON; //設定顯示方式

void CVCLISTDlg::OnList() //設定清單顯示方式

lStyle|=LVS_LIST; //設定顯示方式

void CVCLISTDlg::OnReport() //詳細資料顯示方式

lStyle|=LVS_REPORT; //設定顯示方式

(5)删除功能的實作

要實作删除功能,必須取得選中表項的數和表項總數,并且需要從後向前進行依次删除,其原因是每個表項被删除後,其後各表項的索引号均會發生遞減變化,如果采取從前向後删除的方法,就會造成無法正常删除選中的表項,其功能代碼如下:

void CVCLISTDlg::OnDel() //删除按鈕功能

{   // TODO: Add your control notification handler code here

int i,iState;

int nItemSelected=m_ListCtrl.GetSelectedCount();//所選表項數

int nItemCount=m_ListCtrl.GetItemCount();//表項總數

if(nItemSelected<1) return;

for(i=nItemCount-1;i>=0;i--){

iState=m_ListCtrl.GetItemState(i,LVIS_SELECTED);

if(iState!=0) m_ListCtrl.DeleteItem(i);

(6)排序功能的實作

清單控制有一個特殊的功能,當以詳細資料方式顯示時,清單頂部的表頭可以當作按鈕來使用,這可以通過清單控制建立時的風格來控制。當滑鼠點選清單頭名稱時,清單控制就會向其父視窗發送一個LNV_COLUMNCLICK消息,利用類導向中清單控制IDC_LISTCTRL對應的LNV_COLUMNCLICK消息加入相應處理函數,就可将表列按照特定順序進行排列。其函數使用方法見程式,其中iSort為排序的表列索引号,(PFNLVCOMPARE)CompareFunc為進行具體排序的回調函數,也就是說,通過滑鼠點選表頭實作的排序過程是由第三方開發的專用排序函數來實作的,排序函數隻是實作表項的具體比較操作,而整個排序過程是由SortItemS屬性通過不斷調用這個函數來實作的。正常的排序過程是升序方式,通過調換排序函數中的參數值,就可實作降序排列,即将PARAM1與PARAM2調換位置。這個回調函數的前兩個參數為表列中表項的索引号,第三個參數為排序的表列索引号。

void CVCLISTDlg::OnColumnclickListctrl(NMHDR* pNMHDR, LRESULT* pResult)

{      //滑鼠左鍵單擊表頭處理函數

NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;

// TODO: Add your control notification handler code here

static int iSorted=-1;//排列序号

if (pNMListView->iSubItem==iSorted) return;

iSorted=pNMListView->iSubItem;

m_ListCtrl.SortItems((PFNLVCOMPARE)CompareFunc,iSorted);

*pResult = 0;

} //排序時比較表項的回調函數

int CALLBACK CompareFunc(LPARAM lParam1, LPARAM lParam2,LPARAM lParamSort)

{  

 char *text1,*text2;

switch (lParamSort){

case 0L:text1=Sps[lParam1].szPm;

text2=Sps[lParam2].szPm;break;

case 1L:text1=Sps[lParam1].szSl;

text2=Sps[lParam2].szSl;break;

case 2L:text1=Sps[lParam1].szDj;

text2=Sps[lParam2].szDj;break;

case 3L:text1=Sps[lParam1].szJe;

text2=Sps[lParam2].szJe;break;

return (strcmp(text1,text2));//結果為>0 =0 <0

同樣,也可以通過專用按鈕來實作排序功能,如本文的排序按鈕對應的功能代碼如下:

void CVCLISTDlg::OnSort()

{    // TODO: Add your control notification handler code here

m_ListCtrl.SortItems((PFNLVCOMPARE)CompareFunc,0);

7、清單視的演練技巧

在使用清單視時,其方法與清單控制基本相同,隻不過清單視是在視窗中來實作的而清單控制是在對話框中實作,清單視的各種功能是通過菜單來實作的而清單控制是通過按鈕等方式來實作的,清單控制需要在對話框中建立清單控制控件而清單視直接占據整個視窗,在設計過程中隻要将按鈕和清單控制設計過程變為菜單設計,并注意在功能增加是在類向導中是通過菜單指令來操作,同時在每個功能函數前面增加取得清單視引用的指令( CListCtrl& ListCtrl = GetListCtrl()),而其餘資料結構和代碼均不需要修改,實作起來比較容易。

VC通用控件程式設計之CImageList控件

圖像清單控制(CImageList)是相同大小圖像的一個集合,每個集合中均以0為圖像的索引序号基數,圖像清單通常由大圖示或位圖構成,其中包含透明位圖模式。可以利用WINDOWS32位應用程式接口函數API來繪制、建立和删除圖像,并能實作增加、删除、替換和拖動圖像等操作。圖像清單控制提供了控制圖像清單的基本方法,這些方法在WINDOWS95及以後版本才能實作。

(一)圖像控制的對象結構

1、圖像控制的資料成員

m_hImageList 連接配接圖像對象的控制句柄

2、圖像控制的建立方法

CimageList&imageList建立圖像控制對象結構

Create 初始化圖像清單并綁定對象

圖像控制的建立方法如下:

BOOL Create( int cx, int cy, UINT nFlags, int nInitial, int nGrow );

BOOL Create( UINT nBitmapID, int cx, int nGrow, COLORREF crMask );

BOOL Create( LPCTSTR lpszBitmapID, int cx, int nGrow, COLORREF crMask );

BOOL Create( CImageList& imagelist1, int nImage1, CImageList& imagelist2

,int nImage2,int dx, int dy );

imagelist1 指向圖像清單控制對象的一個指針;nImage1圖像清單1中包含的圖像數 量;imagelist2指向圖像清單控制對象的一個指針;nImage2圖像清單2中包含的圖像數量;dx表示以象素為機關的圖像寬度;dy表示以象素為機關的圖像高度。

同樣,圖像控制的建立也包括兩個步驟,首先建立圖像清單結構,然後建立圖像清單控制。

3、圖像控制的屬性類

圖像控制的屬性類包括傳回m_hImageList.控制句柄GetSafeHandle、取得圖像清單中的圖像數量GetImageCount、設定圖像清單的背景顔色SetBkColor、取得圖像清單的背景顔色SetBkColor和取得圖像的有關資訊SetBkColor。

4、圖像控制的操作方法

圖像控制的操作方法包括将一個圖像清單綁定到一個對象上Attach、将對象上的圖像清單解除綁定并傳回句柄Detach、删除一個圖像清單DeleteImageList、将一個圖像增加到圖像清單中Add和将一個圖像從圖像清單中删除Remove等。

(二)圖像控制的應用技巧

對于圖像控制,同樣不能單獨使用,必須與清單控制、樹控制和标簽控制互相結合應用,下面分别介紹其具體應用技巧。

1、圖像控制在清單控制中的應用技巧

①設定圖像控制CListCtrl::SetImageList的調用格式如下:

CImageList* SetImageList( CImageList* pImageList, int nImageList );

其傳回值是指向前一個圖像清單控制的一個指針,如果不存在前一個圖像清單則為NULL;其中參數pImageList是指向圖像清單的辨別,nImageList是圖像清單的類型,可以是如下值:

LVSIL_NORMAL 用大圖示方式進行圖像清單;

LVSIL_SMALL 用小圖示方式進行圖像清單;

LVSIL_STATE 以圖像狀态進行圖像清單;

②取得圖像控制CListCtrl::GetImageList的調用格式如下:

CImageList* GetImageList( int nImageList ) const;

其傳回值為指向圖像清單控制的指針,其中nImageList用來确定取得傳回值的圖像清單的 值,其取值與設定圖像清單函數相同。

③圖像控制在清單控制中的應用示例

CImageList Cil1,Cil2; //定義大小圖示像清單

  CVCLISTApp *pApp=(CVCLISTApp *)AfxGetApp();//取得清單控制程式

  Cil1.Create(32,32,TRUE,2,2); //建立32位圖像控制

  Cil1.Add(pApp->LoadIcon(IDI_GJ));//增加選中狀态圖像

  Cil1.Add(pApp->LoadIcon(IDI_XS));//增加非選中狀态圖像

  Cil2.Create(16,16,TRUE,2,2); //建立16位圖像控制

  Cil2.Add(pApp->LoadIcon(IDI_GJ));//增加選中狀态圖像

  Cil2.Add(pApp->LoadIcon(IDI_XS));//增加非選中狀态圖像

  m_ListCtrl.SetImageList(&Cil1,LVSIL_NORMAL);//設定大圖示控制

  m_ListCtrl.SetImageList(&Cil2,LVSIL_SMALL);//設定小圖示控制

2、圖像控制在樹控制中的應用技巧

①設定圖像控制CTreeCtrl::SetImageList的調用格式如下:

CImageList* SetImageList( CImageList * pImageList, int nImageListType );

其傳回值為指向前前一個圖像清單的指針,否則為NULL;參數pImageList為指向圖像清單的辨別,如果pImageList為NULL則所有的圖像都将從樹控制中被清除;nImageListType為圖像清單設定的類型,可以是如下值之一:

TVSIL_NORMAL 設定正常圖像清單,其中包括選中和非選中兩種圖示;

TVSIL_STATE 設定圖像清單狀态,指使用者自定義狀态;

②取得圖像控制CTreeCtrl::GetImageList的調用格式如下:

CImageList* GetImageList( UINT nImage );

如果調用成功則傳回圖像清單控制指針,否則為NULL;nImage為取得傳回值的圖像清單類型,其取值和取得圖像清單控制完全相同。

③圖像控制在樹控制中的應用示例

CImageList Cil1,Cil2;//定義大小圖示像清單

CVCTREEApp *pApp=(CVCTREEApp *)AfxGetApp();//擷取應用程式指針

Cil1.Create(16,16,ILC_COLOR,2,2);//建立圖像控制

Cil1.Add(pApp->LoadIcon(IDI_PM));//增加選中狀态圖像

Cil1.Add(pApp->LoadIcon(IDI_CJ));//增加非選中狀态圖像

m_TreeCtrl.SetImageList(&Cil1,TVSIL_NORMAL);//設定圖像控制清單

然後在樹控制的結構定義中進行如下設定:

TCItem.item.iImage=0; //設定未選中圖像索引号

TCItem.item.iSelectedImage=1;//設定選中時圖像引号

3、圖像控制在标簽控制中的應用技巧

①設定圖像控制CTabCtrl::SetImageList的調用格式

CImageList * SetImageList( CImageList * pImageList );

其傳回值為指向前一個圖像清單的指針,如果不存在前一個圖像清單則為NULL;pImageList為辨別TAB控制的圖像清單指針。

②取得圖像控制CTabCtrl::GetImageList的調用格式

HIMAGELIST GetImageList() const;

 其傳回值為指向TAB控制的圖像清單指針,如果調用不成功則為NULL。

VC通用控件程式設計之CHeadCtrl控件

表頭控制(CHeaderCtrl)通常應用在視窗中的文本或資料的清單之上。一般為資料列的标題,可以包括多個部分,使用者可以拖動每個部分并可以控制每列的寬度。表頭控制類提供了普通表頭控制的基本方法,隻有在WINDOWS95以後版本系統中才提供,其方法包含在afxcmn.h檔案中,一般與标簽控制(CTabCtrl)和清單控制(CListCtrl)組合使用。

(一)表頭控制的對象結構

1、表頭控制對象的建立方法

CHeaderCtrl &cheaderCtrl 建立表頭控制對象

Create 建立表頭并綁定對象

CHeaderCtrl::Create的格式如下:

BOOL Create( DWORD dwStyle, const RECT&rect, CWnd* pParentWnd, UINT nID );其傳回值非零時初始化成功,否則失敗。

參數dwStyle用來确定表頭控制類型;rect用來确定表頭控制的大小和位置;ParentWnd用來确定表頭控制的父視窗;nID用來表示表頭控制的标志。

表頭控制風格包括:

HDS_BUTTONS 表示表頭控制外觀類似按鈕;

HDS_HORZ 表示表頭控制為水準排列;

HDS_VERT 表示表頭控制為垂直排列;

HDS_HIDDEN 表示表頭控制為隐藏模式。

它也可以使用普通類控制風格,包括:

CCS_BOTTOM 設定控制位置在父視窗的底部并與父視窗同樣寬度;

CCS_NODIVIDER 在控制頂部形成兩個像素的高亮區;

CCS_NOHILITE 在控制頂部形成一個像素的高亮區;

CCS_NOMOVEY 在響應WM_SIZE消息時重置大小并水準排列;

CCS_NOPARENTALIGN 使控制自動靠近父視窗的頂部或底部;

CCS_NORESIZE 設定初始大小或新值時使控制使用預設寬度和高度;

CCS_TOP 設定在父視窗客戶區域的頂部并與父視窗同樣寬度;

同樣表頭控制也可以使用視窗控制風格,包括:

WS_CHILD 建立一個子視窗,不能用于WS_POPUP視窗類型;

WS_VISIBLE 建立一個初始時不可見的視窗;

WS_DISABLED 建立一個初始時無效的視窗;

WS_GROUP 确定可用光标移動的控制群組;

WS_TABSTOP 确定可用TAB控制移動站點;

表頭控制一般分為兩個步驟,首先确定表頭控制的資料結構,然後建立表頭控制并綁定對象。

2、表頭控制的屬性

表頭控制的屬性包括取得表頭控制中項目的數量GetItemCount、取得表頭控制中某一項目的内容GetItem和設定表頭控制中某一項目的内容SetItem。

3、表頭控制的操作方法

表頭控制的操作方法包括向表頭控制中插入一個新項目InsertItem、從表頭控制中删除一個項目DeleteItem和繪制表頭中給定的項目DrawItem等。

(二)表頭控制的資料結構

在使用表頭控制時,首先必須建立一個資料結構HD_ITEM,其結構定義如下:

typedef struct _HD_ITEM

{    UINT mask; //結構成員有效控制位

int cxy; //表頭項目的寬度

LPSTR pszText; //表頭項目内容

HBITMAP hbm; //表頭項目的位置句柄

int cchTextMax; //表頭内容字元串長度

int fmt; //表頭項目的格式

LPARAM lParam; //應用程式定義的32位資料

} HD_ITEM;

屏蔽控制位說明了資料結構成員中包含的有效資料,可以是下面标志的組合:

HDI_BITMAP hbm成員有效

HDI_FORMAT fmt 成員有效

HDI_LPARAM lParam成員有效

HDI_TEXT pszText 和cchTextMax 成員有效

HDI_WIDTH cxy 成員有效并确定項目寬度值

格式标志位fmt可以是以下标志的組合:

HDF_CENTER 表頭項目居中

HDF_LEFT 表頭項目左對齊

HDF_RIGHT 表頭項目右對齊

HDF_BITMAP 表頭顯示一個位圖

HDF_OWNERDRAW 由主視窗自繪表頭項目

HDF_STRING 表頭項目為一個字元串

(三)表頭控制的應用技巧

由于表頭控制無法單獨使用,其主要是配合清單控制和标簽控制,并多以文字表頭應用多見,InsertItem、SetItem和GetItem是常用的方法,如在清單控制時利用InsertColumn屬性就可以增加一個表列的文本标題,具體用法和技巧見清單控制和标簽控制。下面以在清單控制中的增加表列的方法來具體說明:

lvcol.pszText="品 名";//設定第一清單頭名

lvcol.iSubItem=i; //表列序号

lvcol.cx=70; //表列寬度

m_ListCtrl.InsertColumn(i++,&lvcol);//插入一個表列

lvcol.pszText="數 量";//設定第二清單頭名

......//其它代碼

繼續閱讀