• 关于多画面窗口切换的刷新重绘问题


    这段时间一直在开发电视转发和文件播放的服务器软件,基于PC端的。

    之前在做多画面切换的时候,发现存在一个BUG,当多画面窗口切换的时候,存在窗口画面留有影子的问题,留有之前窗口的边框,看上去像重叠一样的问题,但当我点击全屏操作以后,画面重叠就消除了,一切恢复正常。

    例如当我点击画面切换的时候,从9画面切换到12画面的时候,出现了下面的这种情况:

    这种情况,看上去像是画面没刷新一样,就是说从9画面切到12画面的时候,画面没刷新。

    下面就来看看我的画面关键代码:

    在窗口切换的时候,我们需要先将窗口隐藏,然后再把窗口SHOW出来。

    关键代码1:

    ///////////////////////////////
    //将各个多画面窗口复位到初始化状态
    void CWndFilePlayVideoView::ResetFilePlayMonitorSta(int nWin)
    {

    for(int i=0;i<MULFILE_MONITOR_PLAYS;i++)
    {
    m_MulFilePlayDisplay[i].ShowWindow(SW_HIDE);
    m_MulFilePlayDisplay[i].m_left = 0;
    m_MulFilePlayDisplay[i].m_top = 0;
    m_MulFilePlayDisplay[i].m_width = 0;
    m_MulFilePlayDisplay[i].m_height = 0;

    m_MulFilePlayDisplay[i].m_ischange = false;
    }
    TRACE(" CWndFilePlayVideoView::ResetFilePlayMonitorSta 复位子播放窗口. ");
    }

    关键代码2:

    /////////////////////////////////////
    //对多窗口多画面播放的视频进行窗口重新布局
    //
    void CWndFilePlayVideoView::RestorFilePlayMonitorLayout(int nWin)
    {
    int i=0;
    int iSingleWidth;//单个界面
    int iSingleHeight;

    int tempCurPlayNum=m_iCurFilePlayMonitorNum;//
    //int tempNextPlayNum=m_iNextFilePlayMonitorNum;
    int iRowPlayNum=0;//行
    int iColumnPlayNum=0;//列
    if(tempCurPlayNum==12)//12画面
    {
    iRowPlayNum=3;//
    iColumnPlayNum=4;//
    //计算单个窗口的大小
    //iSingleWidth=m_rectFilePlayVideoView.Width()/iColumnPlayNum;
    //iSingleHeight=m_rectFilePlayVideoView.Height()/iRowPlayNum;
    iSingleWidth=(m_rectFilePlayVideoView.Width()-(iColumnPlayNum+1)*MULFILE_PlAYS_WIDTH_INTERVAL)/iColumnPlayNum;
    iSingleHeight=(m_rectFilePlayVideoView.Height()-(iRowPlayNum+1)*MULFILE_PlAYS_HEIGHT_INTERVAL)/iRowPlayNum;

    for(i=0;i<tempCurPlayNum;i++)//留两个像素点做间距
    {
    //m_MulFilePlayDisplay[i].m_left = m_rectFilePlayVideoView.left+(i%iColumnPlayNum) * iSingleWidth;
    //m_MulFilePlayDisplay[i].m_top = m_rectFilePlayVideoView.top+(i/iColumnPlayNum) * iSingleHeight;
    m_MulFilePlayDisplay[i].m_left = m_rectFilePlayVideoView.left+(i%iColumnPlayNum) * iSingleWidth+(i%iColumnPlayNum+1)*MULFILE_PlAYS_WIDTH_INTERVAL;
    m_MulFilePlayDisplay[i].m_top = m_rectFilePlayVideoView.top+(i/iColumnPlayNum) * iSingleHeight+(i/iColumnPlayNum+1)*MULFILE_PlAYS_HEIGHT_INTERVAL;

    m_MulFilePlayDisplay[i].m_width=iSingleWidth;
    m_MulFilePlayDisplay[i].m_height=iSingleHeight;
    m_MulFilePlayDisplay[i].m_ischange=true;//
    }
    }else{//1-4-9-16画面
    iRowPlayNum=iColumnPlayNum=(int)sqrt((double)tempCurPlayNum);;//
    //计算单个窗口的大小
    //iSingleWidth=m_rectFilePlayVideoView.Width()/iColumnPlayNum;
    //iSingleHeight=m_rectFilePlayVideoView.Height()/iRowPlayNum;
    iSingleWidth=(m_rectFilePlayVideoView.Width()-(iColumnPlayNum+1)*MULFILE_PlAYS_WIDTH_INTERVAL)/iColumnPlayNum;
    iSingleHeight=(m_rectFilePlayVideoView.Height()-(iRowPlayNum+1)*MULFILE_PlAYS_HEIGHT_INTERVAL)/iRowPlayNum;

    for(i=0;i<tempCurPlayNum;i++)//留两个像素点做间距
    {
    //m_MulFilePlayDisplay[i].m_left = m_rectFilePlayVideoView.left+(i%iRowPlayNum) * iSingleWidth+2;
    //m_MulFilePlayDisplay[i].m_top = m_rectFilePlayVideoView.top+(i/iRowPlayNum) * iSingleHeight+2;
    m_MulFilePlayDisplay[i].m_left = m_rectFilePlayVideoView.left+(i%iColumnPlayNum) * iSingleWidth+(i%iColumnPlayNum+1)*MULFILE_PlAYS_WIDTH_INTERVAL;
    m_MulFilePlayDisplay[i].m_top = m_rectFilePlayVideoView.top+(i/iColumnPlayNum) * iSingleHeight+(i/iColumnPlayNum+1)*MULFILE_PlAYS_HEIGHT_INTERVAL;

    m_MulFilePlayDisplay[i].m_width=iSingleWidth;
    m_MulFilePlayDisplay[i].m_height=iSingleHeight;
    m_MulFilePlayDisplay[i].m_ischange=true;//
    }
    }

    /////////////////开始调整位置/////////////////////////
    for(i=0;i<MULFILE_MONITOR_PLAYS;i++)
    {
    if(m_MulFilePlayDisplay[i].m_ischange)
    {
    m_MulFilePlayDisplay[i].RestorPosition();//调整
    m_MulFilePlayDisplay[i].ShowWindow(SW_SHOW);
    TRACE(" CWndFilePlayVideoView::RestorFilePlayMonitorLayout 开始调整%d窗口. ",i);
    }else{

    }
    }
    m_iCurFilePlayMonitorNum=tempCurPlayNum;
    }

    关键代码3:

    ////////////////////////////////////
    //重定义显示窗口位置
    void CWndMulFilePlayDisp::RestorPosition()
    {
    MoveWindow(m_left, m_top, m_width, m_height, TRUE);
    }

    所以在窗口切换的时候,我们的代码调用顺序是:

    m_iCurFilePlayMonitorNum=1;//这里切换到哪个画面,这里就赋值为x
    ResetFilePlayMonitorSta(0);
    RestorFilePlayMonitorLayout(0);

     ====================================

    为什么会出现之前的情况?于是按照自己的判断,画面没刷新的思路,我在画面切换的函数完成以后,调用一次RedrawWindow();立即进行一次画面的刷新。

    但加了以后,在多次切换以后,问题还是没有解决。

    我左右想想,也不知道哪里出了问题,根据程序也发现已经进入了dopaint函数,完成了重绘刷新,但为什么还是出现这种看上去没刷新的问题?

    后面想了好久,感觉难道是因为我们刷新的是父窗口??因为我们这里画面切换都是在父窗口的函数中进行的。

    按照这个思路,我尝试了下在播放的各个子窗口中进行窗口刷新。

    所以最后在子窗口类里面添加onsize和onpaint函数,代码很简单:

    //wm_size消息处理

    void CWndMulFilePlayDisp::OnSize(UINT nType,int cx,int cy)

    {

      TRACE(" CWndMulFilePlayDisp::Onsize. ");

      CSkinStatic::Onsize(nType,cx,cy);

      RedrawWindow();//更新界面

    }

    //重绘消息响应函数

    void CWndMulFilePlayDisp::OnPaint()

    {

    CPaintDC dc(this);

    CRect rcClip, rcClient;
    dc.GetClipBox( &rcClip );
    GetClientRect(&rcClient);

    // Create a compatible memory DC
    CDC memDC;
    memDC.CreateCompatibleDC( &dc );

    // Select a compatible bitmap into the memory DC
    CBitmap bitmap, bmpImage;
    bitmap.CreateCompatibleBitmap( &dc, rcClient.Width(), rcClient.Height() );
    memDC.SelectObject( &bitmap );


    // First let the control do its default drawing.
    //CWnd::DefWindowProc( WM_PAINT, (WPARAM)memDC.m_hDC, 0 );

    /*********************add by lhp******************************/
    DrawTreeItem(&memDC,rcClient,rcClip);
    dc.BitBlt( rcClip.left, rcClip.top, rcClip.Width(),
    rcClip.Height(), &memDC,
    rcClip.left, rcClip.top, SRCCOPY );
    // 删除资源
    memDC.DeleteDC();
    bitmap.DeleteObject();

    }

    添加了上述的代码以后,进行调试,发现问题解决了。

  • 相关阅读:
    《笨办法学Python》 第31课手记
    《笨办法学Python》 第30课手记
    《笨办法学Python》 第29课手记
    《笨办法学Python》 第28课手记
    《笨办法学Python》 第27课手记
    《笨办法学Python》 第26课手记
    《笨办法学Python》 第25课手记
    《笨办法学Python》 第23课手记
    杭电2019
    杭电2018----母牛的故事
  • 原文地址:https://www.cnblogs.com/lihaiping/p/mulfilepalydisp.html
Copyright © 2020-2023  润新知