MFC公共控件

综述

控件类型 WNDCLASS MFC类  
Animation “SysAnimate32” CAnimateCtrl ANIMATE_CLASS
ComboBoxEx “ComboBoxEx32” CComboBoxEx WC_COMBOBOXEX
Data-Time “SysDateTimePick32” CDataTimeCtrl DATETIMEPICK_CLASS
Header “SysHeader32” CHeaderCtrl WC_HEADER
Hotkey “msctls-hotkey32” CHotkeyCtrl HOTKEY_CLASS
Image List N/A CImageList N/A
Ip Address “SysIpAddress32” CIpAddressCtrl WC_IPADDRESS
List-View “SysListView32” CListCtrl WC_LISTVIEW
Month Calendar “SysMonthCal32” CMonthCalCtrl MONTHCAL_CLASS
Progress “msctls_Progress32” CProgressCtrl PROGRESS_CLASS
Property Sheet N/A CPropertySheet N/A
Rebar “ReBarWindow32” CReBarCtrl REBARCLASSNAME
Rich edit “RichEdit20A” “RichEdit20W” CRichEditCtrl RICHEDIT_CLASS
Slider “msctls_trackbar32” CSliderCtrl TRACKBAR_CLASS
Spin Button “msctls_updown32” CSpinButtonCtrl UPDOWN_CLASS
Status bar “msctls_statusbar32” CStatusBarCtrl STATUSCLASSNAME
Tab “SysTabControl32” CTabCtrl WC_TABCONTROL
Tool bar “ToolbarWindow32” CToolBarCtrl TOOLBARCLASSNAME
ToolTip “tooltips_class32” CToolTipCtrl TOOLTIPS_CLASS
TreeView “SysTreeView32” CTreeCtrl WC_TREEVIEW
void GetComctlVersion(DWORD &dwMajor, DWORD &dwMinor)
{
    dwMajor = dwMinor = 0;
    HINSTANCE hLib = ::LoadLibrary(_T("Comctl32.dll"));
    if(hLib != NULL)
    {
        DLLGETVERSIONPROC pDllGetVersion = 
            (DLLGETVERSIONPROC)::GetProcAddress(hLib, _T("DllGetVersion"));
        if(pDllGetVersion)
        {
            DLLVERSIONINFO dvi;
            ::ZeroMemory(&dvi, sizeof(dvi));
            dvi.cbSize = sizeof(dvi);
            HRESULT hr = (*pDllGetVersion)(&dvi);
            if(SUCCEEDED(hr))
            {
                dwMajor = dvi.dwMajorVersion;
                dwMinor = dvi.dwMinorVersion;
            }
        }
        else
        {
            dwMajor = 4;
            dwMinor = 0;
        }
        ::FreeLibrary(hLib);
    }

}
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29

创建公用控件

// 1
#include <afxcmn.h>
...
CProgressCtrl wndProgress;
wndProgress.Create(WS_CHILD | WS_VISIBLE | WS_BORDER, CRect(x1, y1, x2, y2), this, IDC_PROGRESS);
 
 
  • 1
  • 2
  • 3
  • 4
  • 5

// 2
// 对话框RC
CONTROL "", IDC_PROGRESS, PROGRESS_CLASS, WS_BORDER, 32, 32, 80, 16
 
 
  • 1
  • 2
  • 3

公用控件公有得一些样式: 
CCS_TOP 
CCS_BOTTOM 
CCS_LEFT 
CCS_RIGHT 
CCS_VERT 
CCS_NOMOVEX 父窗口大小变化时,禁止控件随之调整大小和位置。X方向。 
CCS_NOMOVEY 父窗口大小变化时,禁止控件随之调整大小和位置。Y方向。 
CCS_NORESIZE 禁止控件随父窗口尺寸变化调整大小 
CCS_NOPARENTALIGN 
CCS_NODIVIDER 清除工具栏控件顶部得分隔栏 
CCS_ADJUSTABLE

SDK风格应用中用公用控件,需调用 ::InitCommonControls/::InitCommonControlsEx加载Comctl32.dll,并注册控件得WNDCLASS。 
在应用程序中多次调用::InitCommonControls/::InitCommonControlsEx无不良影响。

处理WM_NOTIFY: 
公用控件把通知封装在WM_NOTIFY中。 
WM_NOTIFY: 
wParam:子窗口ID 
lParam:NMHDR*

    typedef struct tagNMHDR
    {
        HWND hwndFrom; // 控件得窗口句柄
        UINT idFrom; // 控件ID
        UINT code; // 通知码
    }NMHDR;
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

