游戏用的是DirectDraw, 我的截屏是这样做的: 1.hook了DirectDrawCreate获取了LPDIRECTDRAW 2.hook了CreateSurface, 将主表面地址保存起来 3.创建一个离屏surface,将主表面copy到这个离屏表面上,然后输出到文件
现在问题是这个截屏后,若游戏窗口被遮挡,则被遮挡部分无法获取. 这个是什么原因呢? 是这种截图方式不支持遮挡部分截屏呢? 还是说跟游戏主表面的创建有关,有点诡异,游戏窗口大小是800*600,却创建了一个1400*900(显示器大小)的主表面. 还请高手指点下:)
找到原因了,直接取主表面,copy一份到离屏表面,然后打印,那个结果就是遮挡的还是遮挡. 解决方法就是对主表面的blt函数hook,当主表面更新数据时,即调用blt时,此时传入的src表面是未遮挡的,就是麻烦点,那个src表面就是离屏表面,而且是多个拼凑的... 顺便还做了个小测试,在主表面的blt函数中加了个sleep(50),这个cpu占用率就降低了 哈哈哈
现在问题是这个截屏后,若游戏窗口被遮挡,则被遮挡部分无法获取. 这个是什么原因呢? 是这种截图方式不支持遮挡部分截屏呢? 还是说跟游戏主表面的创建有关,有点诡异,游戏窗口大小是800*600,却创建了一个1400*900(显示器大小)的主表面. 还请高手指点下:)
//创建后台表面 if (g_lpDirectDrawCopySurface == NULL) { LPDIRECTDRAW lpDD = NULL; //创建DirectDraw if (FAILED( DirectDrawCreate(NULL,&lpDD,NULL))) { MyTrace(L_ERROR, "Couldn't create DirectDraw object."); return E_FAIL; } if (FAILED(lpDD->SetCooperativeLevel(hwnd/*NULL*/, DDSCL_NORMAL))) { MyTrace(L_ERROR, "SetCooperativeLevel failed."); lpDD->Release(); return E_FAIL; } //创建后台表面 RECT rc; GetClientRect(hwnd, &rc); DDSURFACEDESC desc; ZeroMemory(&desc,sizeof(desc)); desc.dwSize=sizeof(desc); desc.dwFlags= DDSD_WIDTH|DDSD_HEIGHT|DDSD_CAPS; desc.dwWidth=/*::GetSystemMetrics(SM_CXSCREEN); */ /*primedesc.dwWidth*/ /*800*/ rc.right - rc.left; desc.dwHeight=/*::GetSystemMetrics(SM_CYSCREEN); */ /*primedesc.dwHeight*/ /*600*/ rc.bottom - rc.top; desc.ddsCaps.dwCaps = DDSCAPS_SYSTEMMEMORY | DDSCAPS_OFFSCREENPLAIN; if (FAILED(hr = lpDD->CreateSurface(&desc, &g_lpDirectDrawCopySurface, NULL))) { MyTrace(L_ERROR, "CreateSurface copysurface failed.err=0x%x", hr); lpDD->Release(); return E_FAIL; } } RECT rc; //GetWindowRect(hwnd, &rc); GetClientRect(hwnd, &rc); MyTrace(L_DEBUG, "GetClientRect: %d,%d,%d,%d", rc.left, rc.right, rc.top, rc.bottom); DDSURFACEDESC desc; ZeroMemory(&desc,sizeof(desc)); desc.dwSize = sizeof(desc); if (FAILED(hr = g_lpDirectDrawCopySurface->GetSurfaceDesc(&desc))) { MyTrace(L_ERROR, "copysurface GetSurfaceDesc failed.err=0x%x", hr); return E_FAIL; } else { MyTrace(L_DEBUG, "copysurface GetSurfaceDesc successfully, nWidth=%d, nHeight=%d", desc.dwWidth, desc.dwHeight); } if (FAILED(hr = g_lpDirectDrawCopySurface->BltFast(0,0,g_lpDirectDrawPrimeSurface,&rc,DDBLTFAST_NOCOLORKEY| DDBLTFAST_WAIT))) { MyTrace(L_ERROR, "BltFast failed.err=0x%x", hr); return E_FAIL; } if (FAILED(hr = g_lpDirectDrawCopySurface->Lock(NULL, &desc, DDLOCK_WAIT|DDLOCK_NOSYSLOCK,NULL))) { MyTrace(L_ERROR, "Lock failed.err=0x%x", hr); return E_FAIL; } //save to bmp if(SaveToBitmapFile(&desc, pszFilePath) != S_OK) { g_lpDirectDrawCopySurface->Unlock(NULL); MyTrace(L_ERROR, "SaveToBitmapFile failed."); return E_FAIL; } else { g_lpDirectDrawCopySurface->Unlock(NULL); MyTrace(L_DEBUG, "SaveToBitmapFile successfully."); }
找到原因了,直接取主表面,copy一份到离屏表面,然后打印,那个结果就是遮挡的还是遮挡. 解决方法就是对主表面的blt函数hook,当主表面更新数据时,即调用blt时,此时传入的src表面是未遮挡的,就是麻烦点,那个src表面就是离屏表面,而且是多个拼凑的... 顺便还做了个小测试,在主表面的blt函数中加了个sleep(50),这个cpu占用率就降低了 哈哈哈
收藏的用户(0) X
正在加载信息~
推荐阅读
最新回复 (0)
站点信息
- 文章2300
- 用户1336
- 访客10722994
每日一句
All things in their being are good for something.
天生我材必有用。
天生我材必有用。
新会员