
現在C++のSDKを勉強中の身です。
「猫でも分かるプログラミング」の98章を勉強中に疑問が出てきました。疑問というよりも中身が知りたくて質問させていただきました。
98章 http://www.kumei.ne.jp/c_lang/sdk/sdk_98.htm
いままで何気にやってきたことですが、「デバイスコンテキスト」とはどんなものなんでしょうか?
自分ではクライアント領域を描画するためのメモリ空間だと考えていたんですが、次にこんな関数が出てきました。
(HDC)CreateCompatibleDC(hdc)
この関数で得られるものは「メモリデバイスコンテキストハンドル」
・・・? デバイスコンテキストハンドルはメモリ空間じゃなかったの?と疑問を持ってしまいました。
じゃあメモリデバイスコンテキストとはなんぞや?とまたまた新たなる疑問が次々に発生・・・・・
そして例えばビットマップの表示ならば SelectObject関数により、ビットマップハンドルとメモリデバイスコンテキストハンドルを対応図づける?のですが、このSelectObject関数もなにをやっているのかつかみにくいです。「対応づけ」と理解していますが、それがあっているのかどうかも不明です。
よって解決したい問題は
(1)「デバイスコンテキストハンドル」および「メモリデバイスコンテキストハンドル」とはなんなのか?
(2)SelectObject関数は何をしているのか?
すこし図々しい疑問で恐縮ですが、この疑問に答えられる方は返信よろしくお願いします。
No.2ベストアンサー
- 回答日時:
回答1:『デバイスコンテキストハンドル』とは
・『デバイスコンテキスト』を大きな絵を描くキャンパスとイメージしてみる。
そのキャンパスは、紙であったり、壁であったり、自分の自動車だったりと様々である。
この紙、壁、自動車などがディスプレイ、プリンタなどのデバイスのことを指します。
・そして、このキャンパスのことを『デバイスコンテキスト』という言葉で表します。
このように共通したキャンパスを持つことで、プログラマーからはキャンパスが何に
繋がっているか(ディスプレイ、プリンタなどのディバイス)を気にすることが無くなり、
ディスプレイも、プリンタも同じ『デバイスコンテキスト』という概念で扱えるのです。
→これが抽象的って考えかな。
・また、この共通したキャンパスに関する情報は『デバイスコンテキスト』1つ1つで別々に
内部で管理しています。この管理領域のハンドルこそが『デバイスコンテキストハンドル』です。
・『キャンパス』=『デバイスコンテキスト』に点、線、円、長方形などの図形を描くには
知ってのとおり GDI というグラフィック描画の機能を提供している関数群を利用します。
この関数群は、デバイスコンテキストの内部にビットマップ構造を保持しているメモリ上に
対していろいろなやり取りを行っています。このやり取りを行うには、そのメモリにアクセス
するために『メモリデバイスコンテキストハンドル』を取得する必要があります。
・『メモリデバイスコンテキストハンドル』とは、『デバイスコンテキスト』に表示するための
図形などを保持しているメモリ領域のことです。GDI 関数群はこのメモリ領域に対して直接
図形を描いたりしています。つまり、メモリデバイスコンテキストとはデバイスコンテキストの
ビットマップ構造を持ったメモリ・イメージ領域のことです。
・通常は、このメモリ・イメージを意識しないでも図形が描けるために GDI 関数群がすでに用意
されている状態にあります。このためプログラマーには隠されているメモリ上ですので普通は
特に気にする必要がありません。が、しかし、GDI 関数群を通すと処理に時間がかかってしまったり、
または、ビットマップ画像を直接メモリ・イメージに描画するときには、そのメモリ領域を取得
する必要があります。このメモリ領域のハンドルこそが『メモリデバイスコンテキストハンドル』です。
※http://yokohama.cool.ne.jp/chokuto/urawaza/dispc …→『デスクトップ画面を取得してみる』
回答2:『SelectObject()』関数について
・『デバイスコンテキスト』を絵を描くキャンパスと考えると『筆』にあたる部分が必要です。
この『筆』は人間でも同じく右手などに1つしか持てません。イメージできますよね。
・それでは今、赤色の絵の具のついた筆を持っています。この状態でキャンパスに点、線、円、
長方形の図形を描くと赤い点、赤い線、赤い円、赤い長方形の図形が描けます。
次に緑色のブラシで図形を描くにはどうしますか?
答えは『筆』に新しい緑色の絵の具がついたブラシを手渡せばよいのです。
でも、今まで持っていた赤色の筆はどうしましょうか。絵の具がついていますね。
それでは、赤色の筆を左手に持ち替えてから、新しい緑色のブラシを手渡せばよいのです。
SelectObject() 関数で OldPen などに保存する動作こそ『左手』に持ち替える行為です。
・キャンパスと筆は常にペアで管理します。
これは『紙』なら『クレヨン』、『壁』なら『ペンキ』、『車』なら『スプレー』とベアで
管理するのと同じです。キャンパスにあったペン(筆)があるのです。これらのそれぞれを
キャンパスごとに切り替える動作を SelectObject() 関数が担当しているのです。
・よって、『デバイスコンテキスト』1つ1つに対して持てる『筆』はたったの1つです。
たくさんの色で描くには切り替える仕組みがどうしても必要になります。この仕組みです。
図解:
--------------
アプリケーション
--------------
| ↓
|-----------
| GDI 関数群
|-----------
↓ ↓
----------------------
メモリデバイスコンテキスト
----------------------
↓
-----------------
デバイスコンテキスト
-----------------
解説:
・アプリケーションが GDI 関数群を通さずに直接メモリ・イメージを操作するには、その領域
である『メモリデバイスコンテキスト』のハンドルを取得する必要があります。→CreateCompatibleDC
・一般に『デバイスコンテキスト』は1つの『メモリデバイスコンテキスト』を持っている。
ゲームなどでは『ダブルバッファリング』という技で複数の『メモリデバイスコンテキスト』を
用意してグラフィックにちらつきが起こらない様な仕組みをとる事があります。
・1つの『デバイスコンテキスト』は1つの『メモリデバイスコンテキスト』を持っているが、
決して『デバイスコンテキスト』=『メモリデバイスコンテキスト』ではない。
つまり『メモリデバイスコンテキスト』とは『デバイスコンテキスト』のビットマップ構造を
格納する画像メモリ領域と考えると良い。→MS-DOS 時代の VRAM(Video RAM) と同じ考え方。
最後に:
・『猫でも分かるプログラミング』サイト以外にも下の『参考URL』もどうぞ。
併用することで SDK の勉強を高められます。
・以上。参考情報でした。
参考URL:http://wisdom.sakura.ne.jp/system/winapi/
回答ありがとうございました。
以前にOpenGLのプログラムをしたことがあり、そこでダブルバッファリングの描画を勉強したのでつかみやすかったです。
そして、下の方が紹介されたURLで発生した疑問が解決できました。
最後に「参考URL」を紹介いただきありがとうございました。
SDKにてさらに熟読、熟考できそうです。
No.3
- 回答日時:
プラットフォームSDKのCreateCompatibleDCの解説に
>メモリデバイスコンテキストは、メモリ内にのみ存在します。
というくだりがあるのですが、この部分を書いた人は何か混乱していたのではないかと思います。
「GDIにおけるメモリデバイスとはメモリ上のビットマップを意味します」と解説を置き換えれば
デバイス=描画対象
デバイスコンテキスト=描画に必要な情報
デバイスコンテキストハンドル=デバイスコンテキスト構造体のアドレス
SelectObject=デバイスコンテキストを書き換える手段
このようになって、矛盾もなく非常にすっきりします。
返信ありがとうございました。
デバイスコンテキストハンドルがデバイスコンテキスト構造体のハンドルだとは知りませんでした。
新しい知識をいただきありがとうございます。
たしかに、上で回答されたように整理すると理解しやすいですね。
No.1
- 回答日時:
> (1)「デバイスコンテキストハンドル」および「メモリデバイスコンテキスト
> ハンドル」とはなんなのか?
デバイスコンテキスト/メモリデバイスコンテキストを操作するための把手
(ハンドル)です。Cでファイルを操作するときにファイルポインタというもの
を経由して行いますが、それと同じような性格のものです(さらに低レベルに
もぐると「ファイルハンドル」というのがでてきます)
デバイスコンテキストとは、ディスプレイだとかプリンタのようなデバイスを
抽象化して扱うためのからくりです。デバイスコンテキストを経由して操作を
することにより、
TextOut(hDC, ...);
で文字を描画する操作がデバイスの種類によらず共通になります。
また同じ種類のデバイスであっても、違う機種なんかの場合の違いも吸収
することができます(裏でデバイスドライバが頑張ってるんですが)。
このデバイスコンテキストは、たとえば「線を描画せよ」と指示されたときに
どんな色の、どんな太さの、etc... の線を描画するかという情報を別に持って
いて、それを元に実際の描画を行います。この情報を切り替えるのが
SelectObject です。
メモリデバイスコンテキストとは、通常のデバイスコンテキストが実際の
デバイスと密接に関わっているのとは違ってデバイス独立です。ただし
先に述べたようにデバイスコンテキストは描画時に使用するペンだとか
ブラシなどの情報を保持していますので、メモリデバイスコンテキストも
そういう情報を持っています。
何のためにあるのか、といえば、よく使うのは複雑な描画を行うときに
実際に描画を行いたいデバイスコンテキストにちまちま描画していくと
ちらつきが出るなどの問題が発生することがあります。そこで、描画
データを裏で組み立てておいて、完成したら一気に転送するということを
したりします。そのための作業空間がメモリデバイスコンテキストです。
http://www.char.ne.jp/ppc2002/c104.htm
BitmapLoader~第2週~
http://www.geocities.jp/chiakifujimon/makesoft2/ …
Windows API Tutorial: Canvas
http://www.relisoft.com/win32/canvas.html
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- その他(教育・科学・学問) 関数、写像について 1 2022/04/10 23:45
- 数学 原始関数の存在性の証明について 数学科の3回生です。院試の勉強でつまづいたので助けてほしいです。 R 6 2022/11/13 19:19
- 学校 今まで楽しかった勉強に対しての怒りが止まりません。※とても長いですし内容まとまってません。 はじめま 1 2022/06/26 22:54
- 仕事術・業務効率化 指示に対して疑問で返してくる人の考えが分からない。 7 2022/07/29 14:14
- その他(プログラミング・Web制作) pythonにおける単方向リストの実装について 4 2022/07/13 12:34
- その他(教育・科学・学問) 【数学】数学に精通している方、博識な方にに質問です。 3 2022/08/12 15:55
- 数学 数学の問題の解き方を教えてください! 3 2022/11/02 17:32
- 数学 【高1 数学Ⅰ 二次関数】 二次関数 f(x)=x^2-4ax+8a がある。ただし、aは正の定数と 3 2022/07/23 15:46
- 工学 AMラジオの音は、なぜ「もこもこ」しているのでしょうか? 5 2023/05/07 23:40
- 数学 【 数学 一次関数 】 問題 f(1)=-7,f(3)=-13を満たす1次関数f(x)を求めよ。 疑 4 2022/10/23 17:50
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
WindowsAPIでの画像表示について
-
OpenGLでウィンドウハンドルの取得
-
メモリデバイスコンテキストを...
-
グラフの交点の求め方(Excel)
-
コントロールの書式設定で、“コ...
-
Minecraft 統合版(PC)の描画距...
-
「アイテムは収集されました」...
-
勝手にウィンドウが開いて止ま...
-
液晶14.1型SXGAの利便性
-
エクセルで作った新しいウイン...
-
DLLから表示しているモーダルダ...
-
スピンボタンを右クリックして...
-
マウスの移動範囲を限定するに...
-
VB.NET オーナードロー
-
隠れたウィンドウの画面をキャ...
-
マインクラフト(pc版)で座標...
-
キーボードでのマウスエミュレート
-
C#で、ある条件でFormが自動で...
-
word
-
【VC++】コントロールの上に描画
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
コンテキスト依存とは?
-
PlgBltでの透過
-
OpenGLでウィンドウハンドルの取得
-
メモリデバイスコンテキストを...
-
GetDC()とCreateCompatibleDC()
-
ちらつきについて
-
VBでFD、USBの有効・無効...
-
Active Basic デバイスコンテ...
-
ExtTextOut
-
デバイスコンテキストとデバイ...
-
VC++のTextOutの再描画の仕方
-
画面がチカチカする
-
ハードコピーをプログラムから...
-
メモリデバイスコンテキスト&...
-
C++でBMP解析
-
C 多角形を半透明に塗る方法
-
領域を塗りつぶしたい
-
コントロール内の文字の背景色
-
GetPixelに使うHDCの作り方
-
丸いボタンの表示でCPU100%
おすすめ情報