登录
首页 嵌入式系统 微软嵌入式
回帖 发帖
正文

主题:英创WinCE平台C#例程要点之四

点击:1052 回复:0

英创嵌入式ARM9主板采用微软的Windows CE操作系统,可以采用eVC或者VS2005进行应用开发。C#作为一种简单易用的编程语言工具,由于其在结构构建和API界面上的优势,受到广大客户的喜爱,并为很多用户所选用。为了让广大选用C#的用户能够方便快捷地完成应用开发,英创提供了一些C#的应用例程。一些例程我们已经提供了一些说明文档,发表在英创网站上,它们是:
     ·基于WINCE平台C#编程要点之一
           一、文件的删除和复制
           二、获取存储设备的大小信息
           三、重启系统函数
           四、隐藏/显示Windows任务栏
     ·基于WINCE平台C#编程要点之二
           一、在英创ARM9嵌入式主板上实现GPRS拨号上网
           二、使用TcpClient和TcpListener两个类实现网络数据传输
     ·使用C#进行CAN总线编程—基于WINCE平台C#编程要点之三
     ·CAN接口COM组件在C#语言中的使用
     ·SQL CE数据库的C#编程
     ·C#使用COM组件接口操作精简ISA总线
     ·C#使用COM组件接口进行串口操作
     ·C#调用COM组件的效率分析
     英创不停地根据客户的需求添加相应的应用例程,本文将对下面两个新的要点进行浅析说明(光盘上均有相关例程):
     ·使用C#播放MP3或WAV音频文件
     ·如何定义和使用键盘热键
一、使用C#播放MP3或WAV音频文件
     英创的EM9000和EM9161等嵌入式工控主板进行音频硬件扩展后,可以支持音频的播放,如果客户要在应用产品中播放MP3和WAV等音频文件,我们的例程采用了著名的第三方音频动态链接库fmodce.dll,客户可以按照如下方法进行使用:
     首先,可以在应用工程中创建一个新的音频类文件,如sound.cs,在这个类文件里定义一个音频类,对fmodce.dll的音频函数进行DllImport定义,以便在应用程序中可以调用:
public static IntPtr GetStream(string filename)    //获得音频文件的IntPtr
{
     byte[] filenamebytes = System.Text.Encoding.Default.GetBytes(filename + null);
     GCHandle hfile = GCHandle.Alloc(filenamebytes, GCHandleType.Pinned);
     if (Environment.Version.Major == 1) return new IntPtr(hfile.AddrOfPinnedObject().ToInt32() + 4);
     else return hfile.AddrOfPinnedObject();
}
[DllImport('fmodce.dll', EntryPoint = 'FSOUND_Init', SetLastError = true, CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Winapi)]
public static extern bool Init(int mixrate, int maxsoftwarechannels, int flags);   //初始化
[DllImport('fmodce.dll', EntryPoint = 'FSOUND_Stream_GetLength', SetLastError = true, CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Winapi)]
public static extern int GetLength(IntPtr fstream);   //获得流媒体的长度
[DllImport('fmodce.dll', EntryPoint = 'FSOUND_Stream_GetPosition', SetLastError = true, CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Winapi)]
public static extern UInt32 GetPosition(IntPtr fstream);   //获得流媒体当前播放位置
[DllImport('fmodce.dll', EntryPoint = 'FSOUND_Stream_Open', SetLastError = true, CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Winapi)]
public static extern IntPtr Open(IntPtr data, int mode, int offset, int length);   //打开音频文件
[DllImport('fmodce.dll', EntryPoint = 'FSOUND_Stream_Play', SetLastError = true, CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Winapi)]
public static extern int Play(int channel, IntPtr fstream);    //播放音频文件
[DllImport('fmodce.dll', EntryPoint = 'FSOUND_Stream_SetPosition', SetLastError = true, CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Winapi)]
public static extern bool SetPosition(IntPtr fstream, UInt32 position);   //定位音频文件播放位置
[DllImport('fmodce.dll', EntryPoint = 'FSOUND_Stream_Stop', SetLastError = true, CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Winapi)]
public static extern bool Stop(IntPtr fstream);     //停止播放
[DllImport('fmodce.dll', EntryPoint = 'FSOUND_Close', SetLastError = true, CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Winapi)]
public static extern void Close();     //关闭音频文件
[DllImport('coredll.dll', SetLastError = true)]
public static extern int SetSystemPowerState(string psState, int StateFlags, int Options);
const int POWER_FORCE = 0x1000;
const int POWER_STATE_ON = 0x10000;
     有了这些方便易用的音频函数,而后就可以在应用程序里面自由操作音频文件了。比如,播放一首songmother.mp3歌曲:
