2009年1月22日木曜日

.NET(Mobile) 高DPI対応

VGAとは640×480(192dpi)、QVGAとは320×240(96dpi)です。
WS007SH、X04HTはVGA。
CASIO DT-5200はQVGAとVGAが切り替え可能ですが、QVGAは320×240(96dpi)、VGAは640×480(96dpi)になります。
※640×480(96dpi)のVGAをRealVGAと呼ぶそうです。
RealVGAは情報量は多いですが文字も非常に小さいです。

同じアプリをQVGA機種で動かすと正常に表示されるが、VGA機種で動かすと表示が崩れることがあります。
表示が崩れる現象を確認するために簡単なプログラムを実行してみます。

フォームにパネルを1つ配置し、サイズプロパティをWidth=100、Height=100 にします。
そしてボタンを配置し、クリックイベントに以下のコードを書いて実行してみました。
Me.Panel1.Size = New Size(100, 100)
Size(100,100)のパネルを、ボタンクリックでもう一度Size(100,100)を設定しているだけですが
ボタンクリック後はパネルの幅、高さが半分になってしまいました。
QVGAの機種ではもちろんこの現象は発生しません。

ボタンクリック前


ボタンクリック後



Microsoft 高 DPI 対応アプリケーションの開発
Microsoft 高 DPI アプリケーションの記述方法
上記によると、プログラムで指定したサイズは96 dpi を想定したピクセル値なので、自分でスケーリングしなければならないようです。

画面の解像度(dpi)と画面のサイズを取得するには?と同じようにdpiを取得しスケーリング値を計算します。

'デバイスコンテキストを得る  
<DllImport("coredll.dll")> _  
Private Shared Function GetDC(ByVal hwnd As IntPtr) As IntPtr  
End Function  

'デバイスコンテキストを解放する  
<DllImport("coredll.dll")> _  
Private Shared Function ReleaseDC(ByVal hwnd As IntPtr, ByVal hdc As IntPtr) As Boolean  
End Function  

'指定されたデバイスに関するデバイス固有情報を取得します。  
<DllImport("coredll.dll")> _  
Private Shared Function GetDeviceCaps _  
(ByVal hdc As IntPtr, ByVal nIndex As Integer) As Integer  
End Function  

Private Const LOGPIXELSX As Integer = 88    '論理インチ当たりの画面の水平方向のピクセル数  
Private Const LOGPIXELSY As Integer = 90    '論理インチ当たりの画面の垂直方向のピクセル数  


Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) _  
Handles Button2.Click  

Dim ScreenHdc As IntPtr = GetDC(Me.Handle)

'DPI  
Dim dpiX As Integer = GetDeviceCaps(ScreenHdc, LOGPIXELSX)
Dim dpiY As Integer = GetDeviceCaps(ScreenHdc, LOGPIXELSY)

'SCALE
Dim scaleX As Single = dpiX / 96
Dim scaleY As Single = dpiY / 96

Dim width As Integer = Convert.ToInt32(Math.Round(100 * scaleX))
Dim height As Integer = Convert.ToInt32(Math.Round(100 * scaleY))
Me.Panel1.Size = New Size(width , height )
End Sub  

0 件のコメント: