SetROP2を使用時、正常な色で描画されない

[戻る]
じゃこ 2007/06/14(木) 19:03:43
いつもお世話になっております。

WinXP SP2
V6.0 MFC 使用です。

下記のように、SetROP2を使って、CViewに要素を書き、また削除するという事を
繰り返して処理しています。(ラバーバンドのような処理です)
正常に書いて、消してを繰り返しますが、指定した色で描画してくれません。
下記のソースだと白色になるはずですが、何故かうす暗い赤色で描画されます。

SetROP2に渡すパラメータが悪いのか、OnEraseBkgndが悪いのでしょうか?
SetROP2に渡すパラメータはヘルプを読んでも、初心者の私には理解に苦しんで
います。
(色々なモードを試してみましたが同様です)

よくサンプルで、CreateCompatibleDCを使用したソースをよく見ます。
それをしていないのが悪いのでしょうか?

すいませんが、お知恵を借りたいと思います。
よろしくお願いします。

BOOL CMyClassView::TempDraw() 
{
   INT nTempColor[3];
   nTempColor[0] = nTempColor[1] = nTempColor[2] = 0;

   CDC *pDC = GetDC ();
   if (pDC != NULL) {
      // DC をR2_NOTモードに変更
      INT iBeforDrawMode = pDC->SetROP2 (R2_NOT);
   
      // 描画
      TempDraw2 (pDC, nTempColor, PS_SOLID, 1);

      // DC をR2_NOTモードから元に戻す
      pDC->SetROP2 (iBeforDrawMode);
      int iRet = ReleaseDC(pDC);
   }

   return (TRUE);
}

BOOL CMyClassView::TempDraw2(CDC* pDC, INT nWriteColor[3],
                                       INT nWritePenStyle, INT nWritePenWide) 
{
   LOGBRUSH    LogBrush;

   // 初期化
   ZeroMemory( &LogBrush, sizeof(LogBrush) );
   LogBrush.lbStyle = BS_SOLID;

   // ペンの作成
   LogBrush.lbColor = RGB(nWriteColor[0],
                          nWriteColor[1],
                          nWriteColor[2]);
   hPenElem = ExtCreatePen (PS_GEOMETRIC | nWritePenStyle,
                            nWritePenWide, &LogBrush, 0, NULL );
   OldPen = SelectObject( pDC->m_hDC, hPenElem );
   // ブラシの作成
   hBrush = CreateSolidBrush( RGB(nWriteColor[0],
                                  nWriteColor[1],
                                  nWriteColor[2]) );
   OldBrush = SelectObject( pDC->m_hDC, hBrush );

   // ここで描画
   MoveToEx(pDC->m_hDC, p1.x, p1.y, NULL );
   LineTo  (pDC->m_hDC, p2.x, p2.y );

   // ペンの破棄
   SelectObject( pDC->m_hDC, OldPen );
   DeleteObject( hPenElem );
   // ブラシの破棄
   SelectObject( pDC->m_hDC, OldBrush );
   DeleteObject( hBrush );

   return (TRUE);
}

BOOL CMyClassView::OnEraseBkgnd(CDC* pDC) 
{
   CBrush newBrush;
   newBrush.CreateSolidBrush(RGB(m_nBackGoundColor[0],
                                 m_nBackGoundColor[1],
                                 m_nBackGoundColor[2] ));
   // 変更する背景色のブラシを作成
   HBRUSH hOldBrush = (HBRUSH)SetClassLong(GetSafeHwnd(),                                  
                        GCL_HBRBACKGROUND,
                                           (LONG)(HBRUSH)newBrush.m_hObject);
   // 現在の背景色のブラシを変更
   BOOL bRet = CWnd::OnEraseBkgnd(pDC);
   SetClassLong(GetSafeHwnd(),GCL_HBRBACKGROUND,(LONG)hOldBrush);

   return bRet;
    
//    return CView::OnEraseBkgnd(pDC);
}

らら 2007/06/14(木) 19:43:39
>下記のソースだと白色になるはずですが、何故かうす暗い赤色で描画されます。

