酢ろぐ!

カレーが嫌いなスマートフォンアプリプログラマのブログ。

Windows Mobileでバイブレーションを制御する

バイブレータを鳴動させる機能は.NET Compact Frameworkではサポートされていませんので、WIN32APIをP/Invokeで使用する必要があります。

定義

まずは使用する構造体とネイティブ コードを呼び出す為の定義を行います。

VB.NET

    ' NLED_COUNT_INFO 構造体はLEDの個数を表します。
    Public Structure NLED_COUNT_INFO
        Public cLeds As Integer
    End Structure

    ' NLED_SETTINGS_INFO 構造体はLEDの設定情報を表します。
    Public Structure NLED_SETTINGS_INFO
        Public LedNum As UInt16
        Public OffOnBlink As Integer
        Public TotalCycleTime As Long
        Public OnTime As Long
        Public OffTime As Long
        Public MetaCycleOn As Integer
        Public MetaCycleOff As Integer
    End Structure

    ' NLED_SUPPORTS_INFO 構造体はLEDのサポート情報を表します。
    Public Structure NLED_SUPPORTS_INFO
        Public LedNum As UInt16
        Public lCycleAdjust As Long
        Public fAdjustTotalCycleTime As Boolean
        Public fAdjustOnTime As Boolean
        Public fAdjustOffTime As Boolean
        Public fMetaCycleOn As Boolean
        Public fMetaCycleOff As Boolean
    End Structure

    ' NLedGetDeviceInfo で取得する情報種別ID
    Const NLED_COUNT_INFO_ID As Integer = 0
    Const NLED_SUPPORTS_INFO_ID As Integer = 1
    Const NLED_SETTINGS_INFO_ID As Integer = 2

    ' LEDへ情報を設定します
    <DllImport("coredll.dll")> _
    Private Shared Function NLedSetDevice( _
       ByVal nDeviceId As Integer, _
       ByRef pInput As NLED_SETTINGS_INFO) As Boolean
    End Function

    ' LEDドライバの情報を取得します
    <DllImport("coredll.dll")> _
    Private Shared Function NLedGetDeviceInfo( _
       ByVal nDeviceId As Integer, _
       ByRef pOutput As NLED_COUNT_INFO) As Boolean
    End Function
    <DllImport("coredll.dll")> _
    Private Shared Function NLedGetDeviceInfo( _
       ByVal nDeviceId As Integer, _
       ByRef pOutput As NLED_SUPPORTS_INFO) As Boolean
    End Function

C#

    // NLED_COUNT_INFO 構造体はLEDの個数を表します。
    public struct NLED_COUNT_INFO
    {
        public int cLeds;
    }

    // NLED_SETTINGS_INFO 構造体はLEDの設定情報を表します。
    public struct NLED_SETTINGS_INFO
    {
        public UInt16 LedNum;
        public int OffOnBlink;
        public long TotalCycleTime;
        public long OnTime;
        public long OffTime;
        public int MetaCycleOn;
        public int MetaCycleOff;
    }

    // NLED_SUPPORTS_INFO 構造体はLEDのサポート情報を表します。
    public struct NLED_SUPPORTS_INFO
    {
        public UInt16 LedNum;
        public long lCycleAdjust;
        public bool fAdjustTotalCycleTime;
        public bool fAdjustOnTime;
        public bool fAdjustOffTime;
        public bool fMetaCycleOn;
        public bool fMetaCycleOff;
    }

    // NLedGetDeviceInfo で取得する情報種別ID
    const int NLED_COUNT_INFO_ID = 0;
    const int NLED_SUPPORTS_INFO_ID = 1;
    const int NLED_SETTINGS_INFO_ID = 2;

    // LEDへ情報を設定します
    [DllImport("coredll.dll")]
    private static extern bool NLedSetDevice(int nDeviceId, ref NLED_SETTINGS_INFO pInput);

    // LEDドライバの情報を取得します
    [DllImport("coredll.dll")]
    private static extern bool NLedGetDeviceInfo(int nDeviceId, ref NLED_COUNT_INFO pOutput);
    [DllImport("coredll.dll")]
    private static extern bool NLedGetDeviceInfo(int nDeviceId, ref NLED_SUPPORTS_INFO pOutput);

バイブレータLED

次に

