VS2010 MFC中控件、对话框等背景颜色动态修改的方法
通過類向導,或者手動添加消息:WM_CTLCOLOR,其消息響應函數為:
afx_msg HBRUSH OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)- 1
- 2
在每個控件開始繪制之前,都會向其父窗口發送WM_CTLCOLOR通告消息,在該消息的處理函數中,可以設置控件顯示文本的前景色、背景色以及字體。該消息處理函數還要求返回一個畫刷的句柄,用于在控件具體的繪制之前擦除其客戶區。當窗口重繪時,也會重新繪制每個控件,從而分別調用該函數,這就給了動態修改控件相關顏色特性的機會。
比如在對應的控件下的OnCtrColor函數中寫入:
?pDC->SetTextColor(RGB(255, 0, 0)); //設置文本前景色
pDC->SetBkColor(RGB(255, 255, 255)); //設置文本背景色
pDC->SetBkMode(TRANSPARENT); //TRANSPARENT或OPAQUE
pDC->SelectObject(...)
- 1
- 2
- 3
- 4
- 5
就可以實現修改某個控件的繪制屬性。具體的實現可以參考下面的一段代碼:
?//
//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;
}
?
當然如果是修改dialog的屬性,可以直接在最后的return上返回一個畫刷,填充dialog的背景顏色。
上面這種方法只是一種靜態的修改,因為所有的屬性都是一次性設定好了,似乎沒有根據情況進行改變的可能。這個是時候就要用到上面所提到的一種方法:強迫窗口重繪,可用的函數有Invalidate()和UpdateWindow(),兩者的區別如下:
Invalidate在消息隊列中加入一條WM_PAINT消息,其無效區為整個客戶區。而UpdateWindow直接發送一個WM_PAINT消息,其無效區范圍就是消息隊列中WM_PAINT消息(最多只有一條)的無效區。效果很明顯,調用Invalidate之后,屏幕不一定馬上更新,因為WM_PAINT消息不一定在隊列頭部,而調用UpdateWindow會使WM_PAINT消息馬上執行的,繞過了消息隊列。如果你調用Invalidate之后想馬上更新屏幕,那就加上UpdateWindow()這條語句。
那么剩下的事情就比較簡單了,可以通過設置一個COLORREF m_BrushColor;的成員變量,在調用窗口重繪的函數之前,修改m_BrushColor,然后在OnCtlColor函數中將畫刷的顏色創建為該m_BrushColor:
?m_bkBrush.DeleteObject();
m_bkBrush.CreateSolidBrush(m_BrushColor); //創建一把黃色的背景刷子
?
下面是我所修改的函數:
?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))
{
//此處設置背景的顏色
m_bkBrush.DeleteObject();
m_bkBrush.CreateSolidBrush(RGB(0,255,0)); //創建一把黃色的背景刷子
return m_bkBrush;
}
if((CTLCOLOR_BTN)&&(pWnd->GetDlgCtrlID()==IDOK))
{
m_bkBrush.DeleteObject();
m_bkBrush.CreateSolidBrush(RGB(0,255,0)); //創建一把黃色的背景刷子
return m_bkBrush;
}
m_bkBrush.DeleteObject();
m_bkBrush.CreateSolidBrush(m_BrushColor); //創建一把黃色的背景刷子
// TODO: 如果默認的不是所需畫筆,則返回另一個畫筆
return m_bkBrush;
}
通過上面的函數,可以實現對對話框中的控件或者對話框的背景顏色進行動態修改
總結
以上是生活随笔為你收集整理的VS2010 MFC中控件、对话框等背景颜色动态修改的方法的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: MPEG(mpeg1,mpeg2,mpe
- 下一篇: 互联网商业模式:增值还是减值?