Окно захвата C / C ++ без фрейма (иногда работает, отлаживается)

Я был следующим:
http://msdn.microsoft.com/en-us/library/windows/desktop/dd183402%28v=vs.85%29.aspx

Чтобы захватить область рисования окон ака printscreen это.

Важная функция — «int CaptureAnImage (HWND hWnd)», и каждый работает нормально, когда я копирую его прямо и отправляю законный hWnd.

Однако мне нужно иметь возможность хранить его вне этой функции (возвращать его как растровое изображение), поэтому я создал свою собственную структуру «printscreen».

struct PrintScreen {
BITMAP * bmpScreen;
BITMAPFILEHEADER  * bmfHeader;
BITMAPINFOHEADER  * bi;
char * data;
DWORD len;
};

и изменился, так что он выделяет память, и вместо этого я использую указатели в функции.

(Новый код с использованием выделенной памяти и указателей)

    struct PrintScreen * CaptureAnImage(HWND hWnd)
{
HDC hdcScreen;
HDC hdcWindow;
HDC hdcMemDC = NULL;
HBITMAP hbmScreen = NULL;BITMAP * bmpScreen = GlobalAlloc(GMEM_FIXED,sizeof(BITMAP));
BITMAPFILEHEADER  * bmfHeader = GlobalAlloc(GMEM_FIXED,sizeof(BITMAPFILEHEADER));
BITMAPINFOHEADER  * bi = GlobalAlloc(GMEM_FIXED,sizeof(BITMAPINFOHEADER));
struct PrintScreen * printScreen = GlobalAlloc(GMEM_FIXED,sizeof(struct PrintScreen));

// Retrieve the handle to a display device context for the client
// area of the window.
hdcScreen = GetDC(NULL);
hdcWindow = GetDC(hWnd);

// Create a compatible DC which is used in a BitBlt from the window DC
hdcMemDC = CreateCompatibleDC(hdcWindow);

if(!hdcMemDC)
{
printf("Bajs");
MessageBox(hWnd, _T("CreateCompatibleDC has failed"),_T("Failed"), MB_OK);
goto done;
}

// Get the client area for size calculation
RECT rcClient;
if(!GetClientRect(hWnd, &rcClient)) {
printf("Treash");
}
printf("Rect:%d,%d,%d,%d\n",rcClient.right,rcClient.top, rcClient.left,rcClient.bottom);
//This is the best stretch mode
SetStretchBltMode(hdcWindow,HALFTONE);
SetBrushOrgEx(hdcWindow,0,0,NULL);
//The source DC is the entire screen and the destination DC is the current window (HWND)
if(!StretchBlt(hdcWindow,
0,0,
rcClient.right, rcClient.bottom,
hdcScreen,
0,0,
GetSystemMetrics (SM_CXSCREEN),
GetSystemMetrics (SM_CYSCREEN),
SRCCOPY))
{
printf("Bajs");
MessageBox(hWnd, _T("StretchBlt has failed"),_T("Failed"), MB_OK);
goto done;
}

// Create a compatible bitmap from the Window DC
hbmScreen = CreateCompatibleBitmap(hdcWindow, rcClient.right-rcClient.left, rcClient.bottom-rcClient.top);
printf("\n%ld\n",rcClient.right);
if(!hbmScreen)
{
MessageBox(hWnd, _T("CreateCompatibleBitmap Failed"),_T("Failed"), MB_OK);
goto done;
}

// Select the compatible bitmap into the compatible memory DC.
SelectObject(hdcMemDC,hbmScreen);

// Bit block transfer into our compatible memory DC.
if(!BitBlt(hdcMemDC,
0,0,
rcClient.right-rcClient.left, rcClient.bottom-rcClient.top,
hdcWindow,
0,0,
SRCCOPY))
{
MessageBox(hWnd, _T("BitBlt has failed"), _T("Failed"), MB_OK);
goto done;
}

// Get the BITMAP from the HBITMAP
GetObject(hbmScreen,sizeof(BITMAP),bmpScreen);bi->biSize = sizeof(BITMAPINFOHEADER);
bi->biWidth = bmpScreen->bmWidth;
bi->biHeight = bmpScreen->bmHeight;
bi->biPlanes = 1;
bi->biBitCount = 32;
bi->biCompression = BI_RGB;
bi->biSizeImage = 0;
bi->biXPelsPerMeter = 0;
bi->biYPelsPerMeter = 0;
bi->biClrUsed = 0;
bi->biClrImportant = 0;

DWORD dwBmpSize = ((bmpScreen->bmWidth * bi->biBitCount + 31) / 32) * 4 * bmpScreen->bmHeight;

// Starting with 32-bit Windows, GlobalAlloc and LocalAlloc are implemented as wrapper functions that
// call HeapAlloc using a handle to the process's default heap. Therefore, GlobalAlloc and LocalAlloc
// have greater overhead than HeapAlloc.
char *lpbitmap = (char *)GlobalAlloc(GMEM_FIXED,dwBmpSize);

// Gets the "bits" from the bitmap and copies them into a buffer
// which is pointed to by lpbitmap.
GetDIBits(hdcWindow, hbmScreen, 0,
(UINT)bmpScreen->bmHeight,
lpbitmap,
(BITMAPINFO *)bi, DIB_RGB_COLORS);//findInvWindow(bmpScreen, lpbitmap);

// A file is created, this is where we will save the screen capture.
HANDLE hFile = CreateFile(_T("C:\\Users\\Hugo\\Dropbox\\Code blocks\\Test\\Poe Test\\bin\\Debug\\captureqwsx.bmp"),
GENERIC_WRITE,
0,
NULL,
CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL, NULL);

if(hFile ==  INVALID_HANDLE_VALUE) {
printf("Error creating file");
}
printf("Done");

// Add the size of the headers to the size of the bitmap to get the total file size
DWORD dwSizeofDIB = dwBmpSize + sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
printf("Size:%d\n",dwBmpSize);
//Offset to where the actual bitmap bits start.
bmfHeader->bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER) + (DWORD)sizeof(BITMAPINFOHEADER);

