演练CTab控件

演练CTab控件

(一)标签控制的主要功能

标签控制(Tab Control)是用来在一个窗口如对话框等中的同一用户区域控制多组显示信息或控制信息,由顶部的一组标签来控制不同的信息提示,标签即可以是文本说明也可以是一个代表文本含义的图标,或是两者的组合。针对不同的选择标签,都会有一组提示信息或控制信息与之相对应,供用户进行交互操作,这在WINDOWS98的属性表中最常见。另外还存在一种特殊风格的标签,即TBS_BUTTONS风格的标签,这种标签外观类似按钮,通过鼠标点击改变状态,一般用来执行一些功能而不是用来显示或控制信息。

提到标签,最快想到的应该是属性表对话(Property Sheet),这两者的配合应用更是随处可见。属性表对话框有时也称为多页对话框(Multiple-Page Dialog)或是标签对话框(Table Dialog),最多可设置24个属性页(Property Page),通过顶部的标签来选择不同的属性页。另外还有一种特殊的属性表对话框,就象VC++5.0中的类向导AppWizard一样,其不存在供用户选择的标签,而是按照顺序依次控制属性页的显示,并且还有一般属性页中不存在的“确认”、“上一步”、“下一步”、“完成”和“帮助”等按钮。

标签控制在MFC中只存在一种封装形式,即控制类CtabCtrl。在使用标签时即可以在对话框中直接添加,也可以在窗口中作为子窗口来使用,只不过这样应用时需要选创建标签。

(二)标签控制的对象结构

1、标签控制的建立方法

CTabCtrl&tabCtrl 建立标签控制对象结构

Create 建立标签控制并绑定对象

标签控制CTabCtrl::Create的调用格式如下:

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

其中参数dwStyle用来确定标签控制的风格;rect用来控制标签的大小和位置;pParentWnd用来确定标签控制的父窗口句柄;nID用来确定标签控制的标识符。

标签控制的风格可以是如下值的组合:

TCS_BUTTONS 表示将标签外观定义成类似按钮

TCS_FIXEDWIDTH 使所有标签具有相同的宽度

TCS_FOCUSNEVER 使特定标签永远不接收输入焦点

TCS_FOCUSONBUTTONDOWN 当标签被鼠标点击时接收输入焦点,其仅与TCS_BUTTONS合用

TCS_FORCEICONLEFT 强制图标在左面,剩余部分使标签居中

TCS_FORCELABELLEFT 使图标和标签均左对齐

TCS_MULTILINE 允许标签控制显示多行标签

TCS_OWNERDRAWFIXED 允许父窗口自绘标签

TCS_RIGHTJUSTIFY 使标签右对齐

TCS_SHAREIMAGELISTS 当控制被撤消时标签控制的图像不被撤消

TCS_TOOLTIPS 允许标签控制存在工具提示控制

TCS_TABS 标签正常显示,为默认状态

TCS_SINGLELINE 将标签只显示在一行上,默认状态

TCS_RAGGEDRIGHT 不使标签自动填满控制区域,默认状态

同样,标签控制还可以使用窗口的一些控制风格:

WS_CHILD 为标签控制创建子窗口,只能与WS_POPUP风格一起使用

WS_VISIBLE 建立一个初始可视的标签控制

WS_DISABLED 建立一个初始不可视的标签控制

WS_GROUP 建立标签控制群组的第一个控制

WS_TABSTOP 建立可用TAB键移动的标签控制

2、标签控制的属性类

标签控制的属性类包括取得与标签控制相关联的图像列表GetImageList、设置标签控制的图像列表SetImageList、取得标签控制中标签的总数GetItemCount、取得标签控制中特定标答的相关信息GetItem、设置标签的部分或全部属性SetItem、检测当前被选中的标签GetCurSel、将一个标签设置为选中状态SetCurSel和取得具有当前输入焦点的标签SetCurSel等。

3、标签控制的操作方法

标签控制的操作方法包括在标签控制中插入一个标签InsertItem、删除一个标签 DeleteItem、从标签控制中删除所有项目DeleteAllItems、从标签控制中删除一个图像列表RemoveImage和绘制标签控制中的特定一项DrawItem等。

(三)标签控制的数据结构

