mcrblog

vcpp-ml

2003年04月

25

[vcpp 00060608] Re: スクリーンセーバ設定画面へのプレビュー表示

神戸です

> > スクリーンセーバの作り方なら、
> > MSDNにMFCのサンプルがあるし、
> > 説明もあります。
> > インターネットで探せば沢山あると思うけど。

原因追求はまだですが..
MFCサンプルのsaverを参考に(というかパクリ)
しましたら、きちんとプレビューできるように
なりました.
ありがとうございます
25

[vcpp 00060607] Re: コントロールのサイズ変更での不具合

皆様ありがとうございます

元発言者の神戸です.
先輩方のご意見に追従できないのが現状です.(勉強不足!!)
#一読してますが、理解できないというか..
整理しますと,

1.ドラッグでウィンドウの再描画する.
  Webで調べてOSの設定であると理解しました.
  Win2000でデバックしてますがチェックが入った状態です.
  チェックの有無にかかわらず重たさはあまりかわらない気がしました.
  チェックをはずすのも手かもしれませんが、OS設定を変えるのもどうかと
 考え、この設定でうまく動作するよう検討したいと思います.

2.WM_SIZEメッセージ
  1.でチェックの入った状態ではメッセージがドラッグ中で出てました.(Spy++使用)

3.他
  一応、私の実装は
  WM_SIZE でサイズに応じてメモリDC(仮想メモリ2枚,マスク用3枚)のサイズ変更
  をしてInvalidate()させてます.☆ここが重いです.

  WM_PAINTにてメモリDCをコントロールのクライアントにBitBltしてます.

  一応、サイズ変更と再描画を分けて考えているつもりですが、何かいけない
 でしょうか?

4.最後に
 検討した結果、サイズ変更時、コントロールのリアルタイムの再描画は
 したいので、マスクDCのサイズ変更を軽くするしか手はなさそうです.
 違う方法で、検討してみます.
25

[vcpp 00060606] Re: コントロールのサイズ変更での不具合

Tietew です。

On Fri, 25 Apr 2003 18:18:03 +0900
In article <2...@ns.petoffice.co.jp>
[[vcpp 00060603] Re: コントロールのサイズ変更での不具合]
Shigeru Mabuchi <m...@wing.gr.jp> wrote:

> >富豪的プログラミングの立場からは,無駄ではありません :-)
> >むしろ,ユーザフレンドリなので,推奨されます。

> 描画されなきゃ、いくら OnSize() で処理したって意味ないでしょう。
> Windows Messaging を分かっていっているのでしょうか。

はいな。

> それとも、軽くて速いプログラムよりも、
> 必要以上に重たいプログラムがユーザフレンドリーって
> いいたいのでしょうか?

必要以上に,などとは誰も申しておりません。

> 実際にその仕組みで作ってみればどっちが正しいか、分かることです。
> 私は実際に作ったものでは、全画面に近いサイズのドラッグでも
> リアルタイム表示され、ストレスを全く感じません。CPU が 333Mhz 
> 時代の話です。

Classic Pentium 166MHz でストレスのない再描画を考えてたことも有
るんですが…その時だって,WM_SIZE 毎に UpdateWindow(当然最適化
されている)してましたよ。

> 神戸さんが「重たい」と感じたのは、「サイズの変動」と「描画」という
> 二つの全く独立したメッセージをセットで考えた節があるためです。
> たとえば、ウィンドウが隠れているときにサイズが変わる(復元される)
> ことだってあります。そういうときには WM_SIZE が来ても
> WM_PAINT は来ないことがあります。

そうですね。

> ところで、富豪的プログラミングってなんでしょうか?自分の高速CPU上で
> 満足にさえ動けばいいってことでしょうか?

Google しませう。

> >> (ドラッグでウィンドウの再描画をしない画面設定の場合がそう)
> >
> >だうと。
> >ドラッグでウィンドウの描画を行わない設定(枠だけが移動する設定)
> >の時,ドラッグ中には WM_SIZING (WM_WINDOWPOSCHANGING /
> >WM_GETMINMAXINFO) だけがやってきます。そして,ユーザがボタンを放
> >したとき初めて WM_SIZE (WM_WINDOWPOSCHANGED) がやってきます。
> >
> ># これが OnSizing と OnSize の違いです>元質問者さん

> 思いっきり本末転倒のことを書いていますね。
> Windows 3.1 時代からプログラムを書いている人間でないと
> 勘違いしそうな話です。

ほへ?
ちゃんと理解して書いてますが。

> サイズ変更の時、ボタンを放さなくても WM_MOVE や
> WM_SIZE は何度だって来ます。WM_PAINT が来ないだけです。

来ません。確かめました。WM_SIZE は「サイズ変更が確定した」時にだ
け来ます。枠だけドラッグしているときは,サイズ変更は確定していま
せん。

> (カーネルが代わりに枠を再描画してくれるだけです)
> 昔のマシンは遅いから、必要になるまでなるべく WM_PAINT を
> 処理しないという発想です。

はい。Windows3.1 以前の時代ですね。

> 「ドラッグ中にウィンドウを表示する」という設定は、
> WM_SIZE や WM_MOVE を発行するたびに、WM_PAINT を送る
> かどうか、そういう違いです。WM_SIZE や WM_MOVE を
> 送る、送らないことではありません。

違います。ウィンドウサイズが変更された結果,無効領域ができるので 
WM_PAINT が来るだけです。サイズを縮小方向に変更するのなら,
WM_PAINT は(自動的には)来ません。しかも,UpdateWindow() しない
と,次のアイドル時間まで WM_PAINT は遅延されます。

