Возникла необходимость сделать снимок экрана windows (нужно и в linux но это отдельная история ) в QT4.
Насколько понял, платформонезависимого способа нет поэтому решил использовать в windows winAPI.
Компилирую в QT 4.3.0 + MinGW + QDevelop
Код:
BOOL save2bitmap(HWND hWnd,HBITMAP hBitmap)
{
TCHAR szFileName[MAX_LOADSTRING] = {'x','f','i','l','e'};
BITMAP bmp;
BITMAPINFO *pbmi,bmi;
BITMAPFILEHEADER bfh;
WORD wClrBits;
HANDLE hFile;
LPBYTE lpData;
HDC hDC, hTempDC;
unsigned long ulWritten;
//Получение параметров рисунка
if (!GetObject(hBitmap,sizeof(bmp),&bmp))
return FALSE;
//Количество битов под пиксель
wClrBits = (WORD)(bmp.bmPlanes*bmp.bmBitsPixel);
if (wClrBits == 1);
else if (wClrBits <=4)
wClrBits = 4;
else if (wClrBits <=8)
wClrBits = 8;
else if (wClrBits <=16)
wClrBits = 16;
else if (wClrBits <=24)
wClrBits = 24;
else if (wClrBits <=32)
wClrBits = 32;
//Выделение памяти для BITMAPINFO
if (wClrBits !=24)
pbmi = (PBITMAPINFO)LocalAlloc(LPTR,sizeof(BITMAPINFOHEADER) +
sizeof(RGBQUAD)*(1<<wClrBits));
else
pbmi = (PBITMAPINFO)LocalAlloc(LPTR,sizeof(BITMAPINFOHEADER));
//Заполнение BITMAPINFO
pbmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
pbmi->bmiHeader.biHeight = bmp.bmHeight;
pbmi->bmiHeader.biWidth = bmp.bmWidth;
pbmi->bmiHeader.biPlanes = bmp.bmPlanes;
pbmi->bmiHeader.biBitCount = bmp.bmBitsPixel;
if (wClrBits <24)
pbmi->bmiHeader.biClrUsed = (1<<wClrBits);
pbmi->bmiHeader.biCompression = BI_RGB;
//..количество памяти, необходимоц для таблицы цветов
pbmi->bmiHeader.biSizeImage = ((bmp.bmWidth*wClrBits+31)&~31)/8
* bmp.bmHeight;
pbmi->bmiHeader.biClrImportant = 0;
//Получение памяти под таблицу цветов и массив индексов
lpData = (LPBYTE) GlobalAlloc(GMEM_FIXED,pbmi->bmiHeader.biSizeImage);
if (!lpData)
return FALSE;
//Копирование таблицы цветов в выделенную область памяти
hDC = GetDC(hWnd);
hTempDC = CreateCompatibleDC(hDC);
ReleaseDC(hWnd,hDC);
SelectObject(hTempDC,hBitmap);
bmi = *pbmi;
if (!GetDIBits(hTempDC,hBitmap,0,(WORD)bmp.bmHeight,lpData,&bmi,DIB_RGB_COLORS))
{
ReleaseDC(hWnd,hDC);
//DeleteDC(hTempDC);
GlobalFree((HGLOBAL) lpData);
return FALSE;
}
ReleaseDC(hWnd,hDC);
//DeleteDC(hTempDC);
//Создание файла
if ((hFile=CreateFile(szFileName,GENERIC_WRITE,0,NULL,CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL,NULL)) == INVALID_HANDLE_VALUE)
{
GlobalFree((HGLOBAL) lpData);
return FALSE;
}
//Заполняем структуру информации о файле
bfh.bfType = 0x4d42;
bfh.bfSize = (DWORD)(sizeof(BITMAPFILEHEADER) + pbmi->bmiHeader.biSize +
pbmi->bmiHeader.biClrUsed*sizeof(RGBQUAD) + pbmi->bmiHeader.biSizeImage);
bfh.bfReserved1 = 0;
bfh.bfReserved2 = 0;
//Смещение данных рисунка от начала файлаэ
bfh.bfOffBits = (DWORD)(sizeof(BITMAPFILEHEADER) + pbmi->bmiHeader.biSize +
pbmi->bmiHeader.biClrUsed*sizeof(RGBQUAD));
//Запись данных в файл
//..BITMAPFILEHEADER
if (!WriteFile(hFile,&bfh,sizeof(bfh),&ulWritten,NULL))
{
GlobalFree(lpData);
CloseHandle(hFile);
return FALSE;
}
//..BITMAPINFOHEADER и RGBQUAD
if (!WriteFile(hFile,&pbmi->bmiHeader,sizeof(BITMAPINFOHEADER) +
pbmi->bmiHeader.biClrUsed*sizeof(RGBQUAD),&ulWritten,NULL))
{
GlobalFree(lpData);
CloseHandle(hFile);
return FALSE;
}
//..массив цветов и индексов
if (!WriteFile(hFile,lpData,pbmi->bmiHeader.biSizeImage,&ulWritten,NULL))
{
GlobalFree(lpData);
CloseHandle(hFile);
return FALSE;
}
//Запись закончена
CloseHandle(hFile);
return TRUE;
}
получаю отчёт
Код:
Сборка (make)...
C:/MinGW/bin/mingw32-make.exe -f Makefile.Release
mingw32-make.exe[1]: Entering directory `D:/dev/c/QT+Mingw/fileUp2/bmpToFile/b2f'
g++ -enable-stdcall-fixup -Wl,-enable-auto-import -Wl,-enable-runtime-pseudo-reloc -Wl,-s -Wl,-subsystem,console -mthreads -Wl -o bin\b2f.exe build/dialogimpl.o build/main.o build/moc_dialogimpl.o -L"c:\Qt\4.3.3\lib" -lQtGui4 -lQtCore4
mingw32-make.exe[1]: Leaving directory `D:/dev/c/QT+Mingw/fileUp2/bmpToFile/b2f'
build/dialogimpl.o(.text+0xa39):dialogimpl.cpp: undefined reference to `GetObjectW@12'
build/dialogimpl.o(.text+0xb70):dialogimpl.cpp: undefined reference to `CreateCompatibleDC@4'
build/dialogimpl.o(.text+0xb9e):dialogimpl.cpp: undefined reference to `SelectObject@8'
build/dialogimpl.o(.text+0xbe8):dialogimpl.cpp: undefined reference to `GetDIBits@28'
collect2: ld returned 1 exit status
mingw32-make.exe[1]: *** [bin\b2f.exe] Error 1
C:\MinGW\bin\mingw32-make.exe: *** [release] Error 2
---------------------- Сборка завершена с 2 ошибками ----------------------
Функция GetObjectW' объявлена в файле wingdi.h, но его подключение не помогло.
Есть ли какой то другой способ сохранить в файл снимок окна в С++ вообще и в QT в частности?
Также буду очень благодарен за информацию как то же сделать в linux.
Большое спасибо всем кто откликнется, Андрей.