MFC下如何在响应鼠标双击时改变ListBox的背景颜色~~~~~跪求大神指导!!! 重写ListBox,双击后传RGB值给ListBox。 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 自定义一个ListBoxEx类继承ListBox 然后呢,详细一点是怎样做?完全不会呃。http://download.csdn.net/detail/ftd2013/5154855 然后呢,详细一点是怎样做?完全不会呃。http://download.csdn.net/detail/ftd2013/5154855我看了这个程序,还没试着移植国看来用,因为我还得多一步,即响应左键双击消息,然后才来进行重绘。不过我用OnCtlColor的方法编了一个试试,我放置了3个EditControl,想通过鼠标双击来选中其中一个,并在另一个EditControl里显示选中了3个中的哪一个,然后把选中的那个控件背景改成红色。注意是单选,所以同一时刻只能有一个控件背景为红色。但是遇到点问题,代码如下://自定义Edit类响应左键双击函数void CMyEdit::OnLButtonDblClk(UINT nFlags, CPoint point){ // TODO: 在此添加消息处理程序代码和/或调用默认值 switch(this->GetDlgCtrlID()) { case IDC_EDIT1: ptrDlg->uintID = 1; break; case IDC_EDIT2: ptrDlg->uintID = 2; break; case IDC_EDIT3: ptrDlg->uintID = 3; break; } CEdit::OnLButtonDblClk(nFlags, point); CString temp; temp.Format(_T("%d"),ptrDlg->uintID); ptrDlg->m_Edit4.SetWindowText(temp); UpdateWindow(); // 通过这个来调用CtlColor,呃,不知道这样做对不对....}// 子类的WM_CTLCOLOR响应函数HBRUSH CMyEdit::CtlColor(CDC* pDC, UINT nCtlColor){ // TODO: 在此更改 DC 的任何特性 if((this->GetDlgCtrlID() == IDC_EDIT1) && (nCtlColor == CTLCOLOR_EDIT)|| (this->GetDlgCtrlID() == IDC_EDIT2) && (nCtlColor == CTLCOLOR_EDIT)|| (this->GetDlgCtrlID() == IDC_EDIT3) && (nCtlColor == CTLCOLOR_EDIT)) { if((this->GetDlgCtrlID() == IDC_EDIT1) && (nCtlColor == CTLCOLOR_EDIT)&&(ptrDlg->uintID==1)) { COLORREF clr = RGB(0,0,0); pDC->SetTextColor(clr); clr = RGB(255,0,0); pDC->SetBkColor(clr); m_bkBrush = ::CreateSolidBrush(clr); return m_bkBrush; } else { COLORREF clr = RGB(0,0,0); pDC->SetTextColor(clr); clr = RGB(255,255,255); pDC->SetBkColor(clr); m_bkBrush = ::CreateSolidBrush(clr); return m_bkBrush; } if((this->GetDlgCtrlID() == IDC_EDIT2) && (nCtlColor == CTLCOLOR_EDIT)&&(ptrDlg->uintID==2)) { COLORREF clr = RGB(0,0,0); pDC->SetTextColor(clr); clr = RGB(255,0,0); pDC->SetBkColor(clr); m_bkBrush = ::CreateSolidBrush(clr); return m_bkBrush; } else { COLORREF clr = RGB(0,0,0); pDC->SetTextColor(clr); clr = RGB(255,255,255); pDC->SetBkColor(clr); m_bkBrush = ::CreateSolidBrush(clr); return m_bkBrush; } if((this->GetDlgCtrlID() == IDC_EDIT3) && (nCtlColor == CTLCOLOR_EDIT)&&(ptrDlg->uintID==3)) { COLORREF clr = RGB(0,0,0); pDC->SetTextColor(clr); clr = RGB(255,0,0); pDC->SetBkColor(clr); m_bkBrush = ::CreateSolidBrush(clr); return m_bkBrush; } else { COLORREF clr = RGB(0,0,0); pDC->SetTextColor(clr); clr = RGB(255,255,255); pDC->SetBkColor(clr); m_bkBrush = ::CreateSolidBrush(clr); return m_bkBrush; } } // TODO: 如果不应调用父级的处理程序,则返回非 null 画笔 else return NULL;}结果是,只有第一个控件背景会变红,其他两个都不会……而且当第一个变红后,双击第二个时第一个颜色不会消失,要等到鼠标移至第一个时它才会改变颜色。这这这,完全不符合预期啊~~~~~还请大侠援助~~~~ 如上,我用edit做了一个,但是存在问题…… 如上,我用edit做了一个,但是存在问题……在重绘ListBox类中加个SetItemColor这样的函数,你RGB传值过去,在重绘不就可以了。 如上,我用edit做了一个,但是存在问题……在重绘ListBox类中加个SetItemColor这样的函数,你RGB传值过去,在重绘不就可以了。那响应WM_CTLCOLOR的做法呢?为什么不行呢? ListBox除了在第一次绘制外, 其它时候都只是绘制更新.你只要能强制刷新全部, 就能按你的想法绘制了. 你说的是OnCtlControl还是DrawItem的方法? 我用Edit Control做了一个,代码是这样HBRUSH CMyEdit::CtlColor(CDC* pDC, UINT nCtlColor){ // TODO: 在此更改 DC 的任何特性 if(((this->GetDlgCtrlID() == IDC_EDIT1) && (nCtlColor == CTLCOLOR_EDIT))|| ((this->GetDlgCtrlID() == IDC_EDIT2) && (nCtlColor == CTLCOLOR_EDIT))|| ((this->GetDlgCtrlID() == IDC_EDIT3) && (nCtlColor == CTLCOLOR_EDIT))) { if((this->GetDlgCtrlID() == IDC_EDIT1) && (nCtlColor == CTLCOLOR_EDIT)&&(ptrDlg->uintID==1)) { COLORREF clr = RGB(0,0,0); pDC->SetTextColor(clr); clr = RGB(255,0,0); pDC->SetBkColor(clr); m_bkBrush1 = ::CreateSolidBrush(clr); return m_bkBrush1; } else { COLORREF clr = RGB(0,0,0); pDC->SetTextColor(clr); clr = RGB(255,255,255); pDC->SetBkColor(clr); m_bkBrush01 = ::CreateSolidBrush(clr); return m_bkBrush01; } if((this->GetDlgCtrlID() == IDC_EDIT2) && (nCtlColor == CTLCOLOR_EDIT)&&(ptrDlg->uintID==2)) { COLORREF clr = RGB(0,0,0); pDC->SetTextColor(clr); clr = RGB(255,0,0); pDC->SetBkColor(clr); m_bkBrush2 = ::CreateSolidBrush(clr); return m_bkBrush2; } else { COLORREF clr = RGB(0,0,0); pDC->SetTextColor(clr); clr = RGB(255,255,255); pDC->SetBkColor(clr); m_bkBrush02 = ::CreateSolidBrush(clr); return m_bkBrush02; } if((this->GetDlgCtrlID() == IDC_EDIT3) && (nCtlColor == CTLCOLOR_EDIT)&&(ptrDlg->uintID==3)) { COLORREF clr = RGB(0,0,0); pDC->SetTextColor(clr); clr = RGB(255,0,0); pDC->SetBkColor(clr); m_bkBrush3 = ::CreateSolidBrush(clr); return m_bkBrush3; } else { COLORREF clr = RGB(0,0,0); pDC->SetTextColor(clr); clr = RGB(255,255,255); pDC->SetBkColor(clr); m_bkBrush03 = ::CreateSolidBrush(clr); return m_bkBrush03; } } // TODO: 如果不应调用父级的处理程序,则返回非 null 画笔 else return NULL;}然后我在响应鼠标左键双击函数里用UpdateWindow()来更新,有趣的是,在第一个if里的3个if else语句,哪个放在前就对应只有那个Edit控件会变颜色…………用InvalidateRect也试过,还是一样的…… 我的意思是让其重绘listbox的每一项, Invalidate只会绘制有变化的项, 得想其它方法.这也是我想知道的. 上面代码有个问题,我第一个else里都能返回,所以后面的都无法改变,把代码改成这样就能都变颜色了:HBRUSH CMyEdit::CtlColor(CDC* pDC, UINT nCtlColor){ // TODO: 在此更改 DC 的任何特性 //if(((this->GetDlgCtrlID() == IDC_EDIT1) && (nCtlColor == CTLCOLOR_EDIT))|| // ((this->GetDlgCtrlID() == IDC_EDIT2) && (nCtlColor == CTLCOLOR_EDIT))|| // ((this->GetDlgCtrlID() == IDC_EDIT3) && (nCtlColor == CTLCOLOR_EDIT))) //{ if((this->GetDlgCtrlID() == IDC_EDIT2) && (nCtlColor == CTLCOLOR_EDIT)) { if(ptrDlg->uintID==2) { COLORREF clr = RGB(0,0,0); pDC->SetTextColor(clr); clr = RGB(255,0,0); pDC->SetBkColor(clr); m_bkBrush2 = ::CreateSolidBrush(clr); return m_bkBrush2; } else { COLORREF clr = RGB(0,0,0); pDC->SetTextColor(clr); clr = GetSysColor(COLOR_3DFACE); pDC->SetBkColor(clr); m_bkBrush02 = ::CreateSolidBrush(clr); return m_bkBrush02; } } if((this->GetDlgCtrlID() == IDC_EDIT3) && (nCtlColor == CTLCOLOR_EDIT)) { if(ptrDlg->uintID==3) { COLORREF clr = RGB(0,0,0); pDC->SetTextColor(clr); clr = RGB(255,0,0); pDC->SetBkColor(clr); m_bkBrush3 = ::CreateSolidBrush(clr); return m_bkBrush3; } else { COLORREF clr = RGB(0,0,0); pDC->SetTextColor(clr); clr = GetSysColor(COLOR_3DFACE); pDC->SetBkColor(clr); m_bkBrush03 = ::CreateSolidBrush(clr); return m_bkBrush03; } } if((this->GetDlgCtrlID() == IDC_EDIT1) && (nCtlColor == CTLCOLOR_EDIT)) { if(ptrDlg->uintID==1) { COLORREF clr = RGB(0,0,0); pDC->SetTextColor(clr); clr = RGB(255,0,0); pDC->SetBkColor(clr); m_bkBrush1 = ::CreateSolidBrush(clr); return m_bkBrush1; } else { COLORREF clr = RGB(0,0,0); pDC->SetTextColor(clr); clr = GetSysColor(COLOR_3DFACE); pDC->SetBkColor(clr); m_bkBrush01 = ::CreateSolidBrush(clr); return m_bkBrush01; } } //} // TODO: 如果不应调用父级的处理程序,则返回非 null 画笔 //else return NULL;}但是还存在个问题,响应不及时,比如我一开始点了第一个Edit控件,第一个控件变红了,但是当我点第二个控件时,第二个控件是变红了,但是第一个控件还是红的,需要我把鼠标移到第一个控件的位置才能促使第一个控件变回原来的颜色……就像你说的,只是重绘了有改变的地方。 还有个问题,如果Edit控件里初始时有内容,那恢复颜色时只能恢复中间一块,像这样: 你是要改变整个ListBox的背景色还是ListBox中某项的背景色?周末可以给你写个 这么好!!!我有三个ListBox,不过内容都只有一行我想实现鼠标双击选中的效果,不要单击选中,要双击,并且在三个ListBox之间是单选的,可以随意切换选择。选中以后ListBox的背景要变色,当然切换选项后得变回原来的颜色。其实我是不知道该用什么控件实现这样的效果才这么做的……我在三个控件里会实时地显示数据,鼠标双击其中一个控件,即选中该控件显示的这类数据并做一些输出操作之类的。要是没空也欢迎一起讨论~~~~ 看完之后觉得可以用单选按钮RadioButton的Push风格比较好用ListBox反而不合适,因为还要控制ListBox的高度,如果高度高于1条记录或小于1条记录反倒不和xie windows每个进程都有自己的消息队列,被中断后当前进程挂起。不会你说的冲突 下面是我刚写的一个用单选按钮Radio实现的,只不过单击就有效果了其实用ListBox也是单击就有事件,干嘛要双击呢另外如果你要用ListBox可以就用一个,干嘛要3个?ListBox也可以画的很小或者很大: 因为我要实时地显示一些数据,而选择是根据数据的内容而产生的动作,如果在单选按钮的内容里显示数据不是有点奇怪么。不过我自己也觉得用ListBox有点小题大做的感觉,也因为不太会弄,所以最后选择用EditControl,但是Edit控件又会存在刷新不及时等问题,如我在15、16楼说的一样。。 HBRUSH CMyEdit::CtlColor(CDC* pDC, UINT nCtlColor)注意同一个时刻, 只有 一个 实例 是 有效的 !所以点击 1 , 1 变 红, 点击 2 ,2 变 红, 但 1 不会 变 , 因为 这时你的 代码 只对 2 有效,你的目的是以 一个 edit 实例 来改变 3个 edit 实例的 状态,所以 这个 edit 要 能 存取 兄弟 edit 。。也就是说 这个 edit 类 , 必须 保存 所有 实例的 信息(类的 静态成员 变量) 对于listbox或者listctrl,应该是在DrawItem中实现 给你一段listctrl行颜色设置相关处理代码:BEGIN_MESSAGE_MAP(CAlertColoredListCtrl, CListCtrl) ON_NOTIFY_REFLECT(NM_CUSTOMDRAW, &CAlertColoredListCtrl::OnNMCustomdraw) //ON_WM_ERASEBKGND()END_MESSAGE_MAP() void CAlertColoredListCtrl::OnNMCustomdraw(NMHDR *pNMHDR, LRESULT *pResult){ *pResult = 0; LPNMLVCUSTOMDRAW lplvcd = (LPNMLVCUSTOMDRAW)pNMHDR; int iRow = lplvcd->nmcd.dwItemSpec; switch(lplvcd->nmcd.dwDrawStage) { case CDDS_PREPAINT : { *pResult = CDRF_NOTIFYITEMDRAW; return; } // Modify item text and or background case CDDS_ITEMPREPAINT: { lplvcd->clrText = RGB(0,0,0); // If you want the sub items the same as the item, // set *pResult to CDRF_NEWFONT *pResult = CDRF_NOTIFYSUBITEMDRAW; return; } // Modify sub item text and/or background case CDDS_SUBITEM | CDDS_PREPAINT | CDDS_ITEM: { COLORREF clrNewTextColor, clrNewBkColor; //int nItem = static_cast<int>( pLVCD->nmcd.dwItemSpec ); POSITION pos = GetFirstSelectedItemPosition(); int index = GetNextSelectedItem(pos); if (index == iRow)//如果要刷新的项为当前选择的项,则将文字设为白色,背景色设为蓝色 { clrNewTextColor = RGB(255,255,255); //Set the text to white clrNewBkColor = RGB(49,106,197); //Set the background color to blue lplvcd->clrText = clrNewTextColor; lplvcd->clrTextBk = clrNewBkColor; } else { //if(iRow %2){ // lplvcd->clrTextBk = m_colRow2; //} //else{ // lplvcd->clrTextBk = m_colRow1; //} } //未查看的报警信息以红色字体显示 if (-1 != iRow) { bool bRead = true; int itemData = GetItemData(iRow); std::vector<QueryResGuid>::iterator iter; CMainFrame *pFrame = (CMainFrame *)AfxGetApp()->GetMainWnd(); for (iter=pFrame->GetAlertView()->m_realAlertGuidList.begin(); iter!=pFrame->GetAlertView()->m_realAlertGuidList.end(); iter++) { if (itemData == iter->index) { bRead = iter->readFlag; break; } } if (false == bRead) { clrNewTextColor = RGB(255,0,0); lplvcd->clrText = clrNewTextColor; } } *pResult = CDRF_DODEFAULT; return; } }} 那OnCtlColor也是同一时刻只对一个实例有效是么?所以才会出现当我点击了2,我要移到鼠标到1时才会出现1变回原来颜色的情况?是在鼠标移动过去才进行了刷新? “那OnCtlColor也是同一时刻只对一个实例有效是么?”是 !实例的成员函数只对 当前 实例 有效。请 深刻理解 这句话。只有类的 静态成员 才是 所有实例 共享的 以 3个 edit 为例:1.class CMyEdit : public CEdit{static int m_CurrentID; // 类变量2.// CMyEditint CMyEdit::m_CurrentID=0;// 初始化3.void CMyEdit::OnLButtonDblClk(UINT nFlags, CPoint point) { // TODO: Add your message handler code here and/or call default m_CurrentID=GetDlgCtrlID(); GetParent()->Invalidate();// 叫对话框 发 3 个 edit repaint CEdit::OnLButtonDblClk(nFlags, point);}4.HBRUSH CMyEdit::CtlColor(CDC* pDC, UINT nCtlColor) { // TODO: Change any attributes of the DC here COLORREF clr=0; int CurrentID=GetDlgCtrlID(); if(CurrentID == m_CurrentID) { clr=RGB(255,0,0); } else { clr=RGB(255,255,255); } pDC->SetBkMode(TRANSPARENT); return ::CreateSolidBrush(clr);//NULL;} 上面有一句“GetParent()->Invalidate();// 叫对话框 发 3 个 edit repaint ”其实 有2个问题:1 如果 对话框 有 WS_CLIPCHILDREN 属性, 那么 这句 就 无效了2 如果 对话框 有很多 控件, 都 重绘 就不好了。所以 :void CMyEdit::OnLButtonDblClk(UINT nFlags, CPoint point) { // TODO: Add your message handler code here and/or call default if(m_CurrentID==0) { m_CurrentID=GetDlgCtrlID();// only for this m_CurrentPedit=this; // this window Invalidate(); // re-paint this } else { m_CurrentPedit->Invalidate();// re-paint last m_CurrentID=GetDlgCtrlID(); // only for this m_CurrentPedit=this; // this window Invalidate(); // re-paint this } CEdit::OnLButtonDblClk(nFlags, point);}m_CurrentPedit=this; 定义为:class CMyEdit : public CEdit{static int m_CurrentID;static CWnd *m_CurrentPedit;初始化为:int CMyEdit::m_CurrentID=0;CWnd *CMyEdit::m_CurrentPedit=0;这样 双击 不同 edit 时 , 先 叫 前一个 edit re-paint #if !defined(AFX_MYRADIO_H__4BEBE4F2_3B3B_443D_B114_5AFADE5C47F3__INCLUDED_)#define AFX_MYRADIO_H__4BEBE4F2_3B3B_443D_B114_5AFADE5C47F3__INCLUDED_#if _MSC_VER > 1000#pragma once#endif // _MSC_VER > 1000// MyRadio.h : header file///////////////////////////////////////////////////////////////////////////////// CMyRadio windowclass CMyRadio : public CButton{// Constructionpublic: CMyRadio();// Attributespublic:// Operationspublic:// Overrides // ClassWizard generated virtual function overrides //{{AFX_VIRTUAL(CMyRadio) public: virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct); protected: virtual void PreSubclassWindow(); //}}AFX_VIRTUAL// Implementationpublic: virtual ~CMyRadio(); // Generated message map functionsprotected: //{{AFX_MSG(CMyRadio) // NOTE - the ClassWizard will add and remove member functions here. //}}AFX_MSG DECLARE_MESSAGE_MAP()};///////////////////////////////////////////////////////////////////////////////{{AFX_INSERT_LOCATION}}// Microsoft Visual C++ will insert additional declarations immediately before the previous line.#endif // !defined(AFX_MYRADIO_H__4BEBE4F2_3B3B_443D_B114_5AFADE5C47F3__INCLUDED_)// MyRadio.cpp : implementation file//#include "stdafx.h"#include "Radio.h"#include "MyRadio.h"#ifdef _DEBUG#define new DEBUG_NEW#undef THIS_FILEstatic char THIS_FILE[] = __FILE__;#endif/////////////////////////////////////////////////////////////////////////////// CMyRadioCMyRadio::CMyRadio(){}CMyRadio::~CMyRadio(){}BEGIN_MESSAGE_MAP(CMyRadio, CButton) //{{AFX_MSG_MAP(CMyRadio) // NOTE - the ClassWizard will add and remove mapping macros here. //}}AFX_MSG_MAPEND_MESSAGE_MAP()/////////////////////////////////////////////////////////////////////////////// CMyRadio message handlersvoid CMyRadio::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct) { // TODO: Add your code to draw the specified item CRect rcItem=lpDrawItemStruct->rcItem; CDC *pDC=CDC::FromHandle(lpDrawItemStruct->hDC); BOOL bFocus=lpDrawItemStruct->itemState&ODS_FOCUS; CString strCaption; GetWindowText(strCaption); if(bFocus) { pDC->FillSolidRect(&rcItem,RGB(255,0,0)); pDC->SetTextColor(RGB(0,255,0)); } else { pDC->FillSolidRect(&rcItem,GetSysColor(COLOR_BTNFACE)); pDC->SetTextColor(RGB(0,0,0)); } CSize szText = pDC->GetOutputTextExtent(strCaption); CRect rcText; rcText.left = (rcItem.Width()-szText.cx)/2; rcText.top = (rcItem.Height()-szText.cy)/2; rcText.right = rcText.left + szText.cx; rcText.bottom = rcText.top + szText.cy; pDC->DrawText(strCaption,&rcText,DT_LEFT);}void CMyRadio::PreSubclassWindow() { // TODO: Add your specialized code here and/or call the base class ModifyStyle(0,BS_OWNERDRAW); CButton::PreSubclassWindow();}多个Radio设置如下Push-like属性,然后关联上CMyRadio变量,且其中一个勾选有组属性(Group)就OK了 最后 当 3个 edit 背景不一样时:(上面的 代码 是 2个 白, 一个 红)HBRUSH CMyEdit::CtlColor(CDC* pDC, UINT nCtlColor) { // TODO: Change any attributes of the DC here COLORREF clr=0; if(GetDlgCtrlID() == m_CurrentID) { clr=RGB(255,0,0); pDC->SetBkMode(TRANSPARENT); return ::CreateSolidBrush(clr);//NULL; } if(GetDlgCtrlID() == IDC_EDIT1) { clr=RGB(0,200,255); } if(GetDlgCtrlID() == IDC_EDIT2) { clr=RGB(128,255,0); } if(GetDlgCtrlID() == IDC_EDIT3) { clr=RGB(255,128,0); } pDC->SetBkMode(TRANSPARENT); return ::CreateSolidBrush(clr);//NULL;}结果: 谢谢你的回复,不过最后我还是决定用EditControl来做了~! XML的下拉框怎么写? 关于List Control的问题! 请问如何在一个自制的文件目录浏览框中,添加一个系统的右键菜单 AT_INFO编译时报错 VC6.0可以使用正则表达式吗? 关于向另一个程序发送消息的问题 以CDialogBar 派生类做的工具条上的Edit控间如何更新 串口通讯能否发送9位数据位? 关于局域网数据包截取软件的问题 何谓线程安全? 获取图标文件中每一幅图的方法 求助..VC求大神给看看怎么弄
http://download.csdn.net/detail/ftd2013/5154855
http://download.csdn.net/detail/ftd2013/5154855我看了这个程序,还没试着移植国看来用,因为我还得多一步,即响应左键双击消息,然后才来进行重绘。
不过我用OnCtlColor的方法编了一个试试,我放置了3个EditControl,想通过鼠标双击来选中其中一个,并在另一个EditControl里显示选中了3个中的哪一个,然后把选中的那个控件背景改成红色。注意是单选,所以同一时刻只能有一个控件背景为红色。但是遇到点问题,代码如下:
//自定义Edit类响应左键双击函数
void CMyEdit::OnLButtonDblClk(UINT nFlags, CPoint point)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
switch(this->GetDlgCtrlID())
{
case IDC_EDIT1: ptrDlg->uintID = 1; break;
case IDC_EDIT2: ptrDlg->uintID = 2; break;
case IDC_EDIT3: ptrDlg->uintID = 3; break;
}
CEdit::OnLButtonDblClk(nFlags, point);
CString temp;
temp.Format(_T("%d"),ptrDlg->uintID);
ptrDlg->m_Edit4.SetWindowText(temp);
UpdateWindow(); // 通过这个来调用CtlColor,呃,不知道这样做对不对....
}// 子类的WM_CTLCOLOR响应函数
HBRUSH CMyEdit::CtlColor(CDC* pDC, UINT nCtlColor)
{
// TODO: 在此更改 DC 的任何特性
if((this->GetDlgCtrlID() == IDC_EDIT1) && (nCtlColor == CTLCOLOR_EDIT)||
(this->GetDlgCtrlID() == IDC_EDIT2) && (nCtlColor == CTLCOLOR_EDIT)||
(this->GetDlgCtrlID() == IDC_EDIT3) && (nCtlColor == CTLCOLOR_EDIT))
{
if((this->GetDlgCtrlID() == IDC_EDIT1) && (nCtlColor == CTLCOLOR_EDIT)&&(ptrDlg->uintID==1))
{
COLORREF clr = RGB(0,0,0);
pDC->SetTextColor(clr);
clr = RGB(255,0,0);
pDC->SetBkColor(clr);
m_bkBrush = ::CreateSolidBrush(clr);
return m_bkBrush;
}
else
{
COLORREF clr = RGB(0,0,0);
pDC->SetTextColor(clr);
clr = RGB(255,255,255);
pDC->SetBkColor(clr);
m_bkBrush = ::CreateSolidBrush(clr);
return m_bkBrush;
} if((this->GetDlgCtrlID() == IDC_EDIT2) && (nCtlColor == CTLCOLOR_EDIT)&&(ptrDlg->uintID==2))
{
COLORREF clr = RGB(0,0,0);
pDC->SetTextColor(clr);
clr = RGB(255,0,0);
pDC->SetBkColor(clr);
m_bkBrush = ::CreateSolidBrush(clr);
return m_bkBrush;
}
else
{
COLORREF clr = RGB(0,0,0);
pDC->SetTextColor(clr);
clr = RGB(255,255,255);
pDC->SetBkColor(clr);
m_bkBrush = ::CreateSolidBrush(clr);
return m_bkBrush;
} if((this->GetDlgCtrlID() == IDC_EDIT3) && (nCtlColor == CTLCOLOR_EDIT)&&(ptrDlg->uintID==3))
{
COLORREF clr = RGB(0,0,0);
pDC->SetTextColor(clr);
clr = RGB(255,0,0);
pDC->SetBkColor(clr);
m_bkBrush = ::CreateSolidBrush(clr);
return m_bkBrush;
}
else
{
COLORREF clr = RGB(0,0,0);
pDC->SetTextColor(clr);
clr = RGB(255,255,255);
pDC->SetBkColor(clr);
m_bkBrush = ::CreateSolidBrush(clr);
return m_bkBrush;
} }
// TODO: 如果不应调用父级的处理程序,则返回非 null 画笔
else
return NULL;
}结果是,只有第一个控件背景会变红,其他两个都不会……而且当第一个变红后,双击第二个时第一个颜色不会消失,要等到鼠标移至第一个时它才会改变颜色。这这这,完全不符合预期啊~~~~~还请大侠援助~~~~
如上,我用edit做了一个,但是存在问题……
如上,我用edit做了一个,但是存在问题……
在重绘ListBox类中加个SetItemColor这样的函数,你RGB传值过去,在重绘不就可以了。
如上,我用edit做了一个,但是存在问题……
在重绘ListBox类中加个SetItemColor这样的函数,你RGB传值过去,在重绘不就可以了。那响应WM_CTLCOLOR的做法呢?为什么不行呢?
你只要能强制刷新全部, 就能按你的想法绘制了.
你说的是OnCtlControl还是DrawItem的方法?
我用Edit Control做了一个,代码是这样
HBRUSH CMyEdit::CtlColor(CDC* pDC, UINT nCtlColor)
{
// TODO: 在此更改 DC 的任何特性
if(((this->GetDlgCtrlID() == IDC_EDIT1) && (nCtlColor == CTLCOLOR_EDIT))||
((this->GetDlgCtrlID() == IDC_EDIT2) && (nCtlColor == CTLCOLOR_EDIT))||
((this->GetDlgCtrlID() == IDC_EDIT3) && (nCtlColor == CTLCOLOR_EDIT)))
{
if((this->GetDlgCtrlID() == IDC_EDIT1) && (nCtlColor == CTLCOLOR_EDIT)&&(ptrDlg->uintID==1))
{
COLORREF clr = RGB(0,0,0);
pDC->SetTextColor(clr);
clr = RGB(255,0,0);
pDC->SetBkColor(clr);
m_bkBrush1 = ::CreateSolidBrush(clr);
return m_bkBrush1;
}
else
{
COLORREF clr = RGB(0,0,0);
pDC->SetTextColor(clr);
clr = RGB(255,255,255);
pDC->SetBkColor(clr);
m_bkBrush01 = ::CreateSolidBrush(clr);
return m_bkBrush01;
} if((this->GetDlgCtrlID() == IDC_EDIT2) && (nCtlColor == CTLCOLOR_EDIT)&&(ptrDlg->uintID==2))
{
COLORREF clr = RGB(0,0,0);
pDC->SetTextColor(clr);
clr = RGB(255,0,0);
pDC->SetBkColor(clr);
m_bkBrush2 = ::CreateSolidBrush(clr);
return m_bkBrush2;
}
else
{
COLORREF clr = RGB(0,0,0);
pDC->SetTextColor(clr);
clr = RGB(255,255,255);
pDC->SetBkColor(clr);
m_bkBrush02 = ::CreateSolidBrush(clr);
return m_bkBrush02;
} if((this->GetDlgCtrlID() == IDC_EDIT3) && (nCtlColor == CTLCOLOR_EDIT)&&(ptrDlg->uintID==3))
{
COLORREF clr = RGB(0,0,0);
pDC->SetTextColor(clr);
clr = RGB(255,0,0);
pDC->SetBkColor(clr);
m_bkBrush3 = ::CreateSolidBrush(clr);
return m_bkBrush3;
}
else
{
COLORREF clr = RGB(0,0,0);
pDC->SetTextColor(clr);
clr = RGB(255,255,255);
pDC->SetBkColor(clr);
m_bkBrush03 = ::CreateSolidBrush(clr);
return m_bkBrush03;
}
}
// TODO: 如果不应调用父级的处理程序,则返回非 null 画笔
else
return NULL;
}然后我在响应鼠标左键双击函数里用UpdateWindow()来更新,有趣的是,在第一个if里的3个if else语句,哪个放在前就对应只有那个Edit控件会变颜色…………用InvalidateRect也试过,还是一样的……
上面代码有个问题,我第一个else里都能返回,所以后面的都无法改变,把代码改成这样就能都变颜色了:
HBRUSH CMyEdit::CtlColor(CDC* pDC, UINT nCtlColor)
{
// TODO: 在此更改 DC 的任何特性
//if(((this->GetDlgCtrlID() == IDC_EDIT1) && (nCtlColor == CTLCOLOR_EDIT))||
// ((this->GetDlgCtrlID() == IDC_EDIT2) && (nCtlColor == CTLCOLOR_EDIT))||
// ((this->GetDlgCtrlID() == IDC_EDIT3) && (nCtlColor == CTLCOLOR_EDIT)))
//{
if((this->GetDlgCtrlID() == IDC_EDIT2) && (nCtlColor == CTLCOLOR_EDIT))
{
if(ptrDlg->uintID==2)
{
COLORREF clr = RGB(0,0,0);
pDC->SetTextColor(clr);
clr = RGB(255,0,0);
pDC->SetBkColor(clr);
m_bkBrush2 = ::CreateSolidBrush(clr);
return m_bkBrush2;
}
else
{
COLORREF clr = RGB(0,0,0);
pDC->SetTextColor(clr);
clr = GetSysColor(COLOR_3DFACE);
pDC->SetBkColor(clr);
m_bkBrush02 = ::CreateSolidBrush(clr);
return m_bkBrush02;
}
}
if((this->GetDlgCtrlID() == IDC_EDIT3) && (nCtlColor == CTLCOLOR_EDIT))
{
if(ptrDlg->uintID==3)
{
COLORREF clr = RGB(0,0,0);
pDC->SetTextColor(clr);
clr = RGB(255,0,0);
pDC->SetBkColor(clr);
m_bkBrush3 = ::CreateSolidBrush(clr);
return m_bkBrush3;
}
else
{
COLORREF clr = RGB(0,0,0);
pDC->SetTextColor(clr);
clr = GetSysColor(COLOR_3DFACE);
pDC->SetBkColor(clr);
m_bkBrush03 = ::CreateSolidBrush(clr);
return m_bkBrush03;
}
} if((this->GetDlgCtrlID() == IDC_EDIT1) && (nCtlColor == CTLCOLOR_EDIT))
{
if(ptrDlg->uintID==1)
{
COLORREF clr = RGB(0,0,0);
pDC->SetTextColor(clr);
clr = RGB(255,0,0);
pDC->SetBkColor(clr);
m_bkBrush1 = ::CreateSolidBrush(clr);
return m_bkBrush1;
}
else
{
COLORREF clr = RGB(0,0,0);
pDC->SetTextColor(clr);
clr = GetSysColor(COLOR_3DFACE);
pDC->SetBkColor(clr);
m_bkBrush01 = ::CreateSolidBrush(clr);
return m_bkBrush01;
}
}
//}
// TODO: 如果不应调用父级的处理程序,则返回非 null 画笔
//else
return NULL;
}但是还存在个问题,响应不及时,比如我一开始点了第一个Edit控件,第一个控件变红了,但是当我点第二个控件时,第二个控件是变红了,但是第一个控件还是红的,需要我把鼠标移到第一个控件的位置才能促使第一个控件变回原来的颜色……就像你说的,只是重绘了有改变的地方。
还有个问题,如果Edit控件里初始时有内容,那恢复颜色时只能恢复中间一块,像这样:
周末可以给你写个
这么好!!!
我有三个ListBox,不过内容都只有一行我想实现鼠标双击选中的效果,不要单击选中,要双击,并且在三个ListBox之间是单选的,可以随意切换选择。选中以后ListBox的背景要变色,当然切换选项后得变回原来的颜色。其实我是不知道该用什么控件实现这样的效果才这么做的……我在三个控件里会实时地显示数据,鼠标双击其中一个控件,即选中该控件显示的这类数据并做一些输出操作之类的。要是没空也欢迎一起讨论~~~~
用ListBox反而不合适,因为还要控制ListBox的高度,如果高度高于1条记录或小于1条记录反倒不和xie
另外如果你要用ListBox可以就用一个,干嘛要3个?ListBox也可以画的很小或者很大:
因为我要实时地显示一些数据,而选择是根据数据的内容而产生的动作,如果在单选按钮的内容里显示数据不是有点奇怪么。
不过我自己也觉得用ListBox有点小题大做的感觉,也因为不太会弄,所以最后选择用EditControl,但是Edit控件又会存在刷新不及时等问题,如我在15、16楼说的一样。。
注意同一个时刻, 只有 一个 实例 是 有效的 !
所以点击 1 , 1 变 红, 点击 2 ,2 变 红, 但 1 不会 变 , 因为 这时你的 代码 只对 2 有效,
你的目的是以 一个 edit 实例 来改变 3个 edit 实例的 状态,所以 这个 edit 要 能 存取 兄弟 edit 。
。也就是说 这个 edit 类 , 必须 保存 所有 实例的 信息(类的 静态成员 变量)
BEGIN_MESSAGE_MAP(CAlertColoredListCtrl, CListCtrl)
ON_NOTIFY_REFLECT(NM_CUSTOMDRAW, &CAlertColoredListCtrl::OnNMCustomdraw)
//ON_WM_ERASEBKGND()
END_MESSAGE_MAP()
{
*pResult = 0; LPNMLVCUSTOMDRAW lplvcd = (LPNMLVCUSTOMDRAW)pNMHDR;
int iRow = lplvcd->nmcd.dwItemSpec; switch(lplvcd->nmcd.dwDrawStage)
{
case CDDS_PREPAINT :
{
*pResult = CDRF_NOTIFYITEMDRAW;
return;
} // Modify item text and or background
case CDDS_ITEMPREPAINT:
{
lplvcd->clrText = RGB(0,0,0);
// If you want the sub items the same as the item,
// set *pResult to CDRF_NEWFONT
*pResult = CDRF_NOTIFYSUBITEMDRAW;
return;
} // Modify sub item text and/or background
case CDDS_SUBITEM | CDDS_PREPAINT | CDDS_ITEM:
{
COLORREF clrNewTextColor, clrNewBkColor; //int nItem = static_cast<int>( pLVCD->nmcd.dwItemSpec ); POSITION pos = GetFirstSelectedItemPosition();
int index = GetNextSelectedItem(pos); if (index == iRow)//如果要刷新的项为当前选择的项,则将文字设为白色,背景色设为蓝色
{
clrNewTextColor = RGB(255,255,255); //Set the text to white
clrNewBkColor = RGB(49,106,197); //Set the background color to blue
lplvcd->clrText = clrNewTextColor;
lplvcd->clrTextBk = clrNewBkColor;
}
else
{
//if(iRow %2){
// lplvcd->clrTextBk = m_colRow2;
//}
//else{
// lplvcd->clrTextBk = m_colRow1;
//}
} //未查看的报警信息以红色字体显示
if (-1 != iRow)
{
bool bRead = true;
int itemData = GetItemData(iRow);
std::vector<QueryResGuid>::iterator iter;
CMainFrame *pFrame = (CMainFrame *)AfxGetApp()->GetMainWnd();
for (iter=pFrame->GetAlertView()->m_realAlertGuidList.begin();
iter!=pFrame->GetAlertView()->m_realAlertGuidList.end(); iter++)
{
if (itemData == iter->index)
{
bRead = iter->readFlag;
break;
}
} if (false == bRead)
{
clrNewTextColor = RGB(255,0,0);
lplvcd->clrText = clrNewTextColor;
}
} *pResult = CDRF_DODEFAULT;
return;
}
}
}
那OnCtlColor也是同一时刻只对一个实例有效是么?所以才会出现当我点击了2,我要移到鼠标到1时才会出现1变回原来颜色的情况?是在鼠标移动过去才进行了刷新?
实例的成员函数只对 当前 实例 有效。
请 深刻理解 这句话。
只有类的 静态成员 才是 所有实例 共享的
1.
class CMyEdit : public CEdit
{
static int m_CurrentID; // 类变量
2.
// CMyEdit
int CMyEdit::m_CurrentID=0;// 初始化
3.
void CMyEdit::OnLButtonDblClk(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
m_CurrentID=GetDlgCtrlID();
GetParent()->Invalidate();// 叫对话框 发 3 个 edit repaint
CEdit::OnLButtonDblClk(nFlags, point);
}4.
HBRUSH CMyEdit::CtlColor(CDC* pDC, UINT nCtlColor)
{
// TODO: Change any attributes of the DC here
COLORREF clr=0;
int CurrentID=GetDlgCtrlID();
if(CurrentID == m_CurrentID)
{
clr=RGB(255,0,0);
}
else
{
clr=RGB(255,255,255);
}
pDC->SetBkMode(TRANSPARENT);
return ::CreateSolidBrush(clr);//NULL;
}
其实 有2个问题:
1 如果 对话框 有 WS_CLIPCHILDREN 属性, 那么 这句 就 无效了
2 如果 对话框 有很多 控件, 都 重绘 就不好了。
所以 :
void CMyEdit::OnLButtonDblClk(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
if(m_CurrentID==0)
{
m_CurrentID=GetDlgCtrlID();// only for this
m_CurrentPedit=this; // this window
Invalidate(); // re-paint this
}
else
{
m_CurrentPedit->Invalidate();// re-paint last
m_CurrentID=GetDlgCtrlID(); // only for this
m_CurrentPedit=this; // this window
Invalidate(); // re-paint this
} CEdit::OnLButtonDblClk(nFlags, point);
}m_CurrentPedit=this; 定义为:
class CMyEdit : public CEdit
{
static int m_CurrentID;
static CWnd *m_CurrentPedit;
初始化为:
int CMyEdit::m_CurrentID=0;
CWnd *CMyEdit::m_CurrentPedit=0;这样 双击 不同 edit 时 , 先 叫 前一个 edit re-paint
#if !defined(AFX_MYRADIO_H__4BEBE4F2_3B3B_443D_B114_5AFADE5C47F3__INCLUDED_)
#define AFX_MYRADIO_H__4BEBE4F2_3B3B_443D_B114_5AFADE5C47F3__INCLUDED_#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// MyRadio.h : header file
///////////////////////////////////////////////////////////////////////////////
// CMyRadio windowclass CMyRadio : public CButton
{
// Construction
public:
CMyRadio();// Attributes
public:// Operations
public:// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CMyRadio)
public:
virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct);
protected:
virtual void PreSubclassWindow();
//}}AFX_VIRTUAL// Implementation
public:
virtual ~CMyRadio(); // Generated message map functions
protected:
//{{AFX_MSG(CMyRadio)
// NOTE - the ClassWizard will add and remove member functions here.
//}}AFX_MSG DECLARE_MESSAGE_MAP()
};///////////////////////////////////////////////////////////////////////////////{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.#endif // !defined(AFX_MYRADIO_H__4BEBE4F2_3B3B_443D_B114_5AFADE5C47F3__INCLUDED_)// MyRadio.cpp : implementation file
//#include "stdafx.h"
#include "Radio.h"
#include "MyRadio.h"#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif/////////////////////////////////////////////////////////////////////////////
// CMyRadioCMyRadio::CMyRadio()
{
}CMyRadio::~CMyRadio()
{
}
BEGIN_MESSAGE_MAP(CMyRadio, CButton)
//{{AFX_MSG_MAP(CMyRadio)
// NOTE - the ClassWizard will add and remove mapping macros here.
//}}AFX_MSG_MAP
END_MESSAGE_MAP()/////////////////////////////////////////////////////////////////////////////
// CMyRadio message handlersvoid CMyRadio::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{
// TODO: Add your code to draw the specified item
CRect rcItem=lpDrawItemStruct->rcItem;
CDC *pDC=CDC::FromHandle(lpDrawItemStruct->hDC);
BOOL bFocus=lpDrawItemStruct->itemState&ODS_FOCUS;
CString strCaption;
GetWindowText(strCaption);
if(bFocus)
{
pDC->FillSolidRect(&rcItem,RGB(255,0,0));
pDC->SetTextColor(RGB(0,255,0));
}
else
{
pDC->FillSolidRect(&rcItem,GetSysColor(COLOR_BTNFACE));
pDC->SetTextColor(RGB(0,0,0));
}
CSize szText = pDC->GetOutputTextExtent(strCaption);
CRect rcText;
rcText.left = (rcItem.Width()-szText.cx)/2;
rcText.top = (rcItem.Height()-szText.cy)/2;
rcText.right = rcText.left + szText.cx;
rcText.bottom = rcText.top + szText.cy;
pDC->DrawText(strCaption,&rcText,DT_LEFT);
}void CMyRadio::PreSubclassWindow()
{
// TODO: Add your specialized code here and/or call the base class
ModifyStyle(0,BS_OWNERDRAW);
CButton::PreSubclassWindow();
}多个Radio设置如下Push-like属性,然后关联上CMyRadio变量,且其中一个勾选有组属性(Group)就OK了
HBRUSH CMyEdit::CtlColor(CDC* pDC, UINT nCtlColor)
{
// TODO: Change any attributes of the DC here
COLORREF clr=0;
if(GetDlgCtrlID() == m_CurrentID)
{
clr=RGB(255,0,0);
pDC->SetBkMode(TRANSPARENT);
return ::CreateSolidBrush(clr);//NULL;
}
if(GetDlgCtrlID() == IDC_EDIT1)
{
clr=RGB(0,200,255);
} if(GetDlgCtrlID() == IDC_EDIT2)
{
clr=RGB(128,255,0);
}
if(GetDlgCtrlID() == IDC_EDIT3)
{
clr=RGB(255,128,0);
}
pDC->SetBkMode(TRANSPARENT);
return ::CreateSolidBrush(clr);//NULL;
}
结果:
谢谢你的回复,不过最后我还是决定用EditControl来做了~!