花屏了!花屏了...

黎雨梦荷 2013-04-01 10:39:55
话不多说,见代码!

void DlgOutputShow::OnPaint()
{
CPaintDC dc(this); // device context for painting
// TODO: 在此处添加消息处理程序代码
// 不为绘图消息调用 CDialog::OnPaint()
DrawOutputBorder();
}

void DlgOutputShow::DrawOutputBorder(void)
{
if (!IsWindowVisible())
{
return;
}

CPen *pOldPen = NULL;
CPen pPen;
CRect rc(0,0,0,0);
GetWindowRect(&rc);
g_servMainDlg->GetDlgItem(IDC_STATIC_PREV_WND)->ScreenToClient(&rc);
if (g_servMainDlg->m_iCurWndIndex == m_iSubWndIndex)
{
pPen.CreatePen(PS_SOLID, 2, RGB(0,255,0));//green
}
else
{
pPen.CreatePen(PS_SOLID, 2, RGB(125, 125, 116));
}

rc.right += OUTPUT_INTERVAL/2;
rc.bottom += OUTPUT_INTERVAL/2;

CDC *pDC = g_servMainDlg->GetDlgItem(IDC_STATIC_PREV_WND)->GetDC();
ASSERT(pDC);

pDC->SelectStockObject(NULL_BRUSH);
pOldPen = pDC->SelectObject(&pPen);
pDC->Rectangle(&rc);

if (pOldPen)
{
pDC->SelectObject(pOldPen);
}
else
{
WriteLog( DEBUGLEVEL_ERROR, __FILE__, __LINE__,"GDI leak now,m_camNo[%d] error[%d]!!!", m_camNo, GetLastError());
}

ReleaseDC(pDC);
}


WriteLog开始的时候不会执行,但是一段时间后(不断在重绘,重绘时间间隔由应用程序决定),则会执行WriteLog,GetLastError()为0,更致命的是,应用程序出现了花屏!
求大神帮我看看问题出在哪,谢谢了!
...全文
391 20 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
20 条回复
切换为时间正序
请发表友善的回复…
发表回复
ringphone 2013-04-02
  • 打赏
  • 举报
回复
对话框的OnPaint里绘制其他控件,导致触发对话框的OnPaint事件,再绘制,再触发,如此循环直至GDI资源耗尽,不花才怪。
菜牛 2013-04-02
  • 打赏
  • 举报
回复
你在对话框的OnPaint消息中去绘制其他控件,本身就是错误的,破坏了正常绘制顺序,出现任何错误、花屏都是应该的,正确的方式就是8楼,要在哪个控件中绘图就在该控件自身的刷新函数中去绘制;另外GetDC和ReleaseDC要对应,从哪个窗口GetDC就从要对那个个窗口ReleaseDC,而你不是。 错误的逻辑造成任何异常都不奇怪。
zgl7903 2013-04-01
  • 打赏
  • 举报
回复
与其这样混乱,不如从CStatic派生一个新类来处理 是否还有其他绘制覆盖了 下面的代码测试的没有问题,

  if(g_servMainDlg && g_servMainDlg->GetSafeHwnd())
  {
    CWnd *pWnd = g_servMainDlg->GetDlgItem(IDC_STATIC_PREV_WND);
    if(pWnd && pWnd->GetSafeHwnd())
    {
      CPen pPen; 
      if (1)//g_servMainDlg->m_iCurWndIndex == m_iSubWndIndex) 
      {
        pPen.CreatePen(PS_SOLID, 2, RGB(0,255,0));//green     
      }
      else
      {
        pPen.CreatePen(PS_SOLID, 2, RGB(125, 125, 116)); 
      }
      CRect rc(0,0,0,0);
      pWnd->GetClientRect(&rc);
      rc.right += OUTPUT_INTERVAL/2; rc.bottom += OUTPUT_INTERVAL/2; //这里是不是超出了区域?

      CDC *pDC = pWnd->GetDC();
      ASSERT(pDC);
      CBrush *pOldBrush = (CBrush *)pDC->SelectStockObject(NULL_BRUSH); 
      CPen *pOldPen = pDC->SelectObject(&pPen);
      pDC->Rectangle(&rc);
      
      pDC->SelectObject(pOldPen);
      pDC->SelectObject(pOldBrush);
      
      pWnd->ReleaseDC(pDC); 
    }
  }
shen_wei 2013-04-01
  • 打赏
  • 举报
回复
DrawOutputBorder();为啥放在OnPaint()中,这样就会绘制N多次??
黎雨梦荷 2013-04-01
  • 打赏
  • 举报
