嵌入开发(WinCE)的一些经验[摘录]

-> 移动设备开发 专栏收录该内容
1 篇文章 0 订阅

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)写的串口操作程序,可以下载到开发板上进行测试。当然开发板上需有串口硬件。

 

 

Palm OS ROM
http://www.echoice.com.cn/download/download.asp?softwareID=132

Release configurations use the following macros:
RETAILMSG(cond, printf_exp). Conditionally displays the print message.
RETAILLED(cond, parms). Conditionally outputs WORD values to the LED.
ERRORMSG(cond, printf_exp). Prints "Error: File Line" before the print message.
 
To enable the debug macros, you must build a debug configuration. Debug configurations use the three retail macros listed above, as well as the following debug macros:
DEBUGMSG(cond, printf_exp). Conditionally displays the print message.
DEBUGLED(cond, parms). Conditionally outputs WORD values to the LED.
DEBUGCHK(expr). Asserts the expression. If expr is FALSE, the macro calls DEBUGBREAK.
DEBUGZONE(zone_id). Tests the mask bit in the current debug zone settings. You can use DEBUGZONE to turn debug zones on or off.

Declare Function TranslateMessage Lib "coredll.dll" (ByVal MSG As String) As Boolean
网上down到的,有关unicode的函数集:

Attribute VB_Name = "modUniCode"
Option Explicit
Public Function MemStringToLong(StringIn As String) As Long
       On Error Resume Next
       Dim hWorkVal As String
       ' Convert the String back to Long Integer.
       ' Converting back to Big Endian format.
      Dim i As Long
      For i = 4 To 1 Step -1
       hWorkVal = hWorkVal & Hex(AscB(MidB(StringIn, i, 1)))
      Next i
       ' Return Long Integer value.
       MemStringToLong = CLng("&H" & hWorkVal)
   End Function
Public Function LongToMemoryString(ByVal lInputValue As Long) As String
    Dim hWorkVal As String
    Dim n As Long
    Dim i  As Long
    ' Convert to HEX value.
    hWorkVal = Hex(lInputValue)
    ' Check to see if it is not zero.
    If hWorkVal <> "0" Then
        ' Convert to memory storage format (Little Endian).
        ' For example, 0000A411 would convert to 11A40000.
        '
        ' Place leading zeros in 8 character sequence to
        ' maintain consistent character count
        n = Len(hWorkVal)
        If n < 8 Then
            hWorkVal = String(8 - n, "0") & hWorkVal
        End If
        '
        ' Use ChrB to rebuild Bytes.
        For i = 7 To 1 Step -2
            LongToMemoryString = LongToMemoryString & _
                                 ChrB(CInt("&H" & Mid(hWorkVal, i, 2)))
        Next i
          
    Else
        ' Just return zeros.
        ' Use ChrB to build Bytes.
        LongToMemoryString = ChrB(CInt("&H00"))
        LongToMemoryString = LongToMemoryString & ChrB(CInt("&H00"))
        LongToMemoryString = LongToMemoryString & ChrB(CInt("&H00"))
        LongToMemoryString = LongToMemoryString & ChrB(CInt("&H00"))
    End If
End Function


在EVC3.0下怎样使编出来的窗口最大化(占满所有屏幕),并能够将开始菜单条挡住?
BOOL SHFullScreen(
 HWND  hwndRequester,
 DWORD  dwState);
注意包含Aygshell.h
用shfullscreen产生全屏窗口,用showwindow隐藏任务条,用movewindow设置窗口大小为全屏。
代码如下:
#define MENU_HEIGHT 26
      RECT rc;
      //get window size
      GetWindowRect(hWnd, &rc);
      SHFullScreen(hWnd, SHFS_HIDETASKBAR | SHFS_HIDESIPBUTTON);
      ShowWindow(hwndCB, SW_HIDE);
      MoveWindow(hWnd,
    rc.left,
    rc.top-MENU_HEIGHT,
    rc.right,
    rc.bottom+MENU_HEIGHT,
    TRUE);


Windows CE 3.0 supports the standard Winsock 1.1 functions.except the asychronous functions.

eVC4:
http://msdn.microsoft.com/library/default.asp?url=/nhp/Default.asp?contentid=28000437
Tools(For PPC2002):
http://www.microsoft.com/mobile/developer/downloads/default.asp
OR: http://www.microsoft.com/mobile/developer/default.asp
CEF:
http://msdn.microsoft.com/downloads/default.asp?url=/downloads/sample.asp?url=/msdn-files/027/001/926/msdncompositedoc.xml

