• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:InvalidateRgn()について)

InvalidateRgn()について

このQ&Aのポイント
  • InvalidateRgn()を使用したプログラムで円の部分が欠ける問題について
  • ペンの太さに応じた余白を設定することで問題が解決した
  • ペンの太さによって欠ける部分が異なる理由について

質問者が選んだベストアンサー

  • ベストアンサー
  • redfox63
  • ベストアンサー率71% (1325/1856)
回答No.1

InvalidateRgnで無効にした領域だけを再描画するため 右下が欠けたようになるのだと思います CreateEllipticRgnでリュージョンを生成するのを 描画側でやります 描画には FillRgnとFrameRgnで行い 描画位置更新イベント側では GetRgnBoxでリュージョンの矩形範囲を取得し 進行方向へ膨らませて InvalidateRectを実行して見ましょう // 描画側 hRgn = CreateEllipticRgn(x - hankei, y - hankei, x + hankei, y + hankei); HBRUSH hBrFrame = CreateSolidBrush(RGB(255,0,0)); // hBr: 塗りつぶしようのブラシは生成済みと仮定 FillRgn(hWnd, hRgn, hBr); FrameRgn(hWnd, hRgn, hBrFrame, 3, 3); DeleteObject(hBrFrame); // 消去側 RECT r = {0}; if (hRgn) {   // 矩形範囲を取得   GetRgnBox(hRgn, &r);   // 再描画の増分を考慮   r.right += 4;   r.bottom += 2;   /*     左上に動かすなら left, topを更新     右上なら right,top     左下なら left,bottom   */   InvalidateRect(hWnd, &r, TRUE);   // 使用済みなので リュージョンを破棄   if (DeleteObject(hRgn)) {     hRgn = NULL;   } } x += 4; y += 2;

luna3x
質問者

補足

回答ありがとうございます。 InvalidateRgnを使ったとき背面消去だけリージョンの範囲で行われて 描画は全範囲で行われるものと勘違いしていました。 消去も描画もリージョンの部分のみ行われていたから進行方向のはみだした 部分について描画されなかったんですね。 描画はペンとブラシでEllipse()を使っていたんですが、 FillRgnとFrameRgnでやるんですね。 これを使えばペンの太さとか気にせずに 描画した部分に対してぴったり無効化の範囲を指定できるって事でしょうか? また更新部分のリージョンの指定で以下のようなものを考えてみたのですが 矩形の方が処理が早いとか何かメリットがあるんでしょうか? それとも今回の質問の問題箇所がそれで解決されるので簡単にして書いただけですかね? またいくつか質問になってしまいましたが、よろしくお願い致します。 hRgn1 = CreateEllipticRgn(x - hankei, y - hankei, x + hankei, y + hankei); ボールの位置を変化させる(x,yを変化させる) hRgn2 = CreateEllipticRgn(x - hankei, y - hankei, x + hankei, y + hankei); CombineRgn(hRgn1, hRgn1, hRgn2, RGN_OR); InvalidateRgn(hWnd, hRgn1, TRUE); Sleep(50);

その他の回答 (1)

  • redfox63
  • ベストアンサー率71% (1325/1856)
回答No.2

Ellipseでの描画は 指定された矩形範囲に内接する楕円を描画するのですが 内接するのはペンの中心です // Pen,Brushは選択済みとします Ellipse(hdc, 50, 50, 100, 100); hRgn = CreateEllipseRgn(50,50,100,100); InvalidateRgn(hWnd, hRgn, TRUE); といったコード実行すると Ellipseで描画した縁が消去されないと思います FillRgn/FrameRgnを使えば 生成したリュージョン内での描画になるので上記のような問題は解決されるでしょう 再描画に関してですが WM_PAINTイベントの実装により変わってきますよ BeginPaintを呼び出した際に 返される PAINTSTRUCT構造体psのrcPaintが無効にされた領域です rcPaintだけを BitBltなどで転送する実装だと GetRgnBoxで取得できる領域と等価だとおもいます 無関係にクライアント領域を書き直す実装だと 無駄が多いようにおもいます

luna3x
質問者

お礼

試してみて、リージョンによる描画の違いなど理解しました。 ありがとうございました。

関連するQ&A