0

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.

Richard Heap
  • 48,344
  • 9
  • 130
  • 112

0 Answers0