- ベストアンサー
VC++のTextOutの再描画の仕方
- VC++6.0のMFCでプログラムを組んでいます。OnDrawクラス内であるテキストデータを読み込んで、配列に格納しておいてその中の値がある値を超えたら、文字表示。超えていなければ文字非表示としようと思っているのですが、初めの評価だけでずっと変わりません。
- 試しに赤色に設定してみたところ、ずっと赤色で表示されることがわかりました。
- インターネット上で情報を検索しましたが、解決策が見つからず困っています。
- みんなの回答 (4)
- 専門家の回答
質問者が選んだベストアンサー
まず、デバイスコンテキストにリージョンを選択するということが何を意味するかです。 SelectObjectの解説には、 > パラメータに領域を指定する形式のメンバ関数は、SelectClipRgn メンバ関数と同じタスクを実行します。 と書かれています。つまり、デバイスコンテキストへの描画を、リージョン内に制限することになります。 CDC::SelectObject http://msdn.microsoft.com/ja-jp/library/sa8ahz7h(v=vs.80).aspx これを解除するには、SelectClipRgnに対してNULLを与えます。 CDC::SelectClipRgn http://msdn.microsoft.com/ja-jp/library/txy5hzk3(v=vs.80).aspx 次に、PaintRgnの解説では、単に領域を塗りつぶすとされています。この機能を使用する前に、リージョンを選択する必要があるとはかかれていません。今、開発環境がないので試せませんが、おそらくSelectObjectでリージョンを選択しなくても、PaintRgnは動作します。 CDC::PaintRgn http://msdn.microsoft.com/ja-jp/library/z38612dh(v=vs.80).aspx さらに、フォント・ペン・ビットマップ・ブラシなどを作成した場合は、それを削除しなければなりません。CFont・CPen・CBitmap・CBrushを使用した場合、これらのデストラクタで自動的に削除されるようになっていますが、デバイスコンテキストに選択された状態だと削除に失敗します。これらのリソースが削除されないと、使用しているリソースの量がどんどん増えていき、限界まで達すると画面表示に支障が出ます。 なので、デバイスコンテキストに選択したものは、元に戻しておく必要があります。 ブラシの場合であれば、 CBrush brushNew; CBrush* pbrushOld; pbrushOld = (CBrush*)pDC->SelectObject(&brushNew); ... // 描画などの処理 pDC->SelectObject(pbrushOld); のようにします。(他にもSaveDCとRestoreDCを使う方法もあります) ブラシを元に戻す処理を加えるのと、SelectObjectでリージョンを選択している行を試しにコメントにしてみてください。 もし、SelectObjectでリージョンを選択しないとPaintRgnがうまく動作しないようであれば、PaintRgnのあとにpDC->SelectClipRgn(NULL);を入れてみてください。
その他の回答 (3)
- m-take0220
- ベストアンサー率60% (477/782)
PaintRgnするだけなら、リージョンを選択する必要はないのでは? あと、SelectObjectの戻り値を保存してませんが、ちゃんと元に戻してますか? SelectObjectでリージョンを選択して、そのままにしてるために、リージョンの外側への描画が無視されているということはありませんか?
お礼
ご回答ありがとうございます。 >PaintRgnするだけなら、リージョンを選択する必要はないのでは? そうなのですか。教科書まる写ししたため訳もわからず使っていました。 >あと、SelectObjectの戻り値を保存してませんが、ちゃんと元に戻してますか? していません(汗)。よくわからずに使っているので・・・。 >SelectObjectでリージョンを選択して、そのままにしてるために、リージョンの外側への描画が無視されているということはありませんか? きっとその通りだと思います。試しに CBrush brushBrush(・・・); CreateRectRgn(・・・); pDC->SelectObject(&brushBrush); としてみましたが、こうすると画像は表示されませんが、テキストは思い通りに表示されました。 リージョンを選択せずにPaintRgnするのはどうすれば良いのでしょうか?もしくは、リージョンを選択しても、外側への描画が反映されるようにするにはどうすれば良いのでしょうか? ネットで色々探してみましたが分からずです。力不足な私に何かアドバイスいただけないでしょうか? 重ねての質問すみません。
- Tacosan
- ベストアンサー率23% (3656/15482)
この部分だけ出されても困るので, できるなら OnDraw の部分は全部見せてほしいかな. あと, w の宣言もお願い. 余談だけど, 「w[16][m] の値が (想定した通りに) 変化している」ことは確認できている?
お礼
>この部分だけ出されても困るので, できるなら OnDraw の部分は全部見せてほしいかな 大学の研究なので、全部を見せることはできません(涙)本当なら見せたいところですが・・・。 >あと, w の宣言もお願い. #define LINE 424000 double w[17][LINE]; です。LINEが大きすぎるんですかね(汗)。 >余談だけど, 「w[16][m] の値が (想定した通りに) 変化している」ことは確認できている? CBrush brushBrush(RGB(...));//...にはwから計算した値をintでキャストして代入 CRgn myRgn; myRgn.CreateRectRgn(...);//...には任意のmにより変化する値を代入 pDC->SelectObject(&myRgn); pDC->SelectObject(&brushBrush); pDC->PaintRgn(&myRgn); とうい処理を質問の記述のすぐ後にしていますが、これはmの変化に伴い変化します。映像のようになるのです。これに伴いw[16][m]もmに伴い文字を表示したり、しなかったりしたいのですが・・・。 今わかったのですが、この画像を表示する部分を無効にする(/**/でくくる)と思い通りTextOutの表示は表示されたりされなかったりします。 すべてのソースを記述できずにすみません。
- m-take0220
- ベストアンサー率60% (477/782)
> for文でmを増加させていくのですが それはどこでやってますか? OnDrawの中でないのであれば、mをさせただけでは画面更新の必要があるとWindowsが感知してくれないので、OnDrawが呼ばれません。
お礼
ご回答ありがとうございます。しっかりOnDrawの中で増加させてます。 他にも同時にグレースケールの四角形も表示しているのですが、こちらはmに伴い再描画されます。
お礼
再度の回答、また詳しい回答ありがとうございます。 pDC->SelectClipRgn(NULL); を挿入することでとりあえずは意図する表示ができました。 >なので、デバイスコンテキストに選択したものは、元に戻しておく必要があります。 ブラシの場合であれば、 CBrush brushNew; CBrush* pbrushOld; pbrushOld = (CBrush*)pDC->SelectObject(&brushNew); ... // 描画などの処理 pDC->SelectObject(pbrushOld); のようにします。 の部分がまだよくわからないので、教えていただいたURLなどを参考に勉強してみます。 詳しい回答本当にありがとうございました。