再描画について

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

再描画について

#1

投稿記事 by たこやき » 15年前

ウィンドウの雛形に
case WM_PAINT:{
PAINTSTRUCT ps;
char cbuf[100];
HDC hdc = BeginPaint( hWnd, &ps );
wsprintf( cbuf, _T("Hello window"));
TextOut(hdc,0,100,cbuf,sizeof(cbuf));
SetWindowText( hWnd, cbuf );
EndPaint( hWnd, &ps );
break;
}

を付けて実行したのですが、サイズを大きくしたり小さくしたりするとちらつきが見られるのですが、どうしたらこのちらつきをなくすことが出来るんでしょうか?

Dixq (管理人)

Re:再描画について

#2

投稿記事 by Dixq (管理人) » 15年前

質問する際は名前を統一して下さいますようお願いします。

たこやき

Re:再描画について

#3

投稿記事 by たこやき » 15年前

すみません。気をつけます。

KEYONN_

Re:再描画について

#4

投稿記事 by KEYONN_ » 15年前

サイズとは何のサイズの事でしょうか?
今、私もWindowsプログラミングを勉強しています。
力になれれば良いのですが…。

たこやき

Re:再描画について

#5

投稿記事 by たこやき » 15年前

回答ありがとうございます。サイズとは、ウインドウ自体のサイズのことです。

softya

Re:再描画について

#6

投稿記事 by softya » 15年前

多少のチラツキは避けられません。
ある程度抑える方法としては事前に作っておいた裏画面(バッファ)で描画して、表画面に転送する方法が一般的です。
参考↓
http://oshiete1.goo.ne.jp/qa4093552.html

それと2点気になったので修正しました。
1.UNICODEとマルチバイト文字の扱いの混在が気になったので統一。
2.TextOutの引数が間違っていたので修正。
TCHAR tcbuf[100];
        HDC hdc = BeginPaint( hWnd, &ps );
        _stprintf( tcbuf, _T("Hello window"));
        TextOut(hdc,0,100,tcbuf,_tcslen(tcbuf)); ←バッファ長では無く文字列長を渡してください。
            SetWindowText( hWnd, tcbuf );
        EndPaint( hWnd, &ps );

たこやき

Re:再描画について

#7

投稿記事 by たこやき » 15年前

そうなんですか。その方法でやっていみたいと思います。
まだ実験はしてないですが。ようはstatic HDC hdc;を前のバッファにすればいいのですね。
回答ありがとうございました!

たこやき

Re:再描画について

#8

投稿記事 by たこやき » 15年前

参考にしたサイトを参考にしてやってみましたが、ちらつきが軽減しません。
やり方が間違っているのでしょうか?
ソースを見てください。
case WM_PAINT:{
PAINTSTRUCT ps;
TCHAR tbuf[100];
RECT r;
HRGN hRgn;
hdc = BeginPaint( hWnd, &ps );
GetClientRect(hWnd,&r);
wsprintf( tbuf, _T("on WM_PAINT%d"),t);
TextOut(hdc,0,100,tbuf,::_tcslen(tbuf));
SetWindowText( hWnd, tbuf );
hdc2=hdc;
[pre]        EndPaint( hWnd, &ps );
SetTimer(hWnd,NULL,1,NULL);
break;
}
case WM_TIMER:
PAINTSTRUCT ps;
wchar_t cbuf[100];
RECT r;
HRGN hRgn;
hdc = GetDC( hWnd);
GetClientRect(hWnd,&r);
wsprintf( cbuf, _T("on WM_PAINT%d"),t);
TextOut(hdc,0,100,cbuf,sizeof(cbuf));
ReleaseDC( hWnd, hdc);
t++;
InvalidateRect(hWnd,NULL,FALSE);
break;
です。

たこやき

Re:再描画について

#9

投稿記事 by たこやき » 15年前

このソースでいらないものがあると思いますが。それは無視してください。

たこやき

Re:再描画について

#10

投稿記事 by たこやき » 15年前

ソース間違えました。
HDC hdc,hdc;
case WM_PAINT:{
PAINTSTRUCT ps;
TCHAR tbuf[100];
hdc = BeginPaint( hWnd, &ps );
wsprintf( tbuf, _T("on WM_PAINT%d"),t);
TextOut(hdc,0,100,tbuf,::_tcslen(tbuf));
SetWindowText( hWnd, tbuf );
EndPaint( hWnd, &ps );
SetTimer(hWnd,NULL,1,NULL);
break;
}
case WM_TIMER:
PAINTSTRUCT ps;
TCHAR tbuf[100];
RECT r;
HRGN hRgn;
hdc2 = GetDC( hWnd);
           GetClientRect(hWnd,&r);
