在.NET Compact Framework调用PPC设备的震动功能
利用C#开发Pocket PC程序,想在程序里调用设备的震动功能,至少再wm5中还没有这样的API,上网查了不少例子,都只能再c++下调用。既然这样,那唯一的办法是运用P/Invoke了,在“coredll.dll”中有这样两个函数
BOOL WINAPI NLedGetDeviceInfo( UINT nInfoId, void *pOutput );
BOOL WINAPI NLedSetDevice( UINT nDeviceId, void *pInput );
NLedGetDeviceInfo是获得LED数量,NLedSetDevice是来设置LED状态的,我们只有通过它来启动或者关闭Pocket PC设备的震动与否。说明一下:一般PPC设备都有两个LED,一个就是扬声器0(Radio LED),另一个则是振动器1(Vibrator)了。在我的PPC设备上发现第二个是Vibrator,不知道是不是所有的PPC都是这样子的。后来查到“On the HTC Himalaya the vibration device is implemented at index 1。”也就是HTC内核的都是1.
BOOL WINAPI NLedGetDeviceInfo( UINT nInfoId, void *pOutput );
BOOL WINAPI NLedSetDevice( UINT nDeviceId, void *pInput );
NLedGetDeviceInfo是获得LED数量,NLedSetDevice是来设置LED状态的,我们只有通过它来启动或者关闭Pocket PC设备的震动与否。说明一下:一般PPC设备都有两个LED,一个就是扬声器0(Radio LED),另一个则是振动器1(Vibrator)了。在我的PPC设备上发现第二个是Vibrator,不知道是不是所有的PPC都是这样子的。后来查到“On the HTC Himalaya the vibration device is implemented at index 1。”也就是HTC内核的都是1.
using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
using System.Threading;
namespace BluetoothChatPPC {
class LED {
class NLED_SETTINGS_INFO {
public uint LedNum;
public uint OffOnBlink;
public int TotalCycleTime;
public int OnTime;
public int OffTime;
public int MetaCycleOn;
public int MetaCycleOff;
}
class NLED_COUNT_INFO {
public int cLeds;
}
const int NLED_COUNT_INFO_ID = 0;
const int NLED_SETTINGS_INFO_ID = 2;
//振动器状态
public enum Status {
OFF=0,
ON,
BLINK
}
/// <summary>
/// 获得LED个数
/// </summary>
[DllImport("coredll.dll", CallingConvention = CallingConvention.Winapi, CharSet = CharSet.Unicode,
EntryPoint="NLedGetDeviceInfo",PreserveSig=true,SetLastError=true)]
extern static bool NLedGetDeviceInfo(uint nID, NLED_COUNT_INFO pOutput);
/// <summary>
/// 设置LED状态
/// </summary>
[DllImport("coredll.dll", CallingConvention = CallingConvention.Winapi, CharSet = CharSet.Unicode,
EntryPoint = "NLedSetDevice", PreserveSig = true, SetLastError = false)]
extern static bool NLedSetDevice(uint nID, NLED_SETTINGS_INFO pOutput);
/// <summary>
/// 获得LED个数
/// </summary>
public int GetLedCount() {
int wCount=0;
NLED_COUNT_INFO nci=new NLED_COUNT_INFO();
if (NLedGetDeviceInfo(NLED_COUNT_INFO_ID, nci)) {
wCount = nci.cLeds;
}
return wCount;
}
/// <summary>
/// 设置LED状态
/// </summary>
/// <param name="wLed">Led(1/0),一般是1,即第二个LED</param>
/// <param name="wStatus">状态</param>
public void SetLedStatus(int wLed, Status wStatus) {
NLED_SETTINGS_INFO nsi = new NLED_SETTINGS_INFO();
nsi.LedNum = (uint)wLed;
nsi.OffOnBlink = (uint)wStatus;
NLedSetDevice(NLED_SETTINGS_INFO_ID, nsi);
}
/// <summary>
/// 设置LED状态
/// </summary>
/// <param name="wLed">Led(1/0)</param>
/// <param name="wStatus">状态</param>
/// <param name="millisecondsTimeout">持续时间</param>
public void SetLedStatus(int wLed, Status wStatus,int millisecondsTimeout) {
this.SetLedStatus(wLed, wStatus);
System.Threading.Thread.Sleep(millisecondsTimeout);
//关闭震动
NLED_SETTINGS_INFO nsi = new NLED_SETTINGS_INFO();
nsi.LedNum = (uint)wLed;
nsi.OffOnBlink = (uint)Status.OFF;
NLedSetDevice(NLED_SETTINGS_INFO_ID, nsi);
}
/// <summary>
/// 设置LED状态
/// </summary>
/// <param name="wStatus">状态</param>
public void SetLedStatus(Status wStatus) {
NLED_SETTINGS_INFO nsi = new NLED_SETTINGS_INFO();
nsi.OffOnBlink = (uint)wStatus;
//自动查找震动LED
for (int i = 0; i < this.GetLedCount(); i++) {
nsi.LedNum = (uint)i;
NLedSetDevice(NLED_SETTINGS_INFO_ID, nsi);
}
}
/// <summary>
/// 设置LED状态
/// </summary>
/// <param name="wStatus">状态</param>
/// <param name="millisecondsTimeout">持续时间</param>
public void SetLedStatus(Status wStatus, int millisecondsTimeout) {
this.SetLedStatus(wStatus);
System.Threading.Thread.Sleep(millisecondsTimeout);
//关闭震动
NLED_SETTINGS_INFO nsi = new NLED_SETTINGS_INFO();
nsi.OffOnBlink = (uint)Status.OFF;
for (int i = 0; i < this.GetLedCount(); i++) {
nsi.LedNum = (uint)i;
NLedSetDevice(NLED_SETTINGS_INFO_ID, nsi);
}
}
/// <summary>
/// 循环震动
/// </summary>
/// <param name="times">次数</param>
public void CycleVibrate(int times) {
for (int i = 0; i < times; i++) {
this.SetLedStatus(Status.ON);
Thread.Sleep(400);
this.SetLedStatus(Status.OFF);
Thread.Sleep(200);
}
}
}
}
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
using System.Threading;
namespace BluetoothChatPPC {
class LED {
class NLED_SETTINGS_INFO {
public uint LedNum;
public uint OffOnBlink;
public int TotalCycleTime;
public int OnTime;
public int OffTime;
public int MetaCycleOn;
public int MetaCycleOff;
}
class NLED_COUNT_INFO {
public int cLeds;
}
const int NLED_COUNT_INFO_ID = 0;
const int NLED_SETTINGS_INFO_ID = 2;
//振动器状态
public enum Status {
OFF=0,
ON,
BLINK
}
/// <summary>
/// 获得LED个数
/// </summary>
[DllImport("coredll.dll", CallingConvention = CallingConvention.Winapi, CharSet = CharSet.Unicode,
EntryPoint="NLedGetDeviceInfo",PreserveSig=true,SetLastError=true)]
extern static bool NLedGetDeviceInfo(uint nID, NLED_COUNT_INFO pOutput);
/// <summary>
/// 设置LED状态
/// </summary>
[DllImport("coredll.dll", CallingConvention = CallingConvention.Winapi, CharSet = CharSet.Unicode,
EntryPoint = "NLedSetDevice", PreserveSig = true, SetLastError = false)]
extern static bool NLedSetDevice(uint nID, NLED_SETTINGS_INFO pOutput);
/// <summary>
/// 获得LED个数
/// </summary>
public int GetLedCount() {
int wCount=0;
NLED_COUNT_INFO nci=new NLED_COUNT_INFO();
if (NLedGetDeviceInfo(NLED_COUNT_INFO_ID, nci)) {
wCount = nci.cLeds;
}
return wCount;
}
/// <summary>
/// 设置LED状态
/// </summary>
/// <param name="wLed">Led(1/0),一般是1,即第二个LED</param>
/// <param name="wStatus">状态</param>
public void SetLedStatus(int wLed, Status wStatus) {
NLED_SETTINGS_INFO nsi = new NLED_SETTINGS_INFO();
nsi.LedNum = (uint)wLed;
nsi.OffOnBlink = (uint)wStatus;
NLedSetDevice(NLED_SETTINGS_INFO_ID, nsi);
}
/// <summary>
/// 设置LED状态
/// </summary>
/// <param name="wLed">Led(1/0)</param>
/// <param name="wStatus">状态</param>
/// <param name="millisecondsTimeout">持续时间</param>
public void SetLedStatus(int wLed, Status wStatus,int millisecondsTimeout) {
this.SetLedStatus(wLed, wStatus);
System.Threading.Thread.Sleep(millisecondsTimeout);
//关闭震动
NLED_SETTINGS_INFO nsi = new NLED_SETTINGS_INFO();
nsi.LedNum = (uint)wLed;
nsi.OffOnBlink = (uint)Status.OFF;
NLedSetDevice(NLED_SETTINGS_INFO_ID, nsi);
}
/// <summary>
/// 设置LED状态
/// </summary>
/// <param name="wStatus">状态</param>
public void SetLedStatus(Status wStatus) {
NLED_SETTINGS_INFO nsi = new NLED_SETTINGS_INFO();
nsi.OffOnBlink = (uint)wStatus;
//自动查找震动LED
for (int i = 0; i < this.GetLedCount(); i++) {
nsi.LedNum = (uint)i;
NLedSetDevice(NLED_SETTINGS_INFO_ID, nsi);
}
}
/// <summary>
/// 设置LED状态
/// </summary>
/// <param name="wStatus">状态</param>
/// <param name="millisecondsTimeout">持续时间</param>
public void SetLedStatus(Status wStatus, int millisecondsTimeout) {
this.SetLedStatus(wStatus);
System.Threading.Thread.Sleep(millisecondsTimeout);
//关闭震动
NLED_SETTINGS_INFO nsi = new NLED_SETTINGS_INFO();
nsi.OffOnBlink = (uint)Status.OFF;
for (int i = 0; i < this.GetLedCount(); i++) {
nsi.LedNum = (uint)i;
NLedSetDevice(NLED_SETTINGS_INFO_ID, nsi);
}
}
/// <summary>
/// 循环震动
/// </summary>
/// <param name="times">次数</param>
public void CycleVibrate(int times) {
for (int i = 0; i < times; i++) {
this.SetLedStatus(Status.ON);
Thread.Sleep(400);
this.SetLedStatus(Status.OFF);
Thread.Sleep(200);
}
}
}
}
在程序里调用
LED led=new LED();
led.SetLedStatus(LED.Status.ON,500);//震动500毫秒
以上就是自己通过P/Invoke来实现震动效果,还有一段文字值得注意的:
for example some devices contain a notification Led at position 0 and a vibration device at position 5. There is no way to programmatically determine the index of the vibration device, you can only determine the overall count of devices. Also the vibration device can only be turned on or off so the Blink setting behaves exactly as On would.
当然你可以直接使用OpenNETCF的类库,如下:
OpenNETCF.Notification.Led led = new OpenNETCF.Notification.Led();
//turn on vibration
led.SetLedStatus(1, OpenNETCF.Notification.Led.LedState.On);
//turn off vibration
led.SetLedStatus(1, OpenNETCF.Notification.Led.LedState.Off);