有时候需要在转换页面的时候用振动提示用户以获得更好的用户体验,这就需要提到在WM设备上实现振动的问题了。这里提供2中方式,但都是换汤不换药。一种是P/Invoke调用系统API来实现,另一种是通过使用OpenNETCF来实现(我认为也是通过调用系统API来实现,难道他有设备供应商更底层的接口,呵呵,玩笑!)。
当然,在实现的时候需要考虑是在PPC还是SP平台上,不同的平台有不同实现,这也是由2种平台的差异性造成的。
好,进入正题!
方法一: 通过P/Inovke调用系统API
g 1. 在PPC上
g 2. 在Smartphone上
g 3. 提供统一接口,不考虑平台
因为要考虑不同平台,因此要添加Microsoft.WindowsCE.Forms组件并引用 “using Microsoft.WindowsCE.Forms”。然后就可以通过SystemSettings和WinCEPlatform来判断所属平台了。
方法二: 通过使用OpenNETCF来实现
http://www.opennetcf.com/ 为我们提供非常好用的组件,这其中有许多是免费使用的,当然如果您需要更精彩的内容,支付点美金也是值得的。下面的介绍的方法就是使用该OpenNETCF来实现。
在使用前您需要去http://www.opennetcf.com/Default.aspx?tabid=65下载该文件(免费版即可),下载后安装就可以使用里面的组件了。安装后您会发现有3个文件夹,一个是组件库文件夹,一个是发布文件夹,一个是Sample。
然后需要包含Bin文件夹中的两个组件OpenNETCF.WindowsCE.dll和OpenNETCF.WindowsMobile.dll。前者是提供了在PPC中调用振动的接口,后者提供了在Smartphone中调用振动的接口。
好了,上面的实现相信已经很清楚了,如果还不清楚,可以下载下面的例子试试,调试一下就明白了!
--------------------
例子下载:
Vibrate.rar
修正:
---------------------------------------------------------------------------------------------------------------------------------
2009 - 08 - 24
在“老羽”的指点下,修正了原来的在PPC上调用NLedSetDevice的“short nID”参数问题。
之前的“设备上一般有至少2个Led, 0为扬声器Led, 而振动器为最后一个”的观点在HDC的设备上是
可行的,但并不保证所以的WM设备是可行的,比如”老羽"的夏新N810。
通过P/Inovke调用系统API
在PPC上
/// for PPC
/// </summary>
public class Vibrate_PPC
{
// 可用的Led号
private static uint m_availableNo = 0xFFFFFFFF;
// NLED_COUNT_INFO 结构对应ID
private const int NLED_COUNT_INFO_ID = 0;
// NLED_SUPPORTS_INFO 结构对应ID
private const int NLED_SUPPORTS_INFO_ID = 1;
// NLED_SETTINGS_INFO 结构对应ID
private const int NLED_SETTINGS_INFO_ID = 2;
private Vibrate_PPC()
{
}
// 查找可用的Led,并振动
public static bool Play()
{
bool bRes = false;
NLED_SETTINGS_INFO nsi = new NLED_SETTINGS_INFO();
nsi.OffOnBlink = (int)LedState.On;
if (m_availableNo == 0xFFFFFFFF)
{
// 获取设备数
NLED_COUNT_INFO pOutput = new NLED_COUNT_INFO();
if (!NLedGetDeviceCount(NLED_COUNT_INFO_ID, ref pOutput))
{
// 初始化失败,跑出异常
return false;
}
uint ledCount = pOutput.cLeds;
for (uint i = 0; i < ledCount; ++i)
{
NLED_SUPPORTS_INFO nspti = new NLED_SUPPORTS_INFO();
nspti.LedNum = i;
// 首先获取设备支持
if (NLedGetDeviceSupports(NLED_SUPPORTS_INFO_ID, ref nspti))
{
// 该条件是判断振动器是否可用的条件
if (nspti.lCycleAdjust == -1)
{
m_availableNo = i;
nsi.LedNum = m_availableNo;
bRes = NLedSetDevice(NLED_SETTINGS_INFO_ID, ref nsi);
}
}
}
}
else
{
// 如果之前已经得到正确的Led号,那么就直接调用了
nsi.LedNum = m_availableNo;
bRes = NLedSetDevice(NLED_SETTINGS_INFO_ID, ref nsi);
}
if (bRes)
{
return true;
}
else
{
return false;
}
}
public static bool Stop()
{
if (m_availableNo != 0xFFFFFFFF)
{
NLED_SETTINGS_INFO nsi = new NLED_SETTINGS_INFO();
nsi.LedNum = m_availableNo;
nsi.OffOnBlink = (int)LedState.Off;
if (NLedSetDevice(1, ref nsi))
return true;
else
return false;
}
return false;
}
#region P/Invoke
[DllImport("coredll.dll", EntryPoint = "NLedGetDeviceInfo")]
private static extern bool NLedGetDeviceCount(short nID, ref NLED_COUNT_INFO pOutput);
[DllImport("coredll.dll", EntryPoint = "NLedGetDeviceInfo")]
private static extern bool NLedGetDeviceSupports(short nID, ref NLED_SUPPORTS_INFO pOutput);
[DllImport("coredll.dll")]
private static extern bool NLedSetDevice(short nID, ref NLED_SETTINGS_INFO pOutput);
public enum LedState
{
Off,
On,
Blink
}
[StructLayout(LayoutKind.Sequential)]
private struct NLED_COUNT_INFO
{
public uint cLeds;
}
[StructLayout(LayoutKind.Sequential)]
private struct NLED_SUPPORTS_INFO
{
public uint LedNum;
public int lCycleAdjust;
public bool fAdjustTotalCycleTime;
public bool fAdjustOnTime;
public bool fAdjustOffTime;
public bool fMetaCycleOn;
public bool fMetaCycleOff;
}
[StructLayout(LayoutKind.Sequential)]
private struct NLED_SETTINGS_INFO
{
public uint LedNum;
public int OffOnBlink;
public int TotalCycleTime;
public int OnTime;
public int OffTime;
public int MetaCycleOn;
public int MetaCycleOff;
}
#endregion
--------------------
例子下载:
例子下载:
---------------------------------------------------------------------------------------------------------------------------------
--------------------------------------------------
|
李森 – listen |
|
声明: Announce: |