wsprintf( tbuf, _T("on WM_PAINT%d"),t);
TextOut(hdc2,0,100,tbuf,::_tcslen(tbuf));
ReleaseDC( hWnd, hdc2);
  t++;
InvalidateRect(hWnd,NULL,FALSE);
break;
です。

softya

Re:再描画について

#11

投稿記事 by softya » 15年前

本当にちゃんと読みました?
参考にリンクした情報と全然違うのですが・・・。
リンクの更にリンク先の情報までちゃんと読んでくださいね。
http://oshiete1.goo.ne.jp/qa3052870.html

問題点。
1.常駐のメモリDCが無い。
2.WM_PAINTでBitBltでメモリDCから転送していない。つまり何も変わっていない。

たこやき

Re:再描画について

#12

投稿記事 by たこやき » 15年前

回答ありがとうございます。あ、気づきませんでした。そのサイトで作ってみましたが,
create関数がないのですが、代わりの関数はないのでしょうか?一応探してみてはいるの
ですがみつからなので・・・

softya

Re:再描画について

#13

投稿記事 by softya » 15年前

createと言う関数は知らないので、オリジナル関数じゃないかと思われます。それに小文字で始まるWindowsAPIは見たことありません。
フォントはCreateFont()関数を使ってください。

たこやき

Re:再描画について

#14

投稿記事 by たこやき » 15年前

回答ありがとうございます。TextOutの方は再描画されたのですが、ボタンのほうがチカチカし始めました、どうしたらチカチカをとめるころができるのでしょうか?

たこやき

Re:再描画について

#15

投稿記事 by たこやき » 15年前

ボタンの定義はこれです。
CreateWindow( _T("BUTTON"), _T("何もしない"),BS_PUSHBUTTON | WS_CHILD | WS_VISIBLE ,50, 50, 300,50,
 hWnd, (HMENU)999, hInstance, NULL );

softya

Re:再描画について

#16

投稿記事 by softya » 15年前

ボタンのチカチカを止めることは基本的に無理です。
別ウィンドウとして描画されていますので、どうしてもチカチカしてしまいます。
色々なテクニックでチカチカを抑えることは出来ないことは無いですが、どれも裏技っぽい方法になってしまうのでどうかなと・・・。
それ以前にWindowsAPIの他の知識を深めてもらわないと説明も出来ないので色々とまず基本的なことを勉強してください。

たこやき

Re:再描画について

#17

投稿記事 by たこやき » 15年前

そうなんですか。裏技ですか。。。回答有難うございました。

たこやき

Re:再描画について

#18

投稿記事 by たこやき » 15年前

最後の質問なのでが、WM_TIMERにInvalidateRect(hWnd,NULL,FALSE);を入れて、
WM_PAINTにSetTime()をいれた場合、無限ループになるのでしょうか?また無限ループならどういう風
にかけば無限ループにならないのでしょうか?

softya

Re:再描画について

#19

投稿記事 by softya » 15年前

>最後の質問なのでが、WM_TIMERにInvalidateRect(hWnd,NULL,FALSE);を入れて、
>WM_PAINTにSetTime()をいれた場合、無限ループになるのでしょうか?また無限ループならどういう風
>にかけば無限ループにならないのでしょうか?

私が無限ループと表現したのは、WM_PAINTにInvalidateRect()を入れてしまうとWindowsの処理出来る範囲での最短時間で再描画されてしまうからです。これは描画リソースの無駄遣いですので無限ループと表現しました。
描画負荷のかかるWM_PAINTを呼び出すのは出来るだけ少なくするべきですので、都合の良い出来るだけ長い時間をSetTimerに設定してください。そうすれば描画負荷は最小限になります。1つのアプリがリソースを独占する事はWindowsプログラミングとして出来るだけ避けるべき重要な事柄です。
ちなみにWM_PAINTの度にSetTimer()をしてはいけません。SetTimer()は一回呼び出すだけでタイムアウト時間周期でWM_TIMERメッセージが毎回発生します。