> WM_SIZING はあくまでも、サイズ変動を監視するための、
> WM_SIZE の前処理です。「そのサイズに変更させますか?
> それとも強制的に別のサイズに変更しますか?」という目的の
> ためにあるメッセージです。OKなら WM_SIZE を、ダメなら
> WM_SIZE なし、変更なら、WM_SIZE に異なる値が入るという
> 性格のものです。移動中とか、そういう経過的なものでは
> ありません。ボタンのリリースと関連づけてしまうと、
> カーネルでのメッセージ処理はたいへんなことになります。

USER32.DLL がカーネルかどうかは兎も角,Windows は結構頑張ってま
すよ ;-)

> もう一度よくWindows API をよく読んでみてください。

Windows API って読めるんですか :-p

> いまどきのプログラマには、Windows API の仕組みを理解しなくても
> プログラムが書けるから、内部処理まで考えて書く人間って
> 絶滅しかかっているかも(^^;

そっちこそ思いこみで書いてませんか。


―[ Tietew ]――――――――――――――――――――――――――――
Mail: t...@tietew.net / t...@raug.net
Web : http://www.tietew.net/     Tietew Windows Lab.
PGP fingerprint: 26CB 71BB B595 09C4 0153  81C4 773C 963A D51B 8CAA
25

[vcpp 00060605] RE: コントロールのサイズ変更での不具合

 渋木です。

> > ドラッグでウィンドウの描画を行わない設定(枠だけが移動する設定)
> とは?ウィンドウスタイルでしょうか?
>
> 現状はドラッグでウィンドウの再描画がされて無駄な再描画が働いているかも
> しれないということですよね.
> (実際そのような動作してます)
> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> ↑これを回避するにはどのようにすればよろしいのでしょうか?
>
> LED表示器みたいなのを作っているのですが,ドラック操作で
> ドットがリアルタイムに大きさが変わっていく動作は捨てがたいのですが..
> (画面を大きくすればドットも大きくなる仕様)

 ↑は「近代的 Windows アプリケーション」としては正しい実装です。

 これで、重いとか不都合があるなら、別のコメントにあったように

>基本的に OnSize() で「サイズが変わった」というフラグを立てて、
>OnPaint() で処理するのがよいかと。または、OnPaint() でサイズの変更を
>自動的に検出して、必要なら、メモリDCの再割り当てを行うべきでしょう。

 とかすればよいのではないですか?

--
// 渋木宏明 (Hiroaki SHIBUKI)
// mailto:h...@mbi.nifty.com
// http://www.hidori.jp/
// Microsoft MVP 2002-2003 of Windows Technology
25

[vcpp 00060604] Re: コントロールのサイズ変更での不具合


馬渕です。

Yasuhiro.Kambe wrote in [vcpp 00060601] Re: コントロールのサイズ変更での不具合:

>> ドラッグでウィンドウの描画を行わない設定(枠だけが移動する設定)
>とは?ウィンドウスタイルでしょうか?

XP でいうと、コントロールパネル・システム・詳細設定・
パフォーマンス設定・「ドラッグ中にウィンドウを描画する」
という設定のことです。

>現状はドラッグでウィンドウの再描画がされて無駄な再描画が働いているかも
>しれないということですよね.
>(実際そのような動作してます)
>~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>↑これを回避するにはどのようにすればよろしいのでしょうか?

OnSize() での処理を最小限にすればいいのです。

次のようにすれば、ウィンドウリサイズ中も洪水のように
WM_SIZE が来ていることをデバッグウィンドウで確認できます。
もちろん、「ドラッグ中にウィンドウを描画する」のチェックを
はずしたとき、リサイズの枠描画中もWM_SIZEがジャンジャン
来ます。

void Cxxx::OnSize(UINT nType, int cx, int cy) 
{
  TRACE("x = %d y = %d \n",cx,cy)]



一例ですが、

class Cxxxx { // 追加するメンバ変数
  CSize m_szLastDrawn; // コンストラクタで -1,-1 で初期化しておく
  BOOL  m_bResized;

void Cxxx::OnSize(UINT nType, int cx, int cy) 
{
switch(nType) {
case SIZE_MINIMIZED:
case SIZE_MAXHIDE:
return;
}

if (szLastDrawn != CSize(cx,cy)) {
// 関連コントロールのサイズの再計算が必要なら
// ここで行う(マウス入力などに備え、計算だけです)
// 画面が更新されたかどうかは勝手に判断してはいけません
m_bResized = TRUE;
Invalidate(0);
}
}


void Cxxx::OnPaint(CDC* pDC)
{
if (m_bResized) {
CRect r;
m_bResized = FALSE;
GetClientRect(r);
szLastDrawn = CSize(r);
// サイズが変わったので、
// ここでリソースの再割り当て関数を呼び出すなど
xxxxReallocBitmap(pDC);
}

// ここで通常描画

}

ただし、これは CView でのコーディング例です。
コントロールの場合はためしていません。

WM_SIZE で前処理をしても、WM_PAINT を受け取らなければ、
いくら描画のための前準備をやっても、水の泡と化する可能性
は十分あるためです。
Invalidate() を呼んでも、実際に WM_PAINT が来るとは限りません。
(ウィンドウが隠れているかもしれないし、画面外かもしれないし)

馬渕 茂
KOAH INTERACTIVE
記事検索
Amazon.co.jp
  • ライブドアブログ