VCLZ-42 2023-02-21 18:35 采纳率: 72.2%
浏览 18
已结题

MFC写的屏幕监控界面卡死是为何?

自己写了个mfc跨局域网远程监控软件,有个功能是监控对方的屏幕画面。用的是定时器抓取图像。但是切换到监控画面只能显示一帧,然后立即卡死。

img

这是输出的trace信息

img


/*函数说明:MFC定时器,该函数定义在图传界面的CWatchDialg类里,
其作用用于定时从m_image中读取图片数据,让远程桌面成为动图。
此时,通过父窗口指针得到父窗口的成员m_image,也就是图传线程得到的数据。
设置到CStatic的对象m_picture中,让其显示。
*/
void CWatchdTest::OnTimer(UINT_PTR nIDEvent)
{
    // TODO: 在此添加消息处理程序代码和/或调用默认值

if (nIDEvent==0)
    {
        CRemoteControlClientDlg* pParent = (CRemoteControlClientDlg*)GetParent();
        if (pParent->isFull())
        {
            pParent->getImage().BitBlt(m_pictest.GetDC()->GetSafeHdc(),0,0,SRCCOPY);  //从左上角(0,0)以直接位复制的方式绘制
            m_pictest.InvalidateRect(NULL);//通知重绘
            pParent->getImage().Destroy();
            pParent->setImagestatus();
        }
    }
    CDialogEx::OnTimer(nIDEvent);
}

以下是图传函数

void CRemoteControlClientDlg::threadWatchData()
{
    Sleep(50);
    CClientsocket* pClient = NULL;
    do
    {
        pClient = CClientsocket::getInstance();
    } while (pClient == NULL);
    ULONGLONG tick = GetTickCount64();
    for (;;)
    {
        if (GetTickCount64() - tick < 300)  //增加间隔防止卡死
        {
            Sleep(GetTickCount64() - tick);
        }
        int ret = SendMessage(WM_SEND_PACKET, 6 << 1 | 1);
        if (ret == 6)
        {
            //int cmd = pClient->DealCommand();
            //if (cmd==6)
            if (m_isFull == false)  //更新数据到缓存
            {
                BYTE* pData = (BYTE*)pClient->GetPacket().strData.c_str();
                HGLOBAL hMem = GlobalAlloc(GMEM_MOVEABLE, 0);
                if (hMem == NULL)
                {
                    TRACE("内存不足!");
                    Sleep(1);
                    continue;
                }
                IStream* pStream = NULL;
                HRESULT hRet = CreateStreamOnHGlobal(hMem, TRUE, &pStream);
                if (hRet == S_OK)
                {
                    ULONG length = 0;
                    pStream->Write(pData, pClient->GetPacket().strData.size(), &length);
                    LARGE_INTEGER begin{ 0 };
                    pStream->Seek(begin, STREAM_SEEK_SET, NULL); //跳转到流的开头
                    m_image.Load(pStream);
                    m_isFull = true;
                    TRACE("图片写入成功\r\n");
                }
            }
        }
        else
        {
            Sleep(1);
        }
    }

}


请问这种情况一般是哪里出了问题?

  • 写回答

1条回答 默认 最新

  • CSDN-Ada助手 CSDN-AI 官方账号 2023-02-22 05:41
    关注
    不知道你这个问题是否已经解决, 如果还没有解决的话:

    如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

问题事件

  • 系统已结题 3月2日
  • 已采纳回答 2月22日
  • 创建了问题 2月21日

悬赏问题

  • ¥50 关于#html5#的问题:H5页面用户手机返回的时候跳转到指定页面例如(语言-javascript)
  • ¥15 无法使用此凭据登录,因为你的域不可用,如何解决?(标签-Windows)
  • ¥15 yolov9的训练时间
  • ¥15 二叉树遍历没有报错但无法正常运行
  • ¥15 在linux系统下vscode运行robocup3d上场球员报错
  • ¥15 Python语言实验
  • ¥15 SAP HANA SQL 增加合计行
  • ¥20 用C#语言解决一个英文打字练习器,有偿
  • ¥15 srs-sip外部服务 webrtc支持H265格式
  • ¥15 在使用abaqus软件中,继承到assembly里的surfaces怎么使用python批量调动