そうそう、TextOutによるボタンのチラツキを抑える事はTextOutするウィンドウを子ウィンドウにしてInvalidateRect()で子ウィンドウだけ再描画すれば抑えられますよ。

たこやき

Re:再描画について

#20

投稿記事 by たこやき » 15年前

ソースをいじくりましたが、出来ません。
もうしわけないのですが具体的におしえてください。

たこやき

Re:再描画について

#21

投稿記事 by たこやき » 15年前

できれば例など出していただけると助かります。

たいちう

Re:再描画について

#22

投稿記事 by たいちう » 15年前

> できれば例など出していただけると助かります。

> ボタンのほうがチカチカし始めました

再現できる簡潔なプロジェクトをupしてくれたら手伝えるかも。
どんなボタンか分からないのに1から例を作るのは私は御免。
(ボタンがどこにあるのかとか、どこに描画しているのとか)

たこやき

Re:再描画について

#23

投稿記事 by たこやき » 15年前

はい。わかりました。プロジェクトは入りきらなっかったのでソースだけupします.

たいちう

Re:再描画について

#24

投稿記事 by たいちう » 15年前

再現しました。
多分一番ラクにごまかす方法。
case WM_TIMER: {
    TCHAR tbuf[100];
    SelectObject( hMemDC, hFont );
    int len = wsprintf( tbuf, _T("on  x=%d "),t);
    TextOut(hMemDC,0,100,tbuf,len); // ここは既にsoftyaさんが指摘している
    t++;
    RECT rect;
    SetRect(&rect, 0, 100, 200, 150);
    InvalidateRect(hWnd,&rect,FALSE);
    break;
}
正攻法としては、ダイアログリソースを使うとか、
WM_ERASEBKGROUNDを殺して、ボタンの部分以外をクリッピングして
自分で背景を描画するとかかな。
もちろんsoftyaさんの案の子ウィンドウを使う方法の他にという意味で。

softya

Re:再描画について

#25

投稿記事 by softya » 15年前

とりあえずstaticコントロールに文字を表示しただけの物です。
TextOutも使っていません。

こんな風にも出来るよって参考にしてください。

それとSetTimerの周期を1msにしてもOSのタスク・ディスパッチ周期が早くありませんので、0.001秒の周期ではWM_TIMERメッセージは発行されません。10msでも厳しいと思いますが一応10msにしてあります。

たこやき

Re:再描画について

#26

投稿記事 by たこやき » 15年前

回答ありがとうございます。結局TextOutではチカチカうぃとめることは出来ないということなのでしょうか?

たこやき

Re:再描画について

#27

投稿記事 by たこやき » 15年前

チカチカ止まっていました。回答ありがとうございます。

たこやき

Re:再描画について

#28

投稿記事 by たこやき » 15年前

すみません。やっぱり出来ませんんでした。

softya

Re:再描画について

#29

投稿記事 by softya » 15年前

>すみません。やっぱり出来ませんんでした。

意味がわかりません。
何ができなったんでしょうか?

ちなみにTextOut()を止めてもチラツキは完全には無くなりません。
ある程度抑えることが出来るだけです。

たこやき

Re:再描画について

#30

投稿記事 by たこやき » 15年前

TextOutでボタンのチカチカをとめることは出来なかったと言うことです。
TextOutではチカチカをとめることは出来ないということなのでしょうか?

たこやき

Re:再描画について

#31

投稿記事 by たこやき » 15年前

チカチカとることができました。タイチウさんありがとうございます。
ただ、TextOut()が2つあった場合どうすればよいのでしょうか。
自分でも考えてみたいとおもいます。

たこやき

Re:再描画について

#32

投稿記事 by たこやき » 15年前

原点に戻ってしまいました。ボタンとかのチカチカは消えたのですが、今度はウィンドウのサイズを変更したらまたチカチカするようになりました。助けてください。。。

softya

Re:再描画について

#33

投稿記事 by softya » 15年前

TextOutを子ウィンドウにだけ対応したもの。
どの程度のチカチカを避けたかが分かりませんが、このぐらいが限界です。
今回は、staticコントロールをサブクラス化して専用のウィンドウプロシージャで描画しています。

>ただ、TextOut()が2つあった場合どうすればよいのでしょうか。
この方式なら、どうとでもなります。

たこやき

Re:再描画について

#34

投稿記事 by たこやき » 15年前

わかりました。回答ありがとうございました!!

閉鎖

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