难道没有知道吗?
push again...

解决方案 »

  1.   

    ~~~~真的没有人知道吗?再push....我每天都来push一下,已经push  N天了。... :-(p.s 谢谢seesi
      

  2.   

    从某种意义上说,也算是吧。
    我用的是ddraw的 Lock。如前面所说,有时取出来的是黑屏。
      

  3.   

    我想给多点分。但不知为什么csdn不让给啊。如果确实能帮我解决这个问题,必谢。不只是csdn这冷冰冰的分数啊。
      

  4.   

    问一下~你的主缓冲的指针怎么得道的?
    lock时的参数是什么
      

  5.   

    部分源码如下:LPDIRECTDRAW lpDD = NULL;
    LPDIRECTDRAWSURFACE lpDDSPrime = NULL;
    LPDIRECTDRAWSURFACE lpDDSBack = NULL;
    LPDIRECTDRAWSURFACE lpDDSGdi = NULL;LPDIRECTDRAWSURFACE lpSurf = NULL;DDSURFACEDESC DDSdesc;
    BOOL m_b24=TRUE;
    rfbServerInitMsg m_scrinfo;
    RECT m_bmrect;struct _BMInfo {
    BITMAPINFO bmi;
    BOOL truecolour;
    RGBQUAD cmap[256];
    } m_bminfo; // 用来保存位图信息的结构
    // DirectX初始化。返回当前表面获取一张屏幕位图的存储空间大小
    int DX_Init()
    {
    HRESULT hr;
    // 初始化directX
    hr = DirectDrawCreate(0, &lpDD, 0);
    if (FAILED(hr))
    return FALSE;

    hr = lpDD->SetCooperativeLevel(NULL, DDSCL_NORMAL);
    if (FAILED(hr))
    return FALSE;

    ZeroMemory(&DDSdesc, sizeof(DDSdesc));
    DDSdesc.dwSize = sizeof(DDSdesc);
    DDSdesc.dwFlags = DDSD_CAPS;
    DDSdesc.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
    hr = lpDD->CreateSurface(&DDSdesc, &lpDDSPrime, 0);
    if (FAILED(hr))
    return FALSE;

    hr = lpDD->GetGDISurface(&lpDDSGdi);
    if (FAILED(hr))
    return FALSE;

    ZeroMemory(&DDSdesc, sizeof(DDSdesc));
    DDSdesc.dwSize = sizeof(DDSdesc);
    DDSdesc.dwFlags = DDSD_ALL;
    hr = lpDDSPrime->GetSurfaceDesc(&DDSdesc);
    if (FAILED(hr))
    return FALSE; // 初始化位图信息
    if ((DDSdesc.dwFlags & DDSD_WIDTH) && (DDSdesc.dwFlags & DDSD_HEIGHT))
    {
    m_bmrect.left = m_bmrect.top = 0;
    m_bmrect.right = DDSdesc.dwWidth;
    m_bmrect.bottom = DDSdesc.dwHeight;
    }
    else
    return FALSE; m_bminfo.bmi.bmiHeader.biCompression = BI_RGB;//BI_BITFIELDS;
    m_bminfo.bmi.bmiHeader.biBitCount = DDSdesc.ddpfPixelFormat.dwRGBBitCount; //m_bminfo.truecolour = DDSdesc.ddpfPixelFormat.dwFlags & DDPF_RGB;
    if(m_bminfo.bmi.bmiHeader.biBitCount > 8)
    m_bminfo.truecolour = TRUE;
    else
    m_bminfo.truecolour = FALSE;

    ZeroMemory(&DDSdesc, sizeof(DDSdesc));
    DDSdesc.dwSize = sizeof(DDSdesc);
    DDSdesc.dwFlags = DDSD_CAPS | DDSD_HEIGHT |DDSD_WIDTH; 
    DDSdesc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
    DDSdesc.dwHeight = m_bmrect.bottom - m_bmrect.top;
    DDSdesc.dwWidth = m_bmrect.right - m_bmrect.left;
    hr = lpDD->CreateSurface(&DDSdesc, &lpDDSBack, 0);
    if (FAILED(hr))
    return FALSE;
    //hr = lpDDSPrime->QueryInterface( IID_IDirectDrawSurface3,  (LPVOID *)&lpSurf);
    //if (FAILED(hr))
    // return FALSE;

    switch (m_bminfo.bmi.bmiHeader.biBitCount)
    {
    case 32:
    case 24:
    // Update the bitmapinfo header
    m_b24 = TRUE;
    m_bminfo.bmi.bmiHeader.biSize = sizeof( BITMAPINFOHEADER );
    m_bminfo.bmi.bmiHeader.biWidth = 1024;
    m_bminfo.bmi.bmiHeader.biHeight = 768;
    m_bminfo.bmi.bmiHeader.biPlanes = 1;
    // m_bminfo.bmi.bmiHeader.biBitCount = 24;
    m_bminfo.bmi.bmiHeader.biCompression = BI_RGB;
    m_bminfo.bmi.bmiHeader.biSizeImage =
    abs((m_bminfo.bmi.bmiHeader.biWidth *
    m_bminfo.bmi.bmiHeader.biHeight *
    m_bminfo.bmi.bmiHeader.biBitCount)/ 8);
    m_bminfo.bmi.bmiHeader.biXPelsPerMeter = (1024*1000)/1024;
    m_bminfo.bmi.bmiHeader.biYPelsPerMeter = (768*1000)/768;
    m_bminfo.bmi.bmiHeader.biClrUsed = 0;
    m_bminfo.bmi.bmiHeader.biClrImportant = 0;
    break;
    }  
    return m_bminfo.bmi.bmiHeader.biSizeImage;
    }
    // 捕捉屏幕。rect: 区域。scrBuff: 输出缓冲。scrBuffSize:  缓冲区大小
    BOOL CaptureScreen(RECT &rect, BYTE *scrBuff, UINT scrBuffSize)
    {
    HRESULT hr=0;

    hr = lpDDSBack->BltFast(rect.left,rect.top,lpDDSPrime,&rect,DDBLTFAST_NOCOLORKEY | DDBLTFAST_WAIT);
    if (FAILED(hr))
    {
    return FALSE;
    }

    DDSURFACEDESC surfdesc;
    ZeroMemory(&surfdesc, sizeof(surfdesc)); 
    surfdesc.dwSize = sizeof(surfdesc); hr   = lpDDSBack->Lock(&rect, &surfdesc, DDLOCK_READONLY | DDLOCK_WAIT | DDLOCK_SURFACEMEMORYPTR /*|DDLOCK_NOSYSLOCK*/, NULL);
    //hr   = lpDDSPrime->Lock(&rect, &surfdesc, DDLOCK_READONLY | DDLOCK_WAIT | DDLOCK_SURFACEMEMORYPTR /*|DDLOCK_NOSYSLOCK*/, NULL);
    if (FAILED(hr))
    return FALSE;

    // copy the data into our buffer
    BYTE * destbuffpos, * srcbuffpos;
    m_scrinfo.format.bitsPerPixel = 24;
    srcbuffpos = (BYTE *) surfdesc.lpSurface;
    destbuffpos = scrBuff; memcpy( destbuffpos, srcbuffpos,m_bminfo.bmi.bmiHeader.biSizeImage); // unlock the primary surface
    //lpDDSPrime->Unlock(surfdesc.lpSurface);
    lpDDSBack->Unlock(surfdesc.lpSurface);
    return TRUE;
    }
      

  6.   

    注意到这行语句了吗?memcpy( destbuffpos, srcbuffpos,m_bminfo.bmi.bmiHeader.biSizeImage);我把数据复制到 destbuffpos中输出了。然后我在调用 CaptureScreen() 函数后,我将其数据进行相应处理后保存至文件。请放心,后面的这些步骤是万一无失没有任何错误的。正常情况下,例如在gdi 环境中,保存出来的文件是正常的,在某些DirectX的环境下,保存的文件也是正常的。:-)
      

  7.   

    我关注这问题N天了, 我想通过截获API函数, DirectDrawEx,
    然后通过 GetGDISurface ,得到主表面,然后将这个主表面保存起来,
    不知道行不行。
      

  8.   

    小辉,你就是超级屏捕的作者吧? 我给你写过MAIL 请教过这问题的。
    这问题烦了我很久, 哎,你的DX_Init什么时候运行啊?QQ:5321321
      

  9.   

    小辉,可以给我你的E-MAIL或QQ吗?
      

  10.   

    to alphagx: 呵呵,SuperCapture是我的拙作。本想不继续做下去了,但被人逼着一定要完善。没办法,只好准备升级了。to gosoft:ok,等会联系。qq上见。
      

  11.   

    to alpha:很高兴又碰到你。
      

  12.   

    呵呵,每天上班第一件事:Push!!!
      

  13.   

    不相信这个问题在csdn找不到答案!
      

  14.   

    如何实现游戏截屏功能  现在很多游戏都提供一种截屏的功能,用来截取游戏中的画面,那么这是如何实现的呢?其实就是把游戏当前屏幕的数据存成一个图片文件;在这里我给出一段源程序,它实现了DirectDraw(16位模式)下的的游戏截屏。生成的文件格式为BMP,程序有比较详细的注释,请各位自己看吧。
    bool Is555; // 是否是565模式,这个变量需要用者填写// 功能:将一个16位的DirectDraw表面,存为一张24位BMP位图 (传入主表面即截屏)
    // 输入:表面指针,输出的文件名
    // 输出:是否成功
    bool SaveToBitmapFile(LPDIRECTDRAWSURFACE lpSurface, char* filename)
    {
    WORD* lpBuffer; // 表面指针
    int nPitch;  // 表面跨距
    int nWidth, nHeight; // 表面宽高

    // 打开文件s
    FILE* fp;
    if( (fp=fopen(filename, "wb")) != NULL )
    {
    // 锁定表面
    DDSURFACEDESC ddsd;
    ddsd.dwSize = sizeof(ddsd);
    HRESULT ddrval = lpSurface->Lock( NULL, &ddsd, DDLOCK_WAIT, NULL );
    if( ddrval == DD_OK )
    {
       lpBuffer = (WORD *)ddsd.lpSurface;
    nWidth = ddsd.dwWidth;
    nHeight = ddsd.dwHeight;
    nPitch  = ddsd.lPitch >> 1; //lPitch以Byte为单位,GraphPitch以WORD为单位。所以GraphPitch = lPitch / 2;
    } // 保存文件头
    BITMAPFILEHEADER FileHeader;
    FileHeader.bfType = 'BM';
    FileHeader.bfSize = nWidth * nHeight * 3 + 0x36;
    FileHeader.bfReserved1 = 0;
    FileHeader.bfReserved2 = 0;
    FileHeader.bfOffBits = 0x36;
    fwrite(&FileHeader, sizeof(BITMAPFILEHEADER), 1, fp);

    // 保存文件信息
    BITMAPINFOHEADER Header;
    Header.biSize = sizeof(BITMAPINFOHEADER); // 结构的大小
    Header.biWidth = nWidth; // 宽
    Header.biHeight = nHeight; // 高
    Header.biPlanes = 1; // 固定
    Header.biBitCount = 24; // 颜色数
    Header.biCompression = BI_RGB; // 是否压缩
    Header.biSizeImage = nWidth * nHeight * 3; // 图片的大小
    Header.biXPelsPerMeter = 0;
    Header.biYPelsPerMeter = 0;
    Header.biClrUsed = 0;
    Header.biClrImportant = 0;
    fwrite(&Header, Header.biSize, 1, fp); // 写入具体内容(从下向上存放)
    fseek(fp, 0x36, SEEK_SET);
    WORD word;
    lpBuffer += nWidth * (nHeight - 1);
    for(int i=0; i<nHeight; i++)
    {
    for(int j=0; j<nWidth; j++)
    {
    word = *lpBuffer;
    fputc( GetBlue( word ), fp); // 蓝
    fputc( GetGreen( word ), fp); // 绿
    fputc( GetRed( word ), fp); // 红
    lpBuffer++;
    }
    lpBuffer -= nPitch*2; // 指针转到上一行的开始
    } fclose(fp); // 解锁表面
    ddrval = lpSurface->Unlock( NULL );
    return true;
    } return false;
    }inline unsigned char GetRed(WORD color)
    {
    if( Is555 )
    return (color>>7) & 0xff;
    else
    return (color>>8) & 0xff;
    }inline unsigned char GetGreen(WORD color)
    {
    if( Is555 )
    return (color>>2) & 0xff;
    else
    return (color>>3) & 0xff;
    }

    inline unsigned char GetBlue(WORD color)
    {
    return (color & 0x1f) << 3;
    }
      

  15.   

    当然不行, 你要能得到游戏的主表面才行,你的lpSurface怎么获取啊!
      

  16.   

    谁有兴趣调试Game Master,看他怎么写的。 
    我前几天调的时候看,里面竟然用到了模拟Print Screen,即keybd_event,
    但我想肯定不会这么简单的,
    中国软件水平高的很多,为什么没有人站出来回答这种问题啊??
    奇怪!!! 
      

  17.   

    我现在也写这种程序,计算机的屏幕图象的实时传输,
    当一运行其他的全屏模式的程序,我的程序就会出错。
    在 csdn 上 2001-4-24 8:55:00  挑战CSDN上的DirectX高手!!!!!
    的回帖中有一个叫wyy(紫云) 的说曾看到这样的资料。
    但我找了很长时间一无所获。有谁知道资料的或同wyy(紫云) 
    有联系的请帮帮我。
    我的oicq和e_mail  上面有。
      

  18.   

    回复人:alphagx(alpha) (2001-5-24 16:22:00)  得0分 
    当然不行, 你要能得到游戏的主表面才行,你的lpSurface怎么获取啊!
     
    当然是传进来的了。
    bool SaveToBitmapFile(LPDIRECTDRAWSURFACE lpSurface, char* filename)
      

  19.   

    我是问你传进去的lpSurface是如何得到的
      

  20.   

    昏到!!
    所有操作都在主表面和副表面上进行,只要在某个处理主表面的程序里加个消息处理
    如果想截屏了,就发个消息过去,不就得到了??(这是对局部变量来说。)因为lpSurface一般都是定义成全局变量,所以程序的任何地方都可以使用。