關(guān)于MFC的Picture控件
(2009-10-21 22:12:33) 2009-10-04
前幾天的一個項目,需要在對話框上顯示一張圖片,所以首先想到使用Picture控件來顯示。但是這個東西以前沒有用過,又懶得查幫助,所以就純粹把它當(dāng)作顯示的Canvas,把它的DC取出來,把圖就給刷上去了。呵呵,說到底并沒有真正使用這個控件。不過即使這樣,圖像還是可以顯示,成功蒙混過關(guān)。
后來總覺得心里不踏實,于是總結(jié)了一下,發(fā)現(xiàn)這種做法確實不好。首先是這樣做的話,圖像邊界問題常常要自己考慮,否則一不小心,就把圖刷出界了。原先倒是有寫過一個視頻捕捉的程序,由于視頻流的每一幀是固定大小的,所以當(dāng)時更加偷懶,呵呵,直接搞一個裸奔的對話框,然后把圖像直接滿屏刷到對話框的DC中。這次之所以第一感覺就看上Picture控件,是期望它能幫我完成裁剪的功能。畢竟這次需要顯示的圖像的尺寸差異甚大,所以我希望固定圖片的顯示區(qū)域,超出部分就自動裁剪了多好。可惜沒有那么便宜的事情,光取一個DC就刷圖,MFC居然是不分青紅皂白直接往上刷,管它邊界在哪里,所以Picture控件邊上一些可憐的Static控件努力透出Picture的DC來顯示,整個界面實在看不下去。不得已,最后只好老老實實自己縮放圖片,死活把全圖刷到Picture控件的Rect中,堅決打擊了越界現(xiàn)象;后來又發(fā)現(xiàn)了這樣做的另外一個壞處,就是刷新不及時。每次移動窗口時,MFC就是不主動去刷Picture的圖,此時會出現(xiàn)Picture控件中一部分是圖,一部分是別的桌面元素的現(xiàn)象,實在怪異。當(dāng)下頗為懷念Doc/View結(jié)構(gòu),那玩意兒刷圖到View里實在省事多了。
今天終于痛下決心真正用一下Picture控件,所以稍稍研究了一下,發(fā)現(xiàn)其實用起來也不難。總結(jié)一下步驟:
1. 首先Picture控件的Type選Bitmap,沒查MSDN,不知道這種和別的Type有何區(qū)別,但是至少這個是能用的(名字最符合要求嘛);
2. 用一個CStatic類型的控件變量去關(guān)聯(lián)到這個控件上,例如叫m_picture;
3. 在需要改變圖片的地方,先從圖片生成一個HBITMAP,例如叫m_bitmap,然后只要m_picture.SetBitmap(m_bitmap)就可以了。這樣做的好處很明顯了,越界問題和刷新問題都解決了;如果對Picture的自動裁剪功能不爽,可以自己縮放圖片后再生成m_bitmap。我是用CxImage加載圖片的,因此顯示圖片的這段代碼就是:
CxImage image;
image.Load("welcome.jpg", CXIMAGE_FORMAT_JPG);
if (image.IsValid())
{
if (m_bitmap) DeleteObject(m_bitmap);
image.Resample(m_rect.Width(), m_rect.Height()); //按照Picture控件的大小,(不按比例)縮放原始圖片
m_bitmap = image.MakeBitmap(m_picture.GetDC()->m_hDC);
HBITMAP OldBitmap = m_picture.SetBitmap(m_bitmap);
if (OldBitmap) DeleteObject(OldBitmap);
}