Board logo

Subject: DELPHI 2009的转变,令cnpack的部分公共库的单元失效。 [Print This Page]

Author: xopv    Time: 2008-11-17 21:07     Subject: DELPHI 2009的转变,令cnpack的部分公共库的单元失效。

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs;

type
  TForm1 = class(TForm)
    procedure FormCreate(Sender: TObject);
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

{函数}
function GetVarType(const v: Variant): string;
begin
  case VarType(v) of
    varEmpty    : Result := 'Empty';
    varNull     : Result := 'Null';
    varSmallint : Result := 'Smallint';
    varInteger  : Result := 'Integer';
    varSingle   : Result := 'Single';
    varDouble   : Result := 'Double';
    varCurrency : Result := 'Currency';
    varDate     : Result := 'Date';
    varOleStr   : Result := 'OleStr';
    varDispatch : Result := 'Dispatch';
    varError    : Result := 'Error';
    varBoolean  : Result := 'Boolean';
    varVariant  : Result := 'Variant';
    varUnknown  : Result := 'Unknown';
    varShortInt : Result := 'ShortInt';
    varByte     : Result := 'Byte';
    varWord     : Result := 'Word';
    varLongWord : Result := 'LongWord';
    varInt64    : Result := 'Int64';
    varStrArg   : Result := 'StrArg';
    varString   : Result := 'String';
    varAny      : Result := 'Any';
    varTypeMask : Result := 'TypeMask';
    varArray    : Result := 'Array';
    varByRef    : Result := 'ByRef';
  end;
end;

{测试}
procedure TForm1.FormCreate(Sender: TObject);
var
  i: Integer;
  w: Word;
  s: string;
  d: Double;
begin
  ShowMessage(GetVarType(i)); {Integer}
  ShowMessage(GetVarType(w)); {Word}
  ShowMessage(GetVarType(s)); {string}/////////////////////////////这里判断不出来。
  ShowMessage(GetVarType(d)); {Double}
end;

end.

以上代码,在D7中能有效得到判断出来,无奈DELPHI 2009 VARTYPE函数有BUG,令其判断失效,要修改为以下,才能判断出来:
procedure TForm1.FormCreate(Sender: TObject);
var
  i: Integer;
  w: Word;
  s: string;
  d: Double;
begin
  ShowMessage(GetVarType(i)); {Integer}
  ShowMessage(GetVarType(w)); {Word}
  ShowMessage(GetVarType(AnsiString(s))); {string}/////////////////////////////这里就可以判断出来。
  ShowMessage(GetVarType(d)); {Double}
end;

不知:CnBase64.pas
    Base64 编码解码算法单元
也是不是这个原因,在DELPHI 2009 无法正确地便用?
Author: Passion    Time: 2008-11-18 10:22

你说的第一个VarType函数并不是bug,而是由于Delphi 2009的string默认已经是UnicodeString,从而其VarType已经不是varString而是varUString了。函数中加入对varUString的处理即可。

CnBase64的问题我们查查看。
Author: Passion    Time: 2008-11-18 10:30

cnpack\Examples\Crypt这个例子,在D2009下和在D5下,编译得出的exe,其base64编码解码结果都一样,请问您这边出的是什么问题?
Author: xopv    Time: 2008-11-18 13:36

1.先说声抱歉,搞错了,原来是CnDES单元才对.
  我是这样使用的,先引用CnDES单元,然后:
  EDIT2.TEXT:=DESEncryptStr('KEY',EDIT1.TEXT);{加密显示返回加密后的字串}
  EDIT3.TEXT:=DESDecryptStr('KEY',EDIT2.TEXT);{解密并显示原来的字串}

2.另CnXlsWriter单元,有一方法使用了Vartype函数,在D2009下是没有办法得出结果的,代码始下:
  procedure TCnXlsWriter.SetCells(const ACol: Byte; const ARow: Word; const Value: Variant);
var
  aStr: string;
  aInt: Int64;
  aFloat: Extended;
  aCode: Integer;
begin
  case VarType(Value) of
    varSmallint, varInteger, varByte:
      XlsWriteCellRk(FStream, ACol, ARow, Value);
    varSingle, varDouble, varCurrency:
      XlsWriteCellNumber(FStream, ACol, ARow, Value);
    varString, varOleStr:
      begin
        aStr := Value;
        Val(aStr, aInt, aCode);
        if aCode = 0 then
        begin
          XlsWriteCellRk(FStream, ACol, ARow, Value);
          Exit;
        end;
        Val(aStr, aFloat, aCode);
        if aCode = 0 then
        begin
          XlsWriteCellNumber(FStream, ACol, ARow, Value);
          Exit;
        end;
        XlsWriteCellLabel(FStream, ACol, ARow, Value);
      end;
    varDate:
      XlsWriteCellLabel(FStream, ACol, ARow, DateTimeToStr(Value));
  else
    XlsWriteCellBlank(FStream, ACol, ARow);
  end;
end;
当调用你们所提供的示例(..\Examples\XlsWriter),所生成的EXCEL文件是没有内容的,请修正.
Author: Passion    Time: 2008-11-18 23:59

CnXlsWriter的问题已修正,感谢指出。

对于CnDES的问题,是由于D2009下,Edit.Text属性是UnicodeStirng,对加密返回的字符串进行了多余的Unicode转换,导致解码出了问题,这个问题倒也不能说是CnDES的问题,毕竟CnDES的这俩函数是AnsiString的返回值。
解决办法有俩,一个是用AnsiString的变量来容纳返回值,这样能避免多余的转换,也能顺利还原。


var
  S: AnsiString;

S :=DESEncryptStr('KEY',EDIT1.TEXT);{加密显示返回加密后的字串}
  EDIT3.TEXT:=DESDecryptStr('KEY',S);{解密并显示原来的字串}

另外一法子是可以用DESEncryptStrToHex和DESDecryptStrFromHex俩函数,它们能将结果转换为十六进制,这样和Unicode再转换也就没副作用了。




Welcome to CnPack Forum (http://bbs.cnpack.org/) Powered by Discuz! 5.0.0