string currentSoundTrack = @'\NandFlash\songmother.mp3';
Sound.Init(44100, 16, 0);   //初始化为44.1kHz
IntPtr soundStream = Sound.GetStream(currentSoundTrack);
IntPtr soundHandle = Sound.Open(soundStream, 16 | 32 | 256, 0, 0);
Sound.Play(0, soundHandle);
二、如何定义和使用键盘热键
     在客户的应用开发中,很多终端设备是使用小键盘相应热键来执行相应的应用操作的。WinCE操作系统有很完善的消息传递机制,我们提供了一个热键例程来说明这个过程。
     首先,可以在应用工程中创建一个新的MessageWindow类文件,如MyMessageWindow.cs,以便监视键盘操作并作出实时响应:
class MyMessageWindow : MessageWindow
{
     private Form1 msgform = null;
     //注意,程序的主窗体名称是Form1,所以在此定义一个msgform的Form1以便接收传递的消息
     //下面是构造函数,注意在Form1.cs是通过
     //keyUsage = new MyMessageWindow(this);彼此建立关联的
     public MyMessageWindow(Form1 msgform)
     {
           this.msgform = msgform;
     }
     protected override void WndProc(ref Message m)//监视Windows消息
     {
           const int WM_HOTKEY = 0x0312; //如果m.Msg的值为0x0312那么表示用户按下了热键
           switch (m.Msg)
           {
                 case WM_HOTKEY:
                       Form1.ProcessHotkey(m); //按下热键时调用Form1主窗体的ProcessHotkey()函数
                       break;
           }
           base.WndProc(ref m); //将系统消息传递自父类的WndProc
     }
}
     在主窗体需要对Win32 API热键函数进行声明:
[DllImport('coredll.dll')]       //定义一个系统范围的热键。
public static extern bool RegisterHotKey(IntPtr hWnd, int id, uint fsModifiers, Keys vk);
[DllImport('coredll.dll')]      //在系统中注消热键。
public static extern bool UnregisterHotKey(IntPtr hWnd, int id);
//下面的fsModifoers:定义为了产生WM_HOTKEY消息而必须与由nVirtKey参数定义的键一起按下的键。
public enum KeyModifiers
{
     None = 0,              //该键不按下
     Alt = 1,                //该键为ALT键              
     Control = 2,            //该键为CTL键
     Shift = 4,               //该键为Shift键
     Windows = 8            //该键为任意Windows键
}
     在主窗体函数中定义热键:
public Form1()
{
     InitializeComponent();
     keyUsage = new MyMessageWindow(this);
     //通过构造函数中参数this的传递,主窗体被传入MessageWindow中,
     //主窗体的消息循环按照新的消息循环进行
     RegisterHotKey(keyUsage.Hwnd, 100, 0, Keys.D1);
     // 定义热键数字键'1',请注意句柄是keyUsage.Hwd(而不是Handle)
     RegisterHotKey(keyUsage.Hwnd, 200, 0, Keys.D2); // 定义热键数字键'2'
     RegisterHotKey(keyUsage.Hwnd, 300, 0, Keys.D3); // 定义热键数字键'3'
     RegisterHotKey(keyUsage.Hwnd, 400, 0, Keys.D4); // 定义热键数字键'4'
}
     接收MyMessageWindow传递过来的热键消息,并作进一步处理的函数:
public static void ProcessHotkey(Message m)
{
     IntPtr id = m.WParam; //IntPtr用于表示指针或句柄的平台特定类型
     string sid = id.ToString();
     switch (sid)
     {
           case '100':          //按下了热键'1',执行action1()函数
           {
                 action1();
                 break;
           }
           case '200':          //按下了热键'2',执行action2()函数
           {
                 action2();
                 break;
           }
           case '300':          //按下了热键'3',执行action3()函数
           {
                 action3();
                 break;
           }
           case '400':          //按下了热键'4',执行action4()函数
           {
                 action4();
                 break;
           }
     }
}
     那么接下来,用户只需要在action函数里面添加自己需要进行的操作即可了。
10-06-02 13:04

工控新闻

更多新闻资讯