所有通用控件都传送的一些通知: 
NM_CLICK 
NM_DBLCLK 
NM_RCLICK 
NM_RDBLCLK 
NM_RETURN 控件有焦点时,按下Enter发送。 
NM_KILLFOCUS 
NM_SETFOCUS 
NM_OUTOFMEMORY

大部分公用控件有属于其自身特别的通知码。 
例:

// 树形视图展开
TVN_ITEMEXPANDED

lParam:NM_TREEVIEW*
typedef struct _NM_TREEVIEW
{
    NMHDR hdr;
    UINT action;
    TV_ITEM itemOld;
    TV_ITEM itemNew;
    POINT ptDrag;
}NM_TREEVIEW;

// 树形视图获取信息
TVN_GETDISPINFO
lParam:TV_DISPINFO
typedef struct _TV_DISPINFO
{
    NMHDR hdr;
    TV_ITEM item;
}TV_DISPINFO;
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

封装在WM_NOTIFY消息中的通知通过ON_NOTIFY,ON_NOTIFY_RANGE宏,映射到类的成员函数。 
ON_NOTIFY_REFLECT将其反射回控件。

传给ON_NOTIFY处理程序的参数pnmh就是WM_NOTIFY的lParam。参数 pResult传递函数返回值,意义需依靠特定控件特定消息确定。

滑杆控件

样式: 
TBS_HORZ 水平放置 
TBS_VERT 竖直放置 
TBS_LEFT 刻度线画在竖直滑杆左 
TBS_RIGHT 刻度线画在竖直滑杆右 
TBS_TOP 刻度线画在水平滑杆上 
TBS_BOTTOM 刻度线画在水平滑杆下 
TBS_BOTH 
TBS_NOTICKS 无刻度线 
TBS_AUTOTICKS 每个停止位一个刻度线 
TBS_FIXEDLENGTH 
TBS_NOTHUMB 
TBS_ENABLESELRANGE 
TBS_TOOLTIPS

SliderCtrl: 
SetRange/GetRange 
SetPos/GetPos 
SetTicFreq //设置刻度线间距离 
SetSelection

m_wndSlider.SetRange(0, 8);
m_wndSlider.SetTick(2);
m_wndSlider.SetTick(3);
m_wndSlider.SetTick(6);
m_wndSlider.SetPos(2);
 
 
  • 1
  • 2
  • 3
  • 4
  • 5

UI自定义: 
从CSilderCtrl派生一个类,添加消息处理。改变对按键和鼠标的响应。

移动滑块时,滑杆向其父窗口发WM_HSCROLL,WM_VSCROLL。 
滑杆控件的OnHScroll,OnVScroll接收三个参数: 
1.通知码 
2.滑块位置 
3.CScrollBar*

滑杆通知: 
TB_TOP 滑杆有输入焦点 + 按下Home 
TB_BOTTOM 滑杆有输入焦点 + 按下End 
TB_LINEDOWN 滑杆有输入焦点 + 按下向下/右 
TB_LINEUP 滑杆有输入焦点 + 按下向上/左 
TB_PAGEDOWN 滑杆有输入焦点 + 按下PageDown,单击滑块右/下 单击区间不含滑块。 
TB_PAGEUP 
TB_THUMBTRACK 鼠标把滑块拖动到新位置 
TB_THUMBPOSITION 鼠标拖后,释放 
TB_ENDTRACK

CSilderCtrl: 
SetPageSize 
GetTic 
GetTicPos 
GetTicArray 
GetNumTicks 
ClearSel

微调按钮控件

样式: 
UDS_HORZ 箭头是水平的。 
UDS_WRAP 如前进后退,超过边界值,位置按环式结构确定 
UDS_ARROWKEYS 添加键盘接口 
UDS_NOTHOUSANDS 消除千位分隔符 
UDS_SETBUDDYINT 位置变化时,更新伙伴控件的文本 
UDS_AUTOBUDDY 按Z向顺序选以前的控件做微调按钮的伙伴 
UDS_ALIGNRIGHT 
UDS_ALIGNLEFT

选择按钮控件和它的伙伴控件

