在學一個位圖顯示程式時,發現了圖像顯示能不能重繪的問題,當時看了msdn,也在網上看了不少回複。總感覺不是很了解。後來仔細試了一下,有點心得,特寫出來,以鼓勵自己。順便也為那些和我一樣剛開始學習vc的人提供些許幫助。
程式很簡單,如下:在文檔類中定義變量
下面是我在Doc類下面的變量:::
BITMAPFILEHEADER bf;
BITMAPINFOHEADER bi;
RGBQUAD* quad;
BYTE* lpBuf;
BITMAPINFO*pbi;
int flag;
int numQuad;
在Doc類下面添加了指令處理函數打開檔案:
void CMySeeView::OnFileOpen()
{
// TODO: Add your command handler code here
LPCTSTR lpszFilter= "BMPFiles(*.bmp)|*.bmp ";
CFileDialog dlg1(TRUE,lpszFilter,NULL,OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT,lpszFilter,NULL);
CString filename;
CFile file;
if(dlg1.DoModal()==IDOK)
{
filename=dlg1.GetPathName();
if(file.Open(filename,CFile::modeRead|CFile::shareDenyNone,NULL)==1)
{
file.Read(&bf,sizeof(bf));
}
file.Read(&bi,sizeof(bi));
numQuad=0;
if(bi.biBitCount <24)
{
numQuad=1 < <bi.biBitCount;
}
pbi=(BITMAPINFO*)HeapAlloc(GetProcessHeap(),0,sizeof(BITMAPINFOHEADER)+numQuad*sizeof(RGBQUAD));
memcpy(pbi,&bi,sizeof(bi));
quad=(RGBQUAD*)((BYTE*)pbi+sizeof(BITMAPINFOHEADER));
file.Read(quad,sizeof(RGBQUAD)*numQuad);
bi.biSizeImage=bf.bfSize-bf.bfOffBits;
lpBuf=(BYTE*)HeapAlloc(GetProcessHeap(),0,bi.biSizeImage);
file.Read(lpBuf,bi.biSizeImage);
file.Close();
}
flag==1
}
然後繪圖:畫圖::
void CMySeeView::OnDraw(CDC* pDC)
{
CMySeeDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
if(pDoc->flag==1)
{
SetDIBitsToDevice(pDC->m_hDC,0,0,pDoc->bi.biWidth,pDoc->bi.biHeight,0,0,0,pDoc->bi.biHeight,pDoc->lpBuf,pDoc->pbi,DIB_RGB_COLORS);
}
Invalidate(false);/這個地方用Invalidate(true)和不用的情況下出現的結果寫在下面。
}
現象如下:
(1)Invalidate(false)正常 (2)Invalidate(true)出現刷屏 (3)如果不用,那麼每次打開檔案将不能自動顯示,可以手動更改視窗大小,那麼就可以正常顯示了。
分析如下:當參數為false時,客戶區無效,引起重繪,但不擦除背景,是以我們可以看到我們的圖像。當參數為true時,也引起重繪,我們可以看到自己的圖像,但由于擦除背景以後才發生重繪,是以看到刷屏的現象。而不用的話就會一直顯示背景,除非認為改變視窗或其他方式引發視窗重繪,顯示圖像。