打印
[ZLG-ARM]

转:嵌入开发(WinCE)的一些经验

[复制链接]
2135|13
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
msp430ing|  楼主 | 2011-11-29 22:19 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
wince, ST, TE, AN, ic
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); //更新显示栏
}
评分
参与人数 1威望 +1 收起 理由
sjnh + 1

相关帖子

沙发
msp430ing|  楼主 | 2011-11-29 22:21 | 只看该作者
程序接收到的字符串最后保存到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卡通过.

使用特权

评论回复
板凳
msp430ing|  楼主 | 2011-11-29 22:22 | 只看该作者
用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();
}

使用特权

评论回复
地板
msp430ing|  楼主 | 2011-11-29 22:22 | 只看该作者
(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装置都支持这个函数调用.

使用特权

评论回复
5
msp430ing|  楼主 | 2011-11-29 22:22 | 只看该作者
以下是个调用例子:

#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);
strDeviceInfo += strNextChar;
}
CString strDeviceId =
strDeviceInfo.Mid(40,2) +
strDeviceInfo.Mid(45,9) +
strDeviceInfo.Mid(70,6);

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

使用特权

评论回复
6
msp430ing|  楼主 | 2011-11-29 22:23 | 只看该作者
我用以下代码成功禁止任务栏被点击,但不知怎样才能解除,特此请教,谢谢。
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/do ... T5XP/EN-US/eVC4.exe

eMbedded Visual C++ 4.0 SP1 ENU
http://download.microsoft.com/do ... P/EN-US/eVC4SP1.exe

eMbedded Visual Tools 3.0
http://download.microsoft.com/do ... /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

使用特权

评论回复
7
msp430ing|  楼主 | 2011-11-29 22:26 | 只看该作者
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);

使用特权

评论回复
8
msp430ing|  楼主 | 2011-11-29 22:26 | 只看该作者
Windows CE 3.0 supports the standard Winsock 1.1 functions.except the asychronous functions.

eVC4:
http://msdn.microsoft.com/librar ... ?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/downlo ... sdncompositedoc.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/librar ... imecapabilities.asp
http://msdn.microsoft.com/downlo ... 8/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键控制焦点位置的目的!!!
请问:各个高手这是为何?

使用特权

评论回复
9
msp430ing|  楼主 | 2011-11-29 22:27 | 只看该作者
下一个:::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是横着计算,仅此而已!

使用特权

评论回复
10
msp430ing|  楼主 | 2011-11-29 22:28 | 只看该作者
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,就可以得到你要的东西.也就是解决上面的问题。

使用特权

评论回复
11
msp430ing|  楼主 | 2011-11-29 22:28 | 只看该作者
这儿,我提供方法给那些没有用过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入门.呵呵..

使用特权

评论回复
12
sjnh| | 2011-11-30 15:16 | 只看该作者
这个顶

使用特权

评论回复
13
chy117| | 2011-11-30 18:55 | 只看该作者
mark

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

0

主题

730

帖子

1

粉丝