4

Windowsでカーソルアイコンを取得したい。使用する言語はここではあまり重要ではないと思うので、使用しようとしている WinAPI 関数を使用して疑似コードを記述します。

c = CURSORINFO.new(20, 1, 1, POINT.new(1,1));
GetCursorInfo(c); #provides correctly filled structure with hCursor

DrawIcon(GetWindowDC(GetForegroundWindow()), 1, 1, c.hCursor);

したがって、この部分は正常に機能し、アクティブなウィンドウに現在のカーソルを描画します。しかし、それは私が望むものではありません。ピクセルの配列を取得したいので、メモリに描画する必要があります。

私はこのようにしようとしています:

hdc = CreateCompatibleDC(GetDC(0)); #returns non-zero int
canvas = CreateCompatibleBitmap(hdc, 256, 256); #returns non-zero int too

c = CURSORINFO.new(20, 1, 1, POINT.new(1,1));
GetCursorInfo(c);

DrawIcon(hdc, 1, 1, c.hCursor); #returns 1
GetPixel(hdc, 1, 1); #returns -1

GetPixel() が COLORREF を返さないのはなぜですか? 私は何が欠けていますか?

私は WinAPI の経験があまりないので、おそらくばかげた間違いをしているのでしょう。

4

1 に答える 1

6

デバイス コンテキストに作成するビットマップを選択する必要があります。そうでない場合、GetPixel関数CLR_INVALIDは(0xFFFFFFFF)を返します。

デバイス コンテキスト内でビットマップを選択する必要があります。それ以外の場合CLR_INVALIDは、すべてのピクセルで返されます。

また、あなたが示した疑似コードは、オブジェクトをひどくリークしています。を呼び出すときはいつでもGetDC、使い終わったら呼び出す必要があります。ReleaseDCまた、GDI オブジェクトを作成した場合は、使用が終了したら破棄する必要があります。

最後に、原点 (左上の点) の座標が (1, 1) であると想定しているようです。それらは実際には (0, 0) です。

これが私が書くコードです(簡潔にするためにエラーチェックは省略されています):

// Get your device contexts.
HDC hdcScreen = GetDC(NULL);
HDC hdcMem = CreateCompatibleDC(hdcScreen);

// Create the bitmap to use as a canvas.
HBITMAP hbmCanvas = CreateCompatibleBitmap(hdcScreen, 256, 256);

// Select the bitmap into the device context.
HGDIOBJ hbmOld = SelectObject(hdcMem, hbmCanvas);

// Get information about the global cursor.
CURSORINFO ci;
ci.cbSize = sizeof(ci);
GetCursorInfo(&ci);

// Draw the cursor into the canvas.
DrawIcon(hdcMem, 0, 0, ci.hCursor);

// Get the color of the pixel you're interested in.
COLORREF clr = GetPixel(hdcMem, 0, 0);

// Clean up after yourself.
SelectObject(hdcMem, hbmOld);
DeleteObject(hbmCanvas);
DeleteDC(hdcMem);
ReleaseDC(hdcScreen);

ただし、最後の警告として、DrawIcon関数は期待どおりに機能しない可能性があります。デフォルトのサイズでのアイコンまたはカーソルの描画に制限されています。ほとんどのシステムでは、32x32 になります。ドキュメントから:

DrawIconアイコンのシステム メトリック値によって指定された幅と高さを使用して、アイコンまたはカーソルを描画します。詳細については、 を参照してくださいGetSystemMetrics

代わりに、DrawIconEx関数を使用することをお勧めします。次のコードは、リソースの実際のサイズでカーソルを描画します。

DrawIconEx(hdcMem, 0, 0, ci.hCursor, 0, 0, 0, NULL, DI_NORMAL);
于 2012-05-06T10:09:04.253 に答える