//Size of the file
bmfHeader->bfSize = dwSizeofDIB;

//bfType must always be BM for Bitmaps
bmfHeader->bfType = 0x4D42; //BM

DWORD dwBytesWritten = 0;
WriteFile(hFile, (LPSTR)bmfHeader, sizeof(BITMAPFILEHEADER), &dwBytesWritten, NULL);
WriteFile(hFile, (LPSTR)bi, sizeof(BITMAPINFOHEADER), &dwBytesWritten, NULL);
WriteFile(hFile, (LPSTR)lpbitmap, dwBmpSize, &dwBytesWritten, NULL);//Close the handle for the file that was created
CloseHandle(hFile);printScreen->bmpScreen = bmpScreen;
printScreen->bmfHeader = bmfHeader;
printScreen->bi = bi;
printScreen->data = lpbitmap;
printScreen->len = dwSizeofDIB;

//Clean up
done:
DeleteObject(hbmScreen);
DeleteObject(hdcMemDC);
ReleaseDC(NULL,hdcScreen);
ReleaseDC(hWnd,hdcWindow);

return printScreen;
}

Моя проблема в том, что иногда она работает нормально, и я получаю законный экран печати без рамок, но время от времени я также получаю рамки, размер изображения не меняется, но он сжимает его, так что рамка окна тоже внутри.

Я попытался отладить, какая функция могла бы справиться с этим и так далее, но вроде как новичок в C, и с моей точки зрения все функции говорят, что они успешны.

РЕДАКТИРОВАТЬ:
С рамкой
http://i62.tinypic.com/2uifyj4.jpg

Без, как и должно быть: (редактировать по ссылке)
http://i.stack.imgur.com/iMxhM.jpg

извините за не прямую ссылку, но для этого нужно немного реп. И не может публиковать более 2 ссылок, по-видимому.

EDIT2:
Очевидно, ошибка не в том, что кадр добавляется, вместо того, чтобы захватывать данные окна, он захватывает все, что находится «над / внутри» всего окна, включая кадры.

До сих пор не знаю, что заставляет его иногда получать правильные данные, а иногда нет. Все функции возвращают успех … (Обновленная картинка «frame» для отображения ошибки)

1

Решение

Задача ещё не решена.

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]