金桥科普  
设为首页 关于我们 邮箱登录
科普聚焦时代科技科普生活科学技术自然科学航空航天科技博览历史考古电脑IT
您现在的位置: 首页 >> 科普频道 >> 技巧实践 >> 文章详情
自定义控件编程

软件世界 软件世界 2001-10-30


    摘要 本文分析了Visaul C++中自定义控件DLL的编程方法,以交通灯为例编

    制一个自定义控件DLL,并介绍了客户应用程序中使用自定义控件的方法。

    关健字 自定义控件,DLL,窗口消息

    有一个吸引人的界面是商业软件成功的关键,微软的VisualC++集成开发环境为我们提供了许多标准的控件,如按钮控件,编辑控件,组合框控件等,但是,要设计一个美观的界面这些控件是远远不够的,经常还需要定制自己的特定控件,例如仪器面板、微调按钮等。在Windows的早期程序员开发一个自定义控件DLL非常复杂,现在,开发自己的专用控件,使用MFC库的特性来编制自定义控件DLL就容易多了,如果使用正规的DLL,还可用于任何可接受自定义控件的开发系统。使用自定义控件具有一次编程重复使用,代码小,装入快等优点,因此高级程序员经常使用自定义控件。下面以一个交通灯控件来讨论自定义控件编程,它包括如下过程。

    一、 创建自定义控件的窗口类

    利用Visual C++6.0集成开发环境创建一个名为Ryg的正规的动态连接库。在Ryg.cpp中,加入

extern"C" __declspec(dllexport)void RygEntry(){}

    此虚构的导出RygEntry 函数只是为了DLL能被隐式连接。客户必须包括对该函数的调用,而且调用必须在程序的执行路径里,否则编译器会忽略该调用。作为选择,客户程序也可以在其InitInstance 函数中调用Win32的LoadLibrary函数,这样可显示连接该DLL。 在Ryg.cpp 中加入

CRygWnd::RegisterWndClass(AfxGetInstanceHandle());

此函数注册一个窗口。

    现在编制CRygWnd类,在Insert菜单下选择New Class...子菜单,然后创建一个CWnd的派生类CRygWnd类,打开RygWnd.h文件,增加如下内容:

class CRygWnd : public CWnd

{

.........

public:

static BOOL RegisterWndClass(HINSTANCE hInstance);

.........

};

在RygWnd.h中声明了RegisterWndClass函数,现在打开RygWnd.cpp文件,在此文件中编写此函数如下:

BOOL CRygWnd::RegisterWndClass(HINSTANCE hInstance)

{ WNDCLASS wc; wc.lpszClassName = "RYG"; wc.hInstance = hInstance; wc.lpfnWndProc = RygWndProc; wc.hCursor = ::LoadCursor(NULL,IDC_ARROW); wc.hIcon = 0; wc.lpszMenuName = NULL; wc.hbrBackground = (HBRUSH) ::GetStockObject(LTGRAY_BRUSH); wc.style = CS_GLOBALCLASS; wc.cbClsExtra = 0; wc.cbWndExtra = 0; return (::RegisterClass(&wc) != 0);

}

    在函数RegisterWndClass中,首先是构造一个窗口类结构WNDCLASS ,然后,用窗口注册函数RegisterClass对此窗口注册。对话框资源板利用符号化的窗口类名来指定自定义控件RYG(如图一所示)。在此函数中,最重要的是类名lpszClassName和指向WNDPROC函数的指针 lpfnWndProc 。在构造好WNDCLASS类结构后,函数RegisterClass把该结构拷贝到进程内存,进程中的任何函数都可以用该类创建窗口。当对话框被初始化时,Windows根据保存在模板里的窗口类名,创建自定义控件子窗口。

图 一

    二、 编制Windows过程处理函数WndProc

    在掌握了注册一个窗口类名后,下面要做的是如何编制一个Windows过程WndProc。过程WndProc主要是处理自定义控件窗口消息,它是自定义窗口与类CRygWnd建立连接的桥梁。为了完成这个工作,首先,我们必须用new构造一个C++类目标,然后,告诉Windows把自定义控件窗口中的所有消息送到C++类目标,当第一个消息WM_NCCREATE到达时,句柄hWnd为空,因此必须先用new构造一个C++类。下面是WndProc函数的具体内容。

LRESULT CALLBACK AFX_EXPORT RygWndProc(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam)

{ AFX_MANAGE_STATE(AfxGetStaticModuleState()); CWnd* pWnd; pWnd = CWnd::FromHandlePermanent(hWnd); if(pWnd == NULL){ pWnd = new CRygWnd(); pWnd->Attach(hWnd); } ASSERT(pWnd->m_hWnd == hWnd); ASSERT(pWnd == CWnd::FromHandlePermanent(hWnd)); LRESULT lResult = AfxCallWndProc(pWnd,hWnd,message,wParam,lParam); return lResult;

}

    当对话框管理者构造一个对话框时,它为对话框里的每一个控件依据其类名调用:CreateWindow,因为我们已经为交通灯注册了类名RYG,并且告诉Windows送所有的消息到RygWndProc,所以,当对话框管理者创建交通灯控件时,RygWndProc将接收到消息WM_NCCREATE并构造一个C++类RygWnd。以后所有其他消息将送到AfxCallWndProc。

    三、 自定义控件的窗口消息

    控件窗口与C++类CRygWnd建立起连接后,下面要做的是如何响应窗口消息。控件通过给父窗口发送特定的WM_COMMAND窗口消息与父窗口进行通讯。控件以下面的方式发送窗口消息:

GetParent()->SendMessage(WM_COMMAND,GetDlgCtrlID() | ID_NOTIFYCODE, (LONG)GetSafeHwnd());

在客户方,可以用MFC的ON_CONTROL宏映射消息,如下所示:

ON_CONTROL(ID_NOTIFYCODE,ID_MYCONTROL,OnClickedMyControl)

在此应充分理解SendMessage函数,SendMessage函数原型是:

LRESULT SendMessage( UINT message, WPARAM wParam = 0, LPARAM lParam = 0 )

其中,message是指需要发送的消息,可以是WM_COMMAND,WM_HVSCROLL等消息,wParam和lParam参数是一个32位的附加依赖信息,wParam的高16位为通知码,wParam的低16位为子窗口ID,lParam为子窗口句柄。

    下面创建一个左鼠标按下事件:

void CRygWnd::OnLButtonDown(UINT nFlags, CPoint point)

{GetParent()->SendMessage(WM_COMMAND,GetDlgCtrlID() | 0, (LONG)GetSafeHwnd()); CWnd::OnLButtonDown(nFlags, point);

}

通过以上步骤就建立了一个自定义控件RYG的框架,然后,我们可以写设置背景色、三个交通灯等函数,这样一个自定义控件就圆满完成了。

    四、 在程序中使用自定义控件DLL

    以上是自定义控件DLL编程,下面是客户程序如何应用此自定义控件DLL的例子。首先,用对话框编辑器创建一个IDD_RYGTEMP模板,在控件窗口里,选择自定义控件,然后,在模板里画一个自定义窗口ID_RYG,如图二所示:


图 二

    指定自定义窗口类名为RYG(如图一),然后用ClassWizard生产CDialog派生的类CRygDialog。其次,在RygDialog.cpp文件中编辑构造函数,加入RygEntry()函数,初始化数据成员。最后,映射控件的左按键窗口消息,在RygDialog.cpp文件里加入消息映射入口和控制函数:

ON_CONTROL(0,IDR_RYG,OnClickRyg)

在上面的OnLButtonDown 函数中的SendMessage定义了通知码0,因此,在ON_CONTROL函数中相应的用0通知码。

    通过以上步骤我们就可以掌握自定义控件编程,由于Ryg.dll是 一个正规的DLL,所以可在Borland C++等可接受自定义控件的开发系统中应用。

    参考文献

    1.David J.Kruglinski著, Visual C++技术内幕,清华大学出版社,1999.1

    2.Nigel Thompson ,Simple Custom Controls For 32-Bit Visual C++ Applications,Microsoft Technical Articles,1994.9


  发表评论 写信给编辑 关闭窗口
同栏目内容
· 让你的电脑启动画面绚起来 2007-09-12
· 小技巧帮大忙 极点五笔 2007-09-05
· 如何提高迅雷的下载速度? 2007-09-03
· Vista小技巧 消除红眼 2007-09-03
· 千千静听实用小功能 2007-08-29
· Windows 自动登陆的简单方法 2007-08-20
相关内容
近期主推
我国首架自主产权飞机完成
·我国首架自主产权飞机完成
·机器人版"千手观音"惊艳亮相
·西藏发现青藏高原最大冰川群
·中日: "月亮女神"携手"嫦娥"
·行星大碰撞砸死恐龙催生人类
·美研制会飞汽车定价9万美元
近期热门
科学家解开中子星爆发之谜
·科学家解开中子星爆发之谜
·英海域惊现大龙虾为普通龙虾5倍
·新物种金蛙体表有剧毒
·我国嫦娥工程计划测量月球
·精神病药物可治多种癌症
·视觉震撼:来自海底的精灵
近期焦点
美国发现极其罕见的白化银鲛(图)
·美国发现极其罕见的白化银鲛(图)
·美国展出罕见连体双胎双头龟
·波罗的海发现罕见短吻真海豚
·能帮你做大扫除的机器人[组图]
·法老墓3000年前坚果保存完好
·广西发现罕见溶洞钟乳石有30万年
金桥科普是一个公益性栏目,内容由作者提供或摘自互联网,其目的是向广大网民普及科学技术知识。如果您发现本网站转载或摘编了您拥有著作权的作品,请通知我们(电话:023-63659911),我们立即删除。
关于我们 | 网站地图 | 用户注册 | 广告客户 | 招聘信息 | 业务信息
Copyright@2006-2009 JQInfo.com,WONDER. All Rights Reserved
重庆科技咨询中心.重庆网得信息技术有限公司.版权所有
Email:webmaster@jqinfo.com
重庆数据通信局提供网络带宽. 渝ICP备05002327号