在使用标签控制时,必须使用的函数就是在标签控制中插入标签。函数InsertItem的原形如下:

BOOL InsertItem(int nItem,TC_ITEM * pTabCtrlItem);

该函数中的TC_ITEM为添加标签时所使用信息的数据结构,其数据成员的定义方法及含义如下:

typedef struct _TC_ITEM {

UINT mask; // 确定结构成员的屏蔽或设置位

UINT lpReserved1; // 保留未用

UINT lpReserved2; // 保留未用

LPSTR pszText; // 标签名称字符串

int cchTextMax; // 标签名称字符串缓冲区大小

int iImage; // 标签控制的图像索引号

LPARAM lParam; // 应用程序定义的相关32位数据

} TC_ITEM;

当鼠标点击标签控制中的标签时,标签控制就会向其父窗口发送相关的通知消息,通过处理这些通知消息,程序可以实现各种功能。

(四)属性表和属性页的基本用法

在标签控制过程中,属性表对话框和属性页是必不可少的。在MFC类库中,属性表对话框类CpropertySheet是由CWnd类派生而来的,而属性页类CpropertyPage是由Cdialog类派生而来的,它们的用法基本相同:

1、创建所有的属性页。创建属性页的方法与创建一般对话框资源的方法一样,利用对话框编辑器可以为每个属性页创建一个对话框模板,其区别在于,当利用类向导ClassWizard为属性页生成类时应选择属性页类CpropertyPage作为基类,而不是将一般的对话框类Cdialog作为基类;

2、创建属性表对话框,并将事先创建好的各属性页添加进去,两者的创建顺序可以互换,但在创建完之后将属性页添加到属性表对话框中去这一步是必须要做的;

3、显示属性表对话框。虽然属性表对话框类CpropertySheet不是由对话框类Cdialog派生而来的,但两者的操作非常类似,调用DoModal()函数就会显示一个模态属性表对话框,而调用Create()操作就会显示一个非模态的属性表对话框;

4、对数据交换的处理。和对话框类似,属性表对话框与对象之间的数据交换也是通过数据成员2来实现的,只是属性表本身不带数据成员,而实际进行数据交换的是属性页中的数据成员;

5、对向导对话框的处理。如果要显示一个向导对话框,在显示之前应首先调用SetWizardMode()函数对向导对话框进行特殊处理,对于存在按钮的向导对话框,还应调用SetWizardButtons()来对向导对话框的按钮功能进行定制,在用户操作结束时还应调用SetFinishText()函数将“完成”按钮设置为有效状态。

(五)标签控制的应用技巧示例程序

  本文给出一个基于文档的标签应用实例。实例程序中通过简单设置菜单、标签和属性表来演示标签控制的实际应用技巧,程序通过选择菜单选项弹出设置正文颜色、字体和修饰等属性表对话框来和用户进行简单交互。其实现步骤如下:

1、利用应用程序向导AppWizard创建一个基于文档的工程TAB,在选择工程类型时应选择单文档;

2、利用资源中的菜单生成器,删除无用菜单,并增加如下菜单结构

菜单名 标识符

设置(S) (弹出菜单名)

背景设置(B) IDM_BKGRND

前景设置(F) IDM_FRGRND

3、利用对话框设计器设置属性表对话框所需要的四个属性页,注意在选择基类时应将属性 页类CpropertyPage作为基类,并将对话框及菜单等控件的所有属均改为中文。四个属性页及其包括的控件内容分别为:(1)文字属性对话框包括一个输入文字的文本输入框,用于输入和修改在窗口上显示的文字;(2)字体属性对话框包括三个选中框,用来确定显示的字体修饰;(3)字间距属性对话框包括一个用于显示提示信息的标签和用于输入字间距大小的文本输入框;(4)颜色属性对话框包括一个成组框和三个单选圆钮;(5)窗口中设置一个用于显示输入文字的标签。

以上控制的设置参数如下:


控制名称 标题名称 标识符串


标签控制 IDC_TABCTRL

表态文本 字间距(10-100) IDC_STATIC1

编辑框 IDC_LIST

成组框 颜色 IDC_STATIC2

单选按钮 黑色 IDC_BLACK

红色 IDC_RED

蓝色 IDC_BLUE

文本框(编辑框) IDC_TEXT

