关于嵌入开发(WinCE)的一些经验

WindowsCE下Unicode和Ansi字符间互相转换的例子
纵所周知,WindowsCE下编程99%的问题都和Unicode有关.比如文件编辑,一般都保存为Ansi格式;无线通讯中控制Modem需要发送的AT指令,必须是Ansi格式;网络通讯中,PC端一般都是Ansi的,为了和PC上协议兼容,在WindowsCE中必须把要发送的一个指令从Unicode转换成Ansi格式...等等.很多初学者对于这些问题总是感到很麻烦.其实WindowsCE中有标准的API实现了Unicode和Ansi字符间的互转.下面就是网络通讯中的程序片断.
m_psocket是指向一个从CCeSocket派生的类,如果没有连接的话其为NULL;
m_snd是要发送的CString,和一个EDIT相对应.
  //发送函数片断
  void CClient1Dlg::OnButtonSend()
  {
        // TODO: Add your control notification handler code here
        if (!m_psocket) //无Socket连接,退出
        {
                MessageBox(TEXT("无连接!"),TEXT("信息"));
                return;
        }
        UpdateData(TRUE); //保存输入的字符串到m_snd
        unsigned char buf[129]; //发送缓冲区
        ZeroMemory(buf,sizeof(buf)); //缓冲区清零
        CString tmpstr(m_snd); //复制要发送的字符串
        int multibytelen=WideCharToMultiByte( //计算从Unicode转换到Ansi后需要的字节数
        CP_ACP, //根据ANSI code page转换
        WC_COMPOSITECHECK | WC_DEFAULTCHAR, //转换出错用缺省字符代替
        tmpstr.GetBuffer(m_snd.GetLength()), //要转换的字符串地址
                m_snd.GetLength(), //要转换的个数
                0, //转换后字符串放置的地址
                0, //最多转换字符的个数,为0表示返回转换Unicode后需要多少个字节
                0, //缺省的字符:"/0"
                0 //缺省的设置
         );
        WideCharToMultiByte( //转换Unicode到Ansi
                CP_ACP,
                WC_COMPOSITECHECK | WC_DEFAULTCHAR,
                tmpstr.GetBuffer(m_snd.GetLength()),
                m_snd.GetLength(),
                (char *)buf, //转换到缓冲区中
                128, //最多128个字节
                0,
                0
          );
        int sendcount=m_psocket->Send(buf,multibytelen+1); //发送转换后的缓冲区
        CString statusstr;
        statusstr.Format(TEXT("共发送字节数:%d"),sendcount);
        m_status.SetWindowText(statusstr); //更新显示栏
  }
程序接收到的字符串最后保存到CString tmpstr中.
  //接收函数片断
  void MyCeSocket::OnReceive(int nErrorCode)
  {
        // TODO: Add your specialized code here and/or call the base class
        unsigned char p[129]; //接受缓冲区
        ZeroMemory(p,sizeof(p)); //接收缓冲区清零
        this->Receive(p,128); //接收128个字节
        int widecharlen=MultiByteToWideChar( //计算从Ansi转换到Unicode后需要的字节数
                CP_ACP,
                MB_COMPOSITE,
                (char*)p, //要转换的Ansi字符串
                -1, //自动计算长度
                0,
                0
        );
        CString tmpstr;
        tmpstr.GetBuffer(widecharlen); //为转换后保存Unicode字符串分配内存
        MultiByteToWideChar( //从Ansi转换到Unicode字符
                CP_ACP,
                MB_COMPOSITE,
                (char*)p,
                -1,
                tmpstr.GetBuffer(widecharlen), //转换到tmpstr
                widecharlen //最多转换widecharlen个Unicode字符
        );
        m_clientdlg->m_listbox.InsertString(0,tmpstr); //插入到listbox中显示
        CCeSocket::OnReceive(nErrorCode);
  }
注意:以上代码都是在WindowsCE样板机上运行,PC端发送和接收到的字符均为Ansi格式的.把以上代码稍微修改一下用到自己的产品中,就可以利用以前的协议无缝连接PDA和PC.
以上代码在MicroSoft Embed Visual C++ 3.0 + 联想天玑5100(WindowsCE3.0)
+ Eagle Tec 10M CF卡通过.

 

用eVC编制了一个ActiveX控件,提示需要registered to the desktop,
用vs提供的ActiveX control test container 进行注册,可怎么也注册不上
为什么?应该怎么注册呢?
可以用VC的ActiveX control test container 进行注册,只不过要进行稍微改动。
1.用VC产生一个与EVC相同名字的Active x工程,比如为pocket。
2.把VC工程中的dsp和dsw文件重命名,pocket-win32.dsw和pocket-win32.dsp拷到EVC工程的文件夹中。
3.修改pocket-win32.dsw文件,使他指向pocket-win32.dsp。
 Project: "Pocket"="./Pocket.dsp"