回复
另外希望你帮我解释下为什么你觉得一定要用g_servMainDlg->GetDlgItem(IDC_STATIC_PREV_WND)->ReleaseDC(pDC) 代替ReleaseDC(pDC),谢谢了!
黎雨梦荷 2013-04-01
  • 打赏
  • 举报
回复
还是不行啊,我刚调试了下,发现OnPaint的次数很多,貌似在一直重绘,麻烦你在看看我OnPaint函数是否有问题,我把CDialog::OnPaint()这个删掉了,但是按理说这个应该不是导致不断重绘的原因吧。 谢谢zgl7903的关注!
zgl7903 2013-04-01
  • 打赏
  • 举报
回复
CDC *pDC = g_servMainDlg->GetDlgItem(IDC_STATIC_PREV_WND)->GetDC(); ASSERT(pDC); pDC->SelectStockObject(NULL_BRUSH); pOldPen = pDC->SelectObject(&pPen); pDC->Rectangle(&rc); pDC->SelectObject(pOldPen); g_servMainDlg->GetDlgItem(IDC_STATIC_PREV_WND)->ReleaseDC(pDC);
黎雨梦荷 2013-04-01
  • 打赏
  • 举报
回复
通过我调试发现,同一个m_camNo在执行第二次重绘的时候会进入WriteLog分支,何解?难道是出现DC资源冲突?怎么保存这个这个pOldPen才合适呢?求前辈们继续关注!谢谢了!~
黎雨梦荷 2013-04-01
  • 打赏
  • 举报
回复
谢谢楼上的回复,我试了下还是不行。 我很纳闷为什么pOldPen会为空,这个让我很疑惑!
zgl7903 2013-04-01
  • 打赏
  • 举报
回复
g_servMainDlg->GetDlgItem(IDC_STATIC_PREV_WND)->ReleaseDC(pDC);
黎雨梦荷 2013-04-01
  • 打赏
  • 举报
回复
引用 15 楼 sha_jinhao 的回复:
花瓶 你还调试!! 肯定是根据那个rect 花掉了 然后zaionpaint中处理啊
你似乎说到了点子上,花屏时我的有些线本来是在客户区,但是结果却画在了屏幕坐标中,可否在详细说下“肯定是根据那个rect 花掉了”??? 谢谢你的提醒,下次我知道引用是怎么回事了~
黎雨梦荷 2013-04-01
  • 打赏
  • 举报
回复
引用 15 楼 sha_jinhao 的回复:
花瓶 你还调试!! 肯定是根据那个rect 花掉了 然后zaionpaint中处理啊
花屏是在一种特殊模式下必现,而且就算进入了这种特殊模式,还需要运行一段时间,所以我才调试来着。
jimette 2013-04-01
  • 打赏
  • 举报
回复
回复别人的时候最后加引用 , 不然看不见
jimette 2013-04-01
  • 打赏
  • 举报
回复
花瓶 你还调试!! 肯定是根据那个rect 花掉了 然后zaionpaint中处理啊
黎雨梦荷 2013-04-01
  • 打赏
  • 举报
回复
对,肯定是由于什么原因导致本来需要重绘的地方没有重绘,从跟踪调试的结果上看,每次花屏必现的时候都是会进入WriteLog分支,花屏有一定的规律,但是就是不知道自己错在了哪里!!!
jimette 2013-04-01
  • 打赏
  • 举报
回复
花瓶了, 应该重会的时候那个地方少画了
黎雨梦荷 2013-04-01
  • 打赏
  • 举报
回复
如果可以的话,我还真想传,但是毕竟是工作,这一点你应该比我更懂的。 我想问下,我的pPen是否存在GDI泄露?因为我发现后面我没有显式的调用DeleteObject,求解!
shen_wei 2013-04-01
  • 打赏
  • 举报
回复
可以的话,希望你上全码。。工程项目!!
黎雨梦荷 2013-04-01
  • 打赏
  • 举报
回复
回复zgl7903: 换个实现方法我也想过,但是眼下我最关心的是我错在哪里,我总觉得自己在GDI画图这一块哪里掌握的不够,之前做的一个项目的东西也是这一块有问题,这一次又遇到了类似的问题,所以才在万不得已的情况下发帖求助,还望各个前辈们多多指教,感激不尽了!
黎雨梦荷 2013-04-01
  • 打赏
  • 举报
回复
回复shen_wei: 这个必须加在OnPaint中,以为线条是应用程序画的,不加的话,重绘以后就没了。

15,980

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 界面
社区管理员
  • 界面
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