Implement screenshots with DirectDraw

xiaoxiao2021-03-06  26

In the non-exclusive mode of DirectDraw, the main surface is the current screen. You can directly live the main surface to acquire the main surface image data. However, if you want to perform a lot of data, it is best to build a background surface as the main surface in the system memory. Use BLTFAST to copy a main surface to the background surface, then lock the background surface, then operate, because the CPU is slower than the operation of the memory.

1, initialize DirectDraw

You can respond to the WM_CREATE message and initialize DirectDraw in the onCreate

Void cmainframe :: initdirectX () {

// Create DirectDraw

if (FAILED (DirectDrawCreate (NULL, & ddraw1, NULL))) {TRACE (/ "Couldn / 't create DirectDraw object.//n/");} if (FAILED (ddraw1-> QueryInterface (IID_IDirectDraw2, (LPVOID *) & DDRAW2))) {Trace (/ "couldn / 't query the interface.//n/");} if (ddraw2) {ddraw2-> setCoopeRATIVELEVEL (GetSafehWnd (), DDSCL_NORMAL);} if (DDRAW1) {DDRAW1- > Release (); DDRAW1 = NULL;}

// Create a main surface

HRESULT r; DDSURFACEDESC desc; desc.dwSize = sizeof (desc); desc.dwFlags = DDSD_CAPS; desc.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE; r = ddraw2-> CreateSurface (& desc, & primsurf, 0); if (! R = DD_OK) {AFXMESSAGEBOX (/ "Create Directx Surface Failed /// N /"); PostMessage (WM_Close);} r = DDRAW2-> CreateClipper (0, & Clipper, 0); if (r! = Dd_ok) {AFXMessageBox (/ "CreateClipper Fialed // n / "); PostMessage (WM_Close);} r = clipper-> setWnd (0, getsafehwnd ()); if (r! = dd_ok) {AFXMessageBox (/" sethwnd () failed // n / " ); Postmessage;} r = primsurf-> setClipper; if (r! = Dd_ok) {AFXMESSAGEBOX (/ "setClipper () fem // n /"); postmessage (wm_close);}

// Create a background surface

ZeroMemory (& desc, sizeof (desc)); desc.dwSize = sizeof (desc); desc.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS; desc.dwWidth = :: GetSystemMetrics (SM_CXSCREEN); desc.dwHeight = :: GetSystemMetrics (SM_CYSCREEN) ; Desc.ddscaps.dwcaps = ddscaps_systemMemory | DDSCAPS_OFFSCREENPLAIN; R = DDRAW2-> CreateSurface (& desc, & backss, 0); // Collection Image parameters

DDSURFACEDESC ddsd; ZeroMemory (& ddsd, sizeof (ddsd)); ddsd.dwSize = sizeof (ddsd); backsurf-> GetSurfaceDesc (& ddsd); BitCount = ddsd.ddpfPixelFormat.dwRGBBitCount; lPitch = ddsd.lPitch; dwWidth = ddsd.dwWidth; Dwheight = ddsd.dwheight; dwrbitmask = ddsd.ddpfpixelformat.dwrbitmask; dwgbitmask = ddsd.ddpfpixelformat.dwGbitmask; dwbbitmask = ddsd.ddpfpixelformat.dwbitmask;

/ / Determine the correction of 16bit color (two display formats 565 and 555)

RMOVE = 8;

/ / First assumes 565 format first

Gmove = 3; bmove = 3; if (bitcount == 16) {IF (dwgbitmask == 992) {

// 555 format

Rmove = 7; gmove = 2;} IF (dwgbitmask == 1984)

// 555 format

BMOVE = 2;}}

2, get the start position pointer to image data

DDSURFACEDESC ddsd; ZeroMemory (& ddsd, sizeof (ddsd)); ddsd.dwSize = sizeof (ddsd); if FAILED (backsurf-> Lock (NULL, & ddsd, DDLOCK_WAIT, NULL)) TRACE (/ "backsurf-> lock failed // n / ");

// ddsd.lpsurface is a pointer for image data

3, image data conversion

DirectX is an image format conversion. If you want to get a 24bit image, and the current display mode is 16bit colors, you have to do it yourself (you may find it after reading the code below). The image is inverted, this is what I use to compress the logarithm, you can change its For loop words to change the image).

void CMainFrame :: Conversion () {int x, y; DDSURFACEDESC ddsd; ZeroMemory (& ddsd, sizeof (ddsd)); ddsd.dwSize = sizeof (ddsd); if FAILED (backsurf-> Lock (NULL, & ddsd, DDLOCK_WAIT, NULL )) Trace (/ "backsurf-> lock failed // n /"); byte * Scr = new byte [3 * ddsd.dwheight * ddsd.dwwidth]; Byte * SCRT = SCR; // Surface to RGB Switch (Bitcount )

{Cas 8: {

// trace (/ "8 bit // n /");

BYTE * TEM = (byte *) DDSD.LPSURFACE; PALETTEENTRY Entry [256]; HDC HSCRDC = Createdc (/ "Display /", NULL, NULL, NULL); :: GetSystemPalentries (HSCRDC, 0, 256, Entry); for (Y = (int) dwheight-1; y> = 0; y -) {for (x = 0; x <(int) dwwidth; x ) {* SCRT = entry [TEM [x lpitch * y]]. pered ; * SCRT = entry [TEM [X LPITCH * Y]]. Pegreen; * SCRT = entry [TEM [X LPITCH * Y]]. Peblue;}} Break;} case 16: {

// trace (/ "16 bit // n /");

Word * tem = (word *) DDSD.LPSURFACE; Word Color; for (y = (int) dwheight-1; y> = 0; y -) {for (x = 0; x <(int) LPITCH / 2 ; x ) {color = TEM [x lpitch / 2 * y]; * SCRT = (Byte) ((color & dwrbitmask) >> rmove); * SCRT = (Byte) ((color & dwgbitmask) >> Gmove); * SCRT = (BYTE) ((Color & Dwbbitmask) << bmove);}} Break;} case 24: {

// trace (/ "24 bit // n /");

BYTE * TEM = (Byte *) DDSD.LPSURFACE; for (y = (int) dwheight-1; y> = 0; y -) {for (x = 0; x <(int) dwidth * 3; x = 3) {* SCRT = TEM [x 2 y * lpitch]; * SCRT = TEM [x 1 y * lpitch]; * SCRT = TEM [x y * lpitch];}} Break;} case 32 : {AFXMessageBox (/ "currently does not support 32bit colors // n, adjust to 24bit color or 16bit colors /"); Backsurf-> unlock (null); delete scra; postmessage; break;}} backsurf-> Unlock (null); // In the data processing delete SCR; // data processing is released

}

转载请注明原文地址:https://www.9cbs.com/read-58863.html

New Post(0)