2009年1月22日木曜日

.NET(Mobile) SIPの情報(表示状態、高さ、作業領域)を取得するには?

SIPの情報(表示状態、高さ、作業領域)するには SipGetInfo APIを使用します。
<DllImport("coredll.dll")> _
Public Structure SIPINFO
Public cbSize As Int32
Public fdwFlags As Int32
Public rcVisibleDesktop As RECT
Public rcSipRect As RECT
Public dwImDataSize As Int32
Public pvImData As IntPtr
End Structure

Public Structure RECT
Public left As Int32
Public top As Int32
Public right As Int32
Public bottom As Int32
End Structure

Private Const SIPF_DOCKED As Integer = 0
Private Const SIPF_LOCKED As Integer = 1
Private Const SIPF_OFF As Integer = 2
Private Const SIPF_ON As Integer = 3

<DllImport("coredll.dll")> _
Private Shared Function SipGetInfo(ByRef pSipInfo As SIPINFO) As Boolean
End Function


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

Dim info As SIPINFO
info.cbSize = System.Runtime.InteropServices.Marshal.SizeOf(info)
Call SipGetInfo(info)

'SIP起動状態
Dim isSipOpen As Boolean 
If info.fdwFlags = SIPF_ON Then
isSipOpen = True
ElseIf info.fdwFlags = SIPF_OFF Then
isSipOpen = False
End If
'SIPの高さ
Dim iSipHeight As Integer = info.rcSipRect.bottom - info.rcSipRect.top
'作業領域
Dim iDesktopHeight As Integer = info.rcVisibleDesktop.bottom - info.rcVisibleDesktop.top

MessageBox.Show(String.Format("Sip起動:{0} Sipの高さ:{1} 作業領域の高さ:{2}", isSipOpen, iSipHeight, iDesktopHeight))

End Sub


WS007SH(Willcom)では以下の値が返りました。
SIPが表示されていない状態
Sip起動:False Sipの高さ:160 作業領域の高さ:376
SIPが表示されている状態
Sip起動:True Sipの高さ:160 作業領域の高さ:588


X04HT(SoftBank)では以下の値が返りました。
SIPが表示されていない状態
Sip起動:False Sipの高さ:318 作業領域の高さ:218
SIPが表示されている状態
Sip起動:True Sipの高さ:318 作業領域の高さ:588


DT-5200(CASIO)ではSIPINFO.fdwFlags がSIPF_DOCKED(表示)/SIPF_LOCKED(非表示)になるようです。
DT-5200ではプログラムを以下のように修正します。
'SIP起動状態
Dim isSipOpen As Boolean 
If info.fdwFlags = SIPF_LOCKED Then
isSipOpen = True
ElseIf info.fdwFlags = SIPF_DOCKED Then
isSipOpen = False
End If

SIPが表示されていない状態
Sip起動:False Sipの高さ:105 作業領域の高さ:294
SIPが表示されている状態
Sip起動:True Sipの高さ:105 作業領域の高さ:294
※作業領域の高さがSIPが起動している時も起動していない時も変わらない。

DT-5200はSIPがタスクバーにあるけれど
X04HT、WS007SHはFormのMainMenuでSIPが起動するからその違いなのかな・・・

.NET(Mobile) SIPを表示するには?

SIP(Software Input Panel)を表示するには SipShowIM APIを使用します。
<DllImport("coredll.dll")> _
Private Shared Function SipShowIM(ByVal fOpen As Int32) As Boolean
End Function

'SIPを表示します。
Private Sub ShpShow_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) _
Handles cmdSipShow.Click
Call SipShow(True)
End Sub

'SIPを閉じます。
Private Sub ShpCloas_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) _
Handles cmdSipClose.Click
Call SipShow(False)
End Sub

.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  

.NET(Mobile) 画面の解像度(dpi)と画面のサイズを取得するには?

画面の解像度(dpi)と画面のサイズを取得するにはGetDeviceCaps APIを使用します。

'デバイスコンテキストを得る
<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 HORZRES As Integer = 8   '画面の幅 (ピクセル単位)
Private Const VERTRES As Integer = 10  '画面の高さ (ピクセル単位)
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)

'SCREEN SIZE
Dim screenX As Integer = GetDeviceCaps(ScreenHdc, HORZRES)
Dim screenY As Integer = GetDeviceCaps(ScreenHdc, VERTRES)


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

ReleaseDC(Me.Handle, ScreenHdc)

MessageBox.Show(String.Format("screenX:{0}、screenY:{1}、dpiX:{2}、dpiY:{3}",screenX,screenY, dpiX, dpiY))
End Sub



WS007SH、X04HTでは以下の値が返りました。
screenX:480
screenY:640
dpiX:192
dpiY:192

CASIO DT-5200
QVGA
screenX:480
screenY:640
dpiX:96
dpiY:96
VGA
screenX:240
screenY:320
dpiX:96
dpiY:96

2009年1月21日水曜日

.NET(Mobile) デバイス プラットフォームを取得するには?(使えない!?)