改为Project: "Pocket"="./Pocket_Win32.dsp"
4.修改output 文件的名称,使它指向evc工程的文件夹。
即可


我需要用一种特定的图案填充进度条的条的颜色,不知道能不能实现?
CProgressCtrl mCtrl;
在OnInitDialog()中:
   mCtrl.Create(WS_CHILD|WS_VISIBLE|PBS_SMOOTH, CRect(10,10,200,30),
         this, IDC_PROGRESS);
   mCtrl.SetRange(0,10);
   mCtrl.SetPos(0);
   mCtrl.SetStep(1);
在OnPaint()中:
{
 CPaintDC dc(this);
 CRect rect(10,10,200,30);
         CBitmap bmp;
 bmp.LoadBitmap(IDB_PROGRESS);
 CBrush brush(&bmp);
 dc.FillRect(rect,&brush);
}
在OnStep()中(按一下按钮进度条前进一步)
{
 mCtrl.StepIt();
}


(EVC3)启动PPC2002模拟器,在EVC的TOOLS菜单下选择“Remote File Viewer”,启动Windows CE Remote File Viewer。
使Remote File Viewer与PPC2002模拟器连接,选择工具栏上第一个按钮。弹出Select Windows CE Device对话框,选择对应的模拟器或硬件设备---PPC2002后确定。在Remote File Viewer中就可以看到PPC2002中的文件。
在Remote File Viewer中选择菜单FILE下的“Export File”,将想要的文件传输到模拟器的相应的目录中。

“添加/删除硬件向导”----------“添加/排除设备故障”----------“选择一个硬件设备”中选择“Microsoft Loopback Adapter”.


隐藏“开始”栏
HWND lpClassName;
lpClassName = ::FindWindow(TEXT("HHTaskBar"), NULL);
::ShowWindow(lpClassName, SW_HIDE);

只隐藏Taskbar还不行,你得把work area 设为整个屏幕:
int screenx=GetSystemMetrics(SM_CXSCREEN);
int screeny=GetSystemMetrics(SM_CYSCREEN);
CRect rcWorkArea;
rcWorkArea.left = 0;
rcWorkArea.right = screenx;
rcWorkArea.top = 0;
rcWorkArea.bottom = screeny;
::SystemParametersInfo( SPI_SETWORKAREA, 0, &rcWorkArea, SPIF_SENDCHANGE );


 

如何获取 Pocket PC 2002 装置的序列号(以下例程获取的装置的序列号通常是Flash ROM的ID号.)?
--------------------------------------------------------------------------------
   从 Pocket PC 2000 开始, 微软就建议OEM厂商提供一个叫 KernelIoControl 的函数, 以便用户能访问Pocket PC 2002装置内建的序列号; 遗憾的是, 几乎没有厂商提供这个支持.
从 Pocket PC 2002 开始, 微软开始强制OEM厂商提供此函数. 目前市面上所有经过biplip测试的Pocket PC 2002装置都支持这个函数调用.
以下是个调用例子:

#include
extern "C" __declspec(dllimport)
BOOL KernelIoControl(
  DWORD dwIoControlCode, LPVOID lpInBuf, DWORD nInBufSize,
  LPVOID lpOutBuf, DWORD nOutBufSize, LPDWORD lpBytesReturned
);

#define IOCTL_HAL_GET_DEVICEID CTL_CODE(FILE_DEVICE_HAL, 21, METHOD_BUFFERED, FILE_ANY_ACCESS)

CString GetSerialNumberFromKernelIoControl()
{
 DWORD dwOutBytes;
 const int nBuffSize = 256;
 byte arrOutBuff[nBuffSize];

 BOOL bRes = ::KernelIoControl(IOCTL_HAL_GET_DEVICEID,
                                     0, 0, arrOutBuff, nBuffSize, &dwOutBytes);

 if (bRes) {
  CString strDeviceInfo;
  for (unsigned int i = 0; i   CString strNextChar;
   strNextChar.Format(TEXT("%02X"), arrOutBuff[i]);
   strDeviceInfo += strNextChar;
  }
  CString strDeviceId =
   strDeviceInfo.Mid(40,2) +
   strDeviceInfo.Mid(45,9) +
   strDeviceInfo.Mid(70,6);

  return strDeviceId;
 } else {
  return _T("");
 }
}
=====================================================================================

我用以下代码成功禁止任务栏被点击,但不知怎样才能解除,特此请教,谢谢。
LONG lOldWindowStyle;
RECT rectOldTaskBarRect;

HWND hOldhTaskBar = ::FindWindow(_T("HHTaskBar"),NULL);
 
while( hOldhTaskBar == NULL )
{
 hOldhTaskBar = ::FindWindow(_T("HHTaskBar"),NULL);
 Sleep( 1000 );
}

