zoukankan      html  css  js  c++  java
  • 新旧MFC版本CEdit透明的2种实现方法

    转载请注明来源:http://www.cnblogs.com/xuesongshu/

      最近修改了一下绘算法,因为没有总是绘制整个字符串的必要性。以有后空了,还会完善鼠标事件下的算法。

      MFC 4.2(Visual Studio 6)实现起来很方便,只需要在对话框类下处理WM_CTLCOLOR消息,然后以下代码即可:

      

    HBRUSH CAlphaEditboxDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor) 
    {
    	HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);
    	
    	// TODO: Change any attributes of the DC here
    	pDC->SetBkMode(TRANSPARENT);
    	hbr=(HBRUSH)GetStockObject(HOLLOW_BRUSH);
    	// TODO: Return a different brush if the default is not desired
    	return hbr;
    }
    

      然后在编辑控件的相关事件里调用一下Invalidate。

    void CAlphaEditboxDlg::OnKillfocusEditkey() 
    {
    	// TODO: Add your control notification handler code here
    	Invalidate();
    }
    
    void CAlphaEditboxDlg::OnKillfocusEditmessage() 
    {
    	// TODO: Add your control notification handler code here
    	Invalidate();
    }
    
    void CAlphaEditboxDlg::OnKillfocusEditpath() 
    {
    	// TODO: Add your control notification handler code here
    	Invalidate();
    }
    

      不要忘了,如果删除字符,要重绘一下背景哦。这里只罗列了一部分。

      新版的MFC可谓相当麻烦,因为把背景设为CLR_NONE或者画刷设为HOLLOW_BRUSH,微软会默认会制黑色背景,这一点,微软真是倒退了。废话少说了,编辑控件子类化无可避免了,一定要处理WM_PAINT、WM_CHAR、WM_LBUTTONDOWN、WM_LBUTTONUP这几个消息。如果你想去掉编辑控制自带的边框,还得处理WM_NCPAINT消息,不过这里什么代码都不写,目的是为避免执行默认的CDialogEx::OnNcPaint()方法给画上边框。下面代码实现基本的透明效果,正常输入没问题,如果你想要实现删除、选中与取消选中等功能,请追加处理WM_LBUTTONDOWN、WM_LBUTTONUP消息。

    //////////////////////////////////////////////////////////////////////////
    //绘制窗口。
    //////////////////////////////////////////////////////////////////////////
    void CMyEdit::OnPaint()
    {
    	PAINTSTRUCT ps;
    	TEXTMETRIC tm;
    	int nSelStart=0,nSelEnd=0,nDrawStart=0,nDrawLen=0,nTxtLen=0;
    	RECT r;
    	CBitmap b;
    	LPTSTR szData=(LPTSTR)calloc(1024,sizeof(TCHAR));
    	//指针赋值,不是二重指针,对此指针的操作不影响szData
    	LPTSTR szDraw=szData;
    	CPaintDC* d2=(CPaintDC*)BeginPaint(&ps);
    	CDC d1;
    	CFont f;
    	CWnd* p=GetParent();
    	nTxtLen=GetWindowText(szData,1024);
    	b.LoadBitmap(IDB_BITMAP1);
    	d1.CreateCompatibleDC(p->GetDC());
    	GetWindowRect(&r);
    	p->ScreenToClient(&r);
    	d1.SelectObject(b);
    	d2->BitBlt(0,0,r.right-r.left,r.bottom-r.top,&d1,r.left,r.top,SRCCOPY);
    	f.CreateFontIndirect(&m_lf);
    	d2->SelectObject(f);
    	d2->SetBkMode(TRANSPARENT);
    	d2->GetTextMetrics(&tm);
    	while(*szDraw++);
    	szDraw--;
    	nDrawStart=min(nTxtLen,(r.right-r.left)/tm.tmAveCharWidth);
    	nDrawLen=nDrawStart;
    	while (nDrawStart--)
    		szDraw--;
    	d2->TextOut(0,0,szDraw,nDrawLen);
    	d2->SelectObject(GetStockObject(NULL_BRUSH));
    	d2->SelectObject(CreatePen(PS_DOT,1,RGB(255,0,0)));
    	d2->Rectangle(0,0,r.right-r.left,r.bottom-r.top);
    	POINT pt;
    	pt=GetCaretPos();
    	pt.x=min(nTxtLen*tm.tmAveCharWidth,r.right-r.left);
    	SetCaretPos(pt);
    	delete szData;
    	EndPaint(&ps);
    }
    
    //////////////////////////////////////////////////////////////////////////
    //暂不处理粘滞按键和功能键这2种情况。
    //////////////////////////////////////////////////////////////////////////
    void CMyEdit::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags)
    {
    	TEXTMETRIC tm;
    	int nSelStart=0,nSelEnd=0,nDrawStart=0,nDrawLen=0,nTxtLen=0;
    	RECT r;
    	CBitmap b;
    	LPTSTR szData=(LPTSTR)calloc(1024,sizeof(TCHAR));
    	LPTSTR szInput=(LPTSTR)calloc(1024,sizeof(TCHAR));
    	//指针赋值,不是二重指针,对此指针的操作不影响szData
    	LPTSTR szDraw=szData;
    	CClientDC d2(this);
    	CDC d1;
    	CFont f;
    	CWnd* p=GetParent();
    	nTxtLen=GetWindowText(szData,1024);
    	wsprintf(szInput,L"%c",nChar);
    	lstrcat(szData,szInput);
    	SetWindowText(szData);
    	b.LoadBitmap(IDB_BITMAP1);
    	d1.CreateCompatibleDC(p->GetDC());
    	GetWindowRect(&r);
    	p->ScreenToClient(&r);
    	d1.SelectObject(b);
    	d2.BitBlt(0,0,r.right-r.left,r.bottom-r.top,&d1,r.left,r.top,SRCCOPY);
    	f.CreateFontIndirect(&m_lf);
    	d2.SelectObject(f);
    	d2.SetBkMode(TRANSPARENT);
    	d2.GetTextMetrics(&tm);
    	while(*szDraw++);
    	szDraw--;
    	nDrawStart=min(nTxtLen,(r.right-r.left)/tm.tmAveCharWidth);
    	nDrawLen=nDrawStart;
    	while (nDrawStart--)
    		szDraw--;
    	d2.TextOut(0,0,szDraw,nDrawLen);
    	d2.SelectObject(GetStockObject(NULL_BRUSH));
    	d2.SelectObject(CreatePen(PS_DOT,1,RGB(255,0,0)));
    	d2.Rectangle(0,0,r.right-r.left,r.bottom-r.top);
    	POINT pt;
    	pt=GetCaretPos();
    	pt.x=min(nTxtLen*tm.tmAveCharWidth,r.right-r.left);
    	SetCaretPos(pt);
    	delete szData;
    	delete szInput;
    	//CEdit::OnChar(nChar, nRepCnt, nFlags);
    }
    

      

      以上就是这些了,欢迎一起交流如何实现注释中写明的没有实现有功能。我是菜鸟,大虾请勿见笑。希望你能多多指点。

  • 相关阅读:
    HTML <form> 标签的 accept-charset 属性
    SpringMVC中Controller跳转到另一个Controller方法
    DIV层+CSS实现锁屏
    工作组模式下专用队列(Private Queue)如何引用远程队列路径
    stl之deque双端队列容器
    百度之星资格赛——Disk Schedule(双调旅行商问题)
    android 无线模式下使用ADB调试
    HDU
    NoSQL 数据库产品学习总结(一)
    ThinkPad E431怎样关闭触摸板
  • 原文地址:https://www.cnblogs.com/xuesongshu/p/2955564.html
Copyright © 2011-2022 走看看