我们用MFC开发应用程序时,通常在窗口中放置大量的控件,通过触发这些控件的事件来完成我们的控制。但并不是每个控件都提供所有的事件消息,例如我们在对话窗口中加入一个静态文本控件(CState类),这时在ClassWizard中此控件没有任何消息,也就无法完成所要求的控制。VC++中为我们提供了一个API函数GetWindowRect(),此函数可以获得窗口中所有控件的位置,这样我们就可以在窗口的消息中利用位置判断来实现事件控制。
基于以上原理,可以轻松的实现超链接控制和动态提示以及窗口区域事件捕获等功能。以超链接控制为例,通常我们在对话框中加入电子邮件或主页的超链接,超链接一般要求获得焦点后鼠标变形,并且能响应OnClick事件,下面简单介绍其实现原理。
1.首先创建基于对话框的Sample工程。
2.在Sample工程的资源文件中引入光标文件将其ID设为“IDC_HAND”,在SAMPLE工程中的DIALOG对话框中加入静态文本控件将其ID设为“IDC_LINK”,Caption设为“http://netvc.6to23.com”
3.在对话类的头文件(SampleDlg.h)添加数据成员
protected:
RECT m_pRectLink; //用于保存静态文本框的屏幕坐标
4.获取控件坐标
在对话类成员函数OnInitDialog()中添加以下代码(sampleDlg.cpp):
GetDlgItem(IDC_LINK) -> GetWindowRect(&m_pRectLink);
//将静态文本的屏幕坐标存放在m_pRectLink中
ScreenToClient(&m_pRectLink);
//将屏幕坐标转换为客户坐标
5.变换鼠标形状
利用ClassWizard为对话框添加OnMouseMove()消息,在函数OnMouseMove(UINT nFlags, CPoint point)中,point参数可获得对应于窗口左上角的鼠标坐标,通过判断算法就可实现事件的控制。
//下面设置鼠标在静态文本区时,将光标设成小手状
if (point.x > m_pRectLink.left && point.x < m_pRectLink.right &&
point.y > m_pRectLink.top && point.y < m_pRectLink.bottom)
//此处添加判断坐标算法
{
HCURSOR hCursor;
hCursor = AfxGetApp() -> LoadCursor(IDC_HAND);
//将鼠标设为小手状
SetCursor(hCursor);
}
//下面语句用来设置默认(箭头)鼠标形状,一般鼠标移开后窗口会自动恢复默认鼠标形状,可酌情添加
if (...) //此处酌情添加鼠标不在静态文本区的坐标算法,本例可不加
{
hCURSOR hCursor;
hCursor = AfxGetApp() -> LoadStandardCursor(IDC_IBEAM);
//将光标设为默认值(箭头)
SetCursor(hCursor);
}
6.添加鼠标单击事件
利用ClassWizard为对话框添加OnLButtonDown()消息,参数与OnMouseMove()一样。
if (point.x > m_pRectLink.left && point.x < m_pRectLink.right &&
point.y > m_pRectLink.top && point.y < m_pRectLink.bottom)
//此处添加判断坐标算法
{
if (nFlags == MK_LBUTTON) //鼠标左键按下
{ //为改善鼠标效果,此处加入以上变换鼠标形状的代码
ShellExecute(0, NULL, "http://netvc.6to23.com", NULL,NULL, SW_NORMAL);
//也可以添加电子邮件的链接
}
}
在开发应用程序的过程中,灵活运用控件的位置可以实现一些特殊的消息控制。在以上例子中将静态文本稍加修饰,比如获得焦点时增加亮度或下画线效果会更好