目前大的GIS厂商,如MapInfo和ArcInfo对Paml支持太弱了,我咨询了这两家公司,都说还没有这方面的产品,WinCE下的产品倒是到了应用层次。
国外不少公司有开发出来的产品,比如www.GeoDiscovery.com,但是不提供二次开发接口。不知道大虾们是如何选择这方面的产品的。
电子地图:ArcInfo和MapInfo有全系列的开发包。绝对支持VS。
你打电话向ArcInfo中国代理,好像是富融科技,要一个开发包,当然是试用性质的。或者向MapInfo公司中国代理,是方正,咨询一下开发事宜。
我没有做过WinCE上的GPS和GIS开发。我做过PalmOS下的一些实验。GPS部分是通过串口和Palm连接,并且提供相应的协议,用来解释GPS信息和操纵GPS设备。这个没有什么复杂的。但是地图表现部分却苦于没有合适的地图产品。关于GPS的例子,我是从Palm应用程序的开发工具CodeWarrior的帮助文档中获得的,也就是简单的串口/端口操作,简单的监听->读->分析->表现->控制命令->写.和DOS下串口通信或者控制打印机之类的事情,没有两样。你所需要的,是你所选用的GPS设备的接口标准、开发文档。
你看看www.supermap.com.cn的eSuperMap,能提供二次开发,具体没谈过,有什么消息也告诉我一声,我也想用他们的搞二次开发。
不过eSuperMap同时支持WinCE和Windows 98等。
帮你找到了一个地图,你可以到www.lingtu.com.cn看看,它也支持二次开发。

这样说吧:在EVC编译程序时,有一个重要的选项,在工具栏中的WCE Configuration中。您用EVC自带的模拟器编译时,选择的是Win32 [WCE x86em] Debug/Release。若选择其它,编译时丢出错。
X86em,说明程序运行时的Micro CPU平台。正如UP所说!如果您所有的PDA不在EVC支持的范围之内,则您需要CEPB来生成支持它的SDK。安装后EVC才可以用来开发针对您所用的PDA的应用。
你把EVC的Target类型设为MIPS,然后直接debug,EVC会把XXXd.dll下载到PDA上,这样你就可以在PDA上debug了。不过这些dll挺大的,有好几M,在PDA上debug速度也很慢

http://www.eg3.com/
http://www.c51bbs.com/
www.pday.com.cn
www.move.com.cn
www.pdazone.com.cn
www.palmheart.com.cn
http://www.embed.com.cn/
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnce30/html/realtimecapabilities.asp
http://msdn.microsoft.com/downloads/default.asp?url=/downloads/topic.asp?url=/msdn-files/028/000/219/topic.xml
http://www.palm.com

<<Programming Microsoft Windows CE程序设计>>,北京大学出版社出版
<<Windows CE高级开发指南>>,电子工业出版社出版。可做为手册用!
<<Building Powerful Plarforms with Windows CE>>。最经典的。但国内可能买不到

2002-4-21(在嵌入式和Visual C++中提出下面的问题)
我做了一个应用,读出系统时间显示在6个Edit控件中;同时设置两个按键用于在得到系统时间和设置系统时间之间切换,得到系统时间时不能修改Edit中的内容。
读系统时间由一个线程来实现。

在设置系统时间时,想使用tab键在各个控件之间移动。但我为每个控件都设置了WS_TABSTOP属性后,仍然不能达到使用tab键控制焦点位置的目的!!!
请问:各个高手这是为何?

下一个:::PostMessage(hWnd, WM_NEXTDLGCTL, 0, 0);
前一个:::PostMessage(hWnd, WM_NEXTDLGCTL, 1, 0);
任意control hCtrl:::PostMessage(hWnd, WM_NEXTDLGCTL, (WPARAM)hCtrl, 1L);

 

 

模拟器中是否能使程序自起动?希望高手支招!!!
我认为不能。
在硬件平台上,可修改注册表。
例如:
[HKEY_LOCAL_MACHNE/Init]
"Launch40"="App.exe"
"Depend40"=hex:14,00

我们也用过汉王,是需要自己修改较多的东东才能过到满意的效果。
以下四点是我们修改Hwr.c的注释,我只能提供您这些!!!
1.汉王对笔迹数据的要求是在0xff以内,但触摸屏的尺寸(480X320)超过了此范围,所以要对数据进行调整,以满足任何尺寸的要求。
2.防跨屏操作
3.全屏操作
4.触屏四线不接任何电容

EVC下如何具体编程开机启动?
>>模拟器中是否能使程序自起动?希望高手支招!!!
我认为不能。
在硬件平台上,可修改注册表。
例如:
[HKEY_LOCAL_MACHNE/Init]
"Launch40"="App.exe"
"Depend40"=hex:14,00
>>应该是用api:
BOOL CeRunAppAtEvent(
TCHAR *pwszAppName,
LONG lWhichEvent );
其中lWhichEvent有个值为:
NOTIFICATION_EVENT_WAKEUP
>>>>>>>>>>NOTIFICATION_EVENT_WAKEUP:When the device wakes up.
我认为对开机启动:不能算错误,但也不能说正确。
此处device所指为何?不清楚!
当系统起动时,device被Initialize或wake up,而不只是wake up。
还有,当存在即插即用device 时,插上device ,可能也会引起NOTIFICATION_EVENT_WAKEUP事件。

 有关中文编码问题
请问在winCE操作系统中,用emVC来开发,用linux来做服务器,
请问这两者间通信的中文问题如何解决?非常感谢。
可以写一个Unicode和GB的转换函数,不太难的,只是点阵的计算方式不同,unicode是竖着计算而GB是横着计算,仅此而已!

I use the RegisterDevice API to load the driver and I have no problem doing that on the "old" Pocket PC but on the Pocket PC 2002 the driver fails to load.
I have tested the driver using LoadLibrary and GetProcAddress and calling all functions just to see if there was something wrong with the exported interface from the DLL but I didn't have any problem.