// 1
CSpinButtonCtrl::SetBuddy(CWnd*)
// 2
// 创建微调按钮控件时指定UDS_AUTOBUDDY,则微调按钮控件自动按Z向顺序选中以前的控件作为它的伙伴
// RC
EDITTEXT IDC_EDIT, 60, 80, 40, 14, ES_AUTOHSCROLL
CONTROL "", IDC_SPIN, "msctls_updown32", UDS_SETBUDDYINT | UDS_AUTOBUDDY | UDS_ALIGNRIGHT, 0, 0, 0, 0
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

CSpinButtonCtrl::SetBase // 设置以什么进制来显示数值

微调按钮控件中每单击一次箭头,位置会前进或后退一个。

UDACCEL uda[4];
uda[0].nSec = 0;
uda[0].nInc = 1;
uda[1].nSec = 2;
uda[1].nInc = 2;
uda[2].nSec = 4;
uda[2].nInc = 10;
uda[3].nSec = 8;
uda[3].nInc = 100;
pSpinButton->SetAccel(4, uda);


UINT nCount = pSpinButton->GetAccel(0, NULL);
UDACCEL *puda = new UDACCEL[nCount];
pSpinButton->GetAccel(nCount, puda);
delete[] puda;
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

位置变化前,微调按钮控件向其父窗口发WM_NOTIFY消息。 
通知码:UDN_DELTAPOS 
lParam:NM_UPDOWN* 
处理程序把*pResult设为FALSE,表允许变化发生。

跟在UDN_DELTAPOS通知后的是WM_HSCROLL或WM_VSCROLL。

工具提示控件

CToolTipCtrl 
CToolTipCtrl::Create // 创建一个工具提示控件

m_ctlTT.Create(this);

创立后,下一步是在其中添加工具, 
工具可以是另外一个窗口,也可是窗口的一个矩形区域。

一个工具提示控件可连接任意个工具。

m_ctlTT.AddTool(pWnd, _T("This a Window"), NULL, 0);
m_ctlTT.AddTool(pWnd, _T("This a Window"), CRect(32, 32, 64, 64), IDT_RECTANGLE);
 
 
  • 1
  • 2

MFC的工具提示控件具备子类划分能力。

class CMyToolTipCtrl : public CToolTipCtrl
{
public:
    BOOL AddWindowTool(CWnd* pWnd, LPCTSTR pszText);
    BOOL AddRectTool(CWnd* pWnd, LPCTSTR pszText, LPCRECT pRect, NULL, UINT nIDTool);
};

// cpp
BOOL CMyToolTipCtrl::AddWindowTool(CWnd* pWnd, LPCTSTR pszText)
{
    TOOLINFO ti;
    ti.cbSize = sizeof(TOOLINFO);
    ti.uFlags = TTF_IDISHWND | TTF_SUBCLASS;
    ti.hwnd = pWnd->GetParent()->GetSafeHwnd();
    ti.uId = (UINT)pWnd->GetSafeHwnd();
    ti.hinst = AfxGetInstanceHandle();
    ti.lpszText = (LPTSTR)pszText;

    return (BOOL)SendMessage(TTM_ADDTOOL, 0, (LPARAM)&ti);
}


BOOL CMyToolTipCtrl::AddRectTool(CWnd* pWnd, LPCTSTR lpszText, LPCRECT lpRect, UINT nIDTool)
{
    TOOLINFO ti;
    ti.cbSize = sizeof(TOOLINFO);
    ti.uFlags = TTF_SUBCLASS;
    ti.hwnd = pWnd->GetSafeHwnd();
    ti.uId = nIDTool;
    ti.hInst = AfxGetInstanceHandle();
    ti.lpszText = (LPTSTR)pszText;
    ::CopyRect(&ti.rect, lpRect);
    return (BOOL)SendMessage(TTM_ADDTOOL, 0, (LPARAM)&ti);
}
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34

动态工具提示: 
如在调用AddTool,AddWindowTool,AddRectTool时,给工具提示文本指定了 LPSTRTEXTCALLBACK,工具提示控件会在显示工具提示前给其父窗口发一些通知。 
WM_NOTIFY 
通知码:TTN_NEEDTEXT 
lParam:TOOLTIPTEXT*

typedef struct
{
    NMHDR hdr;
    LPTSTR lpszText;
    char szText[80];
    HINSTANCE hinst;
    UINT uFlags;
}TOOLTIPTEXT;
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

ToolTip控件的父窗口可用三种方式响应TTN_NEEDTEXT通知: 
1.把文本字符串的地址复制到TOOLTIPTEXT结构的lpszText中。 
2.把文本复制到szText。 
3.把字符串资源ID给lpszText。把应用实例句柄给hinst。

