アプリ版:「スタンプのみでお礼する」機能のリリースについて

VC++6.0のMFCでプログラムを組んでいます。

OnDrawクラス内であるテキストデータを読み込んで、配列に格納しておいてその中の値がある値を超えたら、文字表示。超えていなければ文字非表示としようと思っているのですが

if(w[16][m]<-700.0){
pDC->SetTextColor(RGB(0,0,0));pDC->TextOut(20,200,"表示文字");
}else{pDC->SetTextColor(RGB(255,255,255));pDC->TextOut(20,200,"表示文字");
}

としてfor文でmを増加させていくのですが、初めの評価だけでずっと変わりません。(初め-700以下なら文字がずっと表示され、以上ならずっと白で表示されます。赤(255,0,0)にして試してみましたところずっと赤が出ました。)

ネットを方々探しましたが、いまいちわからなく困っています。

わかりづらい質問かもしれませんが、よろしくお願いいたします。

A 回答 (4件)

まず、デバイスコンテキストにリージョンを選択するということが何を意味するかです。


SelectObjectの解説には、

> パラメータに領域を指定する形式のメンバ関数は、SelectClipRgn メンバ関数と同じタスクを実行します。

と書かれています。つまり、デバイスコンテキストへの描画を、リージョン内に制限することになります。

CDC::SelectObject
http://msdn.microsoft.com/ja-jp/library/sa8ahz7h …

これを解除するには、SelectClipRgnに対してNULLを与えます。

CDC::SelectClipRgn
http://msdn.microsoft.com/ja-jp/library/txy5hzk3 …


次に、PaintRgnの解説では、単に領域を塗りつぶすとされています。この機能を使用する前に、リージョンを選択する必要があるとはかかれていません。今、開発環境がないので試せませんが、おそらくSelectObjectでリージョンを選択しなくても、PaintRgnは動作します。

CDC::PaintRgn
http://msdn.microsoft.com/ja-jp/library/z38612dh …


さらに、フォント・ペン・ビットマップ・ブラシなどを作成した場合は、それを削除しなければなりません。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);を入れてみてください。
    • good
    • 0
この回答へのお礼

再度の回答、また詳しい回答ありがとうございます。

pDC->SelectClipRgn(NULL);

を挿入することでとりあえずは意図する表示ができました。

>なので、デバイスコンテキストに選択したものは、元に戻しておく必要があります。
ブラシの場合であれば、

CBrush brushNew;
CBrush* pbrushOld;

pbrushOld = (CBrush*)pDC->SelectObject(&brushNew);
... // 描画などの処理
pDC->SelectObject(pbrushOld);

のようにします。

の部分がまだよくわからないので、教えていただいたURLなどを参考に勉強してみます。

詳しい回答本当にありがとうございました。

お礼日時:2011/05/02 11:15

PaintRgnするだけなら、リージョンを選択する必要はないのでは?


あと、SelectObjectの戻り値を保存してませんが、ちゃんと元に戻してますか?
SelectObjectでリージョンを選択して、そのままにしてるために、リージョンの外側への描画が無視されているということはありませんか?
    • good
    • 0
この回答へのお礼

ご回答ありがとうございます。

>PaintRgnするだけなら、リージョンを選択する必要はないのでは?

そうなのですか。教科書まる写ししたため訳もわからず使っていました。

>あと、SelectObjectの戻り値を保存してませんが、ちゃんと元に戻してますか?

していません(汗)。よくわからずに使っているので・・・。

>SelectObjectでリージョンを選択して、そのままにしてるために、リージョンの外側への描画が無視されているということはありませんか?

きっとその通りだと思います。試しに

CBrush brushBrush(・・・);
CreateRectRgn(・・・);
pDC->SelectObject(&brushBrush);
としてみましたが、こうすると画像は表示されませんが、テキストは思い通りに表示されました。

リージョンを選択せずにPaintRgnするのはどうすれば良いのでしょうか?もしくは、リージョンを選択しても、外側への描画が反映されるようにするにはどうすれば良いのでしょうか?

ネットで色々探してみましたが分からずです。力不足な私に何かアドバイスいただけないでしょうか?

重ねての質問すみません。

お礼日時:2011/05/01 13:31

この部分だけ出されても困るので, できるなら OnDraw の部分は全部見せてほしいかな.


あと, w の宣言もお願い.

余談だけど, 「w[16][m] の値が (想定した通りに) 変化している」ことは確認できている?
    • good
    • 0
この回答へのお礼

>この部分だけ出されても困るので, できるなら 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の表示は表示されたりされなかったりします。

すべてのソースを記述できずにすみません。

お礼日時:2011/04/29 06:28

> for文でmを増加させていくのですが



それはどこでやってますか?
OnDrawの中でないのであれば、mをさせただけでは画面更新の必要があるとWindowsが感知してくれないので、OnDrawが呼ばれません。
    • good
    • 0
この回答へのお礼

ご回答ありがとうございます。しっかりOnDrawの中で増加させてます。

他にも同時にグレースケールの四角形も表示しているのですが、こちらはmに伴い再描画されます。

お礼日時:2011/04/28 13:21

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!