R2_NOT は ペンの色に関係なく、画面の色を反転させるんじゃなかったかしら。
画面の色が白のときは黒、画面が黒のときは白なので、画面の色によってはうす暗い赤色のこと
もあるのでは?

という意味ではなくてですか?違ったらすみません。

じゃこ 2007/06/14(木) 19:52:43
ららさん
いえ、そうです。投稿してからも色々と試してみましたが、そのようです。
と言う事は、画面のバックグラウンドの色に関わらず、白で描画し、その後で削除
したい場合はどのモードを使えば良いのでしょうか?
本当に初歩的な問題で申し訳ありませんが、ご指示をお願いします。

らら 2007/06/14(木) 20:13:51
SetROP2を使ってそういうことできなかったような・・・。
たとえばドラッグでしたら、MouseMoveのたびにその範囲を再描画する感じでしょうか。
ちらつくようなら、OnDraw()のパラメータのDCに直接描かず、一旦、(CDCとCBitmapを作っ
て)メモリ上に描画してから、BitBltでパラメータのDCに貼り付ける方がいいと思います。

Kerry 2007/06/15(金) 13:11:32
まず、背景色のR2_XORPENで描画(これで背景部分が黒になる)
次に、描画色のR2_XORPENで描画
という2回描く方法があります。

じゃこ 2007/06/15(金) 18:05:16
Kerryさん、ありがとうございます。
やってみます。

じゃこ 2007/06/19(火) 22:10:44
Kerryさん、ありがとうございました。
正常に描画と削除が出来るようになりました。
ただ新たな問題が・・・。
連続線などを描画する際に、線と線の交点部分が表示されません。
(当然と言えば、当然なのかもしれませんが)
これはもうどうしようも無いのでしょうか?
お知恵をお願い致します。

Kerry 2007/06/20(水) 09:39:42
一度メモリDC等に描画し、そのビットマップをXORで転送する、
みたいな方法しかないでしょうねぇ。

じゃこ 2007/06/23(土) 17:41:13
Kerryさん、ありがとうございます。
一度メモリDC等に描画し、そのビットマップをXORで転送する方法を試してみます。

じゃこ 2007/07/13(金) 14:45:34
すっかり遅くなり申し訳ありません。
一度メモリDC等に描画し(バックグラウンドの色は本来の画面の色で作成)、そのビット
マップを転送する方法を試してみようと思っているのですが、その方法が良く分かりません。

BitBltを使って転送しようとしましたが、ラスタ オペレーションにSRCCOPYを指定すると
作成したビットマップによって上書きされ、SRCINVERTを指定すると元々の要素の色まで
変色されます。
SRCPAINTだと変色された色でビットマップが描画されます。

TransparentBltだと透過の処理が出来ましたが、ラスターオペレーションの指定がないの
で、ビットマップの部分のみ描画・消去する事が出来ません。

BitBltを使った透過の処理が必要なのでしょうか?
申し訳ありませんが、ご回答をお願い致します。

yoh2 [E-Mail] 2007/07/13(金) 23:07:52
> バックグラウンドの色は本来の画面の色で作成

ここがおかしいのでしょう。


> まず、背景色のR2_XORPENで描画(これで背景部分が黒になる)
> 次に、描画色のR2_XORPENで描画

と同じ方法で描画したいなら、

1. 黒背景に、背景色で描画したビットマップをSRCINVERTでBitBlt。
2. 黒背景に、描画色で描画したビットマップをSRCINVERTでBitBlt。

ではないかと。

でも、メモリDCを併用した反転処理ができる程メモリ&ビットマップ転送速度に余裕があるのなら、

1. 描画前に、元のビットマップをメモリDCに退避。
2. ペンモードはR2_COPYPENのまま描画色で要素を描画。

として、要素を削除する場合は退避したビットマップを書き戻す、というのが一番素直かも。
背景色以外の部分の色がKerryさんの方法と異なり、問答無用で描画色で上書きされますが、ひとつ目の書
き込みを読む限り、xorがかかった図形が描画されるよりも目的に適っているような気が。

古いスレッドには追加発言できません。