0

関数の設計に問題があり、適切な解決策が見つかりません (私は C++ の初心者です)。

数日前、これに関連する別の質問をします。

だから、私はスクリーンキャプチャをする機能を持っています。それは完全に機能します。Image実際には、この関数が実装したクラスからオブジェクトを返すようにしたいのです。

基本的には、次のとおりです。

class Image {
public:
    BYTE *bitPointer;
    int width;
    int height;
};

そして、私の機能は次のようなものです:

Image screenCapture(int width, int height) {

    HDC hdcTemp, hdc;
    BYTE* bitPointer;

    hdc = GetDC(HWND_DESKTOP);
    hdcTemp = CreateCompatibleDC(hdc);

    BITMAPINFO bitmap;
    bitmap.bmiHeader.biSize = sizeof(bitmap.bmiHeader);
    bitmap.bmiHeader.biWidth = width;
    bitmap.bmiHeader.biHeight = -height;
    bitmap.bmiHeader.biPlanes = 1;
    bitmap.bmiHeader.biBitCount = 24;
    bitmap.bmiHeader.biCompression = BI_RGB;
    bitmap.bmiHeader.biSizeImage = 0;
    bitmap.bmiHeader.biClrUsed = 0;
    bitmap.bmiHeader.biClrImportant = 0;
    HBITMAP hBitmap = CreateDIBSection(hdcTemp, &bitmap, DIB_RGB_COLORS, (void**)(&bitPointer), NULL, NULL);
    SelectObject(hdcTemp, hBitmap);
    BitBlt(hdcTemp, 0, 0, width, height, hdc, 0, 0, SRCCOPY);
    ReleaseDC(HWND_DESKTOP, hdc);
    DeleteDC(hdcTemp);

    Image screen;
    screen.bitPointer = bitPointer;
    screen.width = width;
    screen.height = height;

    return screen;
}

bitPointer作成された usingは、CreateDIBSection実際には最初のピクセルの値へのポインターです (よく理解していれば)。

次に、単純なループを使用できます。

for (int i = 0; i >= 0; i++) {
        cout << i << ": " << (int)screenCapture(1366, 768).bitPointer[0] << endl;
    }

これが私の問題です。

hBitmap呼び出して解放するDeleteObject(hBitmap)必要があります。そうしないと、メモリスペースがなくなります (そして、ループが最終的にクラッシュします)。

しかし、私はそれをどこで行うべきかわかりません。

関数内で実行したいのですが、 を呼び出すDeleteObject()と、これも破棄されるため、返されたオブジェクトbitPointerからピクセルにアクセスできなくなります。Image実際、bitPointer変数がポインターであるという事実に少し混乱しています。後で破壊されるのを防ぐためにコピーできないことを意味します。解決策が見つかりません。

私が試した2つの解決策:

  • DeleteObject()my classを呼び出すデストラクタを作成しますImage
    デストラクタはループ内だけでなく関数から呼び出されるため、機能しませんでした。
  • HBITMAP hBitmapクラスに属性を追加し、ループ内からImage呼び出します。 それは本当に便利ではありません。さらに、新しい Image オブジェクトを宣言する必要があり、私が書いたループのように匿名で行うことはできません。DeleteObject()

それで、私は立ち往生しています。誰か助けてもらえますか?

4

1 に答える 1

1

screenCapture 関数の引数として hBitmap を渡すことができます。

screenCapture(int width, int height, HBITMAP& hBitmap)

このようにして、Image メンバーに干渉することなく、必要なときにそれを破棄できます。screenCapture関数の外で「空の」hBitmap を宣言し、それを引数として渡します。この関数は参照を使用してオブジェクトを作成し、bitPointer値の使用が完了したら、screenCapture の外でオブジェクトを破棄できます。

すべてのスクリーンショットを保存する必要がある場合は、メモリ量が限られているため、作業バッファーを実装する必要があります。

于 2014-10-09T19:23:40.247 に答える