发起最完美的Delphi VCL Unicode 兼容计划, 准备在sf.net开项目, 方案已定! 有经验的大虾请进!本计划绝非广告, 是sourceforge.net开源的. 绝对原创, 请高手支持支持.目的:
1.根本上改变Delphi支持Unicode不好的现状, 不改VCL一行代码, 使VCL完美支持Unicode.
2.兼容所有第三方控件, 使这些控件平滑过渡到Unicode.现有问题:
1.Delphi有支持Unicode的函数, 但默认的String根本不支持Unicode. WideString可以支持.
2.Delphi全部字符函数以Byte方式操作, 不支持 Unicode .
3.Delphi对Windows API的封装全部默认"A"函数, 没有选择"W"函数的余地. 以上是造成VCL不能很好支持Unicode的原因.本人解决的方案:
从上面问题来看,进行的最大难点是第二点Delphi全部字符函数以Byte方式操作. 而Unicode的UTF-8编码正好能兼容这些函数, 又能使用Unicode. 所以让VCL内部统一为UTF-8编码, VCL已经基本可以兼容Unicode. 工作流程可以看下面的图:
Unicode ----> UTF-8 Encode ----> String ----> VCL Kernel ----> UTF-8 Decode ----> WideString ----> Win API "W" Unicode Verison
1.VCL内部字符统一是String, String能兼容UTF-8, 只要所有String := Unicode 的赋值都自动 UTF-8 编码, 输入已经没问题. 具体修改 System.pas 的 WCharFromChar:function WCharFromChar(WCharDest: PWideChar; DestChars: Integer; const CharSource: PChar; SrcBytes: Integer): Integer;
begin
Result := MultiByteToWideChar(CP_UTF8, 0, CharSource, SrcBytes,
WCharDest, DestChars);
end; 2.VCL输出到 Unicode Verison API 都自动 UTF-8 解码, 输出也就没问题, 具体修改 System.pas 的 CharFromWChar:function CharFromWChar(CharDest: PChar; DestBytes: Integer; const WCharSource: PWideChar; SrcChars: Integer): Integer;
var
IconvContext: Integer;
begin
Result := WideCharToMultiByte(CP_UTF8, 0, WCharSource, SrcChars,
CharDest, DestBytes, nil, nil);
end; 就这样VCL和第三方控件已经完美升级Unicode了, 是不是很简单? 不过还有一个主要问题, 就是上面的第三点, Windows.pas的定义, 居然没有象VC的 windows.h 那样有UNICODE开关, 为了避免修改庞大的VCL, 必须做一个带有UNICODE开关的Windows.pas, 具体举例:function DrawText(hDC: HDC; lpString: PChar; nCount: Integer;
var lpRect: TRect; uFormat: UINT): Integer;
var
wsTmp: WideString;
begin
wsTmp := lpString;
Result := DrawTextW(hDC, PWideChar(wsTmp), Length(wsTmp), lpRect, uFormat);
end; wsTmp := lpString; 已经完成了 UTF-8 的解码工作, 再赋值到DrawTextW,就可以了. 不过每一个API都做这样的转换工作量很大, 所以想在sf.net开项目,大家一起完成咯. 不过有一个捷径, 就是令Delphi的编译器支持 PChar 转换 PWideChar的工作, 自动完成UTF-8解码, 那就不用写中转函数了. 不过直到Delphi2005还是不支持, 谁能通知Borland就好了. 以上经验,我经过了实践,证明完全可行, 大家试一下, 编译System.dcu的方法是用Borland的Make, 到delphi\source\Win32\rtl下, make, system.dcu会创建在同目录的lib(要自己创建这个目录),然后复制到Lib,重启Delphi编译. 在Delphi7以上新建一个VCL Form,修改 Label1.Caption := PWideChar("测试"); "测试"必须是Unicode的,大家可以用XP的NotePad另存为Unicode获得. 在NT系统, 当Locale不是中国时, Lable1仍然显示正确, 而原来的不兼容Unicode的已经显示乱码. 欢迎大家实践, 参与, 不兼容unicode已经制约Delphi的发展, .net又慢, Unicode兼容的Delphi一定能走更远.
有问题和建议都欢迎跟帖.....
1.根本上改变Delphi支持Unicode不好的现状, 不改VCL一行代码, 使VCL完美支持Unicode.
2.兼容所有第三方控件, 使这些控件平滑过渡到Unicode.现有问题:
1.Delphi有支持Unicode的函数, 但默认的String根本不支持Unicode. WideString可以支持.
2.Delphi全部字符函数以Byte方式操作, 不支持 Unicode .
3.Delphi对Windows API的封装全部默认"A"函数, 没有选择"W"函数的余地. 以上是造成VCL不能很好支持Unicode的原因.本人解决的方案:
从上面问题来看,进行的最大难点是第二点Delphi全部字符函数以Byte方式操作. 而Unicode的UTF-8编码正好能兼容这些函数, 又能使用Unicode. 所以让VCL内部统一为UTF-8编码, VCL已经基本可以兼容Unicode. 工作流程可以看下面的图:
Unicode ----> UTF-8 Encode ----> String ----> VCL Kernel ----> UTF-8 Decode ----> WideString ----> Win API "W" Unicode Verison
1.VCL内部字符统一是String, String能兼容UTF-8, 只要所有String := Unicode 的赋值都自动 UTF-8 编码, 输入已经没问题. 具体修改 System.pas 的 WCharFromChar:function WCharFromChar(WCharDest: PWideChar; DestChars: Integer; const CharSource: PChar; SrcBytes: Integer): Integer;
begin
Result := MultiByteToWideChar(CP_UTF8, 0, CharSource, SrcBytes,
WCharDest, DestChars);
end; 2.VCL输出到 Unicode Verison API 都自动 UTF-8 解码, 输出也就没问题, 具体修改 System.pas 的 CharFromWChar:function CharFromWChar(CharDest: PChar; DestBytes: Integer; const WCharSource: PWideChar; SrcChars: Integer): Integer;
var
IconvContext: Integer;
begin
Result := WideCharToMultiByte(CP_UTF8, 0, WCharSource, SrcChars,
CharDest, DestBytes, nil, nil);
end; 就这样VCL和第三方控件已经完美升级Unicode了, 是不是很简单? 不过还有一个主要问题, 就是上面的第三点, Windows.pas的定义, 居然没有象VC的 windows.h 那样有UNICODE开关, 为了避免修改庞大的VCL, 必须做一个带有UNICODE开关的Windows.pas, 具体举例:function DrawText(hDC: HDC; lpString: PChar; nCount: Integer;
var lpRect: TRect; uFormat: UINT): Integer;
var
wsTmp: WideString;
begin
wsTmp := lpString;
Result := DrawTextW(hDC, PWideChar(wsTmp), Length(wsTmp), lpRect, uFormat);
end; wsTmp := lpString; 已经完成了 UTF-8 的解码工作, 再赋值到DrawTextW,就可以了. 不过每一个API都做这样的转换工作量很大, 所以想在sf.net开项目,大家一起完成咯. 不过有一个捷径, 就是令Delphi的编译器支持 PChar 转换 PWideChar的工作, 自动完成UTF-8解码, 那就不用写中转函数了. 不过直到Delphi2005还是不支持, 谁能通知Borland就好了. 以上经验,我经过了实践,证明完全可行, 大家试一下, 编译System.dcu的方法是用Borland的Make, 到delphi\source\Win32\rtl下, make, system.dcu会创建在同目录的lib(要自己创建这个目录),然后复制到Lib,重启Delphi编译. 在Delphi7以上新建一个VCL Form,修改 Label1.Caption := PWideChar("测试"); "测试"必须是Unicode的,大家可以用XP的NotePad另存为Unicode获得. 在NT系统, 当Locale不是中国时, Lable1仍然显示正确, 而原来的不兼容Unicode的已经显示乱码. 欢迎大家实践, 参与, 不兼容unicode已经制约Delphi的发展, .net又慢, Unicode兼容的Delphi一定能走更远.
有问题和建议都欢迎跟帖.....
>>居然没有象VC的 windows.h 那样有UNICODE开关
delphi2005, 已经部分有了不过,我很支持做这些尝试