ON_NOTIFY(TTN_NEEDTEXT, NULL, OnNeedText)
...
BOOL CMyDialog::OnInitDialog()
{
    m_ctlTT.Create(this);
    m_ctlTT.AddRectTool(this, LPSTR_TEXTCALLBACK, CRect(0, 0, 32, 32), IDT_RECTANGLE);
    return TRUE;
}

void CMyDialog::OnNeedText(NMHDR *pnmh, LRESULT *pResult)
{
    TOOLTIPTEXT *ptt = (TOOLTIPTEXT*)pnmh;
    if(ptt->hdr.idFrom == IDT_RECTANGLE)
    {
        CString string;
        CTime time = CTime::GetCurrentTime();
        string.Format(_T("%.2d:%.2d%.2d"), ...);
        ::lpstrcpy(ptt->szText, (LPCTSTR)string);
    }
}

 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

CToolTipCtrl:: 
GetText 
UpdateTipText 
SetDelayTime

图像列表和ComboBoxEx控件

CImageList: 
为其它控件提供图像,在位图上制造特殊效果。

MFC用三种方式创建图像列表: 
1.先创建空的,再用Add在其中添加图像。 
2.用含图像数组的位图创建初始化了的图像列表。 
3.合并现有图像列表的图像创建初始化了的。

CImageList il;
il.Create(IDB_BITMAP, 18, 1, CLR_NONE);
 
 
  • 1
  • 2

CImageList::SetBkColor // 让背景色画不出来。 
// 在指定DC上显示il中图片 
il.Draw(pDC, 2, point, ILD_NORMAL);

m_il.Create(IDB_IMAGE, 16, 1, RGB(255, 0, 255));
m_wndCBEX.SetImageList(&m_il);
for(int i = 0; i < 5; i++)
{
    CString string;
    string.Format(_T("Item %d"), i);
    COMBOBOXEXITEM cbei;
    cbei.mask = CBEIF_IMAGE | CBEIF_SELECTEDIMAGE | CBEIF_TEXT;
    cbei.iItem = i;
    cbei.pszText = (LPTSTR)(LPCTSTR)string;
    cbei.iImage = 0;
    cbei.iSelectedImage = 0;
    m_wndCBEX.InsertItem(&cbei);
}
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

cbei.iIndent // 指定项目空格数,用于缩进显示。

COMBOBOXEXITEM: 
DeleteItem 
GetItem 
SetItem

CComboBoxEx : public CComboBox

CComboBoxEx还支持几种扩展样式。需用CComboBoxEx::SetExtendedStyle实现。

CComBoBoxEx发给父窗口的CBN通知和传统组合框一样。 
还支持自己特有的通知。 
CComboBoxEx通知 
CBEN_BEGINEDIT 显示下拉列表/单击编辑控件 
CBEN_ENDEDIT 在控件列表里选中或编辑控件的文本 
CBEN_DRAGBEGIN 在控件中拖动某项 
CBEN_INSERTITEM 某项被插入控件 
CBEN_DELETEITEM 某项被删除 
CBEN_GETDISPINFO 
NM_SETCURSOR

进度/动画

CProgressCtrl

m_wndProgress.SetRange
SetPos
OffsetPos
SetStep
StepIt
 
 
  • 1
  • 2
  • 3
  • 4
  • 5

CAnimateCtrl 
Open 
Play 
Stop 
Close

样式: 
ACS_AUTOPLAY 
ACS_CENTER 
ACS_TRANSPARENT 
ACS_TIMER

IP地址

CIpAddressCtrl 
SetAddress 
GetAddress 
ClearAddress 
IsBlank

// .h
BYTE m_nField1, m_nField2, m_nField3, m_nField4;

// cpp
BOOL CMyDialog::OnInitDialog()
{
    CDialog::OnInitDialog();
    m_wndIpAddress.SetAddress(m_nField1, m_nField2, m_nField3, m_nField4);
    return TRUE;
}

void CMyDialog::OnOK()
{
    m_wndIpAddress.GetAddress(m_nField1, m_nField2, m_nField3, m_nField4);
    CDialog::OnOK();
}
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

m_wndIpAddress.SetFieldRange(0, 10, 100);

IP地址控件向其所有者,发四种通知: 
WM_COMMAND: 
EN_SETFOCUS 
EN_KILLFOCUS 
EN_CHANGE

WM_NOTIFY: 
IDN_FIELDCHANGED

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值