设置字体(复选按钮)粗体 IDC_BOLD

斜体 IDC_ITALIC

下划线 IDC_UNDERLINE

按 钮 确认 IDOK

取消 IDCANCEL


利用类向导ClassWizard在属性表对话框CtabDlg、属性页对话框CtextPage和CstylePage中分别加入如下数据成员:


标识符串 类型 数据成员


IDC_TABCTRL CtabCtrl m_tabCtrl

IDC_DIST int m_nDist

IDC_BLACK int m_nColor

IDC_TEXT Cstring m_cText

IDC_BOLD BOOL m_bBold

IDC_ITALIC BOOL m_bItalic

IDC_UNDERLINE BOOL m_bUnderline


以上数据成员也可以在TABDlg.h、StylePage.h和TextPage.h中利用手工方法增加。

4、将要显示的数据成员加入到视类中去,来和对话框之间进行数据交换,并且将其在初始化函数中进行数据初始化。

(1)在TabView.h中增加如下代码:

#include "TabDlg.h"

#include "TextPage.h"

#include "StylePage.h"

class CTabView : public CView

{public:

int nDist;//数值

int nColor;//颜色

CString cText;//中文字符串

BOOL bBold,bItalic,bUnderline;//字体属性

}

(2)在TabView.cpp中对数据成员进行如下初始化。

CTabView::CTabView()

{ nDist=20;

nColor=1;

cText=CString("标签控制演示实例");

bBold=bItalic=bUnderline=FALSE;

}

(3)在TabDlg.cpp中向控制中增加标签,来实现背景设置功能。

BOOL CTabDlg::OnInitDialog()

{ CDialog::OnInitDialog();

TC_ITEM tcItem;//添加标签

tcItem.mask=TCIF_TEXT;

tcItem.pszText="字 间 距";

m_tabCtrl.InsertItem(0,&tcItem);

tcItem.pszText="颜色设置";

m_tabCtrl.InsertItem(1,&tcItem);

m_tabCtrl.SetCurSel(1);

return TRUE;

}

当标签切换时,标签控制会自动向对话框窗口发送TCN_SELCHANGE通知消息,这时需要根据所选择的标签索引号对属性页的显示和隐藏进行切换控制,应完善OnSelchangeTabctrl()函数:

void CTabDlg::OnSelchangeTabctrl(NMHDR* pNMHDR, LRESULT* pResult)

{ int iPage=m_tabCtrl.GetCurSel();//所选标签号

switch(iPage){

case 0://字间距

GetDlgItem(IDC_STATIC2)->ShowWindow(SW_HIDE);//隐藏选择按钮

GetDlgItem(IDC_BLACK)->ShowWindow(SW_HIDE);//隐藏选择按钮

GetDlgItem(IDC_RED)->ShowWindow(SW_HIDE);//隐藏选择按钮

GetDlgItem(IDC_BLUE)->ShowWindow(SW_HIDE);//隐藏选择按钮

GetDlgItem(IDC_STATIC1)->ShowWindow(SW_SHOW);//显示输入项数

GetDlgItem(IDC_DIST)->ShowWindow(SW_SHOW);//显示输入项数

break;

case 1://颜色设置

GetDlgItem(IDC_STATIC1)->ShowWindow(SW_HIDE);//隐藏项数输入

GetDlgItem(IDC_DIST)->ShowWindow(SW_HIDE);//隐藏项数输入

GetDlgItem(IDC_STATIC2)->ShowWindow(SW_SHOW);//显示选项选择

GetDlgItem(IDC_BLACK)->ShowWindow(SW_SHOW);//显示选项选择

GetDlgItem(IDC_RED)->ShowWindow(SW_SHOW);//显示选项选择

GetDlgItem(IDC_BLUE)->ShowWindow(SW_SHOW);//显示选项选择

break;

}

*pResult = 0;

}

(4)菜单功能的完善。在执行相应的菜单功能时,必须对类向导增加的相应功能函数进行代码完善,这就要处理TabView.cpp文件,背景设置功能函数如下:

void CTabView::OnBkgrnd()

{ CTabDlg ctd;

ctd.m_nDist=nDist;

ctd.m_nColor=nColor;

if(ctd.DoModal()==IDCANCEL) return;

nDist=ctd.m_nDist;

nColor=ctd.m_nColor;

Invalidate();//重新绘制窗口

}