::GetWindowRect( hOldhTaskBar, &rectOldTaskBarRect );
::SetWindowPos( hOldhTaskBar, HWND_BOTTOM, 0, 0, 0, 0, SWP_HIDEWINDOW|SWP_NOACTIVATE|SWP_NOMOVE|SWP_NOSIZE);
lOldWindowStyle = GetWindowLong(hOldhTaskBar, GWL_STYLE);
::SetWindowLong( hOldhTaskBar, GWL_STYLE, lOldWindowStyle|WS_DISABLED );


比如控制打开一个jpg文件。
我用的是ShellExecute,好像有点问题:
ExecuteFile(LPCTSTR filename)
{
 SHELLEXECUTEINFO info; 
 info.cbSize=sizeof(SHELLEXECUTEINFO);
 info.fMask=SEE_MASK_NOCLOSEPROCESS;
 info.hwnd=this->GetSafeHwnd();
 info.lpVerb=L"open";
 info.lpFile=filename;
 info.lpParameters=NULL;
 info.lpDirectory=NULL;
 info.nShow=SW_SHOW;
 return ShellExecuteEx(&info);
}
这会用IE来打开jpg
每次总是第一次的时候对,以后调用的时候总是自动调原来的东西,没有更新。还有其他更好用的api吗?

Microsoft® eMbedded Visual C++ 4.0
http://download.microsoft.com/download/WindowsCENETPlatformBuilder/Install/4.0/NT5XP/EN-US/eVC4.exe

eMbedded Visual C++ 4.0 SP1 ENU
http://download.microsoft.com/download/WinCENET41PlatBuilder/SP/4.0/NT5XP/EN-US/eVC4SP1.exe

eMbedded Visual Tools 3.0
http://download.microsoft.com/download/9/d/2/9d2f6ee8-4c75-4749-86df-2dd5189e6081/evt2002web_min.exe

OK" 按钮隐掉
SHDoneButton(AfxGetMainWnd()->m_hWnd,SHDB_HIDE);
"X" 按钮隐掉
ModifyStyle(AfxGetMainWnd()->m_hWnd,WS_CAPTION,WS_MINIMIZEBOX,SWP_NOSIZE);


ftp://ftp.wy.hziee.edu.cn/winsoft

单步调试是完全可以的。
首先安装微软的同步软件在PC机上;其次在PC机上运行该同步软件的同时,在小机上运行/Windows/repllog.exe文件;如果同步成功,在PC机上会出现一个盘符(Mobile device)。在其中可以看到小机的文件。这样同步即完成。
在选择了该目标机后,在开始调试前会出现同步提示框。同步成功后即可单步调试;我是通过这样的方法来调试CE系统的,单步不成问题!

如果您是在硬件上运行您的程序,除了SDK外还需要装同步软件,一般是Microsoft ActiveSync。可以在微软的网站上下载到。

全球第一款中文Windows手机,dopod具有强大的功能:配备Intel SA-1110 CPU,主频为206MHz,运算能力相当于PII。内存采用32兆/64兆SDRAM,32兆/64兆闪存。配备SD卡接口,可以用SD卡实现存储扩容。显示屏规格为3.5" 240x320 pixels, 4096彩色反射式TFT。内置GSM/GPRS模块,分别支持900/1800 MHz的GSM和GPRS无线通信功能。在基本应用程序方面,dopod686类似其他采用Pocket PC操作系统的高端掌上电脑,具有Pocket Word、Pocket Excel、Pocket TV以及Windows Media Player等功能。支持中文连笔手写识别,并可以做到中英文混合识别。通过Microsoft ActiveSync可以与PC同步进行数据传输。也可以通过红外接口与笔记本、其他掌上设备以及手机进行数据交换。通过类似Outlook式的联系人功能管理移动电话、电子邮件、短信等通信功能,可以方便地进行短信群发等操作。传统PDA的各种功能在dopod中仅仅能算是最为基本的功能,其最大亮点在于其强大的多媒体功能,可以非常流畅地播放音频和视频文件。

1.好像没有其它方法,为什么不用__FILE__ 中取?
2.fopen,您可以加上全路径。
3.wince2.11没有用过,但我想是支持的。在CE帮助中,一般均说明此函数从那个版本开始支持,但fopen中却没有。
4.下面是CE帮助中的一段:
    CWinApp::WriteProfileString
This method writes the specified string into the specified section of the .ini file in the application.

BOOL WriteProfileString(
LPCTSTR lpszSection,
LPCTSTR lpszEntry,
LPCTSTR lpszValue );
5.不知您所用的CE版本为多少。CE3.0不支持中文,如果您所用的是3.0,那一定是OEM商汉化了CE。可能只支持一种字体;最新版.Net支持中文,有多种字体供选择。

PC与掌上电脑的串口是不是一样,这很难说。因为嵌入式开发是针对不同硬件平台进行的!
有的掌上电脑用的是标准的RS232,有的不是。
您用EVT(EVC和EVB)写的串口操作程序,可以下载到开发板上进行测试。当然开发板上需有串口硬件。

你可能感兴趣的:(关于嵌入开发(WinCE)的一些经验)