MFC自定义控件_第1页
MFC自定义控件_第2页
MFC自定义控件_第3页
MFC自定义控件_第4页
MFC自定义控件_第5页
已阅读5页,还剩1页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、MFC自定义控件详细» 关于Custom Control 自定义控件的介绍,有一篇文章感觉不错,不过是英文的,英语不好的也没关系,不 是有“有道”吗?再说了,我们只要看代码就行了,而且步骤也就那么几步,结合教程图片稍微猜一下也 就知道了。 原文地址: 接下来我把上面教程的操作步骤简单描述一下: 1、首先往对话框添加一个“自定义控件”,然后右击该控件选择“建立类向导”,在弹出的对话框点击 “Add Class.”,选择“New.", 之后“Name"项填CMyCustomControl, “Base Class"选择generic CWnd,点确定。 在M

2、yCustomControl.h 添加函数声明 BOOL RegisterWndClass(; 给CMyCustomControl 类添加如下函数: BOOL CMyCustomControl:RegisterWndClass( WNDCLASS windowclass; HINSTANCE hInst=AfxGetInstanceHandle(; if(!:GetClassInfo(hInst,"MyDrawPad",&windowclass windowclass.style=CS_DBLCLKS; windowclass.lpfnWndProc=:DefWin

3、dowProc; windowclass.cbClsExtra=windowclass.cbWndExtra=0; windowclass.hInstance=hInst; windowclass.hIcon=NULL; windowclass.hCursor=AfxGetApp(->LoadStandardCursor(IDC_ARROW; windowclass.hbrBackground=:GetSysColorBrush(COLOR_WINDOW; windowclass.lpszMenuName=NULL; windowclass.lpszClassName="MyD

4、rawPad" if(!AfxRegisterClass(&windowclass AfxThrowResourceException(; return FALSE; return TRUE; 在MyCustomControl 类构造函数中调用RegisterWndClass 函数,如下: CMyCustomControl:CMyCustomControl( RegisterWndClass(; 接着右击对话框里“自定义控件”,选择属性,“种类”框里填上MyDrawPad(窗口类)。给对话框类添 加一个CMyCustomControl 类对象(是在*Dlg.h)。如: CMy

5、CustomControl m_drawpad;(记得包含头文件)。 #include "MyCustomControl.h" 对话框类的DoDataExchange 函数里添加如下语句: void CThirdDlg:DoDataExchange(CDataExchange* pDX CDialog:DoDataExchange(pDX; /AFX_DATA_MAP(CThirdDlg / NOTE: the ClassWizard will add DDX and DDV calls here /AFX_DATA_MAP DDX_Control(pDX,IDC_CUST

6、OM1,m_drawpad;/IDC_CUSTOM1 为自定义控件的ID 号 到了这里,自定义控件的基本问题算是解决了。可自行给CMyCustomControl 类添加消息响应函数,运行一 下吧。 自定义控件仿工具栏 标题名是仿工具栏控件,其实也只是仿下工具栏那个模式而已,想一下,工 具栏类里有那么多个函数,能仿得过来吗?如果有谁觉得用自定义控件模仿这个 太麻烦的话,也可直接从按钮控件(CButton派生出类来代替“自定义控件”类。 我这里就直接以上面工程的CMyCustomControl 类为例。 1、首先往工程里引三张图片如下: 2、再引入六个图标,用于项显示图标,ID 号保持默认不变,

7、3、CMyCustomControl 添加如下成员变量(私有变量) 4、响应自定义控件(CMyCustomControl WM_ERASEBKGND、WM_LBUTTONDOWN、 WM_LBUTTONUP、WM_MOUSEMOVE、WM_PAINT、WM_TIMER 消息 5、添加如下成员函数 6、构造函数中初始化部分成员变量(私有变量初始化) 7、添加各函数代码 8、成员函数要在.h 中的public 中声明 void SetBitmapIDs(UINT BKID,UINT itemMOverID,UINT itemPushID; BOOL SetItemSize(int Width,in

8、t Height,int itemSpacing=5; BOOL SetImageList(CImageList *pImageList; BOOL AddItem(UINT nID; 9、在*Dlg.h 中定义一个需要用到的变量 CImageList m_ImageList; 10、在*.cpp 中添加初始化响应函数 m_ImageList.Create(32,32,ILC_COLOR32|ILC_MASK,1,0; for(int i=0;i<6;i+ m_ImageList.Add(AfxGetApp(->LoadIcon(IDI_ICON1+i; m_drawpad.Set

9、ImageList(&m_ImageList; m_drawpad.SetBitmapIDs(IDB_BK,IDB_ITEMOVER,IDB_ITEMPUSH; m_drawpad.SetItemSize(38,40,3; for(i=0;i<6;i+ m_drawpad.AddItem(1001+i; 11、如果要处理项按钮单击消息的话,需手动添加消息映射,方法跟添加工具栏 控件项单击消息映射一样。前面给第一项设置ID 号为1001,那么添加这个项单 击消息映射就是: 在*Dlg.cpp 中的BEGIN_MESSAGE_MAP(CThirdDlg, CDialog函数下添加 O

10、N_COMMAND(1001,OnItem1/OnItem1 为消息处理函数 BEGIN_MESSAGE_MAP(CThirdDlg, CDialog END_MESSAGE_MAP(为消息映射区域 如何获知ID 号:查看Resource.h 成员变量的初始化可以再构造函数中进行。 存在分配相同ID 的可能。详情见下: ID 的分配是通过头文件控制的。 你看你的resource.h 的最后几行(注释是我加的,源文件里没有): #ifndef APSTUDIO_READONLY_SYMBOLS #define _APS_NEXT_RESOURCE_VALUE 2000 / 下一个资源的ID,比如

11、字符串资源,位图资源等 #define _APS_NEXT_COMMAND_VALUE 40001 / 下一个command 的ID,这个一般是作为WM_COMMAND 消息的参数用的。 #define _APS_NEXT_CONTROL_VALUE 1001 / 下一个控件的ID #define _APS_NEXT_SYMED_VALUE 101 / 下一个符号的ID #endif 比如,如果这个时候你用 VC 的对话框插入一个字符串,那么这个字符串的 ID 就会自动被分配成2000,同时_APS_NEXT_RESOURCE_VALUE 会被改成2001。其他 几个值也是以类似方式工作的。

12、所以其实VC 自动分配的ID 号,跟你自己定义的是有可能重复的。你必须自己保 证没有重复,而不是依赖于VC 帮你检查。一个办法是,比如你要新加一个控件, 你可以用_APS_NEXT_CONTROL_VALUE 的值作为这个控件的 ID,然后自己手动把 _APS_NEXT_CONTROL_VALUE 的值加1,这样就能保持跟VC 的ID 分配机制一致。 全文复制如下: 关于Custom Control 自定义控件的介绍,有一篇文章感觉不错,不过是英文的,英语不好的也没关系,不 是有“有道”吗?再说了,我们只要看代码就行了,而且步骤也就那么几步,结合教程图片稍微猜一下也 就知道了。 原文地址: 接

13、下来我把上面教程的操作步骤简单描述一下: 首先往对话框添加一个“自定义控件”,然后右击该控件选择“建立类向导”,在弹出的对话框点击“Add Class.”,选择“New.", 之后“Name"项填CMyCustomControl, “Base Class"选择generic CWnd,点确定。 给CMyCustomControl 类添加如下函数: BOOL CMyCustomControl:RegisterWndClass( WNDCLASS windowclass; HINSTANCE hInst=AfxGetInstanceHandle(; if(!:GetC

14、lassInfo(hInst,"MyDrawPad",&windowclass windowclass.style=CS_DBLCLKS; windowclass.lpfnWndProc=:DefWindowProc; windowclass.cbClsExtra=windowclass.cbWndExtra=0; windowclass.hInstance=hInst; windowclass.hIcon=NULL; windowclass.hCursor=AfxGetApp(->LoadStandardCursor(IDC_ARROW; windowcla

15、ss.hbrBackground=:GetSysColorBrush(COLOR_WINDOW; windowclass.lpszMenuName=NULL; windowclass.lpszClassName="MyDrawPad" if(!AfxRegisterClass(&windowclass AfxThrowResourceException(; return FALSE; return TRUE; 在MyCustomControl 类构造函数中调用RegisterWndClass 函数,如下: CMyCustomControl:CMyCustomCont

16、rol( RegisterWndClass(; 接着右击对话框里“自定义控件”,选择属性,“种类”框里填上MyDrawPad(窗口类)。给对话框类添 加一个CMyCustomControl 类对象。如: CMyCustomControl m_drawpad;(记得包含头文件)。对话框类的DoDataExchange 函数里添加如下语句: void CThirdDlg:DoDataExchange(CDataExchange* pDX CDialog:DoDataExchange(pDX; /AFX_DATA_MAP(CThirdDlg / NOTE: the ClassWizard will

17、add DDX and DDV calls here /AFX_DATA_MAP DDX_Control(pDX,IDC_CUSTOM1,m_drawpad;/IDC_CUSTOM1 为自定义控件的ID 号 到了这里,自定义控件的基本问题算是解决了。可自行给CMyCustomControl 类添加消息响应函数,运行一 下吧。 自定义控件仿工具栏 标题名是仿工具栏控件,其实也只是仿下工具栏那个模式而已,想一下,工具栏类里有那么多个函数,能 仿得过来吗?如果有谁觉得用自定义控件模仿这个太麻烦的话,也可直接从按钮控件(CButton派生出类 来代替“自定义控件”类。我这里就直接以上面工程的CMyCu

18、stomControl 类为例。 首先往工程里引三张图片如下: 自定义控件背景,ID 号:IDB_BK 鼠标停留时,项背景,ID 号:IDB_ITMEOVER 鼠标单击时,项背景,ID 号:IDB_ITEMPUSH 再引入六个图标,用于项显示图标,ID 号保持默认不变,IDI_ICON1、IDI_ICON2。IDI_ICON6 CMyCustomControl 添加如下成员变量: private: CRect m_itemRect10;/各项区域 UINT m_itemID10;/各项ID 号 CImageList *m_pImageList;/各项图标 int m_itemCount;/项数

19、量 UINT m_BKID;/控件背景位图ID 号 UINT m_itemMOverID;/项鼠标停留时的背景位图ID 号 UINT m_itemMPushID;/项鼠标按下时的背景位图ID 号 int m_itemWidth;/项宽 int m_itemHeight;/项高 int m_itemSpacing;/项区域间距,上下左右。 int m_CurMouseItem;/记录当前鼠标位置所在项 int m_TimerID;/计时器ID 号 BOOL m_MousePush;/鼠标是否在按下中 响应自定义控件(CMyCustomControl WM_ERASEBKGND、WM_LBUTTO

20、NDOWN、WM_LBUTTONUP、WM_MOUSEMOVE、 WM_PAINT、WM_TIMER 消息,各消息处理函数如下: BOOL CMyCustomControl:OnEraseBkgnd(CDC* pDC void CMyCustomControl:OnLButtonDown(UINT nFlags, CPoint point void CMyCustomControl:OnLButtonUp(UINT nFlags, CPoint point void CMyCustomControl:OnMouseMove(UINT nFlags, CPoint point void CMyC

21、ustomControl:OnPaint( void CMyCustomControl:OnTimer(UINT nIDEvent 添加如下成员函数: BOOL CMyCustomControl:AddItem(UINT nID/此函数添加项 /设置控件背景位图ID,项状态位图背景ID(鼠标停留,单击) void CMyCustomControl:SetBitmapIDs(UINT BKID, UINT itemMOverID, UINT itemMPushID BOOL CMyCustomControl:SetImageList(CImageList *pImageList/设置图像列表 B

22、OOL CMyCustomControl:SetItemSize(int Width, int Height,int itemSpacing/设置项宽高 构造函数中初始化部分成员变量: CMyCustomControl:CMyCustomControl( m_pImageList=NULL; m_itemCount=0; m_itemWidth=26; m_itemHeight=30; m_BKID=NULL; m_itemSpacing=5; m_CurMouseItem=-1; m_TimerID=1500; m_MousePush=FALSE; RegisterWndClass(;/如果

23、是从按钮控件(CButton派生出的类,则不要调用此语句 各函数代码如下: BOOL CMyCustomControl:OnEraseBkgnd(CDC* pDC / TODO: Add your message handler code here and/or call default return TRUE;/直接返回真 /return CWnd:OnEraseBkgnd(pDC;/禁止父类擦除背景,重画。 void CMyCustomControl:OnLButtonDown(UINT nFlags, CPoint point / TODO: Add your message handl

24、er code here and/or call default m_MousePush=TRUE;/鼠标左键处于按下状态 this->Invalidate(;/刷新控件窗口 CWnd:OnLButtonDown(nFlags, point; void CMyCustomControl:OnLButtonUp(UINT nFlags, CPoint point / TODO: Add your message handler code here and/or call default m_MousePush=FALSE; this->Invalidate(;/刷新(控件窗口 if(

25、m_CurMouseItem!=-1/给父窗口发送项被单击消息 GetParent(->SendMessage(WM_COMMAND, MAKEWPARAM(m_itemIDm_CurMouseItem,0,LPARAM(GetSafeHwnd(; CWnd:OnLButtonUp(nFlags, point; void CMyCustomControl:OnMouseMove(UINT nFlags, CPoint point if(m_CurMouseItem=-1 SetTimer(m_TimerID,50,NULL;/设置计时器 CWnd:OnMouseMove(nFlags,

26、point; void CMyCustomControl:OnPaint( CPaintDC dc(this; / device context for painting /先在内存DC 里完成所有要进行的画图操作,然后再把内存DC 里的画图(数据)一次性画上去。 CDC memDC; memDC.CreateCompatibleDC(&dc; CRect rect; GetClientRect(rect; CBitmap bmp; bmp.CreateCompatibleBitmap(&dc,rect.Width(,rect.Height(; memDC.SelectObje

27、ct(&bmp; if(m_BKID!=NULL /画位图背景 CDC bmpDC; bmpDC.CreateCompatibleDC(&memDC; CBitmap mBmp; mBmp.LoadBitmap(m_BKID; bmpDC.SelectObject(&mBmp; BITMAP bmpInfo; mBmp.GetBitmap(&bmpInfo; memDC.StretchBlt(0,0,rect.Width(,rect.Height(,&bmpDC,0,0, bmpInfo.bmWidth,bmpInfo.bmHeight,SRCCOPY;

28、 int spacing=0; if(m_CurMouseItem!=-1 CDC bmpDC; bmpDC.CreateCompatibleDC(&memDC; CBitmap mBmp; if(m_MousePush spacing=2; mBmp.LoadBitmap(m_itemMPushID; else mBmp.LoadBitmap(m_itemMOverID; bmpDC.SelectObject(&mBmp; BITMAP bmpInfo; mBmp.GetBitmap(&bmpInfo; memDC.StretchBlt(m_itemRectm_Cur

29、MouseItem.left,m_itemRectm_CurMouseItem.top, m_itemRectm_CurMouseItem.Width(,m_itemRectm_CurMouseItem.Height(, &bmpDC,0,0,bmpInfo.bmWidth,bmpInfo.bmHeight,SRCCOPY; for(int i=0;iDraw(&memDC,i,pt,ILD_NORMAL; dc.BitBlt(0,0,rect.Width(,rect.Height(,&memDC,0,0,SRCCOPY; / TODO: Add your messag

30、e handler code here void CMyCustomControl:OnTimer(UINT nIDEvent int oldMouseItem=m_CurMouseItem; / TODO: Add your message handler code here and/or call default POINT pt; :GetCursorPos(&pt;/获取鼠标当前位置 ScreenToClient(&pt;/转换成相对于客户区坐标 /判断当前鼠标是否在某一个项上 for(m_CurMouseItem=0;m_CurMouseItemInvalidate(

31、; else if(m_CurMouseItem!=oldMouseItem/鼠标位置所在项已改变 this->Invalidate(; CWnd:OnTimer(nIDEvent; BOOL CMyCustomControl:AddItem(UINT nID if(m_itemCount=10 return FALSE;/增加项超过10 个 m_itemIDm_itemCount=nID; /计算设置各项区域位置 if(m_itemCount=0 m_itemRect0=CRect:CRect(m_itemSpacing,m_itemSpacing, m_itemWidth+m_ite

32、mSpacing,m_itemHeight+m_itemSpacing; else m_itemRectm_itemCount.left=m_itemRectm_itemCount-1.right+m_itemSpacing; m_itemRectm_itemCount.top=m_itemSpacing; m_itemRectm_itemCount.right=m_itemRectm_itemCount.left+m_itemWidth; m_itemRectm_itemCount.bottom=m_itemSpacing+m_itemHeight; /根据当前项信息调整控件窗口大小,位置。 MoveWindow(0,0,m_itemRectm_itemCount.right+m_itemSpacing, m_itemRectm_itemCount.bottom+m_itemSpacing; m_itemCount+;/项数量增一 return TRUE; /设置控件背景位图ID,项状态位图背景ID(鼠标停留,单击) void CMyCustomControl:SetBitmapIDs(UINT BKID, UINT itemMOverID, UINT itemMPushID m_BKID=BKID; m_itemM

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论