vc静态文本框问题 20
基于对话框的程序我在上面添加静态文本框控件当我的鼠标移动到它上面时静态文本框就变颜色请问如何实现啊...
基于对话框的程序 我在上面添加静态文本框控件 当我的鼠标移动到它上面时 静态文本框就变颜色 请问如何实现啊
展开
3个回答
展开全部
hopeztm的实现思路有些问题:
1)楼主要的是静态文本框,怎么能随便换成CEdit?
必须继承自CStatic
2)消息映射有ON_WM_MOUSELEAVE()这个宏吗?
因为MFC不支持WM_MOUSELEAVE消息,必须将WM_MOUSELEAVE看成是自定义消息,手工添加消息映射宏:ON_MESSAGE(WM_MOUSELEAVE, myFunc);
myFunc的函数签名为:afx_msg LRESULT myFunc(WPARAM, LPARAM);
3)第五条能这样关联吗?
通过SubClassDlgItem进行关联。
我做了个CClrStatic的类,头文件为ClrStatic.h,CPP文件为ClrStatic.cpp。楼主可以看下。
另外需要对做一些解释:
1)WM_MOUSELEAVE可以看成是自定义消息,该消息WINDOWS默认是不会发送给我们的控件的,必须为控件先调用TrackMouseEvent函数才能在鼠标离开控件时,控件能收到WM_MOUSELEAVE
2)当鼠标在控件中时,可以简单捕获WM_MOUSEMOVE消息,需要注意的是在鼠标移动时,不能总是Invalidate,否则控件比较大时,会出现闪屏。当鼠标进入控件或离开时,简单关联一个BOOL变量,让CClrStatic知道,当前鼠标是否在控件里或离开,第一次进入控件即首次获得WM_MOUSEMOVE消息时,将BOOL变量设置成TRUE,并调用一次Invalidate,以后当鼠标持续在控件中时便可以不用调用Invalidate,避免出现闪屏。
3)CStatic和对话框一样,一般是有3种颜色需要控制,一个是背景颜色,即客户区的颜色。该颜色的作用比喻是:
画家在墙上作画时,画了一幅山水画,欣赏者看过了山水画的效果后,画家还想让欣赏者看人物画。这个时候不可能在山水画上直接画的,技术上可以,但画出来的还是人物画吗?因此画家需要将墙壁用白色画刷将前面的山水画全部涂掉,因此白色就是窗口背景的颜色。每次Invalidate后,都会用白色把客户区刷白了,当然白色不一定是我们想要的,可以将白色换成其他颜色。
第二个颜色是字体颜色,该颜色在CDC::GetTextColor获得,在CDC::SetTextColor设置;
第三个颜色是存托字体的背景色,该颜色在CDC::GetBkColor获得,在CDC::SetBkColor设置,这个概念和客户区的概念有点混淆,反正它是一块很小的区域,正好可以围住文字的那块矩形区域,文字多了,该区域的宽相应会增加。实在不明白,楼主可用我提供的函数SubClass来试验一下。其中最后两个参数指定了CClrStatic需要使用的客户区背景色和字体背景色。
4)SubClass是个CClrStatic的自定义函数,该函数可以用来和对话框进行交流,函数定义虽然是在CClrStatic中,但其实该函数是给对话框来调用的。
5)SubClassDlgItem是个CWnd的成员函数,是个MFC函数,不是我们自己的自定义函数,它的概念解释比较麻烦,楼主可以参考MSDN。
以下是代码:
-------------------------CClrStatic.h------------------------------
#pragma once
// CClrStatic
class CClrStatic : public CStatic
{
DECLARE_DYNAMIC(CClrStatic)
public:
CClrStatic();
virtual ~CClrStatic();
protected:
DECLARE_MESSAGE_MAP()
public:
afx_msg LRESULT OnMouseLeave(WPARAM, LPARAM);
public:
bool m_fClr;
public:
afx_msg HBRUSH CtlColor(CDC* /*pDC*/, UINT /*nCtlColor*/);
public:
virtual BOOL SubClass(UINT nID, CWnd* pParent, COLORREF clrBackground, COLORREF clrBk);
public:
afx_msg void OnMouseMove(UINT nFlags, CPoint point);
public:
COLORREF m_clrBackground;
public:
COLORREF m_clrBk;
};
----------------------------------ClrStatic.cpp-----------------------------
// ClrStatic.cpp : 实现文件
//
#include "stdafx.h"
#include "ShowExtensions.h"
#include "ClrStatic.h"
// CClrStatic
IMPLEMENT_DYNAMIC(CClrStatic, CStatic)
CClrStatic::CClrStatic()
: m_fClr(false)
{
}
CClrStatic::~CClrStatic()
{
}
BEGIN_MESSAGE_MAP(CClrStatic, CStatic)
ON_MESSAGE(WM_MOUSELEAVE, OnMouseLeave)
ON_WM_CTLCOLOR_REFLECT()
ON_WM_MOUSEMOVE()
END_MESSAGE_MAP()
// CClrStatic 消息处理程序
LRESULT CClrStatic::OnMouseLeave(WPARAM wParam, LPARAM lParam)
{
if (m_fClr) {
m_fClr = FALSE;
Invalidate();
}
return 0;
}
HBRUSH CClrStatic::CtlColor(CDC* pDC, UINT /*nCtlColor*/)
{
// TODO: 在此更改 DC 的任何属性
// TODO: 如果不应调用父级的处理程序,则返回非空画笔
if (m_fClr) {
pDC->SetTextColor(RGB(255, 0, 255));
pDC->SetBkColor(m_clrBk);
return CreateSolidBrush(m_clrBackground);
}
return NULL;
}
BOOL CClrStatic::SubClass(UINT nID, CWnd* pParent, COLORREF clrBackground, COLORREF clrBk)
{
BOOL fRet = SubclassDlgItem(nID, pParent);
ModifyStyle(0, SS_NOTIFY);
m_clrBackground = clrBackground;
m_clrBk = clrBk;
return fRet;
}
void CClrStatic::OnMouseMove(UINT nFlags, CPoint point)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
CStatic::OnMouseMove(nFlags, point);
if (!m_fClr) {
m_fClr = TRUE;
Invalidate();
TRACKMOUSEEVENT tme = { sizeof(tme) };
tme.dwFlags = TME_LEAVE;
tme.hwndTrack = this->GetSafeHwnd();
TrackMouseEvent(&tme);
}
}
-------------------------------CTestDlg.h-----------------------------------
//#include "xxx.h" etc.
#include "ClrStatic.h"
//some codes etc.
class CTestDlg : public CDialog
{
//some codes etc.
public:
CClrStatic m_clrStatic;
//some codes etc.
};
-------------------------------CTestDlg.cpp---------------------------------
//#include "xxx.h" etc.
#include "ClrStatic.h"
//some codes etc.
BOOL CTestDlg::OnInitDialog()
{
//some codes etc.
m_clrStatic.SubClass(IDC_STATIC1, this, (COLORREF)GetSysColor(COLOR_BTNFACE), (COLORREF)GetSysColor(COLOR_BTNFACE));
//some codes etc.
}
1)楼主要的是静态文本框,怎么能随便换成CEdit?
必须继承自CStatic
2)消息映射有ON_WM_MOUSELEAVE()这个宏吗?
因为MFC不支持WM_MOUSELEAVE消息,必须将WM_MOUSELEAVE看成是自定义消息,手工添加消息映射宏:ON_MESSAGE(WM_MOUSELEAVE, myFunc);
myFunc的函数签名为:afx_msg LRESULT myFunc(WPARAM, LPARAM);
3)第五条能这样关联吗?
通过SubClassDlgItem进行关联。
我做了个CClrStatic的类,头文件为ClrStatic.h,CPP文件为ClrStatic.cpp。楼主可以看下。
另外需要对做一些解释:
1)WM_MOUSELEAVE可以看成是自定义消息,该消息WINDOWS默认是不会发送给我们的控件的,必须为控件先调用TrackMouseEvent函数才能在鼠标离开控件时,控件能收到WM_MOUSELEAVE
2)当鼠标在控件中时,可以简单捕获WM_MOUSEMOVE消息,需要注意的是在鼠标移动时,不能总是Invalidate,否则控件比较大时,会出现闪屏。当鼠标进入控件或离开时,简单关联一个BOOL变量,让CClrStatic知道,当前鼠标是否在控件里或离开,第一次进入控件即首次获得WM_MOUSEMOVE消息时,将BOOL变量设置成TRUE,并调用一次Invalidate,以后当鼠标持续在控件中时便可以不用调用Invalidate,避免出现闪屏。
3)CStatic和对话框一样,一般是有3种颜色需要控制,一个是背景颜色,即客户区的颜色。该颜色的作用比喻是:
画家在墙上作画时,画了一幅山水画,欣赏者看过了山水画的效果后,画家还想让欣赏者看人物画。这个时候不可能在山水画上直接画的,技术上可以,但画出来的还是人物画吗?因此画家需要将墙壁用白色画刷将前面的山水画全部涂掉,因此白色就是窗口背景的颜色。每次Invalidate后,都会用白色把客户区刷白了,当然白色不一定是我们想要的,可以将白色换成其他颜色。
第二个颜色是字体颜色,该颜色在CDC::GetTextColor获得,在CDC::SetTextColor设置;
第三个颜色是存托字体的背景色,该颜色在CDC::GetBkColor获得,在CDC::SetBkColor设置,这个概念和客户区的概念有点混淆,反正它是一块很小的区域,正好可以围住文字的那块矩形区域,文字多了,该区域的宽相应会增加。实在不明白,楼主可用我提供的函数SubClass来试验一下。其中最后两个参数指定了CClrStatic需要使用的客户区背景色和字体背景色。
4)SubClass是个CClrStatic的自定义函数,该函数可以用来和对话框进行交流,函数定义虽然是在CClrStatic中,但其实该函数是给对话框来调用的。
5)SubClassDlgItem是个CWnd的成员函数,是个MFC函数,不是我们自己的自定义函数,它的概念解释比较麻烦,楼主可以参考MSDN。
以下是代码:
-------------------------CClrStatic.h------------------------------
#pragma once
// CClrStatic
class CClrStatic : public CStatic
{
DECLARE_DYNAMIC(CClrStatic)
public:
CClrStatic();
virtual ~CClrStatic();
protected:
DECLARE_MESSAGE_MAP()
public:
afx_msg LRESULT OnMouseLeave(WPARAM, LPARAM);
public:
bool m_fClr;
public:
afx_msg HBRUSH CtlColor(CDC* /*pDC*/, UINT /*nCtlColor*/);
public:
virtual BOOL SubClass(UINT nID, CWnd* pParent, COLORREF clrBackground, COLORREF clrBk);
public:
afx_msg void OnMouseMove(UINT nFlags, CPoint point);
public:
COLORREF m_clrBackground;
public:
COLORREF m_clrBk;
};
----------------------------------ClrStatic.cpp-----------------------------
// ClrStatic.cpp : 实现文件
//
#include "stdafx.h"
#include "ShowExtensions.h"
#include "ClrStatic.h"
// CClrStatic
IMPLEMENT_DYNAMIC(CClrStatic, CStatic)
CClrStatic::CClrStatic()
: m_fClr(false)
{
}
CClrStatic::~CClrStatic()
{
}
BEGIN_MESSAGE_MAP(CClrStatic, CStatic)
ON_MESSAGE(WM_MOUSELEAVE, OnMouseLeave)
ON_WM_CTLCOLOR_REFLECT()
ON_WM_MOUSEMOVE()
END_MESSAGE_MAP()
// CClrStatic 消息处理程序
LRESULT CClrStatic::OnMouseLeave(WPARAM wParam, LPARAM lParam)
{
if (m_fClr) {
m_fClr = FALSE;
Invalidate();
}
return 0;
}
HBRUSH CClrStatic::CtlColor(CDC* pDC, UINT /*nCtlColor*/)
{
// TODO: 在此更改 DC 的任何属性
// TODO: 如果不应调用父级的处理程序,则返回非空画笔
if (m_fClr) {
pDC->SetTextColor(RGB(255, 0, 255));
pDC->SetBkColor(m_clrBk);
return CreateSolidBrush(m_clrBackground);
}
return NULL;
}
BOOL CClrStatic::SubClass(UINT nID, CWnd* pParent, COLORREF clrBackground, COLORREF clrBk)
{
BOOL fRet = SubclassDlgItem(nID, pParent);
ModifyStyle(0, SS_NOTIFY);
m_clrBackground = clrBackground;
m_clrBk = clrBk;
return fRet;
}
void CClrStatic::OnMouseMove(UINT nFlags, CPoint point)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
CStatic::OnMouseMove(nFlags, point);
if (!m_fClr) {
m_fClr = TRUE;
Invalidate();
TRACKMOUSEEVENT tme = { sizeof(tme) };
tme.dwFlags = TME_LEAVE;
tme.hwndTrack = this->GetSafeHwnd();
TrackMouseEvent(&tme);
}
}
-------------------------------CTestDlg.h-----------------------------------
//#include "xxx.h" etc.
#include "ClrStatic.h"
//some codes etc.
class CTestDlg : public CDialog
{
//some codes etc.
public:
CClrStatic m_clrStatic;
//some codes etc.
};
-------------------------------CTestDlg.cpp---------------------------------
//#include "xxx.h" etc.
#include "ClrStatic.h"
//some codes etc.
BOOL CTestDlg::OnInitDialog()
{
//some codes etc.
m_clrStatic.SubClass(IDC_STATIC1, this, (COLORREF)GetSysColor(COLOR_BTNFACE), (COLORREF)GetSysColor(COLOR_BTNFACE));
//some codes etc.
}
展开全部
最近比较忙,不能给你亲自调代码了
实现思路这样的
1 自己定义类 myCEdit,这个类继承CEdit
2 在CEdit 中定义函数 函数 OnMouseMove 和 OnMouseLeave ,前者用于鼠标进入静态文本后响应,而后者用于鼠标离开后响应
3 做鼠标消息映射
BEGIN_MESSAGE_MAP(ParameterDialog, CDialog)
ON_WM_MOUSELEAVE()
ON_WM_MOUSEMOVE()
END_MESSAGE_MAP()
4 实现OnMouseMove和MouseLeave函数,改变背景颜色
5 在对话框的映射关系如下 DDX_Control(pDX,IDC_EDIT4,myCEdit);(myCEidt是类成员变量)
实现思路这样的
1 自己定义类 myCEdit,这个类继承CEdit
2 在CEdit 中定义函数 函数 OnMouseMove 和 OnMouseLeave ,前者用于鼠标进入静态文本后响应,而后者用于鼠标离开后响应
3 做鼠标消息映射
BEGIN_MESSAGE_MAP(ParameterDialog, CDialog)
ON_WM_MOUSELEAVE()
ON_WM_MOUSEMOVE()
END_MESSAGE_MAP()
4 实现OnMouseMove和MouseLeave函数,改变背景颜色
5 在对话框的映射关系如下 DDX_Control(pDX,IDC_EDIT4,myCEdit);(myCEidt是类成员变量)
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
展开全部
额,上面的高手已经说得非常明白了
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询