背景を更新するには?

解決


キムラ  2009-05-07 11:55:28  No: 70123  IP: [192.*.*.*]

デスクトップに円など描画したいのですが
背景が最初に描画したときの背景から更新されません。

例)円を描画した背景にIEのウィンドウがあるとして、
そのときIEのウィンドウを移動させても、円の周りの背景はIEのウィンドウの絵が表示されたままになってしまいます。どうすれば背景が更新されるのでしょう?

↓プログラム
//デスクトップのハンドルとデバイスコンテキスト取得
HWND hWndDesktop    =  GetDesktopWindow();
HDC  hdcDesktop    =  GetDC(hWndDesktop);

//円の描画
Ellipse(hdcDesktop,100,100,200,200);

//デバイスコンテキストの開放
ReleaseDC(hWndDesktop, hdcDesktop);

編集 削除
gak  2009-05-07 17:15:44  No: 70124  IP: [192.*.*.*]

> 円を描画した背景にIEのウィンドウがあるとして 〜 どうすれば背景が更新されるのでしょう?
InvalidateRect(NULL, NULL, TRUE);

IE云々の所が旨く理解できなかったので的を外しているかもしれない。

編集 削除
キムラ  2009-05-07 18:03:05  No: 70125  IP: [192.*.*.*]

>IE云々の所が旨く理解できなかったので的を外しているかもしれない。
説明が下手で申し訳ないです。IE云々は忘れてください。
絵を見せるのが一番いいと思うのですが・・・

円をデスクトップ上に書いた後、
円の後ろの背景を変えても(円の下にあるウィンドウを動かすなど)
円の周りの背景が変わらないんです。

あと、プログラムを終了してから、また実行してみても
円の周りの背景は一番初めのにプログラムを実行したときの背景が
残っています。

PCを起動して一回目の円を書くプログラム起動時の背景が
ずっと残っているみたいです。

>InvalidateRect(NULL, NULL, TRUE);
MSDNを見た感じではこれで行けると思ったんですが、だめでした。

編集 削除
gak  2009-05-08 17:30:04  No: 70126  IP: [192.*.*.*]

> HWND hWndDesktop = GetDesktopWindow();
> HDC  hdcDesktop = GetDC(hWndDesktop);
> Ellipse(hdcDesktop,100,100,200,200);
> ReleaseDC(hWndDesktop, hdcDesktop);
VC6sp6+XPsp3 環境で↑を試してみたら円は描画されなかった。
# HWND hWndDesktop = NULL;
# に変更してみたら表面上問題無く描画されたけど
なので、コレは恐らく環境依存の症状だと思われる。

キムラさんの環境が”OS が Vista で Aero が有効”な環境だったりしない?
もしそうならば、Vista の DWM(Desktop Window Manager)が影響してるのかもしんない。

XP以前では、スクリーンという一枚のキャンバスの領域を直接各ウィンドウ毎に割り振ってスクリーンの描画を行っている。

だけど、Vista(Aero)ではダブルバッファリングでスクリーンへの描画を行うように変わった。
また、各ウィンドウは其々専用のキャンバスを持っていてそこに自身の画面イメージを持っている。
で、実際のスクリーンへの描画は
1、オフスクリーンに各ウィンドウの専用キャンバスで持っている内容を合成
2、オフスクリーンの内容をスクリーンに転送
っていう感じの処理が行われていたと俺の脳は記憶している。
なので、今回のように自分が管理しているウィンドウ外の領域に描画とかしちゃうと問題がでるのかもしんない。

# Vista 環境が無いのでキムラさんの提示コードを実際に Vista で動かしてません。
# なので、益々的外れな回答をしているかもしれないが…自分が思いついた点を書いてみた。
# 関係なさそうだったらスルーしてください。

編集 削除
キムラ  2009-05-10 16:19:22  No: 70127  IP: [192.*.*.*]

返信が遅くなってスミマセン。

gakさんが言うとおり「Aero」が原因でした。
Aeroを切ったらちゃんと思い通りのものが描画できました。
ありがとうございます。

暫定回避方法で円を描画する前にBitBltを使って描画場所を取り込むと
背景が更新されるので「かっこ悪いけどこれでいいか」とあきらめてました。

gakさんのおかげでへんなコードを使わずにすみました。
ありがとうございました。

暫定回避の変なコード↓
//デスクトップのハンドルとデバイスコンテキスト取得
HWND hWndDesktop = GetDesktopWindow();
HDC  hdcDesktop = GetDC(hWndDesktop);

//これがあるとなぜか背景が更新される。
BitBlt(hdc,0,0,100,100,hdcDesktop,100,100,SRCCOPY);

//円の描画
Ellipse(hdcDesktop,100,100,200,200);

//デバイスコンテキストの開放
ReleaseDC(hWndDesktop, hdcDesktop);

編集 削除
キムラ  2009-05-10 16:23:04  No: 70128  IP: [192.*.*.*]

書き忘れ…

HWND hWndDesktop = GetDesktopWindow();
はgakさんが言ったとおり
HWND hWndDesktop = NULL;
に変えないとデスクトップに描画できませんでした。

編集 削除