难道没有知道吗?
push again...
push again...
解决方案 »
- mfc中能不能实现类似于qq聊天对话框中“对方形象”左面那个三角形的功能
- 向一个已有的CCmdTarget类中添加一个从IDispatch派生的接口,我是这样做的。
- 点击一个SPIN按钮,它的伴侣控件EDIT显示值会变化,但EDIT的关联值(int m_EditSpeed )却为什么不变??
- CListBox如何隐藏数据
- 是否有两种lib库?
- 用atl做的组件,使用接口函数传递结构给vb用,结构中的时间信息如何定义,如何使用?谢谢
- ADO & ODBC 我应怎样选择? (初学者的困惑和迷茫)
- ***该死的系统..干了些啥?..咋办?...***14~(这里有分捡).
- 高分请教:从事情报系统开发该前途如何?
- 类的堆空间释放
- 巨难的问题
- 控件请教
我用的是ddraw的 Lock。如前面所说,有时取出来的是黑屏。
lock时的参数是什么
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;
}
然后通过 GetGDISurface ,得到主表面,然后将这个主表面保存起来,
不知道行不行。
这问题烦了我很久, 哎,你的DX_Init什么时候运行啊?QQ:5321321
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;
}
我前几天调的时候看,里面竟然用到了模拟Print Screen,即keybd_event,
但我想肯定不会这么简单的,
中国软件水平高的很多,为什么没有人站出来回答这种问题啊??
奇怪!!!
当一运行其他的全屏模式的程序,我的程序就会出错。
在 csdn 上 2001-4-24 8:55:00 挑战CSDN上的DirectX高手!!!!!
的回帖中有一个叫wyy(紫云) 的说曾看到这样的资料。
但我找了很长时间一无所获。有谁知道资料的或同wyy(紫云)
有联系的请帮帮我。
我的oicq和e_mail 上面有。
当然不行, 你要能得到游戏的主表面才行,你的lpSurface怎么获取啊!
当然是传进来的了。
bool SaveToBitmapFile(LPDIRECTDRAWSURFACE lpSurface, char* filename)
所有操作都在主表面和副表面上进行,只要在某个处理主表面的程序里加个消息处理
如果想截屏了,就发个消息过去,不就得到了??(这是对局部变量来说。)因为lpSurface一般都是定义成全局变量,所以程序的任何地方都可以使用。