I have extracted my screenshot code from dart Win32 screenshot example (text). I have modified it a little bit to suit my case. Here is my modified code:
Map<int, Pointer<Uint32>> captureImage(int hwnd) {
final hdcScreen = GetDC(NULL); // get the desktop device context
//final hdcWindow = GetDC(hwnd);
final hdcMemDC = CreateCompatibleDC(hdcScreen);
final bmpScreen = calloc<BITMAP>();
try {
// if (hdcMemDC == 0) {
// MessageBox(
// hwnd, TEXT('CreateCompatibleDC failed.'), TEXT('Failed'), MB_OK);
// return;
// }
final rcClient = calloc<RECT>();
GetClientRect(hwnd, rcClient);
//SetStretchBltMode(hdcScreen, HALFTONE);
StretchBlt(
hdcScreen,
0,
0,
rcClient.ref.right,
rcClient.ref.bottom,
hdcScreen,
0,
0,
GetSystemMetrics(SM_CXSCREEN),
GetSystemMetrics(SM_CYSCREEN),
SRCCOPY,
);
final hbmScreen = CreateCompatibleBitmap(
hdcScreen,
rcClient.ref.right - rcClient.ref.left,
rcClient.ref.bottom - rcClient.ref.top);
SelectObject(hdcMemDC, hbmScreen);
BitBlt(hdcMemDC, 0, 0, rcClient.ref.right - rcClient.ref.left,
rcClient.ref.bottom - rcClient.ref.top, hdcScreen, 0, 0, SRCCOPY);
GetObject(hbmScreen, sizeOf<BITMAP>(), bmpScreen);
final bitmapFileHeader = calloc<BITMAPFILEHEADER>();
final bitmapInfoHeader = calloc<BITMAPINFOHEADER>()
..ref.biSize = sizeOf<BITMAPINFOHEADER>()
..ref.biWidth = bmpScreen.ref.bmWidth
..ref.biHeight = bmpScreen.ref.bmHeight
..ref.biPlanes = 1
..ref.biBitCount = 32
..ref.biCompression = BI_RGB;
final dwBmpSize =
((bmpScreen.ref.bmWidth * bitmapInfoHeader.ref.biBitCount + 31) /
32 *
4 *
bmpScreen.ref.bmHeight)
.toInt();
final lpBitmap = calloc<Uint8>(dwBmpSize);
GetDIBits(hdcScreen, hbmScreen, 0, bmpScreen.ref.bmHeight, lpBitmap,
bitmapInfoHeader.cast(), DIB_RGB_COLORS);
final hFile = CreateFile(TEXT('captureqwsz.bmp'), GENERIC_WRITE, 0, nullptr,
CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
final dwSizeOfDIB =
dwBmpSize + sizeOf<BITMAPFILEHEADER>() + sizeOf<BITMAPINFOHEADER>();
bitmapFileHeader.ref.bfOffBits =
sizeOf<BITMAPFILEHEADER>() + sizeOf<BITMAPINFOHEADER>();
bitmapFileHeader.ref.bfSize = dwSizeOfDIB;
bitmapFileHeader.ref.bfType = 0x4D42; // BM
final dwBytesWritten = calloc<DWORD>();
WriteFile(hFile, bitmapFileHeader, sizeOf<BITMAPFILEHEADER>(),
dwBytesWritten, nullptr);
WriteFile(hFile, bitmapInfoHeader, sizeOf<BITMAPINFOHEADER>(),
dwBytesWritten, nullptr);
WriteFile(hFile, lpBitmap, dwBmpSize, dwBytesWritten, nullptr);
CloseHandle(hFile);
print(dwBytesWritten);
Map<int, Pointer<Uint32>> m = <int, Pointer<Uint32>>{
dwSizeOfDIB: dwBytesWritten
};
return m;
} finally {
DeleteObject(hdcMemDC);
ReleaseDC(NULL, hdcScreen);
//ReleaseDC(hwnd, hdcScreen);
}
}
I initially made the return type as Pointer<Uint32>>
and when I print the results it gave me the address of the pointer.
so I needed to convert it to Uint8List
so that I can pass it to Image.memory()
but
.asTypedList(Length) requested for the length of the pointer which is why I made the method returned Map<int,Pointer<Uint32>>
. I had a button in the UI when pressed, a function getScreenshot is called which then calls the above code like this:
void getScreenShot() async {
var test = captureImage(28282);
var imgbyte = test.values.first.asTypedList(test.keys.first);
//print(imgbyte);
//print("LENGTH : ${test.keys.first} ~~~ ${imgbyte.length}");
setState((){
bitmap = Bitmap.fromHeadful(width, height, imgbyte.buffer.asUint8List());
bytes = bitmap.buildHeaded();
screen = Image.memory(bytes!);
});
}
I always get this error in the console : Unhandled Exception: Bad state: Too few elements
I have noticed the problem is from the size of the pointer I don't know how to solve it. Please help me out.
The above is what I've tried out but without any good result.