资源描述
设置CEdit控件背景为透明 C++ MFC
分类: Windows编程 非发表文章 代码片段2009-02-07 17:30 835人阅读 评论(0) 收藏 举报
view plain
1. HBRUSH CPenWidthsDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
2. {
3. // Call the base class implementation first! Otherwise, it may
4. // undo what we''re trying to accomplish here.
5. HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);
6.
7. // Are we painting the IDC_MYSTATIC control? We can use
8. // CWnd::GetDlgCtrlID() to perform the most efficient test.
9. if (pWnd->GetDlgCtrlID() == IDC_EDIT)
10. {
11. // Set the text color to red
12. pDC->SetTextColor(RGB(255, 0, 0));
13.
14. // Set the background mode for text to transparent
15. // so background will show thru.
16. pDC->SetBkMode(TRANSPARENT);
17.
18. // Return handle to our CBrush object
19. return (HBRUSH)::GetStockObject(NULL_BRUSH);
20. }
21.
22. return hbr;
23. }
、
MFC中Static控件透明,重影,长度问题
2011-06-10 23:11
做MFC编程,Static控件是会经常用到的了,而使Static控件背景透明,以及改变文本的内容、字体、颜色等属性,都是会比较容易碰到的情况。
王道做法当然是继承CStatic然后重载OnPaint(),完全自己来画,这样能够获得最大的灵活性,但就是比较麻烦,像我这种比较懒的,就更喜欢用下面的懒方法了。
同样创建一个CStatic的派生类,处理父窗口的反射消息WM_CTLCOLOR,即添加HBRUSH CtlColor(CDC *pDC, UINT nCtlColor)这个消息映射函数。注意,不是HBRUSH OnCtlColor(CDC *pDC, CWnd *pWnd, UINT nCtlColor)!我也不知道具体原理,反正我用后者从来没成功过,甚至程序都不会运行到里面。。。
其实还有一个方法,就是处理父窗口的OnCtlColor(),更简单一点,但是不符合封装的原则,所以这里就不提了。
C++代码
1.HBRUSH CSample::CtlColor(CDC* pDC, UINT nCtlColor)
2.{
3. // TODO: Change any attributes of the DC here
4. pDC->SetBkMode(TRANSPARENT); // 设置透明背景
5. pDC->SetTextColor(RGB(0, 0, 255)); // 设置文本颜色
6.
7. // TODO: Return a non-NULL brush if the parent's handler should not be called
8. return (HBRUSH)GetStockObject(HOLLOW_BRUSH); // 返回透明画刷
9.}
通过上述代码,就可以得到彩色的文本以及透明的背景,但是,还存在一个问题,当该Static控件的文本内容或者属性,在运行过程中发生变化的时候,由于背景一直没有擦除(为了实现透明),会出现重影,导致文本模糊成一团。
解决方法是,让父窗口进行重绘更新,对,不要看错了,是控件所属的父窗口,而不是控件本身,让控件本身重绘也不会解决问题的,同样我也不太清楚原理。。。
这里还会引出一个问题,如果重绘整个父窗口,由于GDI并不内嵌双缓冲,势必造成严重的闪烁问题,解决办法当然是只让父窗口重绘控件所占的部分,其他部分不进行重绘,代码如下:
C++代码
1.void CSample::SetText(const TCHAR *pszText)
2.{
3. this->SetWindowText(pszText);
4.
5. RECT stRect;
6. // 获取控件位置
7. this->GetWindowRect(&stRect);
8. // 重要!调用父窗口的S2C函数进行坐标转换
9. this->GetParent()->ScreenToClient(&stRect);
10. // 重绘控件所在区域,在这里擦除背景
11. this->GetParent()->InvalidateRect(&stRect, true);
12.}
这样就能够实现动态改变文本属性而不出现重影现象,注意这里调用了父窗口的ScreenToClient()函数来进行坐标的转换,调用控件本身的S2C函数的话,得到的坐标无法用来进行下一步的重绘工作。
现在还有一个比较隐蔽的问题,就是文本字符串的长度,如果新的字符串的长度比原来的长,而之前拖放Static控件长度又不足的时候,就会造成超出的部分无法显示,当然你大可以在拖放的时候就尽量弄得长一点,但是如果能随着文本内容而自动调整控件长度,那不是会好得多么。
为了实现这样的效果,上面的代码要修改如下:
C++代码
1.void CSample::SetText(const TCHAR *pszText)
2.{
3. CDC *pDC = this->GetDC();
4. // 获取文本在当前绘图环境下所占的宽度和高度
5. CSize clSize = pDC->GetTextExtent(pszText, _tcslen(pszText));
6.
7. RECT stRect;
8.
9. // 获取控件当前矩形区域
10. this->GetWindowRect(&stRect);
11. // 调整宽度为新文本所占宽度
12. stRect.right = stRect.left + clSize.cx;
13. // 重要!调用父窗口S2C函数转换坐标
14. this->GetParent()->ScreenToClient(&stRect);
15. // 调整控件大小以适应新文本
16. this->MoveWindow(&stRect);
17.
18. // 重绘控件以避免重影
19. this->GetWindowRect(&stRect);
20. this->GetParent()->ScreenToClient(&stRect);
21. this->GetParent()->InvalidateRect(&stRect, true);
22.}
同样,这里也是调用父窗口的S2C函数,这样得到的坐标才能正确使用。代码经过上述修改,就实现了控件随文本动态调整宽度的效果。
以上只是实现Static背景透明、更改文本颜色以及动态调整控件大小的简单演示,实际的应用中可能还需要考虑很多情况,适当修改代码,但基本原理是不变的。当然要获得最大的灵活性,还是得自己来绘制了 - -
最简单的方法是修改完
GetDlgItem(IDC_2222)->SetWindowText("好好好");
GetDlgItem(IDC_2222)->ShowWindow(SW_HIDE);
GetDlgItem(IDC_2222)->ShowWindow(SW_SHOW);
BRUSH CMyDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);
switch(pWnd->GetDlgCtrlID())
{
case IDC_STATICC:
pDC->SetBkMode(TRANSPARENT);
pDC->SetTextColor(RGB(0,255,0));
return (HBRUSH)GetStockObject(HOLLOW_BRUSH);
break;
case IDC_STATICA:
pDC->SetBkMode(TRANSPARENT);
pDC->SetTextColor(RGB(84,226,95));
return (HBRUSH)GetStockObject(HOLLOW_BRUSH);
break;
case IDC_STATICB:
pDC->SetBkMode(TRANSPARENT);
pDC->SetTextColor(RGB(84,226,95));
return (HBRUSH)GetStockObject(HOLLOW_BRUSH);
break;
/* case IDC_STATICD:
pDC->SetBkMode(TRANSPARENT);
pDC->SetTextColor(RGB(0,255,0));
return (HBRUSH)GetStockObject(HOLLOW_BRUSH);
break; */
case IDC_EDIT1:
pDC->SetTextColor(RGB(0,0,0));
break;
case IDC_STATICQQQ:
pDC->SetBkMode(TRANSPARENT);
pDC->SetTextColor(RGB(84,226,95));
return (HBRUSH)GetStockObject(HOLLOW_BRUSH);
break;
}
return hbr;
}
MFC中设置静态文本的字体颜色、背景透明以及解决字体重叠
分类: VC++2010-11-10 10:42 1402人阅读 评论(6) 收藏 举报
原创:qsycn
改变static的颜色和设为背景透明可以在父窗口的WM_CTLCOLOR中实现(即HBRUSH OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor))
将static设为背景透明时,改变该控件的文本将会出现文字重叠的现象。
其实设置为透明背景也就是在static重画背景时返回一个空的刷子而已,所以你改变文本并没有改变上次残留的背景,从而导致重叠现象。
为了解决这个问题,我们可以让父窗口重绘此区域。
以下是我的解决方法:
1. 从CStatic继承一个类CStaticEx
2. 增加WM_CTLCOLOR的消息反射(把很多事情留给父窗口处理并不是一件推荐的事,就让CStaticEx自己处理这件事,这样还可以不影响到其它的static)
3. 处理WM_SETTEXT,当文本改变时,重绘父窗口的该控件所在区域
view plain
1. // StaticEx.cpp : implementation file
2. //
3.
4. #include "stdafx.h"
5. #include "StaticEx.h"
6.
7.
8. // CStaticEx
9.
10. IMPLEMENT_DYNAMIC(CStaticEx, CStatic)
11.
12. CStaticEx::CStaticEx()
13. {
14.
15. }
16.
17. CStaticEx::~CStaticEx()
18. {
19. }
20.
21.
22. BEGIN_MESSAGE_MAP(CStaticEx, CStatic)
23. ON_WM_CTLCOLOR_REFLECT()
24. END_MESSAGE_MAP()
25.
26.
27.
28. // CStaticEx message handlers
29.
30.
31.
32. HBRUSH CStaticEx::CtlColor(CDC* pDC, UINT /*nCtlColor*/)
33. {
34. // TODO: Change any attributes of the DC here
35. pDC->SetTextColor(RGB(255, 0, 0));//设置文字的颜色
36. pDC->SetBkMode(TRANSPARENT);//透明
37. return (HBRUSH)::GetStockObject(NULL_BRUSH);
38.
39. // TODO: Return a non-NULL brush if the parent''s handler should not be called
40. //return NULL;
41. }
42.
43. LRESULT CStaticEx::DefWindowProc(UINT message, WPARAM wParam, LPARAM lParam)
44. {
45. // TODO: Add your specialized code here and/or call the base class
46. if(message==WM_SETTEXT) {
47. CRect rect;
48. GetWindowRect(&rect);
49. CWnd* pParent = GetParent();
50. if(pParent) {
51. pParent->ScreenToClient(&rect);
52. pParent->InvalidateRect(&rect);
53. }
54. }
55.
56. return CStatic::DefWindowProc(message, wParam, lParam);
57. }
view plain
1. // StaticEx.h : header file
2. //
3.
4. #pragma once
5.
6.
7. // CStaticEx
8.
9. class CStaticEx : public CStatic
10. {
11. DECLARE_DYNAMIC(CStaticEx)
12.
13. public:
14. CStaticEx();
15. virtual ~CStaticEx();
16.
17. protected:
18. virtual LRESULT DefWindowProc(UINT message, WPARAM wParam, LPARAM lParam);
19.
20. protected:
21. DECLARE_MESSAGE_MAP()
22. afx_msg HBRUSH CtlColor(CDC* pDC, UINT /*nCtlColor*/);
23. };
创建对话框时,如何更改默认按扭,以及设置默认输入Edit
VS2005环境下(C++),用对话框编辑器,我在创建一个对话框时,想更改其默认的按扭,在不删除OK 和 Cancle 按扭下,我在重载OnInitDialog 中 用
SetDefID(IDC_CALC);
GetDlgItem(IDC_EXPNUM)->SetFocus();
来改变默许值,但是没有效果,请问该如何做。(删除OK和Cancle后默认按扭改了,默认输入没有改成我想要的输入框)
还有如何改变对话框中Tab键的顺序。如我添加的控件顺序为:Button->Edit->Button->Edit,运行后Tab键顺序也是这样。
但如果我在不删除控件重新添加下,想改成Edit->Edit->Button->Button该如何做?
我试过把控件的值改成我想要的顺序,但还是原来的没变!!!
展开阅读全文