I know that mapping from physical to virtuall addressing is done bye OEMAddressTable in ARM
Virtual to physical mapping is done by the CPU Memory Management Unit (MMU)not the address table. The SHx and MIPS processors have some pre-fixed mappings defined in the CPU architecture. The other CPUs do not and therefore use the OEMAddressTable to specify where in Virtual memory certain on-chip resources are to be mapped so the OAL and interrupt handlers can access them.

我们都知道windows操作系统有支持ANSI和支持Unicode的版本,也有都支持的.其中,windows98只能支持ANSI系统环境.windows2000可以支持Unicode和NSI.windowsCE只支持Unicode.WindowsXP好象也是两个都支持.所以我们在开发多国语言的时候一般都选用windows2000.因为我们可以构件Unicode工程来支持多国语言的显示.(如果你不理解什么是Unicode可以参看<<Windows核心编程>>的第二章.(在ttp://www.china-pub.com/computers/common/info.asp?id=131提供第二章的免费下载).|完整的下载,我都忘记了|.
    为了在控件中显示别国语言(如日文,阿拉伯文等)而不至于显示成????,或者说文字可以显示在控件上,但是你无法获取他们并将他们保存到我们常用的CString中,这就需要你创建Unicode工程,这样才能支持.如果你一定要在Ansi系统(win98),开发这样的东西.我暂时还没有搞出来。.呵呵,在<<windows核心编程>>里面说得很清楚,如果你要把这个东西加到里面,即便成功也会造成无法想象的不稳定.关于这点显示的问题,我在下面还有一些支持在98下显示的问题说明,介绍的是用DHTML控件的.下面我先说建立Unicode工程和用Rich Edit 控件(用CRichEditCtrl类支持)显示多语言的问题.
    创建Unicode工程只要按照下面步骤进行就可以了.(/***/注释段为摘抄)
/******************* //构件Unicode Debug
1.前提条件:
   运行VC++的安装程序,选中MFC的UNICODE支持。
2。VC++Build->configurations...->Add->Configuration->"Unicode Debug"->OK
3.Project->Setting->C++->Preprosesser Definitions->加入UNICODE,_UNICODE, 去掉MBCS即可
4。Project->Setting->lINK->Category->)Outputw->加入wWinMainCRTStartup。
5选择"Win32 Unicode debug"编译方式,代码按照Unicode encoding!
6. Hope it has some help to you.
********************/
    实际上只要下面两步骤:
1.project下面选setting,然后选C/C++,在preprocessor definitions中加入
_UNICODE.(不需要去掉_MBCS)
2.就是上面的4.
   有了上面步骤,就说明你的工程已经是Unicode工程了.如果你是想把原来的程序改造成Unicode.编译后可能会发生错误,这就要求你改正成Unicode的正确形式..一般情况下对,字符串常量..你只要在前面加上_T("字符串常量"),就可以了.剩下的多为函数调用和字符转换的问题如strcpy->lstrcpy和CString<->Char *之类的(可以看核心编程)..关于这个转换问题,我这里有一个出自CSDN精华区的网页(别人的总结),不知道现在里面有没有了?如果没有你想要,可以和我联系告知.我将尽力帮助.这里对_T宏说明一点,其实它在ANSI环境下也是通过的.而且就读成相应的环境形式.所以一般情况下,我觉得编程,应该都加上这个宏.免得将来麻烦:).还有一个要考虑的,Unicode因为都是双字节的,所以读取的时候要注意,特别是在写文件的时候.首先,如果你要让你的文件成为Unicode文件,一定要在文件头加上0xFFFE.还有假如你用的是CFile 读写文件也要注意.如果你创建的是以非文本读写的..你应该考虑下面的问题:
    CFile file;
    CString htm;
    if(!file.Open(filename,CFile::modeCreate|CFile::modeWrite))
         //Open fail;
    WORD wFlag=0xFEFF;
    file.Write(&wFlag,2);  //这是写Unicode文件标志头.
    htm=_T("alkdsj flajdflajdlsfj")
    file.Write(htm,htm.GetLength()+1);//这是错误的.应该把后面的长度这样才能把htm内容完整的写到文件里面.
                                      //你可以自己考虑具体问题出现在哪.:).
    接着,我再说一下关于Rich Edit控件的问题.因为是昨天刚遇到,所以今天就抽空帮别人解决了.他的问题是这样,在2000下,Unicode工程,RichEdit控件中输入小语种(日文,阿拉伯),无法用GetWindowText等函数获取.(获取的都是????).问题原因主要是因为:
(1).Rich Edit控件的版本太低,如RichEdit1.0(riched32.dll)就是不支持Unicode的.所以必须换成RichEdit2.0或者3.0(riched20.dll)的.所以在你的程序InitInstance()里面应该有下面代码:
 HINSTANCE richEdit=::LoadLibrary(_T("riched20.dll"));
 if(!richEdit)
  AfxMessageBox(_T("Unable to load RichEdit2.0"));
 AfxInitRichEdit();
(2).修改你的资源*.rc.打开rc文件.(Open->*.rc|Text方式|)..把原来的"RICHEDIT"改成"RICHEDIT20W"就可以了.如下:
    CONTROL         "",IDC_RICHEDIT1,"RICHEDIT20W",WS_BORDER |
    这样,你利用GetWindowText,就可以得到你要的东西.也就是解决上面的问题。
    这儿,我提供方法给那些没有用过RichEdit的人去构造这个控件.
A.当你在对话框中有了Rich Edit后..你编译时发现不能弹出对话框了.请在你的InitInstance()开头加上.AfxInitRichEdit();
B.如果你初始化的话..用下面方式(在OnInitDialog里面加)
 SetIcon(m_hIcon, TRUE);   // Set big icon
 SetIcon(m_hIcon, FALSE);  // Set small icon
 CHARFORMAT cfDefault;
 memset(&cfDefault,0,sizeof(cfDefault));
 cfDefault.cbSize=sizeof(cfDefault);
 cfDefault.dwMask =  CFM_FACE | CFM_SIZE |CFM_CHARSET | CFM_SPACING;
 cfDefault.yHeight = 200;
 cfDefault.bCharSet =ARABIC_CHARSET; //这是阿拉伯文的.这个好象不会影响控件.|我没研究清楚.不过是不可以用来让我们在非Unicode中获取文字的(或者没有上面解决方式).
 strcpy(cfDefault.szFaceName,"Arial");
 m_RichEdit1.SetDefaultCharFormat(cfDefault);//设置模式
c.如果要设置你的RichEdit响应事件消息(Envent)用:
        CWnd* pWnd=GetDlgItem(IDC_RICHEDIT1);
 CRichEditCtrl* pRich=(CRichEditCtrl*)(pWnd);
 long nEvn=pRich->GetEventMask();
 nEvn |=ENM_CHANGE;       //响应OnChangeEdit函数.
 pRich->SetEventMask(nEvn);
    上面这些就是RichEdit入门.呵呵..

 

 

 我这里有一个我测试时写的一个源程序.(很简单).可以用来输入多国语言(用的是RichEdit),并且获取显示.还有就是把他的Unicode代码显示出来.如果你要..请和我联系.我给你们发过去.(尽力而为).

    这里我还要提出一些关于显示多国语言里面我曾经思考的问题..作为参考留给大家..至于实现,我这个低级选手暂时只能望尘莫及了.
(1):我当时曾考虑过如何在98下显示并获取的问题,当中用到了vb上面的一个RichText控件.那时侯发现,其实里面的文本可以用RTF格式取出来.但是RTF格式及其让人讨厌..所以当时是在没有办法的情况下(转悠了15天,急了),才考虑到准备把里面的内码值抠出来..呵呵.
(2):仔细分析情况,(我个人认为)为什么会得到???,是因为内码对应不正确的问题..或者字符集不正确.例如:我们现在的操作环境对应的是GB2312码(里面有中文繁体字,以及中文日文字,我们虽然可以输入,但却被认成了中文的相应字符).当你把控制面版里区域选项下面的预设默认值设为中文简体时,它将被选入系统.以至于影响到你的vc程序.导致了无法获取的问题.关于这内码还要提一点..如果你是用繁体的,由于他没有简体和日文字体,所以无法正确显示.这里要说明一下..设置这个预设默认值,是为了构造环境,如果你预设是日文,然后你的程序连接也用的是日文资源dll.那么你的程序即便是在中文Win平台下,用vc,在这时候也可以获得对日文的支持显示和处理功能.(其实就是相单于构造了日文操作平台).
(3):这个和支持多国语资源没有关系..如果你想在你资源里面多加日文资源,那只能保证你可以用 日文windows显示那些文字.但却不能共同显示中文,日文.我看到了<<用VC5_0实现软件中的多种语言支持>>文章..完全和这个是不一样的事情.而且它和我们常遇到的多国语言下载组件支持也没有任何关系.
(4):我的一个同事由于研究给软件安装输入法时,发现可以利用DHTML控件来支持呼叫和显示,无论是98还是2000.都可以,只不过里面内容都为网页,所以必须自己抠出来(我想不会很难).

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

单步调试是完全可以的。

首先安装微软的同步软件在PC机上;其次在PC机上运行该同步软件的同时,在小机上运行/Windows/repllog.exe文件;如果同步成功,在PC机上会出现一个盘符(Mobile device)。在其中可以看到小机的文件。这样同步即完成。

在选择了该目标机后,在开始调试前会出现同步提示框。同步成功后即可单步调试;我是通过这样的方法来调试CE系统的,单步不成问题!

没有做过这一部分东东,看了您的问题,但不太清楚您想如何做!

如果只是想做一个与backlight功能相同的软件,而不是集成在您所说的属性项,应该可以实现。可能对电源管理部分要有一定的了解!否则就难说了。
至于分析率的问题,要看您所用的东东是否够高级了。一般想改分辨率较困难!一是受硬件的限制;二是驱动的问题。


如果您是在硬件上运行您的程序,除了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上有的硬件不是模拟器可以使用的!!!

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

我现在正在做一个串口测试程序,对硬件部开发的串口驱动程序进行测试。功能已经实现,但还需一些易用性的完善。

Palm OS ROM
http://www.echoice.com.cn/download/download.asp?softwareID=132

Release configurations use the following macros:
RETAILMSG(cond, printf_exp). Conditionally displays the print message.
RETAILLED(cond, parms). Conditionally outputs WORD values to the LED.
ERRORMSG(cond, printf_exp). Prints "Error: File Line" before the print message.
 
To enable the debug macros, you must build a debug configuration. Debug configurations use the three retail macros listed above, as well as the following debug macros:
DEBUGMSG(cond, printf_exp). Conditionally displays the print message.
DEBUGLED(cond, parms). Conditionally outputs WORD values to the LED.
DEBUGCHK(expr). Asserts the expression. If expr is FALSE, the macro calls DEBUGBREAK.
DEBUGZONE(zone_id). Tests the mask bit in the current debug zone settings. You can use DEBUGZONE to turn debug zones on or off.

Declare Function TranslateMessage Lib "coredll.dll" (ByVal MSG As String) As Boolean
网上down到的,有关unicode的函数集:

Attribute VB_Name = "modUniCode"
Option Explicit
Public Function MemStringToLong(StringIn As String) As Long
       On Error Resume Next
       Dim hWorkVal As String
       ' Convert the String back to Long Integer.
       ' Converting back to Big Endian format.
      Dim i As Long
      For i = 4 To 1 Step -1
       hWorkVal = hWorkVal & Hex(AscB(MidB(StringIn, i, 1)))
      Next i
       ' Return Long Integer value.
       MemStringToLong = CLng("&H" & hWorkVal)
   End Function
Public Function LongToMemoryString(ByVal lInputValue As Long) As String
    Dim hWorkVal As String
    Dim n As Long
    Dim i  As Long
    ' Convert to HEX value.
    hWorkVal = Hex(lInputValue)
    ' Check to see if it is not zero.
    If hWorkVal <> "0" Then
        ' Convert to memory storage format (Little Endian).
        ' For example, 0000A411 would convert to 11A40000.
        '
        ' Place leading zeros in 8 character sequence to
        ' maintain consistent character count
        n = Len(hWorkVal)
        If n < 8 Then
            hWorkVal = String(8 - n, "0") & hWorkVal
        End If
        '
        ' Use ChrB to rebuild Bytes.
        For i = 7 To 1 Step -2
            LongToMemoryString = LongToMemoryString & _
                                 ChrB(CInt("&H" & Mid(hWorkVal, i, 2)))
        Next i
          
    Else
        ' Just return zeros.
        ' Use ChrB to build Bytes.
        LongToMemoryString = ChrB(CInt("&H00"))
        LongToMemoryString = LongToMemoryString & ChrB(CInt("&H00"))
        LongToMemoryString = LongToMemoryString & ChrB(CInt("&H00"))
        LongToMemoryString = LongToMemoryString & ChrB(CInt("&H00"))
    End If
End Function

 

 

在EVC3.0下怎样使编出来的窗口最大化(占满所有屏幕),并能够将开始菜单条挡住?
BOOL SHFullScreen(
 HWND  hwndRequester,
 DWORD  dwState);
注意包含Aygshell.h
用shfullscreen产生全屏窗口,用showwindow隐藏任务条,用movewindow设置窗口大小为全屏。
代码如下:
#define MENU_HEIGHT 26
      RECT rc;
      //get window size
      GetWindowRect(hWnd, &rc);
      SHFullScreen(hWnd, SHFS_HIDETASKBAR | SHFS_HIDESIPBUTTON);
      ShowWindow(hwndCB, SW_HIDE);
      MoveWindow(hWnd,
    rc.left,
    rc.top-MENU_HEIGHT,
    rc.right,
    rc.bottom+MENU_HEIGHT,
    TRUE);


Windows CE 3.0 supports the standard Winsock 1.1 functions.except the asychronous functions.

这个问题较难回答!但如果您熟悉微软的东东,特别是Visual C++,学嵌入式应用编程用EVC,即嵌入式VC可能上手快一些。
否则,还是考虑其它的吧。因为微软的东东不便宜啊!这个领域的D版没有PC这么多,还是较难找的。

这几个文件最好不要冲突!国为它们被集成同一文件中。
它们唯一的区别是其作用范围不同。例如在Common下的文件对您所编译的每一个平台(如CEPC、SH等)都起作用;Hardware Spec...,这个我也不清楚;Project Spec...是只对这个工程起作用。它们的效果是一样的。
但我认为应在Hardware Spec...中修改!
方法:用您新的驱动程序代替原来的驱动程序,再重新编译。

eVC4:
http://msdn.microsoft.com/library/default.asp?url=/nhp/Default.asp?contentid=28000437
Tools(For PPC2002):
http://www.microsoft.com/mobile/developer/downloads/default.asp
OR: http://www.microsoft.com/mobile/developer/default.asp
CEF:
http://msdn.microsoft.com/downloads/default.asp?url=/downloads/sample.asp?url=/msdn-files/027/001/926/msdncompositedoc.xml

目前大的GIS厂商,如MapInfo和ArcInfo对Paml支持太弱了,我咨询了这两家公司,都说还没有这方面的产品,WinCE下的产品倒是到了应用层次。
国外不少公司有开发出来的产品,比如www.GeoDiscovery.com,但是不提供二次开发接口。不知道大虾们是如何选择这方面的产品的。
电子地图:ArcInfo和MapInfo有全系列的开发包。绝对支持VS。
你打电话向ArcInfo中国代理,好像是富融科技,要一个开发包,当然是试用性质的。或者向MapInfo公司中国代理,是方正,咨询一下开发事宜。
我没有做过WinCE上的GPS和GIS开发。我做过PalmOS下的一些实验。GPS部分是通过串口和Palm连接,并且提供相应的协议,用来解释GPS信息和操纵GPS设备。这个没有什么复杂的。但是地图表现部分却苦于没有合适的地图产品。关于GPS的例子,我是从Palm应用程序的开发工具CodeWarrior的帮助文档中获得的,也就是简单的串口/端口操作,简单的监听->读->分析->表现->控制命令->写.和DOS下串口通信或者控制打印机之类的事情,没有两样。你所需要的,是你所选用的GPS设备的接口标准、开发文档。
你看看www.supermap.com.cn的eSuperMap,能提供二次开发,具体没谈过,有什么消息也告诉我一声,我也想用他们的搞二次开发。
不过eSuperMap同时支持WinCE和Windows 98等。
帮你找到了一个地图,你可以到www.lingtu.com.cn看看,它也支持二次开发。

当然可以。
抱谦!笔误......
这样说吧:在EVC编译程序时,有一个重要的选项,在工具栏中的WCE Configuration中。您用EVC自带的模拟器编译时,选择的是Win32 [WCE x86em] Debug/Release。若选择其它,编译时丢出错。
X86em,说明程序运行时的Micro CPU平台。正如UP所说!如果您所有的PDA不在EVC支持的范围之内,则您需要CEPB来生成支持它的SDK。安装后EVC才可以用来开发针对您所用的PDA的应用。
你把EVC的Target类型设为MIPS,然后直接debug,EVC会把XXXd.dll下载到PDA上,这样你就可以在PDA上debug了。不过这些dll挺大的,有好几M,在PDA上debug速度也很慢

http://www.eg3.com/
http://www.c51bbs.com/
www.pday.com.cn
www.move.com.cn
www.pdazone.com.cn
www.palmheart.com.cn
http://www.embed.com.cn/
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnce30/html/realtimecapabilities.asp
http://msdn.microsoft.com/downloads/default.asp?url=/downloads/topic.asp?url=/msdn-files/028/000/219/topic.xml
http://www.palm.com

<<Programming Microsoft Windows CE程序设计>>,北京大学出版社出版
<<Windows CE高级开发指南>>,电子工业出版社出版。可做为手册用!
<<Building Powerful Plarforms with Windows CE>>。最经典的。但国内可能买不到

 

2002-4-21(在嵌入式和Visual C++中提出下面的问题)
我做了一个应用,读出系统时间显示在6个Edit控件中;同时设置两个按键用于在得到系统时间和设置系统时间之间切换,得到系统时间时不能修改Edit中的内容。
读系统时间由一个线程来实现。

在设置系统时间时,想使用tab键在各个控件之间移动。但我为每个控件都设置了WS_TABSTOP属性后,仍然不能达到使用tab键控制焦点位置的目的!!!

请问:各个高手这是为何?

下一个:::PostMessage(hWnd, WM_NEXTDLGCTL, 0, 0);
前一个:::PostMessage(hWnd, WM_NEXTDLGCTL, 1, 0);
任意control hCtrl:::PostMessage(hWnd, WM_NEXTDLGCTL, (WPARAM)hCtrl, 1L);

在管理内(每页的最上面或最下面均有),点击进入。在想给分的人后输入所给的分数;输入您的密码,点击给分!哈哈......

模拟器中是否能使程序自起动?希望高手支招!!!
我认为不能。
在硬件平台上,可修改注册表。
例如:
[HKEY_LOCAL_MACHNE/Init]
"Launch40"="App.exe"
"Depend40"=hex:14,00

我们也用过汉王,是需要自己修改较多的东东才能过到满意的效果。
以下四点是我们修改Hwr.c的注释,我只能提供您这些!!!
1.汉王对笔迹数据的要求是在0xff以内,但触摸屏的尺寸(480X320)超过了此范围,所以要对数据进行调整,以满足任何尺寸的要求。
2.防跨屏操作
3.全屏操作
4.触屏四线不接任何电容

EVC下如何具体编程开机启动?
>>模拟器中是否能使程序自起动?希望高手支招!!!
我认为不能。
在硬件平台上,可修改注册表。
例如:
[HKEY_LOCAL_MACHNE/Init]
"Launch40"="App.exe"
"Depend40"=hex:14,00
>>应该是用api:
BOOL CeRunAppAtEvent(
TCHAR *pwszAppName,
LONG lWhichEvent );
其中lWhichEvent有个值为:
NOTIFICATION_EVENT_WAKEUP
>>>>>>>>>>NOTIFICATION_EVENT_WAKEUP:When the device wakes up.
我认为对开机启动:不能算错误,但也不能说正确。
此处device所指为何?不清楚!
当系统起动时,device被Initialize或wake up,而不只是wake up。
还有,当存在即插即用device 时,插上device ,可能也会引起NOTIFICATION_EVENT_WAKEUP事件。

 有关中文编码问题
请问在winCE操作系统中,用emVC来开发,用linux来做服务器,
请问这两者间通信的中文问题如何解决?非常感谢。
可以写一个Unicode和GB的转换函数,不太难的,只是点阵的计算方式不同,unicode是竖着计算而GB是横着计算,仅此而已!

I use the RegisterDevice API to load the driver and I have no problem doing that on the "old" Pocket PC but on the Pocket PC 2002 the driver fails to load.
I have tested the driver using LoadLibrary and GetProcAddress and calling all functions just to see if there was something wrong with the exported interface from the DLL but I didn't have any problem.

I know that mapping from physical to virtuall addressing is done bye OEMAddressTable in ARM
Virtual to physical mapping is done by the CPU Memory Management Unit (MMU)not the address table. The SHx and MIPS processors have some pre-fixed mappings defined in the CPU architecture. The other CPUs do not and therefore use the OEMAddressTable to specify where in Virtual memory certain on-chip resources are to be mapped so the OAL and interrupt handlers can access them.

 

我们都知道windows操作系统有支持ANSI和支持Unicode的版本,也有都支持的.其中,windows98只能支持ANSI系统环境.windows2000可以支持Unicode和NSI.windowsCE只支持Unicode.WindowsXP好象也是两个都支持.所以我们在开发多国语言的时候一般都选用windows2000.因为我们可以构件Unicode工程来支持多国语言的显示.(如果你不理解什么是Unicode可以参看<<Windows核心编程>>的第二章.(在ttp://www.china-pub.com/computers/common/info.asp?id=131提供第二章的免费下载).|完整的下载,我都忘记了|.
    为了在控件中显示别国语言(如日文,阿拉伯文等)而不至于显示成????,或者说文字可以显示在控件上,但是你无法获取他们并将他们保存到我们常用的CString中,这就需要你创建Unicode工程,这样才能支持.如果你一定要在Ansi系统(win98),开发这样的东西.我暂时还没有搞出来。.呵呵,在<<windows核心编程>>里面说得很清楚,如果你要把这个东西加到里面,即便成功也会造成无法想象的不稳定.关于这点显示的问题,我在下面还有一些支持在98下显示的问题说明,介绍的是用DHTML控件的.下面我先说建立Unicode工程和用Rich Edit 控件(用CRichEditCtrl类支持)显示多语言的问题.
    创建Unicode工程只要按照下面步骤进行就可以了.(/***/注释段为摘抄)
/******************* //构件Unicode Debug
1.前提条件:
   运行VC++的安装程序,选中MFC的UNICODE支持。
2。VC++Build->configurations...->Add->Configuration->"Unicode Debug"->OK
3.Project->Setting->C++->Preprosesser Definitions->加入UNICODE,_UNICODE, 去掉MBCS即可
4。Project->Setting->lINK->Category->)Outputw->加入wWinMainCRTStartup。
5选择"Win32 Unicode debug"编译方式,代码按照Unicode encoding!
6. Hope it has some help to you.
********************/
    实际上只要下面两步骤:
1.project下面选setting,然后选C/C++,在preprocessor definitions中加入
_UNICODE.(不需要去掉_MBCS)
2.就是上面的4.
   有了上面步骤,就说明你的工程已经是Unicode工程了.如果你是想把原来的程序改造成Unicode.编译后可能会发生错误,这就要求你改正成Unicode的正确形式..一般情况下对,字符串常量..你只要在前面加上_T("字符串常量"),就可以了.剩下的多为函数调用和字符转换的问题如strcpy->lstrcpy和CString<->Char *之类的(可以看核心编程)..关于这个转换问题,我这里有一个出自CSDN精华区的网页(别人的总结),不知道现在里面有没有了?如果没有你想要,可以和我联系告知.我将尽力帮助.这里对_T宏说明一点,其实它在ANSI环境下也是通过的.而且就读成相应的环境形式.所以一般情况下,我觉得编程,应该都加上这个宏.免得将来麻烦:).还有一个要考虑的,Unicode因为都是双字节的,所以读取的时候要注意,特别是在写文件的时候.首先,如果你要让你的文件成为Unicode文件,一定要在文件头加上0xFFFE.还有假如你用的是CFile 读写文件也要注意.如果你创建的是以非文本读写的..你应该考虑下面的问题:
    CFile file;
    CString htm;
    if(!file.Open(filename,CFile::modeCreate|CFile::modeWrite))
         //Open fail;
    WORD wFlag=0xFEFF;
    file.Write(&wFlag,2);  //这是写Unicode文件标志头.
    htm=_T("alkdsj flajdflajdlsfj")
    file.Write(htm,htm.GetLength()+1);//这是错误的.应该把后面的长度这样才能把htm内容完整的写到文件里面.
                                      //你可以自己考虑具体问题出现在哪.:).
    接着,我再说一下关于Rich Edit控件的问题.因为是昨天刚遇到,所以今天就抽空帮别人解决了.他的问题是这样,在2000下,Unicode工程,RichEdit控件中输入小语种(日文,阿拉伯),无法用GetWindowText等函数获取.(获取的都是????).问题原因主要是因为:
(1).Rich Edit控件的版本太低,如RichEdit1.0(riched32.dll)就是不支持Unicode的.所以必须换成RichEdit2.0或者3.0(riched20.dll)的.所以在你的程序InitInstance()里面应该有下面代码:
 HINSTANCE richEdit=::LoadLibrary(_T("riched20.dll"));
 if(!richEdit)
  AfxMessageBox(_T("Unable to load RichEdit2.0"));
 AfxInitRichEdit();
(2).修改你的资源*.rc.打开rc文件.(Open->*.rc|Text方式|)..把原来的"RICHEDIT"改成"RICHEDIT20W"就可以了.如下:
    CONTROL         "",IDC_RICHEDIT1,"RICHEDIT20W",WS_BORDER |
    这样,你利用GetWindowText,就可以得到你要的东西.也就是解决上面的问题。
    这儿,我提供方法给那些没有用过RichEdit的人去构造这个控件.
A.当你在对话框中有了Rich Edit后..你编译时发现不能弹出对话框了.请在你的InitInstance()开头加上.AfxInitRichEdit();
B.如果你初始化的话..用下面方式(在OnInitDialog里面加)
 SetIcon(m_hIcon, TRUE);   // Set big icon
 SetIcon(m_hIcon, FALSE);  // Set small icon
 CHARFORMAT cfDefault;
 memset(&cfDefault,0,sizeof(cfDefault));
 cfDefault.cbSize=sizeof(cfDefault);
 cfDefault.dwMask =  CFM_FACE | CFM_SIZE |CFM_CHARSET | CFM_SPACING;
 cfDefault.yHeight = 200;
 cfDefault.bCharSet =ARABIC_CHARSET; //这是阿拉伯文的.这个好象不会影响控件.|我没研究清楚.不过是不可以用来让我们在非Unicode中获取文字的(或者没有上面解决方式).
 strcpy(cfDefault.szFaceName,"Arial");
 m_RichEdit1.SetDefaultCharFormat(cfDefault);//设置模式
c.如果要设置你的RichEdit响应事件消息(Envent)用:
        CWnd* pWnd=GetDlgItem(IDC_RICHEDIT1);
 CRichEditCtrl* pRich=(CRichEditCtrl*)(pWnd);
 long nEvn=pRich->GetEventMask();
 nEvn |=ENM_CHANGE;       //响应OnChangeEdit函数.
 pRich->SetEventMask(nEvn);
    上面这些就是RichEdit入门.呵呵..

    我这里有一个我测试时写的一个源程序.(很简单).可以用来输入多国语言(用的是RichEdit),并且获取显示.还有就是把他的Unicode代码显示出来.如果你要..请和我联系.我给你们发过去.(尽力而为).

    这里我还要提出一些关于显示多国语言里面我曾经思考的问题..作为参考留给大家..至于实现,我这个低级选手暂时只能望尘莫及了.
(1):我当时曾考虑过如何在98下显示并获取的问题,当中用到了vb上面的一个RichText控件.那时侯发现,其实里面的文本可以用RTF格式取出来.但是RTF格式及其让人讨厌..所以当时是在没有办法的情况下(转悠了15天,急了),才考虑到准备把里面的内码值抠出来..呵呵.
(2):仔细分析情况,(我个人认为)为什么会得到???,是因为内码对应不正确的问题..或者字符集不正确.例如:我们现在的操作环境对应的是GB2312码(里面有中文繁体字,以及中文日文字,我们虽然可以输入,但却被认成了中文的相应字符).当你把控制面版里区域选项下面的预设默认值设为中文简体时,它将被选入系统.以至于影响到你的vc程序.导致了无法获取的问题.关于这内码还要提一点..如果你是用繁体的,由于他没有简体和日文字体,所以无法正确显示.这里要说明一下..设置这个预设默认值,是为了构造环境,如果你预设是日文,然后你的程序连接也用的是日文资源dll.那么你的程序即便是在中文Win平台下,用vc,在这时候也可以获得对日文的支持显示和处理功能.(其实就是相单于构造了日文操作平台).
(3):这个和支持多国语资源没有关系..如果你想在你资源里面多加日文资源,那只能保证你可以用 日文windows显示那些文字.但却不能共同显示中文,日文.我看到了<<用VC5_0实现软件中的多种语言支持>>文章..完全和这个是不一样的事情.而且它和我们常遇到的多国语言下载组件支持也没有任何关系.
(4):我的一个同事由于研究给软件安装输入法时,发现可以利用DHTML控件来支持呼叫和显示,无论是98还是2000.都可以,只不过里面内容都为网页,所以必须自己抠出来(我想不会很难).
    好了,就写到这里,算是我这一段时间的总结,呵呵..如果你头晕了,千万要记得,我的交友申请,欢迎和我联系,一起研究,另外本人可能要转入多媒体了,也希望多交一些搞多煤体的朋友.

eVC3 SN:
TRT7H-KD36T-FRH8D-6QH8P-VFJHQ
EVC4 SN:
TRT7H-KD36T-FRH8D-6QH8P-VFJHQ







  • 0
    点赞
  • 5
    评论
  • 0
    收藏
  • 打赏
    打赏
  • 扫一扫,分享海报

评论 5 您还未登录,请先 登录 后发表或查看评论
©️2022 CSDN 皮肤主题:大白 设计师:CSDN官方博客 返回首页

打赏作者

gztoby

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值