对话框的Picture控件重绘

时间:2022-12-16 14:37:12
 要完成的任务是显示wav波形,遇到的问题是当窗口被覆盖再显示的时候,在picture控件上的图像就没有了。

  我的做法是在对话框中插入一个picture控件,设置type为Rectangle。当我点击选择的wav文件后,就在该控件中显示该文件的波形。在打开文件消息响应函数中我是这么写的。

   void CDraw_WAVDlg::OnOK()
{
   ....//前面是对wav数据的加载,和在内存中画图。
   CDC *dc;
   CRect crect;
   CWnd *pic;
   pic=GetDlgItem(IDC_PICTURE);   //IDC_PICTURE是picture控件的id
   pic->GetClientRect(crect); 
   dc = pic->GetDC();
   dc->BitBlt(crect.left,crect.top,crect.right,crect.bottom,&m_dcBuffer,0,0,SRCCOPY); 
   //m_dcBuffer是CDraw_WAVDlg的CDC类型的成员,用来在内存中画图
   ReleaseDC(dc);
}

   在OnPaint函数中的实现如下:
   void CDraw_WAVDlg::OnPaint()
{

if (IsIconic())
{
   CPaintDC dc(this); // device context for painting
 
   SendMessage(WM_ICONERASEBKGND, (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
  {
   CDC *dc;
   CRect crect;
   CWnd *pic;
   pic=GetDlgItem(IDC_PICTURE);   //IDC_PICTURE是picture控件的id
   pic->GetClientRect(crect); 
   dc = pic->GetDC();
   dc->BitBlt(crect.left,crect.top,crect.right,crect.bottom,&m_dcBuffer,0,0,SRCCOPY); 
   CDialog::OnPaint();  
   }
}

分数不多了,大家帮帮忙看是哪里的问题吧。

6 个解决方案

#1


OnPaint内 利用CPaintDC dc(this);
dc-> BitBlt(crect.left,crect.top,crect.right,crect.bottom,&m_dcBuffer,0,0,SRCCOPY); 
去实现绘图即可, 其他操作


如dc = pic->GetDC(); 
是多余的,而且后边没有ReleaseDC
会导致内存泄露!

#2


另外,如果在Picture控件内绘图,那么应该自写一个 CYourPic: public CStatic
然后在CYourPic::OnPaint() 内执行绘图dc的操作,就可以了。

#3


你完全可以重载picture控件,
在空间的OnPaint函数中绘图,这样能避免你说的问题。

q:是当窗口被覆盖再显示的时候,在picture控件上的图像就没有了。

#4


引用 3 楼 tttyd 的回复:
你完全可以重载picture控件,
在空间的OnPaint函数中绘图,这样能避免你说的问题。

q:是当窗口被覆盖再显示的时候,在picture控件上的图像就没有了。


问个叫弱的问题,在CStatic继承类中调用BitBlt函数时,
dc->BitBlt(rc.left,rc.top,rc.Width(),rc.Height(), ,0,0,SRCCOPY);
原本属于内存数据的那个参数不知道该填什么。在我的实现中它是CDraw_WAVDlg的一个公共成员。

#5


引用 4 楼 danxiaodemao 的回复:
引用 3 楼 tttyd 的回复:
 你完全可以重载picture控件,
 在空间的OnPaint函数中绘图,这样能避免你说的问题。

 q:是当窗口被覆盖再显示的时候,在picture控件上的图像就没有了。


 问个叫弱的问题,在CStatic继承类中调用BitBlt函数时,
 dc->BitBlt(rc.left,rc.top,rc.Width(),rc.Height(), ,0,0,SRCCOPY);
 原本属于内存数据的那个参数不知道该填什么。在我的实现中它是CDraw_WAVDlg的一个公共成员。

你可以通过GetParent获取父窗口的指针,通过指针访问CDraw_WAVDlg的成员变量

#6


受教了,谢谢大侠们

#1


OnPaint内 利用CPaintDC dc(this);
dc-> BitBlt(crect.left,crect.top,crect.right,crect.bottom,&m_dcBuffer,0,0,SRCCOPY); 
去实现绘图即可, 其他操作


如dc = pic->GetDC(); 
是多余的,而且后边没有ReleaseDC
会导致内存泄露!

#2


另外,如果在Picture控件内绘图,那么应该自写一个 CYourPic: public CStatic
然后在CYourPic::OnPaint() 内执行绘图dc的操作,就可以了。

#3


你完全可以重载picture控件,
在空间的OnPaint函数中绘图,这样能避免你说的问题。

q:是当窗口被覆盖再显示的时候,在picture控件上的图像就没有了。

#4


引用 3 楼 tttyd 的回复:
你完全可以重载picture控件,
在空间的OnPaint函数中绘图,这样能避免你说的问题。

q:是当窗口被覆盖再显示的时候,在picture控件上的图像就没有了。


问个叫弱的问题,在CStatic继承类中调用BitBlt函数时,
dc->BitBlt(rc.left,rc.top,rc.Width(),rc.Height(), ,0,0,SRCCOPY);
原本属于内存数据的那个参数不知道该填什么。在我的实现中它是CDraw_WAVDlg的一个公共成员。

#5


引用 4 楼 danxiaodemao 的回复:
引用 3 楼 tttyd 的回复:
 你完全可以重载picture控件,
 在空间的OnPaint函数中绘图,这样能避免你说的问题。

 q:是当窗口被覆盖再显示的时候,在picture控件上的图像就没有了。


 问个叫弱的问题,在CStatic继承类中调用BitBlt函数时,
 dc->BitBlt(rc.left,rc.top,rc.Width(),rc.Height(), ,0,0,SRCCOPY);
 原本属于内存数据的那个参数不知道该填什么。在我的实现中它是CDraw_WAVDlg的一个公共成员。

你可以通过GetParent获取父窗口的指针,通过指针访问CDraw_WAVDlg的成员变量

#6


受教了,谢谢大侠们