WINAPIについての質問です

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
びぎなぁ

WINAPIについての質問です

#1

投稿記事 by びぎなぁ » 13年前

コード:

HDC CreateEmptyBMP(HDC hdc, int width, int height){
    HBITMAP hbmp;
    HDC hdc_work;

    hbmp = CreateCompatibleBitmap(hdc, width, height);
    hdc_work = CreateCompatibleDC(hdc);
    SelectObject(hdc_work, hbmp);
    PatBlt(hdc_work, 0, 0, width, height, WHITENESS); // 白で塗りつぶす
    DeleteObject(hbmp);
    return hdc_work;
}
メインループ内で(~はその他最低限必要なものが記述されていると思ってください、変数宣言、メッセージ処理など)

コード:

int WINAPI WinMain(~){
    //変数宣言
    ~
    HDC hDC_Test;
    ~
    while(1){
        ~
        hDC_Test = CreateEmptyBMP(~);
    }
    return 0;
}
このように何度も呼び出した場合、上の関数のhdc_workは自動解放されますか?

某所でも質問したのですが、あまりにも酷いコードと言われるだけで、なんの建設的な回答すら得られなかったので
具体的にどのあたりが悪いコードなのかもご教授いただければ嬉しいです。

YuO
記事: 947
登録日時: 15年前
住所: 東京都世田谷区

Re: WINAPIについての質問です

#2

投稿記事 by YuO » 13年前

WindowsのGDIオブジェクトやカーネルオブジェクトは,プロセス終了時まで自動的に解放されることはありません。
そもそも,ハンドルが使われていないことをWindowsが検知することは不可能ですから。

さらに,選択された状態のGDIオブジェクトをDeleteObjectすることはできません。
DeleteObject functionのReturn Valueの所にも,
「成功すれば非0を,ハンドルが無効かDCに選択されていれば0を返す」という書き方で,DCに選択されているオブジェクトをDeleteObjectできないことが書かれています。

どちらもリソースリークなので,いつかCreateCompatibleBitmapやCreateCompatibleDCで失敗します。

びぎなぁ

Re: WINAPIについての質問です

#3

投稿記事 by びぎなぁ » 13年前

なるほど。やはりリークしてるんですね。

解放系はすべてif文で返却値を確認したほうがよさそうかな。
少し自分で調べて改良してみます。

ありがとうございました。

ISLe
記事: 2650
登録日時: 15年前
連絡を取る:

Re: WINAPIについての質問です

#4

投稿記事 by ISLe » 13年前

CreateCompatibleDCで作成したデバイスコンテキストはDeleteDCを使って削除します。
自動的には削除されません。

あらかじめDeletObjectしておけば、デバイスコンテキストの消滅に合わせてビットマップも消滅すると考えたのでしょうが、ビットマップオブジェクトにスマートポインタのような機能はありません。
そもそもビットマップオブジェクトは複数のデバイスコンテキストに選択することはできないので、特定のデバイスコンテキストと結び付けてしまうとデバイスの変化に対応できません。

描画する直前に描画対象と互換性のあるデバイスコンテキストを作成、ビットマップを選択、描画、描画後にビットマップを選択解除、速やかに互換性のあるデバイスコンテキストを削除、とするのが一般的です。

デスクトップ画面に描画するだけだからといって、プログラム起動時に作成したデスクトップ画面と互換性のあるデバイスコンテキストがプログラム終了時まで互換性を維持できるとも限りません。提示されたようなコードだとプログラム実行中にふいに画面の描画が無くなる可能性が無きにしもあらずです。

閉鎖

“C言語何でも質問掲示板” へ戻る