Microsoftに方法 : デバイス プラットフォームを取得する方法があったので、ついでに試してみました。
Private Shared SPI_GETPLATFORMTYPE As System.UInt32 = 257

<DllImport("coredll.dll", EntryPoint:="SystemParametersInfo")> _
Friend Shared Function SystemParametersInfo _
(ByVal uiAction As System.UInt32, _
ByVal uiParam As System.UInt32, _
ByVal pvParam As System.Text.StringBuilder, _
ByVal fWinIni As System.UInt32) As Boolean
End Function

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) _
Handles Button1.Click
Dim buffer As New System.Text.StringBuilder(200)
SystemParametersInfo(SPI_GETPLATFORMTYPE, 200, buffer, 0)
MessageBox.Show(buffer.ToString)
End Sub


結果は
W-ZERO3(WS007SH)、X04HTともに「POCKET PC」が返ります。


Windows Mobile 6.0では以下の3つのEditionがあります。
Windows Mobile 6 Professional Edition …比較的大型のタッチスクリーンを搭載し、必須ではないが、多くの場合、QWERTYキーボードを備える。
Windows Mobile 6 Standard Edition …Windows Smartphoneの後継で、タッチスクリーンを搭載しない
Windows Mobile 6 Classic …電話機能がないPPCデバイスの後継。


Windows Mobile 5.0では以下の3つのEditionがあります。
Windows Mobile 5.0 for Smartphon
Windows Mobile 5.0 for Pocket PC Phone Edition
Windows Mobile 5.0 for Pocket PC

Windows Mobile 6とWindows Mobile 5.0は以下のような対応になるようです。
Windows Mobile 6Windows Mobile 5.0
Professional EditionSmartphon
Standard EditionPocket PC Phone Edition
ClassicPocket PC



W-ZERO3はSmartPhoneが返ってきそうなのですが、Willcomが特殊で「POCKET PC」が返るそうです。
X04HTはWindowsMobile6.0以降はEditionにかかわらず、すべて「POCKET PC」が返るそうです。


つまり使えないってこと!?

.NET(Mobile) OSのバージョンを取得するには?

OSのバージョン情報はSystem.EnvironmentクラスのOSVersionプロパティにより取得できます。
Dim os As System.OperatingSystem
os = System.Environment.OSVersion


Willcom W-ZERO3(WS007SH) (WindowsMobile5.0)では以下の値が返りました。
os.Pratform = System.PratformID.WinCE(3)
os.Version.Major = 5
os.Version.Minor = 1
os.Version.Build = 195
os.Version.Revision = -1
os.ToString = Microsoft Windows CE 5.1.195


SoftBank X04HT(Windows Mobile 6.1 Professional)では以下の値が返りました。
os.Pratform = System.PratformID.WinCE(3)
os.Version.Major = 5
os.Version.Minor = 2
os.Version.Build = 19971
os.Version.Revision = -1
os.ToString = Microsoft Windows CE 5.2.19971

CASIO DT-5200(Windows Mobile 6.1 Professional)では以下の値が返りました。
os.Pratform = System.PratformID.WinCE(3)
os.Version.Major = 5
os.Version.Minor = 0
os.Version.Build = 1400
os.Version.Revision = -1
os.ToString = Microsoft Windows CE 5.0.1400

.NET(Mobile) 端末の機種名を取得するには?

端末の機種名を取得するにはSystemParametersInfo APIを使用します。

Imports System.Runtime.InteropServices

Public Class Form1

Friend Const SPI_GETOEMINFO As Integer = 258

<DllImport("coredll.dll")> _
Friend Shared Function SystemParametersInfo _
(ByVal uiAction As System.UInt32, _
ByVal uiParam As System.Int32, _
ByVal pvParam As System.Text.StringBuilder, _
ByVal fWinIni As System.UInt32 _
) As Boolean
End Function


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

Dim buffer As New System.Text.StringBuilder
If SystemParametersInfo(SPI_GETOEMINFO, buffer.Capacity, buffer, 0) Then
MessageBox.Show(buffer.ToString)
Else
Messagebox.show("取得失敗")
End If

End Sub
End Class


Willcom W-ZERO3[es](WS007SH)の場合「SHARP WS007SH」が表示されます。
SoftBank X04HTの場合「X04HT」が表示されます。
CASIO DT-5200の場合「PY021]が表示されます。

2009年1月16日金曜日

雑記 子供が大きくなったらプログラマーになるそうです。

子供が保育園の卒業アルバムに乗せる「プロフィール」を持って帰って来た。

家で親と一緒に書いて提出して下さいとの事だった。

項目は
  • 好きな食べ物
  • 好きな遊び
  • 大きくなったらなりたい職業


子供が好きな食べ物に「ぶどう」と書いた。

子供が好きな遊びに「おにごっこ」と書いた。

子供が大きくなったらなりたい職業に「ぷろぐらまー」と書こうとしたので、「どうぶつのおいしゃさん」に誘導した・・・。

「大きくなったらパソコンのお仕事して、手伝ってあげる」って言ってくれるのにゴメンよ~。

大きくなったらなりたい職業に「ぷろぐらまー」って、あまりに夢がないと思ったから・・・(ノД`)