VB.NET

    ' LEDの個数を取得する
    Private Function GetLedCount() As Integer

        Dim ledCount As Integer = 0

        ' LEDの個数を取得する
        Dim nci As NLED_COUNT_INFO
        If (NLedGetDeviceInfo(NLED_COUNT_INFO_ID, nci)) Then
            ledCount = nci.cLeds
        End If

        Return ledCount
    End Function

    ' VibratorLEDのIDを取得する
    Private Function GetVibratorLedID() As Integer

        Dim vibratorLedID As Integer = -1
        Dim ledCount As Integer = GetLedCount()

        For id As Integer = 0 To ledCount - 1

            Dim nsi As NLED_SUPPORTS_INFO
            nsi.LedNum = id

            ' サポート情報を取得する
            NLedGetDeviceInfo(NLED_SUPPORTS_INFO_ID, nsi)
            If (nsi.lCycleAdjust = -1) Then
                vibratorLedID = id
                Exit For
            End If

        Next id

        Return vibratorLedID
    End Function

C#

    // LEDの個数を取得する
    private int GetLedCount()
    {
        
        int ledCount = 0;
        
        // LEDの個数を取得する
        NLED_COUNT_INFO nci = default(NLED_COUNT_INFO);
        if (NLedGetDeviceInfo(NLED_COUNT_INFO_ID, nci)) {
            ledCount = nci.cLeds;
        }
        
        return ledCount;
    }

    // VibratorLEDのIDを取得する
    private int GetVibratorLedID()
    {
        
        int vibratorLedID = -1;
        int ledCount = GetLedCount();
        
        for (int id = 0; id <= ledCount - 1; id++) {
            
            NLED_SUPPORTS_INFO nsi = default(NLED_SUPPORTS_INFO);
            nsi.LedNum = id;
            
            // サポート情報を取得する
            NLedGetDeviceInfo(NLED_SUPPORTS_INFO_ID, nsi);
            if (nsi.lCycleAdjust == -1) {
                vibratorLedID = id;
                break; // TODO: might not be correct. Was : Exit For
                
            }
        }
        
        return vibratorLedID;
    }

LED情報の設定を行う

VB.NET

    ' LED情報の設定を行う
    Private Sub SetLedStatus(ByVal ledID As Integer, ByVal isStatus As Boolean)

        Dim count As Integer = GetLedCount()
        If ((ledID < 0) AndAlso (count <= ledID)) Then
            Return
        End If

        Dim offOnBlink As Integer = 0
        If (isStatus) Then
            offOnBlink = 1
        End If

        Dim settings As NLED_SETTINGS_INFO
        settings.LedNum = ledID
        settings.OffOnBlink = offOnBlink

        NLedSetDevice(NLED_SETTINGS_INFO_ID, settings)

    End Sub

    ' バイブレータLEDのIDを取得する
    Private Sub Vibrate(ByVal milliSecondsTimeout As Integer)

        Dim vibratorLedID As Integer = GetVibratorLedID()

        ' バイブレータLEDが存在していなければ何もしない
        If (vibratorLedID < 0) Then
            Return
        End If

        SetLedStatus(vibratorLedID, True)

        System.Threading.Thread.Sleep(milliSecondsTimeout)

        SetLedStatus(vibratorLedID, False)

    End Sub

C#

    // LED情報の設定を行う
    private void SetLedStatus(int ledID, bool isStatus)
    {
        
        int count = GetLedCount();
        if ((ledID < 0) && (count <= ledID)) {
            return;
        }
        
        int offOnBlink = 0;
        if (isStatus) {
            offOnBlink = 1;
        }
        
        NLED_SETTINGS_INFO settings = default(NLED_SETTINGS_INFO);
        settings.LedNum = ledID;
        settings.OffOnBlink = offOnBlink;
        
        NLedSetDevice(NLED_SETTINGS_INFO_ID, settings);
    }

    // バイブレータLEDのIDを取得する
    private void Vibrate(int milliSecondsTimeout)
    {
        
        int vibratorLedID = GetVibratorLedID();
        
        // バイブレータLEDが存在していなければ何もしない
        if (vibratorLedID < 0) {
            return;
        }
        
        SetLedStatus(vibratorLedID, true);
        
        System.Threading.Thread.Sleep(milliSecondsTimeout);
        
        SetLedStatus(vibratorLedID, false);
    }

参照

関連記事

Windows Mobile(.NET Compact Framework)を使ってアプリ開発する際に逆引きとしてお使いください。