学习笔记一(一个关于TextOut和Invalidate的问题)

新建一个MFC工程文件,然后想显示一幅图片,统计图片的黑白像素个数,

设置在文件打开菜单中打开一幅图像,在自己建的菜单中统计个数,如下:

打开菜单对应函数

 

  1. void CTestDoc::OnFileOpen() 
  2. {
  3.  // TODO: Add your command handler code here
  4.  LPCTSTR   lpszFilter= "BMPFiles(*.bmp)|*.bmp|所有文件|*.*||"
  5.  CFileDialog   dlg1(TRUE,lpszFilter,NULL,OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT,lpszFilter,NULL); 
  6.  CString   filename; 
  7.  CFile   file; 
  8.  if(dlg1.DoModal()==IDOK) 
  9.  { 
  10.  filename=dlg1.GetPathName(); 
  11.  if(file.Open(filename,CFile::modeRead|CFile::shareDenyNone,NULL)==1) 
  12.  { 
  13.  file.Read(&bf,sizeof(bf)); 
  14.  } 
  15.  file.Read(&bi,sizeof(bi)); 
  16.  numQuad=0; 
  17.  if(bi.biBitCount<24) 
  18.  { 
  19.  numQuad=1<
  20.  } 
  21.  pbi=(BITMAPINFO*)HeapAlloc(GetProcessHeap(),0,sizeof(BITMAPINFOHEADER)+numQuad*sizeof(RGBQUAD)); 
  22.  memcpy(pbi,&bi,sizeof(bi)); 
  23.  quad=(RGBQUAD*)((BYTE*)pbi+sizeof(BITMAPINFOHEADER)); 
  24.  file.Read(quad,sizeof(RGBQUAD)*numQuad); 
  25.  bi.biSizeImage=bf.bfSize-bf.bfOffBits; 
  26.  lpBuf=(BYTE*)HeapAlloc(GetProcessHeap(),0,bi.biSizeImage); 
  27.  lpDIBBits=(BYTE*)HeapAlloc(GetProcessHeap(),0,bi.biSizeImage); 
  28.  lpNewDIBBits=(BYTE*)HeapAlloc(GetProcessHeap(),0,bi.biSizeImage); 
  29.  file.Read(lpBuf,bi.biSizeImage); 
  30.  memcpy(lpDIBBits,lpBuf,bi.biSizeImage);
  31.  file.Close(); 
  32.  } 
  33.   flag=1 ;
  34. }
  35. Ondraw函数如下:
  36. void CTestView::OnDraw(CDC* pDC)
  37. {
  38.  CTestDoc* pDoc = GetDocument();
  39.  ASSERT_VALID(pDoc);
  40.  // TODO: add draw code for native data here
  41.  if(pDoc->flag==1)
  42.  {
  43.   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);
  44.   SetDIBitsToDevice(pDC->m_hDC,pDoc->bi.biWidth,0,pDoc->bi.biWidth,pDoc->bi.biHeight,0,0,0,pDoc->bi.biHeight,pDoc->lpDIBBits,pDoc->pbi,DIB_RGB_COLORS);
  45.  }
  46.     Invalidate(FALSE);
  47. }
  48. //统计函数
  49. void CTestView::OnCount() 
  50. {
  51.  // TODO: Add your command handler code here
  52. // TODO: Add your command handler code here
  53.  CTestDoc* pDoc=GetDocument();
  54.  int count,count2;
  55.  count=0;count2=0;
  56.   for(int i=0;ibi.biHeight;i++)
  57.    {
  58.     for(int j=0;jbi.biWidth;j++)
  59.     { 
  60.      if(pDoc->lpDIBBits[pDoc->bi.biWidth*3*i+3*j]==255)
  61.      {
  62.       count=count+1;
  63.      }
  64.      else
  65.      count2=count2+1;   
  66.     }
  67.   
  68.    }
  69.  mcount=count;
  70.  str.Format("白色像素个数: %5d",count);
  71.  str1.Format("黑色像素个数为: %5d",count2);
  72.  //lpszPathName.Format("E://desktop//temp//test//SNV%d.bmp",j);
  73.  CClientDC dc(this);
  74.  dc.TextOut(0,490,str);
  75.  dc.TextOut(0,510,str1);
  76.  }

