SelectObject 関数利用時の注意事項

Last Update: feedback 共有

こんにちは、Japan Developer Support Core チームです。

今回は、アプリケーションで GDI を利用する際に注意していただきたいことをご案内します。
2021 年 3 月 以降の更新プログラムを適用すると GDI 関連の処理が厳格化され、以前動作していた特定のコード(例:プリンターに画像を出力する)が失敗するようになりましたので、以下に該当される場合にはアプリケーションの修正をお願いします。

詳細情報

SelectObject 関数で デバイス コンテキスト (Device Context、以下 DC) に デバイス依存ビットマップ (Device-Dependent Bitmap、以下 DDB) を設定する場合は、DCと DDB が適切に対応するよう、デバイスに対応する DC から生成したメモリDCに対し、同様にデバイスに対応する DC を指定して CreateCompatibleBitmap 関数等で生成した DDB を設定する必要があります。

特に、CreateCompatibleDC 関数では、引数に NULL を指定した場合は、アプリケーションの現在のスクリーンに対応する メモリ DC を生成しますので、以下のコード例のように、スクリーンに対応したメモリ DC に対してプリンター DC に基づき生成された DDB を SelectObject 関数で設定しないように注意してください。

1
2
3
4
HDC printerDC = myPrintDlg.hDC;     
HDC compatibleDC = CreateCompatibleDC(NULL);  // スクリーン DC を基にメモリDC が生成されます
HBITMAP printerBmp = CreateCompatibleBitmap(printerDC, nWidth, nHeight);  // プリンター DC を基に DDB が生成されます
HGDIOBJ hgdiOld = SelectObject(compatibleDC, printerBmp);

また、2021 年 3 月以降の更新プログラムを適用した OS では GDI 関連の処理が厳格化され、このようなコードでは SelectObject 関数の実行が失敗するようになりました。このため、前述のようなコードを利用されていた場合には、適切な DC から メモリ DC を生成するなど修正をお願いします。

1
2
3
4
HDC printerDC = myPrintDlg.hDC;
HDC compatibleDC = CreateCompatibleDC(printerDC);  // プリンター DC を基にメモリDCが生成されます
HBITMAP printerBmp = CreateCompatibleBitmap(printerDC, nWidth, nHeight);  // プリンター DC を基に DDB が生成されます
HGDIOBJ hgdiOld = SelectObject(compatibleDC, printerBmp);

参考情報

CreateCompatibleDC function (wingdi.h)
https://docs.microsoft.com/en-us/windows/win32/api/wingdi/nf-wingdi-createcompatibledc

CreateCompatibleBitmap function (wingdi.h)
https://docs.microsoft.com/en-us/windows/win32/api/wingdi/nf-wingdi-createcompatiblebitmap

SelectObject function (wingdi.h)
https://docs.microsoft.com/en-us/windows/win32/api/wingdi/nf-wingdi-selectobject


本ブログの内容は弊社の公式見解として保証されるものではなく、開発・運用時の参考情報としてご活用いただくことを目的としています。もし公式な見解が必要な場合は、弊社ドキュメント (https://docs.microsoft.comhttps://support.microsoft.com) をご参照いただくか、もしくは私共サポートまでお問い合わせください。