方法一:
在OnPaint中StretchBlt
具體是:注釋掉CDialog::OnPaint()或放到結尾(原因何在呢?),並加入貼圖代碼
- void CqqqqqDlg::OnPaint()
- {
- if (IsIconic())
- {
- CPaintDC dc(this); // device context for painting
- SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);
- // Center icon in client rectangle
- int cxIcon = GetSystemMetrics(SM_CXICON);
- int cyIcon = GetSystemMetrics(SM_CYICON);
- CRect rect;
- GetClientRect(&rect);
- int x = (rect.Width() - cxIcon + 1) / 2;
- int y = (rect.Height() - cyIcon + 1) / 2;
- // Draw the icon
- dc.DrawIcon(x, y, m_hIcon);
- }
- else
- {
- //CDialog::OnPaint();//<span style="color:#6600cc;">注釋此句,如果不注釋的話,就放到結尾,原因何在呢?
- </span> //貼背景圖片
- CPaintDC dc(this);
- CBitmap bmpBk;
- bmpBk.LoadBitmapW(IDB_BITMAP_tempbk);
- //m_bmpBK.LoadBitmapW(IDB_BMPBK);
- BITMAP bmpSize;
- bmpBk.GetBitmap(&bmpSize);//獲取背景圖片尺寸
- CRect rect;
- GetClientRect(&rect);//獲取客戶區尺寸
- CDC dcMem;
- dcMem.CreateCompatibleDC(&dc);
- dcMem.SelectObject(&bmpBk);
- dc.StretchBlt(0,0,rect.Width(),rect.Height(),&dcMem,0,0,bmpSize.bmWidth,bmpSize.bmHeight,SRCCOPY);//將背景圖片拉伸或者壓縮copy至客戶區
- //貼背景圖片
- }
- }
執行效果截圖如下:
方法二:
在OnEraseBkgnd中StretchBlt
具體是:注釋掉return CDialog::OnEraseBkgnd(pDC);直接返回true(為什么不能返回這個要返回true呢?),代碼如下:
- BOOL CqqqqqDlg::OnEraseBkgnd(CDC* pDC)
- {
- // TODO: Add your message handler code here and/or call default
- //貼背景圖片
- CBitmap bmpBk;
- bmpBk.LoadBitmapW(IDB_BITMAP_tempbk);
- //m_bmpBK.LoadBitmapW(IDB_BMPBK);
- BITMAP bmpSize;
- bmpBk.GetBitmap(&bmpSize);//獲取背景圖片尺寸
- CRect rect;
- GetClientRect(&rect);//獲取客戶區尺寸
- CDC dcMem;
- dcMem.CreateCompatibleDC(pDC);
- dcMem.SelectObject(&bmpBk);
- pDC->StretchBlt(0,0,rect.Width(),rect.Height(),&dcMem,0,0,bmpSize.bmWidth,bmpSize.bmHeight,SRCCOPY);//將背景圖片拉伸或者壓縮copy至客戶區
- //貼背景圖片
- return true;
- //return CDialog::OnEraseBkgnd(pDC);
- }
效果與方法一相同,圖片就不貼了,參見上圖。
而且這里還有一個很有意思的現象,若在OnEraseBkgnd貼圖,在OnPaint()函數中不調用基類的OnPaint,即注釋掉CDialog::OnPaint(),則將界面隱藏后再顯示出來則控件全沒了,只有對話框以及背景。如下圖:
原因見《在OnPaint中必須調用一次BeginPaint和EndPaint,且也只能調用一次。》
方法三:
在OnCtlColor中返回帶有背景位圖的畫刷
具體是:
1、在頭文件中定一個背景刷
- public:
- CBrush m_brushBk;
2、在OnInitDialog中加入以下句
- // TODO: Add extra initialization here
- CBitmap bmp;
- bmp.LoadBitmap(IDB_BITMAP_tempbk);
- m_brushBk.CreatePatternBrush(&bmp);
- //m_brushBk.CreateSolidBrush(RGB(0,255,0)); //用純色作為背景
- bmp.DeleteObject();
3、在OnCtlColor函數中返回背景畫刷
- HBRUSH CXXXXXDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
- {
- HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);
- // TODO: Change any attributes of the DC here
- // TODO: Return a different brush if the default is not desired
- if(pWnd==this) //this代表當前對話框窗口
- {
- return m_brushBk;
- }
- return hbr;
- }
效果如下圖所示:
注意這個函數里面的if判斷,這個pWnd參數很關鍵。
我們看看,如果沒有這個if判斷,直接返回m_brushBk;會是什么結果呢,代碼如下:
- HBRUSH CqqqqqDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
- {
- HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);
- // TODO: Change any attributes of the DC here
- // TODO: Return a different brush if the default is not desired
- return m_brushBk;
- }
截圖如下:
看圖說話,不解釋,你懂的。
這種方法的缺點是不具備StretchBlt函數的圖片自動適應對話框(目標矩形)大小的功能。