ページ 11

ウィンドウクライアント領域DCのはずが?

Posted: 2006年6月08日(木) 23:17
by Indigo Visualist
お世話になります。現在デバイスコンテキストやらビットマップの操作に四苦八苦していまして、
資料を読んで少しずつ理解し始めていたのですが、どうしても不可解な現象に行き当たってしまったので、
自分の手には負えず、ご教授して頂きたいです。
まず、Oriosさんのページより、スケルトンウィンドウのコードをお借りして、次のようなコードを書きました。 そしてこれを実行したところ、ウィンドウのクライアント領域でなく、デスクトップ画面の左上に黒い四角が表示されてしまいました。
どうしてこのようなことが起るのでしょうか?

P.S.
44行目の

コード: 全て選択

			hMainDC = GetDC(hMainWnd)

コード: 全て選択

			hMainDC = GetDC(hWnd)
に変えるとちゃんとクライアント領域に表示されました。
この書き方に問題があるんでしょうか?

Re: ウィンドウクライアント領域DCのはずが?

Posted: 2006年6月08日(木) 23:31
by 7
> そしてこれを実行したところ、ウィンドウのクライアント領域でなく、デスクトップ画面の左上に黒い四角が表示されてしまいました。
> どうしてこのようなことが起るのでしょうか?
WM_CREATEが送られてくる時、ってのがまだhMainWndにウィンドウハンドルを代入する前だからじゃないでしょうか?
hMainWndに対してのデバイスコンテキストを取得してるんじゃなくて、0に対してのデバイスコンテキストを取得しちゃってると。

Posted: 2006年6月08日(木) 23:34
by NoWest
取り合えず、解決のヒントを書いておきます。

GetDCはウィンドウ全体のデバイスコンテキストを取得します。
しかし、実際にはユーザが描画するのはウィンドウのクライアント領域だけなので
GetDCは特別な理由が無い限りは使用しません。

また、Createイベントでデバイスコンテキストを取得するのもおススメしません。
GetDCでやるとしてもPaintイベントでhWndを指定して毎回取得した方がよいです。
というのもCreateイベントで得られたデバイスコンテキストと現在描画対象となっているデバイスコンテキストに互換性があるという保障が無いからです。

ですので、描画に使用するデバイスコンテキストはGetDCを使わないで取得しましょう。

ってことでBeginPaint、EndPaintをヘルプかネットで調べてみてください。


P.S.
7様が先に書き込まれたようですね。内容は違いますが。。。

7様が仰るようにWM_CREATEメッセージが送信されてきた時には
まだhMainWndの中身は0です。

順番としては
1.CreateWindowEx関数が呼ばれる。
2.ウィンドウが作成される。(まだCreateWindowExは実行中)
3.WM_CREATEメッセージが送信される。(まだCreateWindowExは実行中)
4.CreateWindowEx関数が終了し戻り値にハンドルが返る。

私も最初のうちは戸惑いました。(笑


Posted: 2006年6月09日(金) 16:28
by Indigo Visualist
ご回答ありがとうございます。おかげで納得することができました。
>7さん
WM_CREATEが送られてくる時、ってのがまだhMainWndにウィンドウハンドルを代入する前だからじゃないでしょうか?
これは初めて知りました。今後気をつけるようにします。
hMainWndに対してのデバイスコンテキストを取得してるんじゃなくて、0に対してのデバイスコンテキストを取得しちゃってると。
これも初めて知りました。GetDCでデスクトップ画面のDCまで取得できるんですね。

>NoWestさん
GetDCはウィンドウ全体のデバイスコンテキストを取得します。
しかし、実際にはユーザが描画するのはウィンドウのクライアント領域だけなので
GetDCは特別な理由が無い限りは使用しません。
すみません、ヘルプを確認したのですが、GetDCはクライアント領域で、
ウィンドウ全体を取得するのはGetWindowDCではないでしょうか?
というのもCreateイベントで得られたデバイスコンテキストと現在描画対象となっているデバイスコンテキストに互換性があるという保障が無いからです。
そうだったんですか。気をつけるようにします。

お二人とも本当にありがとうございました。