学期末的一个MFC项目,想做一个软件:描述:局域网内,在一台机器上用行该软件,实现捕捉当前屏幕,然后传输到其他机器上在另一个辅助软件上显示。我想了解一下其中用到的技术,希望可以得到比较具体的介绍!形势比较急,希望大家可以帮忙!不胜感激!!!!

解决方案 »

  1.   

    涉及到WinSock套接字编程,图像传输。获取当前桌面并保存为bitmap结构。
    网上搜索“局域网监控软件”的代码。
      

  2.   

    www.codeproject.com上面找找。记得有一个这样的软件,只不过里面用的大部分是SDK。功能比楼主要求的还多。
      

  3.   

    谢谢KevinJHoo,英文网站,找起来困难啊,大家帮帮忙!
      

  4.   

    bo2000,很强的,有源码,我放到csdn下载资源里面了,还有几个类似的,你去下载看看。
      

  5.   

    http://download.csdn.net/hicsdn/sxcong
    在这里,前三个都是类似的
      

  6.   

    谢谢 sxcong 非常感谢,大家再帮忙提供些资源!^_^ 谢谢!
      

  7.   

    我的blog里面有一个捕捉屏幕的函数
    1捕捉屏幕图像
    2压缩
    3传输
    4解压
    5显示
      

  8.   

    要代码么 我帖:(我自己的啊  呵呵)
    /*
     * 发送和接收图像数据的函数 
     */
    BOOL SendData(SOCKET *ptalk,BYTE * pdata,int datalen,BYTE * tempdata,int templen,int w,int h)
    {
    ZeroMemory(tempdata,templen); if(templen < datalen)
    return FALSE;
    //先压缩
    int ret = compress2(tempdata,(unsigned long *)&templen,pdata,datalen,Z_BEST_SPEED);
    if(templen > datalen) //无用就是看看
    AfxMessageBox("压缩后变大了");
    if(ret != Z_OK)
    return FALSE;

    myhead head;
    head.w = w;
    head.h = h;
    head.datalen = datalen;
    head.clen = templen;

    ret = ::send(*ptalk,(char *)&head,sizeof(head),0); //发送头
    if(ret <= 0)
    return FALSE;
    int left = templen;
    int pos = 0;
    while(left > 0)
    {
    ret = ::send(*ptalk,(char *)tempdata+pos,left,0); //发送数据
    if(ret < 0)
    return FALSE;
    pos += ret;
    left -= ret;
    }
    CString temp;
    temp.Format("send byte %d",pos);
    OutputDebugString(temp);
    return TRUE;
    }BOOL RecvData(SOCKET *ptalk,BYTE *pdata,int *pdatalen,BYTE * tempdata,int templen,int *w,int *h)
    {
    ZeroMemory(tempdata,templen); myhead head;
    int ret = ::recv(*ptalk,(char *)&head,sizeof(head),0); //先接收头部
    if(ret <= 0)
    return FALSE; *w = head.w; //得到图的长和宽
    *h = head.h; int left = head.clen;
    int pos = 0;
    while(left > 0)
    {
    ret = ::recv(*ptalk,(char *)tempdata+pos,left,0); //接收数据部分
    if(ret <= 0)
    return FALSE;
    pos += ret;
    left -= ret;
    }
    if(pos != head.clen)
    {
    CString temp;
    temp.Format("pos = %d,head.clen = %d",pos,head.clen);
    OutputDebugString(temp);
    return FALSE;
    }
    ret = uncompress(pdata,(unsigned long *)pdatalen,tempdata,head.clen);
    if(ret != Z_OK)
    return FALSE; return TRUE;
    }//执行操作的函数BOOL XOR(char *a,char *b,char *res,int len) //对数据进行抑或
    {
    for(int i = 0;i < len;i++)
    res[i] = a[i]^b[i];
    return TRUE;
    }
    BOOL GetScreenCaps(int *x,int *y) //得到屏幕的分辨率
    {
    HDC hScrDC;

    hScrDC = CreateDC("DISPLAY", NULL, NULL, NULL);
    *x = GetDeviceCaps(hScrDC, HORZRES);
    *y = GetDeviceCaps(hScrDC, VERTRES);
    DeleteObject(hScrDC); return TRUE;
    }
    /*将鼠标光标画到指定的地方去*/
    BOOL DrawMouse(HDC hdc,HCURSOR hcursor)
    {
    POINT CursorPos;
    ICONINFO IconInfo;// hcursor = ::GetCursor();
    // If the mouse cursor handle is invalid then forget it
    if (hcursor == NULL)
    return FALSE;

    // Get the cursor position
    if (!GetCursorPos(&CursorPos))
    return FALSE;

    // Translate position for hotspot
    if (GetIconInfo(hcursor, &IconInfo))
    {
    CursorPos.x -= ((int) IconInfo.xHotspot);
    CursorPos.y -= ((int) IconInfo.yHotspot);
    if (IconInfo.hbmMask != NULL)
    DeleteObject(IconInfo.hbmMask);
    if (IconInfo.hbmColor != NULL)
    DeleteObject(IconInfo.hbmColor);
    }

    // Draw the cursor
    DrawIconEx(
    hdc, // handle to device context 
    CursorPos.x, CursorPos.y, //
    hcursor, // handle to icon to draw 
    0,0, // width of the icon 
    0, // index of frame in animated cursor 
    NULL, // handle to background brush 
    DI_NORMAL | DI_COMPAT // icon-drawing flags 
    ); return TRUE;
    }
    //取屏幕数据,lpRect指定取屏幕的范围,len指定buf的大小
    //
    // 当buf不为NULL且长度足够拷贝数据时,返回图片数据大小
    // 当buf为NULL或者长度不够拷贝数据时,返回图片数据大小
    // 当执行失败时返回0
    unsigned GetScrnData(LPRECT lpRect, unsigned char * buf, unsigned len)
    {
    HDC       hScrDC, hMemDC;     // 屏幕和内存设备描 述表  
    HBITMAP    hBitmap, hOldBitmap;   // 位图句柄

    // 位图宽度和高度
    int iWidth, iHeight;
    iWidth = lpRect->right- lpRect->left;
    iHeight = lpRect->bottom - lpRect->top;

    //为屏幕创建设备描述表
    hScrDC = CreateDC("DISPLAY", NULL, NULL, NULL);

    // 获得屏幕分辨率
    int       xScrn, yScrn;         
    xScrn = GetDeviceCaps(hScrDC, HORZRES);
    yScrn = GetDeviceCaps(hScrDC, VERTRES);

    //为屏幕设备描述表创建兼容的内存设备描述表
    hMemDC = CreateCompatibleDC(hScrDC);
    hBitmap = CreateCompatibleBitmap(hScrDC, iWidth,iHeight);
    hOldBitmap = (HBITMAP)SelectObject(hMemDC, hBitmap);
    StretchBlt(hMemDC, 0, 0, iWidth, iHeight, hScrDC, 0, 0, xScrn,yScrn, SRCCOPY);

    /*这里把鼠标的图标画到图像中去*/
    if(buf && len)
    {
    // DrawMouse(hMemDC);
    HCURSOR cur = ::GetCursor();
    POINT curPos;
    GetCursorPos(&curPos);
    DrawIcon(hMemDC,curPos.x,curPos.y,cur);
    }
    // 创建位图头
    BITMAPINFO bmpInfo;
    ZeroMemory(&bmpInfo,sizeof(BITMAPINFO));
    bmpInfo.bmiHeader.biSize=sizeof(BITMAPINFOHEADER);
    bmpInfo.bmiHeader.biWidth = iWidth;
    bmpInfo.bmiHeader.biHeight = iHeight;
    bmpInfo.bmiHeader.biPlanes = 1;
    bmpInfo.bmiHeader.biBitCount = 24;
    bmpInfo.bmiHeader.biCompression = BI_RGB;

    //图片信息
    if (0 == GetDIBits(hMemDC, hBitmap, 0, iHeight, NULL, &bmpInfo, DIB_RGB_COLORS))
    {
    MessageBox(NULL,"GetDIBits Fail !","ERROR",MB_OK);
    return 0;
    }

    //当接收缓冲为空或者,长度不够时返回需要的长度
    if (NULL == buf || len < bmpInfo.bmiHeader.biSizeImage)
    {
    // return bmpInfo.bmiHeader.biSizeImage;
    goto hah;
    }

    //把图片数据拷至缓冲中去
    GetDIBits(hMemDC, hBitmap, 0, iHeight, buf, &bmpInfo, DIB_RGB_COLORS);

    hBitmap = (HBITMAP)SelectObject(hMemDC, hOldBitmap);
    hah:
    int erro = DeleteObject(hBitmap);
    erro = DeleteDC(hScrDC);
    erro = DeleteDC(hMemDC);
    // DeleteObject(hBitmap);

    // 返回位图句柄
    return bmpInfo.bmiHeader.biSizeImage;
    }void DisplayPicture(HDC hdc,char *pdata,int datalen,int s_w,int s_h,int w,int h) //显示图像
    {
    BITMAPINFO bmpInfo;
    ZeroMemory(&bmpInfo,sizeof(BITMAPINFO));
    bmpInfo.bmiHeader.biSize=sizeof(BITMAPINFOHEADER);
    bmpInfo.bmiHeader.biWidth = 0;
    bmpInfo.bmiHeader.biHeight = 0;
    bmpInfo.bmiHeader.biPlanes = 1;
    bmpInfo.bmiHeader.biBitCount = 24;
    bmpInfo.bmiHeader.biCompression = BI_RGB;
    bmpInfo.bmiHeader.biSizeImage = datalen;
    bmpInfo.bmiHeader.biWidth = w;
    bmpInfo.bmiHeader.biHeight = h; StretchDIBits(hdc,0,0,s_w,s_h,
    0,0,w,h,pdata,&bmpInfo,
    DIB_RGB_COLORS,SRCCOPY);
    }BOOL DisposeFun(CServerDlg *pdlg)
    {
    SOCKET *ptalk = &pdlg->m_talk;

    int w,h;
    GetScreenCaps(&w,&h);
    RECT rect;
    rect.left = 0;
    rect.top = 0;
    rect.right = 1024;
    rect.bottom = 768; int datalen = BITMAPSIZE;
    BYTE *pdata = new BYTE[datalen];
    ZeroMemory(pdata,datalen); int templen = BITMAPSIZE;
    BYTE *tempdata = new BYTE[templen];
    ZeroMemory(tempdata,templen);

    int xorlen = BITMAPSIZE;
    BYTE *xordata = new BYTE[xorlen];
    ZeroMemory(xordata,xorlen); int sorlen = BITMAPSIZE;
    BYTE *sordata = new BYTE[sorlen];
    ZeroMemory(sordata,sorlen); int reallen;
    reallen = GetScrnData(&rect,NULL,0);
    if(datalen < reallen)
    return FALSE; GetScrnData(&rect,pdata,datalen);
    memcpy(sordata,pdata,reallen);
    int ret = SendData(ptalk,pdata,reallen,tempdata,templen,rect.right,rect.bottom);

    DWORD newtime,oldtime,count; while(pdlg->m_bisSubWork)
    {
    oldtime  = GetTickCount();
    GetScrnData(&rect,pdata,datalen);
    XOR((char *)sordata,(char *)pdata,(char *)xordata,reallen);
    memcpy(sordata,pdata,reallen);

    ret = SendData(ptalk,xordata,reallen,tempdata,templen,rect.right,rect.bottom);
    if(!ret)
    break;
    newtime = GetTickCount(); count = oldtime - newtime;
    if(count < 100)
    Sleep(100 - count); }

    pdlg->m_bisSubWork = FALSE;
    ::closesocket(*ptalk);
    delete []pdata;
    delete []tempdata;
    delete []xordata;
    delete []sordata;
    return TRUE;
    }要给分啊 我不容易啊
      

  9.   

    我的图像传输是这样:先抓 1张图  发送 然后抓下一张 与第一张进行疑惑 把疑惑的结果发过去(发送之前都是要压缩的,我用的是zip压缩算法) 然后将这张图保存为第一张图  以后 都这样处理 虽然可能处理上耗费些时间 但是网络的负担小很多