ド素人の推察です[dpi値](’14/10)(追記('14/11)


前にここで、VC++のGetDeviceCapsという 関数を実行した結果のついてド素人の思いつき
を不遜にもアップしてしまいました(^^;。

それは、整理整頓がダメなゆえに、4年以上のブランクの間にどこかに行方不明になっている
2002年頃購入した私にとって貴重なバイブル的な存在であったMicrosoft出版社発行のwindows
プログラミングという本の記載と合わないゆえのことでした。
再掲しますと、要するに、GetDeviceCapsにLOGPIXELSX,LOGPIXELSYを指定した戻り値は96、
したがって、分解能は96dpi、HORZRESを指定した戻り値は1920、VERTRESを指定した
戻り値は1080したがってスクリーンの幅方向総ピクセル数は1920、高さ方向総ピクセル数は
1080ということから、この値から算定するなら、
 水平方向幅=1920/96×25.4≒508[mm]、垂直方向高さ=1080/96×25.4≒286
のはずなのに、HORZSIZE、VERTSIZEを指定したときの戻り値は
 水平方向幅=477[mm] 垂直方向高さ=268[mm]
となって不一致であるというものでした。ただし、このHORZSIZE,VERTSIZEで画面の大きさを
計算すると約21.5[inch]となって私のモニターと一致しているという・・・


今回、マッピングモードというものを勉強していて関連の話を発見しました。
理解力に乏しい(というか思い込みが激しくて、はなはだしく誤解していてそれが理解の妨げ
になっていたことに今更気が付きましたが)私、以前は全然理解できなかったんですが、今回
やっと理解できたようです(つもりかな?(^^;)

そもそも「語彙」で惑わされたところがあります。多くのGDIのAPIのパラメータとして指定する
のが「論理座標」、画面上の座標が「物理座標(デバイス座標)」ということは頭ではわかって
いたつもりですけど、どこかで混同していたんですね(^^;。ま、論理座標を「ウインドウ」、物理
座標を「ビューポート」と称するというのは、そう覚えればとこだわりはなかったんですが・・・

SetWindowOrgExとかSetViewportOrgExという関数を理解する中で、私の中で

 物理座標はあくまで、左上隅が(0,0)でピクセル単位である

ということを十分わかっていなかったことがわかりました。これがすべての基本なんですね。
それでマップモードも理解できました。結局、

 GDIの関数のパラメータのx,y座標値が画面ではどこに位置するか

というのが基本で、それを示すのがマップモードということだという、こんな初歩的・基本的概
念をやっとこさ理解できたという情けない輩です<私(^^;。
そして、その変換率が可変なMM_ISOTROPIC,MM_ANISOTROPICというモードのみで有効な、
SetWindowExtEx,SetViewportExtExというWin32APIの説明にあった「範囲」という用語そして
その変換方法がわかりましたので、その概念を応用することで、変換率が固定であるデフォ
ルトのMM_TEXTばかりでなく、MM_LOMETRIC,MM_HIMETRIC,MM_LOENGLISH,
MM_HIENGLISHそしてMM_TWIPSというのも一挙に理解できました。
前に前述の私のバイブル読んでいたときには全然理解できなかったというか無理やり、自分
をごまかして(結局は誤解していたのですが)わかったつもりでいました(^^;。

これらは、論理座標の値1が物理座標ではどうなるかを示したもので、

 (物理座標距離)=(論理座標距離)×(変換比率)

が基本ということです。ここで、

 変換比率=(整数で表した物理座標値)/(整数で表した論理座標値)

ということです。そして、SetWindowExtExでは「範囲」はそれぞれの最大値と書いてはありま
すが、結局は「比」が使われるだけですので、必ずしも「最大値」でなくても、同じ比率になる
整数値どうしを「範囲」という意味でつかえばよいわけですね。現に記憶ではその比率関係
が固定である前述の6つのモードの範囲はそれで示されていました。
記憶では、例えば、
MM_LOENGLISHはウインドウ範囲:(100,100)、ビューポート範囲:(96,-96)
MM_LOMETRICはウインドウ範囲:(254,254)、ビューポート範囲:(96,-96)
と書かれていたと思います。
MM_LOENGLISHは「論理座標が0.01インチにマップされる」とありますので、論理座標値の
100が物理座標の1インチに対応することになります。そして、96dpiですから、1インチは
は96ピクセルとなりますので、比率=96/100というわけです。y値で「−」がついているの
はMM_LOMETRIC,MM_HIMETRIC,MM_LOENGLISH,MM_HIENGLISH,MM_TWIPSの場合、y軸
方向が逆になって画面上では上が正方向にされているからです。
MM_LOMETRICの方は「論理座標が0.1mmにマップされる」とありますので、論理座標の10
が物理座標の1mmに相当します。そして、1mmは1/25.4インチですから、結局、論理座標
の254が1インチしたがって96ピクセルに相当することになり、比率は96/254というわけです。

しかしながら、これはWindows2000/Windows98でVC++6.0の頃、執筆された本でした。
それでも、ネット見てますと、「96dpi」という数値が出てきています。

ところが、私のWindows8.1マシンでVC++2013(VS 2013 EXPRESS)でSetMapModeとLPtoDP
というWin32APIで試してみたところ、な、なんと、96ではなく、102となりました。
すなわち、1インチは102ピクセルだと言っているようなものです。そして、この102は前述の
HORZSIZE,VERTSIZEの結果の考察による値と一致しています。
私の検索が悪いのか、そういう追及をネットでは目にしていません。ですから、ド素人の私
の勝手な推測の可能性は大ですけど、どうも対外的には96dpiというのは変えてはいなくて
も実際には最近のOSでは実情に合わせて変えたんではないかと思うのですが・・・

前述のwindowsプログラミングという本では確か、Windows95のときはHORZSIZE,VERTSIZE
の値は定数として設定されていたようなことが書かれていました。ですから、上記で考察し
た考え方はその本に記載があったWindows2000の考え方の流用です。

Windows2000はWindowsNT系の最終バージョンであり、Windows9X系とは開発者が異なり、
conceptも違うわけで、多分に両者を統合したWindowsXP以降はNT系のconceptを引き継い
でいるのではないかとこれまた素人考えをしていてそれで上記のような考察をしてきたわけ
です。

ネットでも記載がありましたが、プリンタと異なり、モニタというのは自分の情報をPCに伝達
したりしていませんし、APIにそれを調べるような関数がないらしいです。
そして、どうやら、同じ1920×1080と称していても、モニターはメーカによる相違があるそう
です。そんな状況では、未来永劫、同じでは実情とのギャップが出てくるのは必定な気がし
ています。正確に測ったわけではありませんが、ちょろっと定規を当ててみたところ、前述
の477mmというのは私のDELLの21.5インチモニタではおおよそあっている感じがします。
そして、MapModeを変えたときの出てくる値と前述のように整合性がありますので、見直し
がされているのではないかと考えた次第です。ちなみに、LOGPIXELSX,LOGPIXELSYは単
に、古くからの統一的な数値96を示しているだけで現実には使っていないのではないかとい
うのが、ド素人の私の本稿での推測結論です。(’14/10)

・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・
(追記’14/11)
前からVC++2014(by VisualStudio2013 Exress)で画面に文字列表示するときのフォントはど
うなっているかが私の疑問でした。ちょろっとネット眺めても欲しい情報が出てこない・・

今回、CreateFontというWin32APIでパラメータを変えていろいろ試した結果、この関数の
第1パラメータ nHeigt
  −MulDiv(11, 102, 72)
第14パラメータlpszFace
  TEXT("MS ゴシック")
を指定すると同一(私の眼にはそう見える)となることがわかりました。

尚、私の環境はWindows8.1(DELL XPS8700)で、DELLの21.5インチモニタです。
ここで、本来、msdnライブラリによれば、nHeightは
  −MulDiv((Point数), GetDeviceCaps(hDC,LOGPIXELSY), 72)
ですが、このGetDeviceCaps(hDC,LOGPIXELSY)は96となります。そこで、試に前述で結果
で見た"102"を代わりに入れてみたらちょうどうまくいきました。
これからも実際には"96dpi"ではなく、"102dpi"でやっているのではないかという感をます
ます強くしました。

私、まだよくわかっていないのは、ネット記事によれば、Windows8,8.1のシステムフォントは
"Meiryo"となったとのことですが、GetStockObjectで選択する"SYSTEM_FONT"というのは
それではないということです。"Meiryo"とか"meiryo UI"を指定してみましたが小さい文字に
なってしまうんです。以前は日本語Windowsのシステムフォントは"MS P明朝"と書かれてい
たのですが、これとも合いません。

戻る