同样,也要对前景设置功能函数进行完善:

void CTabView::OnFrgrnd()

{ CPropertySheet cps("前景设置");//创建属性表对象

CTextPage ctp; //显示文字属性页

CStylePage csp;//显示字体属性页

ctp.m_cText=cText;

csp.m_bBold=bBold;

csp.m_bItalic=bItalic;

csp.m_bUnderline=bUnderline;

cps.AddPage(&ctp);//添加属性页

cps.AddPage(&csp);

if(cps.DoModal()==IDCANCEL) return;

cText=ctp.m_cText;

bBold=csp.m_bBold;

bItalic=csp.m_bItalic;

bUnderline=csp.m_bUnderline;

Invalidate();//重新绘制窗口

}

(5)为了充分演示标签控制与各属性页之间的数据交换功能,应该实现标签控制各属性页与用户之间数据交换结束后的窗口显示功能,笔者实现的功能函数显示了由属性页中输入的字体及背景网格功能,TabView.cpp中的对应函数代码如下:

void CTabView::OnDraw(CDC* pDC)

{ CTabDoc* pDoc = GetDocument();

ASSERT_VALID(pDoc);

// TODO: add draw code for native data here

RECT rc;

GetClientRect(&rc);

int i,j,k;

CPen pen,*pOldPen;

COLORREF color;

switch (nColor){

case 0:color=RGB(0,0,0); //设置黑色

break;

case 1:color=RGB(0xff,0,0);//设置红色

break;

case 2:color=RGB(0,0,0xff);//设置蓝色

break;

}

pen.CreatePen(PS_SOLID,1,color);

pOldPen=pDC->SelectObject(&pen);//绘制背景网格

j=rc.right/nDist+1;

k=rc.bottom/nDist+1;

for(i=0;i<j+k;i++){

pDC->MoveTo(i*nDist,0);

pDC->LineTo(0,i*nDist);

if(i<j){

pDC->MoveTo(i*nDist,0);

pDC->LineTo(rc.right,(j-i)*nDist);

} else {

pDC->MoveTo(0,(i-j)*nDist);

pDC->LineTo(rc.right,i*nDist);

}

}

pDC->SelectObject(&pOldPen);

CFont font,*pOldFont;

font.CreateFont(50,0,0,0,bBold?1000:200,

bItalic,bUnderline,0,ANSI_CHARSET,

OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,

DEFAULT_QUALITY,DEFAULT_PITCH,NULL);

pOldFont=pDC->SelectObject(&font);

pDC->TextOut(20,20,cText);

pDC->SelectObject(pOldFont);

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
CScrollWnd 这是一个从MFC的源码中扒出来的一个滚动窗口类,功能基本类似于CScrollView, 但是它的基类是CWnd,这样为一些不需要使用Document View结构但又想使用滚动窗口的小程序提供了比较方便的方法,他的接口除了两个坐标转换函数以外与CScrollView基本相同,同时在画的地方采用了内存DC缓冲,避免了闪烁,这下你可以随意的刷新了(当然刷新太多了对效率还是有一些影响的) 因为是工作需要,所以设计了这个类,目前只测试了基本的功能,映射模式为MM_TEXT在屏幕上显示正常,至于打印的支持还没有做。 因为跟CScrollView功能基本相同,所以没有写什么注释,大家可以查MSDN中CScrollView的帮助,如果发现跟CScrollView不一致的地方给我mail吧。 使用方法,跟CScrollView一样,在你的类中继承,实现OnInitialUpdate和OnDraw就成了。 CTabSheet 一个TabCtrl,可以方便的把各种窗口加入到其中,做成属性页的形式,功能很简单,但是很 实用。 CStaticSplitter 静态切分窗口,这个类是从WTL的SplitterWnd里面扒出来的,因为MFC的SplitterWnd实在是太太太难用了,而且很难看,看到WTL里面的这个不错,想拿来用,不过如果是MFC程序的话再加上WTL的风格有些不协调,就干脆把它的形式改成MFC的风格了,函数看着挺多,不过常用并不多,至于注释嘛,我只是在经常用的函数声明上大概写了几句,相知道具体实现,那就去看代码吧:)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值