VS2010 MFC中控件、对话框等背景颜色动态修改的方法
通過(guò)類向?qū)?#xff0c;或者手動(dòng)添加消息:WM_CTLCOLOR,其消息響應(yīng)函數(shù)為:
afx_msg HBRUSH OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)- 1
- 2
在每個(gè)控件開(kāi)始繪制之前,都會(huì)向其父窗口發(fā)送WM_CTLCOLOR通告消息,在該消息的處理函數(shù)中,可以設(shè)置控件顯示文本的前景色、背景色以及字體。該消息處理函數(shù)還要求返回一個(gè)畫刷的句柄,用于在控件具體的繪制之前擦除其客戶區(qū)。當(dāng)窗口重繪時(shí),也會(huì)重新繪制每個(gè)控件,從而分別調(diào)用該函數(shù),這就給了動(dòng)態(tài)修改控件相關(guān)顏色特性的機(jī)會(huì)。
比如在對(duì)應(yīng)的控件下的OnCtrColor函數(shù)中寫入:
?pDC->SetTextColor(RGB(255, 0, 0)); //設(shè)置文本前景色
pDC->SetBkColor(RGB(255, 255, 255)); //設(shè)置文本背景色
pDC->SetBkMode(TRANSPARENT); //TRANSPARENT或OPAQUE
pDC->SelectObject(...)
- 1
- 2
- 3
- 4
- 5
就可以實(shí)現(xiàn)修改某個(gè)控件的繪制屬性。具體的實(shí)現(xiàn)可以參考下面的一段代碼:
?//
//m_font1與m_font2為CTestDlg的成員,類型為CFont
//
BOOL CTestDlg::OnInitDialog()
{
......
// TODO: Add extra initialization here
m_font1.CreatePointFont(120, TEXT("Impact"));
m_font2.CreatePointFont(120, TEXT("Arial"));
......
}
HBRUSH CTestDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);
// TODO: Change any attributes of the DC here
if (nCtlColor == CTLCOLOR_STATIC)
{
switch (pWnd->GetDlgCtrlID())
{
case IDC_STATIC_1:
pDC->SetTextColor(RGB(255, 0, 0));
pDC->SetBkColor(RGB(255, 255, 255));
pDC->SetBkMode(TRANSPARENT);
pDC->SelectObject(&m_font1);
return (HBRUSH)::GetStockObject(BLACK_BRUSH);
break;
case IDC_STATIC_2:
pDC->SetTextColor(RGB(255, 255, 0));
pDC->SetBkColor(RGB(255, 255, 255));
pDC->SelectObject(&m_font2);
return (HBRUSH)::GetStockObject(BLACK_BRUSH);
break;
default:
break;
}
}
// TODO: Return a different brush if the default is not desired
return hbr;
}
?
當(dāng)然如果是修改dialog的屬性,可以直接在最后的return上返回一個(gè)畫刷,填充dialog的背景顏色。
上面這種方法只是一種靜態(tài)的修改,因?yàn)樗械膶傩远际且淮涡栽O(shè)定好了,似乎沒(méi)有根據(jù)情況進(jìn)行改變的可能。這個(gè)是時(shí)候就要用到上面所提到的一種方法:強(qiáng)迫窗口重繪,可用的函數(shù)有Invalidate()和UpdateWindow(),兩者的區(qū)別如下:
Invalidate在消息隊(duì)列中加入一條WM_PAINT消息,其無(wú)效區(qū)為整個(gè)客戶區(qū)。而UpdateWindow直接發(fā)送一個(gè)WM_PAINT消息,其無(wú)效區(qū)范圍就是消息隊(duì)列中WM_PAINT消息(最多只有一條)的無(wú)效區(qū)。效果很明顯,調(diào)用Invalidate之后,屏幕不一定馬上更新,因?yàn)閃M_PAINT消息不一定在隊(duì)列頭部,而調(diào)用UpdateWindow會(huì)使WM_PAINT消息馬上執(zhí)行的,繞過(guò)了消息隊(duì)列。如果你調(diào)用Invalidate之后想馬上更新屏幕,那就加上UpdateWindow()這條語(yǔ)句。
那么剩下的事情就比較簡(jiǎn)單了,可以通過(guò)設(shè)置一個(gè)COLORREF m_BrushColor;的成員變量,在調(diào)用窗口重繪的函數(shù)之前,修改m_BrushColor,然后在OnCtlColor函數(shù)中將畫刷的顏色創(chuàng)建為該m_BrushColor:
?m_bkBrush.DeleteObject();
m_bkBrush.CreateSolidBrush(m_BrushColor); //創(chuàng)建一把黃色的背景刷子
?
下面是我所修改的函數(shù):
?HBRUSH ChandControllerDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
HBRUSH hbr = CDialogEx::OnCtlColor(pDC, pWnd, nCtlColor);
// TODO: 在此更改 DC 的任何特性
if((CTLCOLOR_SCROLLBAR)&&(pWnd->GetDlgCtrlID()==IDC_SLIDER1 || pWnd->GetDlgCtrlID()==IDC_SLIDER2))
{
//此處設(shè)置背景的顏色
m_bkBrush.DeleteObject();
m_bkBrush.CreateSolidBrush(RGB(0,255,0)); //創(chuàng)建一把黃色的背景刷子
return m_bkBrush;
}
if((CTLCOLOR_BTN)&&(pWnd->GetDlgCtrlID()==IDOK))
{
m_bkBrush.DeleteObject();
m_bkBrush.CreateSolidBrush(RGB(0,255,0)); //創(chuàng)建一把黃色的背景刷子
return m_bkBrush;
}
m_bkBrush.DeleteObject();
m_bkBrush.CreateSolidBrush(m_BrushColor); //創(chuàng)建一把黃色的背景刷子
// TODO: 如果默認(rèn)的不是所需畫筆,則返回另一個(gè)畫筆
return m_bkBrush;
}
通過(guò)上面的函數(shù),可以實(shí)現(xiàn)對(duì)對(duì)話框中的控件或者對(duì)話框的背景顏色進(jìn)行動(dòng)態(tài)修改
總結(jié)
以上是生活随笔為你收集整理的VS2010 MFC中控件、对话框等背景颜色动态修改的方法的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: MPEG(mpeg1,mpeg2,mpe
- 下一篇: 互联网商业模式:增值还是减值?