Захват окна Win32 с BitBlt без отображения границы - PullRequest
3 голосов
/ 19 марта 2010

Я написал некоторый код на C ++ для захвата окна в файл .bmp.

BITMAPFILEHEADER get_bitmap_file_header(int width, int height)
{
 BITMAPFILEHEADER hdr;
 memset(&hdr, 0, sizeof(BITMAPFILEHEADER));
 hdr.bfType  = ((WORD) ('M' << 8) | 'B'); // is always "BM"
 hdr.bfSize  = 0;//sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + (width * height * sizeof(int));
 hdr.bfReserved1 = 0;
 hdr.bfReserved2 = 0;
 hdr.bfOffBits = (DWORD)(sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER));

 return hdr;
}

BITMAPINFO get_bitmap_info(int width, int height)
{
 BITMAPINFO bmi;
 memset(&bmi.bmiHeader, 0, sizeof(BITMAPINFOHEADER));
 //initialize bitmap header
 bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
 bmi.bmiHeader.biWidth = width;
 bmi.bmiHeader.biHeight = height;
 bmi.bmiHeader.biPlanes = 1;
 bmi.bmiHeader.biBitCount = 4 * 8;
 bmi.bmiHeader.biCompression = BI_RGB;
 bmi.bmiHeader.biSizeImage = width * height * 4;

 return bmi;
}

void get_bitmap_from_window(HWND hWnd, int * imageBuff)
{
 HDC hDC = GetWindowDC(hWnd);
 SIZE size = get_window_size(hWnd);
 HDC hMemDC = CreateCompatibleDC(hDC);
 RECT r;

 HBITMAP hBitmap = CreateCompatibleBitmap(hDC, size.cx, size.cy);
 HBITMAP hOld = (HBITMAP)SelectObject(hMemDC, hBitmap);

 BitBlt(hMemDC, 0, 0, size.cx, size.cy, hDC, 0, 0, SRCCOPY);
    //PrintWindow(hWnd, hMemDC, 0);

 BITMAPINFO bmi = get_bitmap_info(size.cx, size.cy);
 GetDIBits(hMemDC, hBitmap, 0, size.cy, imageBuff, &bmi, DIB_RGB_COLORS);

 SelectObject(hMemDC, hOld);
    DeleteDC(hMemDC);
    ReleaseDC(NULL, hDC);
}

void save_image(HWND hWnd, char * name)
{
 int * buff;
 RECT r;
 SIZE size;

 GetWindowRect(hWnd, &r);
 size.cx = r.right-r.left;
 size.cy = r.bottom-r.top;

 buff = (int*)malloc(size.cx * size.cy * sizeof(int));

 get_bitmap_from_window(hWnd, buff);

 BITMAPINFO bmi = get_bitmap_info(size.cx, size.cy);
 BITMAPFILEHEADER hdr = get_bitmap_file_header(size.cx, size.cy);

 FILE * fout = fopen(name, "w");
 fwrite(&hdr, 1, sizeof(BITMAPFILEHEADER), fout);
 fwrite(&bmi.bmiHeader, 1, sizeof(BITMAPINFOHEADER), fout);
 fwrite(buff, 1, size.cx * size.cy * sizeof(int), fout);

 fflush(fout);
 fclose(fout);
 free(buff);
}

Работает поиск под XP, но под Vista граница окна прозрачна.

Использование PrintWindow решает проблему, но недопустимо по соображениям производительности.

Есть ли изменение кода исполнителя или настройка, которую можно изменить, чтобы сделать границу непрозрачной?

Ответы [ 2 ]

0 голосов
/ 12 марта 2014

Используйте ниже вместо

BitBlt(hMemDC, 0, 0, size.cx, size.cy, hDC, 0, 0, SRCCOPY | CAPTUREBLT);
0 голосов
/ 22 марта 2010

Оказывается, это связано с тем, что в окне установлен атрибут WS_EX_LAYERED.

См. http://www.eggheadcafe.com/software/aspnet/31543575/dwm-composition--get-par.aspx для обсуждения связанных вопросов.

Странно, один раз используя PrintWindow, а потом BitBlt решает проблему ...

...