none
CStatic::SetBitmap の引数:HBITMAP hBitmapについて RRS feed

  • 質問

  • visual studio 2008 VC++(MFCダイアログベース)をやっています。

    ビットマップ画像を元のままの画像サイズではなく、自分でサイズを指定して使いたいと思い 

    m_CStatic_PicBox.SetBitmap
     (
      (HBITMAP)LoadImageW(
       AfxGetResourceHandle(), MAKEINTRESOURCE(IDD_BITMAP1), IMAGE_BITMAP, 100, 100, LR_DEFAULTCOLOR
      )
     );

    というソースを書いています。今のところ、ビルドは通って、動作上の不具合はないのですが、こういうキャストは危険ですか?それともこのまま放置しても大丈夫でしょうか?もし、危険な場合、安全な方法が他にあれば教えて頂ければ幸いです。

    よろしくお願いいたします。

    2010年11月13日 10:51

回答

  • 一応補足しておきます。

    LoadImage 関数で読み込めるのは、アイコン、カーソル、アニメーションカーソル、ビットマップとなっています。ハンドルで言えば、HICON、HCUSOR、HBITMAP の 3 種類が読み込める、という事になります。

    その為、LoadImage 関数は特定のハンドルを返さず、ただの HANDLE を返す API になっているのでしょう。

    言い換えれば、キャストされる事を前提とした API とも言えるわけですので、今回の HBITMAP へのキャストで問題が生じる可能性は無い、と考えます。

    • 回答としてマーク AnalogTerebi 2010年11月14日 9:06
    2010年11月14日 8:18

すべての返信

  • こんにちわ。

    LoadImage 関数が返すのが HANDLE であり、CStatic::SetBitmap 関数の引数が HBITMAP なので、このキャストは大丈夫か、という疑問ですよね。

    CDC::SelectObject の引数と戻り値と同じ感じで処理されるでしょうから、問題なかったと思います。MFC では CGdiObject にまとめられているぐらいですから。

     

    フォーラムの質問の為に省かれていると思いますが、LoadImage が失敗した場合の対処方法と、CStatic が破棄されるタイミングで LoadImage で読み込んだビットマップを DeleteObject するのを忘れない様にする、ぐらいでしょうか。ビットマップハンドルはメンバ変数として確保しておいてもいいでしょうし、破棄するタイミングで CStatic::GetBitmap で取り出してもいいと思います。

     

    個人的には、何故 LoadImageW なのかと、ビットマップなのに IDD_BITMAP1 というコントロール ID なのが気に掛かるぐらいですね。

    2010年11月13日 14:39
  • ミッヒーさんありがとうございます。

     

    LoadImage 関数が返すのが HANDLE であり、CStatic::SetBitmap 関数の引数が HBITMAP なので、このキャストは大丈夫か、という疑問ですよね。

    CDC::SelectObject の引数と戻り値と同じ感じで処理されるでしょうから、問題なかったと思います。MFC では CGdiObject にまとめられているぐらいですから。

    疑問の内容は、おっしゃるとおりの内容です。安易にキャストすると、あとあと嫌なことが起こることもあるので質問させていただきました。

      

    フォーラムの質問の為に省かれていると思いますが、LoadImage が失敗した場合の対処方法と、CStatic が破棄されるタイミングで LoadImage で読み込んだビットマップを DeleteObject するのを忘れない様にする、ぐらいでしょうか。ビットマップハンドルはメンバ変数として確保しておいてもいいでしょうし、破棄するタイミングで CStatic::GetBitmap で取り出してもいいと思います。

     私自身が、widowsに不慣れなもので、 エラー処理についてどうしようか、あまり考えがまとまらず、書いていない場面が多いです。これから少しは何か考えていこうとは思っていますので、参考にさせていただきます。 

    個人的には、何故 LoadImageW なのかと、ビットマップなのに IDD_BITMAP1 というコントロール ID なのが気に掛かるぐらいですね。

     LoadImageWは、現状、あまり深く考えずに書いますので、私にとっては今後の課題です。IDはただのタイプミスです。

     

     

     

     

     

    2010年11月14日 1:36
  • 一応補足しておきます。

    LoadImage 関数で読み込めるのは、アイコン、カーソル、アニメーションカーソル、ビットマップとなっています。ハンドルで言えば、HICON、HCUSOR、HBITMAP の 3 種類が読み込める、という事になります。

    その為、LoadImage 関数は特定のハンドルを返さず、ただの HANDLE を返す API になっているのでしょう。

    言い換えれば、キャストされる事を前提とした API とも言えるわけですので、今回の HBITMAP へのキャストで問題が生じる可能性は無い、と考えます。

    • 回答としてマーク AnalogTerebi 2010年11月14日 9:06
    2010年11月14日 8:18
  • ミッヒーさん、ありがとうございます。

    キャストされる事を前提とした API とも言えるわけですので、今回の HBITMAP へのキャストで問題が生じる可能性は無い、と考えます。

    そういうことなのですね。分かりました。

     

    2010年11月14日 9:06