一、void CStaticAS::OnPaint()
{
CPaintDC dc(this); // device context for painting
CRect rect;
GetClientRect(&rect);
CFont myFont;
myFont.CreatePointFont (120,_T("宋体"));
CFont *pOldFont=(CFont *)dc.SelectObject (&myFont);
dc.SetBkMode(TRANSPARENT);
//dc.SetTextColor(RGB(255,255,0));
CString StrWndText;
GetWindowText(StrWndText);
dc.DrawText(/*"I LOVE YOU"*/StrWndText, rect, DT_LEFT|DT_VCENTER|DT_SINGLELINE);
// dc.SetBkMode (OPAQUE);
dc.SelectObject (pOldFont);
myFont.DeleteObject ();
// Do not call CStatic::OnPaint() for painting messages
}
二、控件使用
在Parent Wnd对应的窗体上放上一个static,并绑定如下变量
CString m_Str;
CStaticAS m_Stc;
父窗体中提供专门函数:
void CDialingBoxDlg::SetContactName(CString StrContactName)
{
CRect CtrlRt;
m_Stc.GetWindowRect(CtrlRt);
ScreenToClient(CtrlRt);
InvalidateRect(CtrlRt);//point A
//Invalidate();//point B
m_Str=StrContactName;
UpdateData(FALSE);
}
Invalid()操作一定要在改变m_Str之前,否则static将在父窗体上留下灰色的区域。
使用point B处也能行。
point A处避免刷新整个窗口,而仅仅刷控件所在区域,较之Point B处更为高效。
三、模仿skype IM时的应用
有一种情况需要考虑:即,如果模仿skype那样的界面——用户拨号后出现并切换至“正在拨号”对话框,用户若挂断,则“正在拨号”对话框停留若干时间后自动消失,且界面切回原来的页面。
利用Tab页面不难实现。主要是以delete pCWnd与m_wndView.SendMessage(WM_NOTIFY,IDC_TABCTRL,(LPARAM)&nh);来实现窗体的删除和切换。
在上述代码所在的函数中,若不加以修改,在窗体消失之前Static控件会留下灰色的底色。必须作如下处理
在delete pWnd;之前,需要调用pWnd->UpdateWindow(),如此即可。
需要指出的是:此前的Invalidate/InvalidateRect仅仅计算无效矩形,而UpdateWindow()才能强行发送一个WM_PAINT消息。如果强行SendMessage一个WM_PAINT则将会引发不可预测的问题。WM_PAINT消息比较特殊,不存在于windows message queue中,而是windows内部的一个标志为决定是否需要PAINT。在系统相对空闲时,会根据标志为自行去PAINT。个人猜想,是否是在WM_DESTROY消息进入队列时,便不考察那个标志位了,除非强制性地以UpdateWindow()去修改标志位。
四、经试验,该方法对于绑定CButton的checkbox也能使其文字透明。
{
CPaintDC dc(this); // device context for painting
CRect rect;
GetClientRect(&rect);
CFont myFont;
myFont.CreatePointFont (120,_T("宋体"));
CFont *pOldFont=(CFont *)dc.SelectObject (&myFont);
dc.SetBkMode(TRANSPARENT);
//dc.SetTextColor(RGB(255,255,0));
CString StrWndText;
GetWindowText(StrWndText);
dc.DrawText(/*"I LOVE YOU"*/StrWndText, rect, DT_LEFT|DT_VCENTER|DT_SINGLELINE);
// dc.SetBkMode (OPAQUE);
dc.SelectObject (pOldFont);
myFont.DeleteObject ();
// Do not call CStatic::OnPaint() for painting messages
}
二、控件使用
在Parent Wnd对应的窗体上放上一个static,并绑定如下变量
CString m_Str;
CStaticAS m_Stc;
父窗体中提供专门函数:
void CDialingBoxDlg::SetContactName(CString StrContactName)
{
CRect CtrlRt;
m_Stc.GetWindowRect(CtrlRt);
ScreenToClient(CtrlRt);
InvalidateRect(CtrlRt);//point A
//Invalidate();//point B
m_Str=StrContactName;
UpdateData(FALSE);
}
Invalid()操作一定要在改变m_Str之前,否则static将在父窗体上留下灰色的区域。
使用point B处也能行。
point A处避免刷新整个窗口,而仅仅刷控件所在区域,较之Point B处更为高效。
三、模仿skype IM时的应用
有一种情况需要考虑:即,如果模仿skype那样的界面——用户拨号后出现并切换至“正在拨号”对话框,用户若挂断,则“正在拨号”对话框停留若干时间后自动消失,且界面切回原来的页面。
利用Tab页面不难实现。主要是以delete pCWnd与m_wndView.SendMessage(WM_NOTIFY,IDC_TABCTRL,(LPARAM)&nh);来实现窗体的删除和切换。
在上述代码所在的函数中,若不加以修改,在窗体消失之前Static控件会留下灰色的底色。必须作如下处理
在delete pWnd;之前,需要调用pWnd->UpdateWindow(),如此即可。
需要指出的是:此前的Invalidate/InvalidateRect仅仅计算无效矩形,而UpdateWindow()才能强行发送一个WM_PAINT消息。如果强行SendMessage一个WM_PAINT则将会引发不可预测的问题。WM_PAINT消息比较特殊,不存在于windows message queue中,而是windows内部的一个标志为决定是否需要PAINT。在系统相对空闲时,会根据标志为自行去PAINT。个人猜想,是否是在WM_DESTROY消息进入队列时,便不考察那个标志位了,除非强制性地以UpdateWindow()去修改标志位。
四、经试验,该方法对于绑定CButton的checkbox也能使其文字透明。