结果并没有出现我想要的TextOut的统计数字,在视图窗口上没有显示。后来发现如下面这样就可以了。


  1. void CTestDoc::OnFileOpen() 
  2. {
  3.     // TODO: Add your command handler code here
  4.     LPCTSTR   lpszFilter= "BMPFiles(*.bmp)|*.bmp|所有文件|*.*||"
  5.     CFileDialog   dlg1(TRUE,lpszFilter,NULL,OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT,lpszFilter,NULL); 
  6.     CString   filename; 
  7.     CFile   file; 
  8.     if(dlg1.DoModal()==IDOK) 
  9.     { 
  10.     filename=dlg1.GetPathName(); 
  11.     if(file.Open(filename,CFile::modeRead|CFile::shareDenyNone,NULL)==1) 
  12.     { 
  13.     file.Read(&bf,sizeof(bf)); 
  14.     } 
  15.     file.Read(&bi,sizeof(bi)); 
  16.     numQuad=0; 
  17.     if(bi.biBitCount<24) 
  18.     { 
  19.     numQuad=1<
  20.     } 
  21.     pbi=(BITMAPINFO*)HeapAlloc(GetProcessHeap(),0,sizeof(BITMAPINFOHEADER)+numQuad*sizeof(RGBQUAD)); 
  22.     memcpy(pbi,&bi,sizeof(bi)); 
  23.     quad=(RGBQUAD*)((BYTE*)pbi+sizeof(BITMAPINFOHEADER)); 
  24.     file.Read(quad,sizeof(RGBQUAD)*numQuad); 
  25.     bi.biSizeImage=bf.bfSize-bf.bfOffBits; 
  26.     lpBuf=(BYTE*)HeapAlloc(GetProcessHeap(),0,bi.biSizeImage); 
  27.     lpDIBBits=(BYTE*)HeapAlloc(GetProcessHeap(),0,bi.biSizeImage); 
  28.     lpNewDIBBits=(BYTE*)HeapAlloc(GetProcessHeap(),0,bi.biSizeImage); 
  29.     file.Read(lpBuf,bi.biSizeImage); 
  30.     memcpy(lpDIBBits,lpBuf,bi.biSizeImage);
  31.     file.Close(); 
  32.     } 
  33.     
  34.     flag=1 ;
  35.     this->GetRoutingView()->Invalidate(FALSE);
  36. }
  37. void CTestView::OnDraw(CDC* pDC)
  38. {
  39.     CTestDoc* pDoc = GetDocument();
  40.     ASSERT_VALID(pDoc);
  41.     // TODO: add draw code for native data here
  42.     if(pDoc->flag==1)
  43.     {
  44.         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);
  45.         SetDIBitsToDevice(pDC->m_hDC,pDoc->bi.biWidth,0,pDoc->bi.biWidth,pDoc->bi.biHeight,0,0,0,pDoc->bi.biHeight,pDoc->lpDIBBits,pDoc->pbi,DIB_RGB_COLORS);
  46.     }
  47. }

发现又是Invalidate的问题,一般在显示一幅图片时,最好不要把Invalidate放在Ondraw里面,这样很容易重绘,却也容易出现一些不想要的图像。在这个例子中,因为在OnDraw里加入了Invalidate(),导致窗口重绘,而Ondraw函数中没有相应的TextOut代码,所以程序运行时就看不到想要显示的字符。可以如上这样修改,程序就可以出现结果了。但当窗口发生变化时,文字消失,要重点统计菜单。还有一种修改方式,就是把text Out语句放到Ondraw里面,这样,就可以一直显示了。

你可能感兴趣的:(C/C++/VC学习)