LOFTER for ipad —— 让兴趣,更有趣

点击下载 关闭

LOFTER-网易轻博

delphi

2197浏览    392参与
XXX

HP被诅咒的娃儿 有个脑洞

突然想看Delphi和Scorpio在一起,带着Scorpio变成自信的复刻版小龙!

不知道有没有文啊0 0 没有的话求哪位大大考虑考虑呗🙇🏻‍♀️

而且明明俩人颜值很配的对不对!

突然想看Delphi和Scorpio在一起,带着Scorpio变成自信的复刻版小龙!

不知道有没有文啊0 0 没有的话求哪位大大考虑考虑呗🙇🏻‍♀️

而且明明俩人颜值很配的对不对!

oblind

WM_COPYDATA

WM_COPYDATA  
wParam = (WPARAM) (HWND) hwnd;            // handle of sending window
lParam = (LPARAM) (PCOPYDATASTRUCT) pcds; // pointer to structure with data

发送端:

procedure TMainForm.btnClick(Sender: TObject...

WM_COPYDATA  
wParam = (WPARAM) (HWND) hwnd;            // handle of sending window
lParam = (LPARAM) (PCOPYDATASTRUCT) pcds; // pointer to structure with data

发送端:

procedure TMainForm.btnClick(Sender: TObject);
var
  p: PRec;
  cd: TCopyDataStruct;
begin
  h := FindWindow('TClientForm', nil);
  if h <> 0 then
  begin
    GetMem(p, SizeOf(TRec));
    cd.cbData := SizeOf(TRec);
    cd.lpData := p;
    SendMessage(h, WM_COPYDATA, Handle, Integer(@cd));
    FreeMem(p);
  end;

end;

注:必须使用SendMessage不能用PostMessage

接收端:

procedure OnCopyData(var msg: TWMCopyData); message WM_COPYDATA;

procedure TClientForm.OnCopyData(var msg: TWMCopyData);
var p: PRec;
begin
  p := msg.CopyDataStruct.lpData;
end;


oblind

Delphi, C语言, DOS文件中的时间格式及转换

Delphi中的时间

Delphi中的时间类型TDateTime实质是个64位 double 双精度浮点数,占8个字节,其值为以1899-12-30 00:00:00为基准的时间,整数部分表示天数,小数部分表示时间,1/86400表示1秒(24*60*60)

C语言中时间

C语言中时间类型time_t实质是个32位 long 长整形数,占4个字节,其值为以1970-1-1 00:00:00为基准的秒数,就是所谓的日历时间,不过这个格式有个大问题,2^31/365/24/60/60=68.096,只能表示1970年前后68年的时间,也就是说这个日历到2038年就到头了,好吧,据说世界末日是...

Delphi中的时间

Delphi中的时间类型TDateTime实质是个64位 double 双精度浮点数,占8个字节,其值为以1899-12-30 00:00:00为基准的时间,整数部分表示天数,小数部分表示时间,1/86400表示1秒(24*60*60)

C语言中时间

C语言中时间类型time_t实质是个32位 long 长整形数,占4个字节,其值为以1970-1-1 00:00:00为基准的秒数,就是所谓的日历时间,不过这个格式有个大问题,2^31/365/24/60/60=68.096,只能表示1970年前后68年的时间,也就是说这个日历到2038年就到头了,好吧,据说世界末日是2012年……

DOS文件中的时间

DOS文件中的时间就有意思了,微软刚开发DOS那会儿存储空间还金贵得很,一切都以省字当头,所以那时用的FAT12/FAT16文件系统还是8.3文件名,就是文件名占8个字节,扩展名占3个字节,我们现在在DOS下查看Program Files文件夹时还能看到它的短文件名形式Progra~1。文件名都这么省那时间呢?DOS文件中的时间也占4个字节32位,其中高2字节表示日期,低2字节表示时间,表示日期的2字节中高7位表示从1980年起的年份,中间4位表示月,剩下的低5位表示日。表示时间的2字节中高5位表示小时,中间6位表示分钟,剩下低5位表示秒。

等等,用5位表示秒?2^5=32,不够60秒啊!所以这5位其实是秒数的高5位,最低位偷偷补了个0,也就是说那时的DOS文件系统分不出2秒钟以内建立文件的先后,好在DOS下时间只显示到分,要不一看文件时间的秒数清一色偶数,那不露馅了。

再说下这DOS时间的年数,2^7=128,从1980年起最多就到2107年,这也就是为什么有当年闹得沸沸扬扬的千年虫问题了,好在现在的FAT32,NTFS早已解决这问题了。

 Delphi和C语言时间的转换

1899-12-30到1970-1-1之间相隔25569天,知道这个转换就简单了

//C语言时间:int32格式,1970-1-1 00:00:00为起点秒数
//Delphi时间:Double格式,1899-12-30 00:00:00为起点天数
//2.75: 1900-1-1 18:00
function CTimeToTime(t: LongInt): TDateTime;
begin
  Result := t / 86400 + 25569;
end;

function TimeToCTime(t: TDateTime): LongInt;
begin
  Result := Round((t - 25569) * 86400);
end;

Delphi 和 DOS文件时间的转换

Delphi中提供了现成的转换函数

//DOS文件时间转换为Delphi时间

function FileDateToDateTime(FileDate: Integer): TDateTime;

//Delphi时间转换为DOS文件时间

function DateTimeToFileDate(DateTime: TDateTime): Integer;


oblind

Variant, TVarData, TVarRec

TVarData 是Variant 的内部实现类型

TVarRec 是pascal中 open array 参数的实现类型

TVarArrayBound = packed record

  ElementCount: Integer;

  LowBound: Integer;

end;

TVarArrayBoundArray = array [0..0] of TVarArrayBound;

  PVarArray = ^TVarArray;

TVarArray = packed record...


TVarData 是Variant 的内部实现类型

TVarRec 是pascal中 open array 参数的实现类型

TVarArrayBound = packed record

  ElementCount: Integer;

  LowBound: Integer;

end;

TVarArrayBoundArray = array [0..0] of TVarArrayBound;

  PVarArray = ^TVarArray;

TVarArray = packed record

  DimCount: Word;

  Flags: Word;

  ElementSize: Integer;

  LockCount: Integer;

  Data: Pointer;

  Bounds: TVarArrayBoundArray;

end;

  TVarData = packed record

    case Integer of

      0: (VType: TVarType;

          case Integer of

            0: (Reserved1: Word;

                case Integer of

                  0: (Reserved2, Reserved3: Word;

                      case Integer of

                        varSmallInt: (VSmallInt: SmallInt);

                        varInteger:  (VInteger: Integer);

                        varSingle:   (VSingle: Single);

                        varDouble:   (VDouble: Double);

                        varCurrency: (VCurrency: Currency);

                        varDate:     (VDate: TDateTime);

                        varOleStr:   (VOleStr: PWideChar);

                        varDispatch: (VDispatch: Pointer);

                        varError:    (VError: HRESULT);

                        varBoolean:  (VBoolean: WordBool);

                        varUnknown:  (VUnknown: Pointer);

                        varShortInt: (VShortInt: ShortInt);

                        varByte:     (VByte: Byte);

                        varWord:     (VWord: Word);

                        varLongWord: (VLongWord: LongWord);

                        varInt64:    (VInt64: Int64);

                        varString:   (VString: Pointer);

                        varAny:      (VAny: Pointer);

                        varArray:    (VArray: PVarArray);

                        varByRef:    (VPointer: Pointer);

                     );

                  1: (VLongs: array[0..2] of LongInt);

               );

            2: (VWords: array [0..6] of Word);

            3: (VBytes: array [0..13] of Byte);

          );

      1: (RawData: array [0..3] of LongInt);

  end;

PVarRec = ^TVarRec;

TVarRec = record

  case Byte of

      vtInteger:    (VInteger: Integer; VType: Byte);

      vtBoolean:    (VBoolean: Boolean);

      vtChar:       (VChar: Char);

      vtExtended:   (VExtended: PExtended);

      vtString:     (VString: PShortString);

      vtPointer:    (VPointer: Pointer);

      vtPChar:      (VPChar: PChar);

      vtObject:     (VObject: TObject);

      vtClass:      (VClass: TClass);

      vtWideChar:   (VWideChar: WideChar);

      vtPWideChar:  (VPWideChar: PWideChar);

      vtAnsiString: (VAnsiString: Pointer);

      vtCurrency:   (VCurrency: PCurrency);

      vtVariant:    (VVariant: PVariant);

      vtInterface:  (VInterface: Pointer);

      vtWideString: (VWideString: Pointer);

      vtInt64:      (VInt64: PInt64);

end;


oblind

学的有点杂,总混,留作备忘吧

php时间函数

字符串转时间

function strtotime ($time, $now = 'time()')

eg:

$t = strtotime('2017-11-18');

echo strtotime('next Sunday', $t), '<br>';//$t后的周日,自然语言,好傻逼

echo strtotime('+5hours');//当前时间5小时后

时间转字符串

function date ($format, $timestamp ...

学的有点杂,总混,留作备忘吧

php时间函数

字符串转时间

function strtotime ($time, $now = 'time()')

eg:

$t = strtotime('2017-11-18');

echo strtotime('next Sunday', $t), '<br>';//$t后的周日,自然语言,好傻逼

echo strtotime('+5hours');//当前时间5小时后

时间转字符串

function date ($format, $timestamp = null)

date('Y-m-d H:i:s');


javascript

 字符串转时间

let t = new Date('2018-03-06 12:00:00')

时间转字符串

let s = (new Date).getTime()


java

static final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault());

字符串转时间long t = new Date().getTime()long t = sdf.parse("2018-03-06 12:00:00'").getTime();getTime返回1970-01-01 00:00:00起的毫秒数时间转字符串String s = sdf.format(t);


Delphi

uses SysUtils

ShortDateFormat := 'yyyy-mm-dd';

LongTimeFormat := 'hh:nn:ss';

Application.UpdateFormatSettings := False;


采花贼°এ

易笔记 全方位编程学习程序 包含 vb vc java php asp c# c++c语言 易语言 等文档资源 QQ群 713165688 欢迎下载

易笔记 全方位编程学习程序 包含 vb vc java php asp c# c++c语言 易语言 等文档资源 QQ群 713165688 欢迎下载

采花贼°এ
易笔记 全方位编程学习程序 包...

易笔记 全方位编程学习程序 包含 vb vc java php asp c# c++c语言 易语言 等文档资源 QQ群  713165688  欢迎下载

易笔记 全方位编程学习程序 包含 vb vc java php asp c# c++c语言 易语言 等文档资源 QQ群  713165688  欢迎下载

星五博客

WebPascal脚本模型教程 - 编写脚本内函数

在脚本内部,其实也是可以编写脚本的,比如某个小功能被反复使用,就可以写成小函数进行调用,不过需要注意的是,这个小函数只在当前脚本内有效。

<?

//定义函数

function$wlog

begin

    log($Params.0+' 共'+$params.count+'个参数。',$Params.1);

end;

function$wlog2

begin

    log($msg,$fname);

end;

//调用函数

$wlog('日志内容1','日志');

//注意,因为给了变量名,...

在脚本内部,其实也是可以编写脚本的,比如某个小功能被反复使用,就可以写成小函数进行调用,不过需要注意的是,这个小函数只在当前脚本内有效。

<?

//定义函数

function$wlog

begin

    log($Params.0+' 共'+$params.count+'个参数。',$Params.1);

end;

function$wlog2

begin

    log($msg,$fname);

end;

//调用函数

$wlog('日志内容1','日志');

//注意,因为给了变量名,所以顺序无所谓,填参数时,不要带$

$wlog2(fname:'日志',msg:'日志内容2');

?>

结果:

2018-06-09 00:02:21.285; 日志内容1 共2个参数。

2018-06-09 00:02:21.287; 日志内容2

是不是非常简单?你学会了吗?


星五博客

WebPascal脚本模型添加多域名支持

WebPascal脚本模型添加多域名支持,也就是说,一个服务支持多个域名的绑定,类似IIS那样,可以在一套服务里放置多个网站;

比如分别将 offeu.com 和 webpascal.com 绑定到一个ip上,当用户访问不同的域名时,实际上是通过相同服务进行解析的;

当然,不同域名对应的脚本及内容也是不一样的,都是相对独立的,不仅仅是简单的多域名绑定。

目前没有时间制作webpascal.com的网站,也就是 webpascal脚本模型 的官网,以后有空了再搞,不过域名已经可以访问了。


WebPascal脚本模型添加多域名支持,也就是说,一个服务支持多个域名的绑定,类似IIS那样,可以在一套服务里放置多个网站;

比如分别将 offeu.com 和 webpascal.com 绑定到一个ip上,当用户访问不同的域名时,实际上是通过相同服务进行解析的;

当然,不同域名对应的脚本及内容也是不一样的,都是相对独立的,不仅仅是简单的多域名绑定。

目前没有时间制作webpascal.com的网站,也就是 webpascal脚本模型 的官网,以后有空了再搞,不过域名已经可以访问了。


星五博客

TNetHTTPCleint提交JSON串

这里,我们拿友盟的推送接口做个测试,它是要求同时提交get参数和post参数,post参数内容为json串,需要引用DateUtils和md5算法单元,代码如下:

procedureTForm1.Button3Click(Sender: TObject);

var

  vHttp: TNetHTTPClient;

  vS, vR: TStringStream;

  appkey, ams, timestamp, method, url, body, md5: string;

begin

  vHttp := TNetHTTPClient....

这里,我们拿友盟的推送接口做个测试,它是要求同时提交get参数和post参数,post参数内容为json串,需要引用DateUtils和md5算法单元,代码如下:

procedureTForm1.Button3Click(Sender: TObject);

var

  vHttp: TNetHTTPClient;

  vS, vR: TStringStream;

  appkey, ams, timestamp, method, url, body, md5: string;

begin

  vHttp := TNetHTTPClient.Create(nil);

  vS := TStringStream.Create('', TEncoding.UTF8);

  vR := TStringStream.Create('', TEncoding.UTF8);

  try

    withvHttp do

    begin

      ConnectionTimeout := 2000; // 2秒

      ResponseTimeout := 10000; // 10秒

      AcceptCharSet := 'utf-8';

      AcceptEncoding := '65001';

      AcceptLanguage := 'zh-CN';

      ContentType := 'application/json';

      UserAgent := 'Embarcadero URI Client/1.0';

      appkey := '您的AppKey';

      ams := '您的App Master Secret';

      timestamp := FloatToStr(DateTimeToUnix(now, False));//返回unix时间戳

      method := 'POST';

      url := 'http://msg.umeng.com/api/send';

      body := '{"appkey":"'+ appkey + '",'

        + '"timestamp":"'+ timestamp + '",'

        + '"type":"customizedcast",'

      // +'"device_tokens":"",'

        + '"alias_type": "别名类型",'

        + '"alias":"别名1,别名2",'

        + '"payload":{"aps":{"alert": "您好!祝您生活愉快!'

        + '","badge":1,"sound":"default"}},'

        + '"description": "测试"}';

      vS.WriteString(method + url + body + ams);//友盟要求的签名算法

      md5 := LowerCase(MD5Print(MD5Stream(vS)));//签名要用md5输出,小写32位

      vS.Clear;

      vS.WriteString(body);

      vS.Position := 0;

      try

        Post(url + '?sign='+ md5, vS, vR);//拼接url并进行post提交

        Memo1.Lines.Add('post:'+ vR.DataString);

      except

        onE: Exception do

          // Error sending data: (12002) 操作超时.

          // Error receiving data: (12002) 操作超时

          ifCopy(E.Message, 1, Pos(':', E.Message) - 1) = 'Error sending data'

          then

            Memo1.Lines.Add('post:连接失败!')

          elseifCopy(E.Message, 1, Pos(':', E.Message) - 1) = 'Error receiving data'

          then

            Memo1.Lines.Add('post:接收失败,请延长接收超时时间!')

          else

            Memo1.Lines.Add('post:'+ E.Message);

      end;

    end;

  finally

    vS.Free;

    vR.Free;

    vHttp.Free;

  end;

end;

其实就是按流的形式进行提交就可以了,和拼接xml去post请求soap接口是一个道理。

星五博客

百度WebUploader的使用

webpascal脚本模型如何使用百度文件上传插件WebUploader呢?非常简单,仅调整一个fileVal参数即可,不多说,上代码:

<!-- 注意路径 -->

<link rel="stylesheet"type="text/css"href="webuploader.css">

 

<!-- 显示进度条 -->

<link rel="stylesheet"href="https://cdn.bootcss...

webpascal脚本模型如何使用百度文件上传插件WebUploader呢?非常简单,仅调整一个fileVal参数即可,不多说,上代码:

<!-- 注意路径 -->

<link rel="stylesheet"type="text/css"href="webuploader.css">

 

<!-- 显示进度条 -->

<link rel="stylesheet"href="https://cdn.bootcss.com/bootstrap/3.0.3/css/bootstrap.min.css">

<!-- 用到jquery -->

<script src="https://cdn.bootcss.com/jquery/2.1.3/jquery.min.js"></script>

<div id="uploader"class="wu-example">

<!--用来存放文件信息-->

    <div id="thelist"class="uploader-list"></div>

    <div class="btns">

        <div id="picker">选择文件</div>

    </div>

</div>

 

<!-- 注意路径 -->

<script type="text/javascript"src="webuploader.js"></script>

<script type="text/javascript">

    var$list=$('#thelist');

    varuploader = WebUploader.create({

        // 文件接收服务端。也可以是网址

        server: 'https://www.offeu.com/upfile',

        // 选择文件的按钮。可选。

        // 内部根据当前运行是创建,可能是input元素,也可能是flash.

        pick: '#picker',

        //设置接收接口文件接收名

        fileVal:'fname',

        //选择文件后自动上传

        auto:true,

        // 不压缩image, 默认如果是jpeg,文件上传前会压缩一把再上传!

        resize: false

    });

    // 当有文件被添加进队列的时候

    uploader.on( 'fileQueued', function( file ) {

        $list.append( '<div id="'+ file.id + '" class="item">'+

            '<h4 class="info">'+ file.name + '</h4>'+

            '<p class="state">等待上传...</p>'+

        '</div>');

    });

    // 文件上传过程中创建进度条实时显示。

    uploader.on( 'uploadProgress', function( file, percentage ) {

        var$li = $( '#'+file.id ),

            $percent = $li.find('.progress .progress-bar');

 

        // 避免重复创建

        if( !$percent.length ) {

            $percent = $('<div class="progress progress-striped active">'+

              '<div class="progress-bar" role="progressbar" style="width: 0%">'+

              '</div>'+

            '</div>').appendTo( $li ).find('.progress-bar');

        }

 

        $li.find('p.state').text('上传中');

 

        $percent.css( 'width', percentage * 100 + '%');

    });

    // 文件成功、失败处理

    uploader.on( 'uploadSuccess', function( file,response ) {

        //webpascal上传接口返回值是json,可以直接处理

        //{"Result":"Success",

        //"SourceFileName":"Desert.jpg",

        //"ObjectFileName":"\/up\/Desert.jpg"}

        $( '#'+file.id ).find('p.state').text('已上传,'+response.ObjectFileName);

    });

 

    uploader.on( 'uploadError', function( file ) {

        $( '#'+file.id ).find('p.state').text('上传出错');

    });

 

    uploader.on( 'uploadComplete', function( file ) {

        $( '#'+file.id ).find('.progress').fadeOut();

    });

</script>

以上就是主要部分的代码,是不是很简单?百度WebUploader的多文件上传,是按单文件分开上传的,所以直接支持Webpascal脚本模型的文件上传接口,不需要调整。

测试环境:WebUploader 0.1.5 版 、Chrome 61.0.3163.91版 


星五博客

Delphi东京版FireDAC连接MSSQL2000

在Delphi 10.2.1 东京 版中,FireDAC默认不兼容MSSQL2000,会提示“[FireDAC][Phys][ODBC][Microsoft][ODBC SQL Server Driver][SQL Server]对象名 'SYS.DATABASES' 无效。”的错误,对此需要修改FireDAC.Phys.MSSQL.pas单元进行修复:

首先从delphi目录下把FireDAC.Phys.MSSQL.pas文件复制出来,然后打开它,注释掉 {$I FireDAC.inc},然后查找到“procedure TFDPhysMSSQLConnection...

在Delphi 10.2.1 东京 版中,FireDAC默认不兼容MSSQL2000,会提示“[FireDAC][Phys][ODBC][Microsoft][ODBC SQL Server Driver][SQL Server]对象名 'SYS.DATABASES' 无效。”的错误,对此需要修改FireDAC.Phys.MSSQL.pas单元进行修复:

首先从delphi目录下把FireDAC.Phys.MSSQL.pas文件复制出来,然后打开它,注释掉 {$I FireDAC.inc},然后查找到“procedure TFDPhysMSSQLConnection.InternalSetMeta;”,再找到“sCompatLvl := '(SELECT COMPATIBILITY_LEVEL FROM SYS.DATABASES WHERE LOWER(NAME) = ' +AnsiLowerCase(sCurCatalog) + ')';”,将其修改为:

if oConnMeta.ServerVersion >= svMSSQL2008 then

   sCompatLvl := '(SELECT compatibility_level FROM sys.databases WHERE name = '

   + AnsiLowerCase(sCurCatalog) + ')'

else// MSSQL2005、MSSQL2000没有sys.databases表

   sCompatLvl := IntToStr(oConnMeta.ServerVersion div10000000);

经过以上步骤,就完成FireDAC兼容MSSQL2000的修改了。

星五博客

TSMBIOS

The SMBIOS (System Management BIOS) is a standard developed by the DMTF. The information stored in the SMBIOS includes devices manufacturer, model name, serial number, BIOS version, asset tag, processors, ports and device memory installed.

The TSMBIOS libary allows access the System Management...

The SMBIOS (System Management BIOS) is a standard developed by the DMTF. The information stored in the SMBIOS includes devices manufacturer, model name, serial number, BIOS version, asset tag, processors, ports and device memory installed.

The TSMBIOS libary allows access the System Management BIOS (SMBIOS) using the Object Pascal language (Delphi or Free Pascal).

https://github.com/RRUZ/tsmbios

Features

Some features of this project are

  • Source Full documented compatible with the help insight feature, available since Delphi 2005.

  • Supports SMBIOS Version from 2.1 to 2.8

  • Supports Delphi 5, 6, 7.

  • Supports RAD Studio 2005-2010

  • Supports RAD Studio XE-XE8

  • Supports RAD Studio 10 Seattle, RAD Studio 10.1 Berlin, RAD Studio 10.2 Tokyo

  • Compatible with FPC 2.4.0+

  • Supports Windows, Linux.

  • SMBIOS Data can be saved and/or load to a file.

  • SMBIOS Data can be obtained from remote machines (via WMI).

SMBIOS Tables supported


星五博客

Delphi下GetCPUID实现(x86和x64)

以下方法还是通过汇编实现,不过针对x64做了调整,以支持x86和x64两种环境,代码如下:

// 获取cpu序列号

type

  TCPUID = array[1.. 4] ofLongint;

 

functionGetCPUID: TCPUID;

asm

  {$IF Defined(CPUX86)}

  push  ebx

  push  edi

  mov   edi, eax

  mov   eax, 1

  dw  ...

以下方法还是通过汇编实现,不过针对x64做了调整,以支持x86和x64两种环境,代码如下:

// 获取cpu序列号

type

  TCPUID = array[1.. 4] ofLongint;

 

functionGetCPUID: TCPUID;

asm

  {$IF Defined(CPUX86)}

  push  ebx

  push  edi

  mov   edi, eax

  mov   eax, 1

  dw    $A20F

  stosd

  mov   eax, ebx

  stosd

  mov   eax, ecx

  stosd

  mov   eax, edx

  stosd

  pop   edi

  pop   ebx

  {$ELSEIF Defined(CPUX64)}

  PUSH    RBX

  PUSH    RDI

  MOV     RDI,RCX

  MOV     EAX,1

  CPUID

  mov    [rdi], eax;

  mov    [rdi+4], ebx;

  mov    [rdi+8], ecx;

  mov    [rdi+12], edx;

  POP     RDI

  POP     RBX

  {$IFEND}

  (* 调用示例

  var id: TCPUID;

  id := GetCPUID;

  ShowMessage(IntToHex(id[4], 8) + IntToHex(id[1], 8));

   *)

end;

最后注释里是使用示例,在d10.1up2中测试通过。

星五博客

SecureBlackbox SEC_ERROR_UNKNOWN_ISSUER

SecureBlackbox使用了一段时间,但有个问题,发现火狐浏览器一直不支持,提示SEC_ERROR_UNKNOWN_ISSUER,提示说可能需要额外的加载一个中间证书;经过分析和网上资料的参考,发现问题出在“证书链不完整”这里,也就是中间证书没有被加载,ie和chrome浏览器会自动去下载,而火狐和安卓系统下的微信内置浏览器(x5浏览器)不会,所以才有了这个么异常提示。

一直以为是加载问题,尝试了在加载pfx的基础上,再把root和ca证书分别加载,也都没有解决这个问题;回头看代码,在rtc插件这里发现有个证书链的参数,设置为强制证书链,结果问题解决了,坑啊。。。这里写一下,做个标记,...

SecureBlackbox使用了一段时间,但有个问题,发现火狐浏览器一直不支持,提示SEC_ERROR_UNKNOWN_ISSUER,提示说可能需要额外的加载一个中间证书;经过分析和网上资料的参考,发现问题出在“证书链不完整”这里,也就是中间证书没有被加载,ie和chrome浏览器会自动去下载,而火狐和安卓系统下的微信内置浏览器(x5浏览器)不会,所以才有了这个么异常提示。

一直以为是加载问题,尝试了在加载pfx的基础上,再把root和ca证书分别加载,也都没有解决这个问题;回头看代码,在rtc插件这里发现有个证书链的参数,设置为强制证书链,结果问题解决了,坑啊。。。这里写一下,做个标记,希望有需要的网友能看到,不用再浪费时间。


星五博客

Delphi正则表达式匹配中文

Delphi中支持unicode的语法为\x{}而不是\u,根据unicode的范围,所以匹配中文的正则应该是“[\x{4E00}-\x{9FA5}]+”,比如有数据“abc,中文,测试,123”,用表达式“[a-zA-Z0-9\x{4E00}-\x{9FA5}]+”进行匹配,结果为:

abc
中文
测试
123

Delphi中支持unicode的语法为\x{}而不是\u,根据unicode的范围,所以匹配中文的正则应该是“[\x{4E00}-\x{9FA5}]+”,比如有数据“abc,中文,测试,123”,用表达式“[a-zA-Z0-9\x{4E00}-\x{9FA5}]+”进行匹配,结果为:

abc
中文
测试
123

星五博客

NativeExcel获取Excel所有列

当我们打开一个Excel文件时,我们往往需要将它的数据进行处理,比如获取文件中所有行和列的数据,并进行显示。

这里,我简单的演示一下如何列举所有列名:

procedureTForm1.Button1Click(Sender: TObject);

Var

  book: IXLSWorkbook;

  i: integer;

begin

  book := TXLSWorkbook.Create();

  book.Open('c:\a.xls');

  // 列出excel中工作表1的所有已使用的列的列名...

当我们打开一个Excel文件时,我们往往需要将它的数据进行处理,比如获取文件中所有行和列的数据,并进行显示。

这里,我简单的演示一下如何列举所有列名:

procedureTForm1.Button1Click(Sender: TObject);

Var

  book: IXLSWorkbook;

  i: integer;

begin

  book := TXLSWorkbook.Create();

  book.Open('c:\a.xls');

  // 列出excel中工作表1的所有已使用的列的列名

  fori := 1tobook.Sheets[1].UsedRange.LastCol do

    Memo1.Lines.Add(book.Sheets[1].UsedRange.Item[1, i].Value);

  book.Close;

end;

代码中,我们读取Sheet1第一行的所有列,并循环输出它的内容,请注意,这里应该使用UsedRange,而不是Cells,如果你使用Cells,那么LastCol将显示Excel支持的总列数,而不是实际已经使用的列数。

举一反三,那么如何获取所有行的数据呢?是不是只要使用UsedRange.LastRow就行了?那么,通过两个循环,就可以输出Excel中所有的内容了,是不是很简单?


星五博客

TNetHttpClient上传文件

Delphi如何实现multipart/form-data方式上传文件呢?以前我们是使用indy,也就是用idHttp加TIdMultiPartFormDataStream来实现;本着研究精神,今天看了一下TNetHttpClient的定义,发现有个function Post(const AURL: string; const ASource: TMultipartFormData; const AResponseContent: TStream = nil;  const AHeaders: TNetHeaders = nil): IHTTPResponse; overload;的...

Delphi如何实现multipart/form-data方式上传文件呢?以前我们是使用indy,也就是用idHttp加TIdMultiPartFormDataStream来实现;本着研究精神,今天看了一下TNetHttpClient的定义,发现有个function Post(const AURL: string; const ASource: TMultipartFormData; const AResponseContent: TStream = nil;  const AHeaders: TNetHeaders = nil): IHTTPResponse; overload;的定义,然后官网查看了一下TMultipartFormData的说明,确认TNetHttpClient是可以独立完成formdata方式上传文件操作的,实验代码如下:

usesSystem.Net.Mime, // 用于支持 TMultipartFormData

  System.Net.HttpClientComponent; // 用于支持 TNetHTTPClient

 

procedureTfrmMain.Button1Click(Sender: TObject);

var

  cHttp: TNetHTTPClient;

  vData: TMultipartFormData;

  vRsp: TStringStream;

begin

  ifOpenDialog1.Execute then

  begin

    cHttp := TNetHTTPClient.Create(nil);

    vData := TMultipartFormData.Create;

    vRsp := TStringStream.Create('', TEncoding.GetEncoding(65001));

    try

      vData.AddFile('fname', OpenDialog1.FileName);

      withcHttp do

      begin

        ConnectionTimeout := 2000; // 2秒

        ResponseTimeout := 10000; // 10秒

        AcceptCharSet := 'utf-8';

        AcceptEncoding := '65001';

        AcceptLanguage := 'zh-CN';

        ContentType := 'multipart/form-data';

        UserAgent := 'Embarcadero URI Client/1.0';

        try

          Memo1.Lines.Add('尝试上传文件 '+ OpenDialog1.FileName);

          Post('https://www.offeu.com/upfile', vData, vRsp);

          Application.ProcessMessages;

        except

          onE: Exception do

            // Error sending data: (12002) 操作超时.

            // Error receiving data: (12002) 操作超时

            ifCopy(E.Message, 1, Pos(':', E.Message) - 1) = 'Error sending data'

            then

              Memo1.Lines.Add('Error:连接失败!')

            elseifCopy(E.Message, 1, Pos(':', E.Message) - 1) = 'Error receiving data'

            then

              Memo1.Lines.Add('Error:接收失败,请延长接收超时时间!')

            else

              Memo1.Lines.Add('Error:'+ E.Message);

        end;

        Memo1.Lines.Add(vRsp.DataString);

      end;

    finally

      cHttp.Free;

      vRsp.Free;

      vData.Free;

    end;

  end;

end;

我拿自己的网站的formdata接口进行了测试,上传文件很稳定。

不过,有个问题,因为emb官方没有提供数据发送的定义,所以无法实现上传进度的显示,但针对下载这块,又提供了,所以只能显示下载进度。


星五博客

NativeExcel获取Excel所有列

当我们打开一个Excel文件时,我们往往需要将它的数据进行处理,比如获取文件中所有行和列的数据,并进行显示。

这里,我简单的演示一下如何列举所有列名:

  • procedureTForm1.Button1Click(Sender: TObject);

  • Var

  •   book: IXLSWorkbook;

  •   i: integer;

  • begin

  •   book := TXLSWorkbook.Create();

  •   book.Open('c:\a.xls');

  •   // 列出excel中工作表1的所...

当我们打开一个Excel文件时,我们往往需要将它的数据进行处理,比如获取文件中所有行和列的数据,并进行显示。

这里,我简单的演示一下如何列举所有列名:

  • procedureTForm1.Button1Click(Sender: TObject);

  • Var

  •   book: IXLSWorkbook;

  •   i: integer;

  • begin

  •   book := TXLSWorkbook.Create();

  •   book.Open('c:\a.xls');

  •   // 列出excel中工作表1的所有已使用的列的列名

  •   fori := 1tobook.Sheets[1].UsedRange.LastCol do

  •     Memo1.Lines.Add(book.Sheets[1].UsedRange.Item[1, i].Value);

  •   book.Close;

  • end;


代码中,我们读取Sheet1第一行的所有列,并循环输出它的内容,请注意,这里应该使用UsedRange,而不是Cells,如果你使用Cells,那么LastCol将显示Excel支持的总列数,而不是实际已经使用的列数。

举一反三,那么如何获取所有行的数据呢?是不是只要使用UsedRange.LastRow就行了?那么,通过两个循环,就可以输出Excel中所有的内容了,是不是很简单?


星五博客

WebPascal脚本模型2.1发布

WebPascal是使用Delphi开发网站的一套解决方案,兼容主流Web前端框架,让Delphi程序员能够轻松开发Web网站、Web应用、WebAPI、JsonAPI等基于HTTP的应用,且支持HTTPS(SSL/TLS)。

请查看doc目录下的升级日志、注意事项和部分说明三个文本文件
目录结构:
Bin\                可执行文件、脚本和资源等。
Demo\      ...

WebPascal是使用Delphi开发网站的一套解决方案,兼容主流Web前端框架,让Delphi程序员能够轻松开发Web网站、Web应用、WebAPI、JsonAPI等基于HTTP的应用,且支持HTTPS(SSL/TLS)。

请查看doc目录下的升级日志、注意事项和部分说明三个文本文件
目录结构:
Bin\                可执行文件、脚本和资源等。
Demo\            一些演示,ScriptDemo目录下的复制到Bin\Script目录下就可测试。
Doc\                一些文档,请认真查看。
Plugin\            一些js插件,做网站时可用。

网站案例展示:https://www.offeu.com同时可下载该站整站前后端脚本和资源。
WebAPI演示:https://www.offeu.com/www/getip2.api返回客户端ip及相应的物理位置信息。
文件上传演示:https://www.offeu.com/www/upfile.html阿里云服务器,上传速度不错。
在线教程:https://www.offeu.com/www/index_id_119.html

授权:免费使用,无任何限制,个人或企业均可无限制使用,但不可对软件进行逆向等操作。
QQ群:免费用户请加群 579473754,需要源码的请加会员群 296308592(源码收费)。
介绍:http://bbs.2ccc.com/topic.asp?topicid=512865
下载:http://pan.baidu.com/s/1o7E964a

*修正 +增加 -去除 ^调整
2.1
 ^调整urlencode编码时将空格转换为%20而不再是+号,以兼容其它语言;
 +文件上传接口增加验证功能,上传时可以设置上传令牌(字符串),在配置文件中定义“utt=令牌”即可,未设置
  上传令牌的,接口里不会去验证,非空时才会去验证,不设置就不影响之前调用文件上传接口的实现;
 +增加SendMail函数,用于发送电子邮件,基于smtp,支持ssl模式;
 +增加upcache临时文件上传接口,与upfile类似,上传的文件保存到cache临时目录下,会被自动清除,如果配置
  文件中设置了utt上传令牌,也会进行验证;upcache接口上传的临时文件也会按日期分开保存,但自动清除时也
  是一次性清空的,需要长期保存的文件,请用upfile接口上传;
 +增加同名函数UpperCase和LowerCase,用于字母大小写转换;
 +增加同名函数QuotedStr,用于为字符串两边增加单引号,比如拼接SQL语句时使用;
 *修正数据库相关函数中,参数限死的问题,比如预设3个参数,拼接SQL时只用到2个参数,从而出错的问题;
 *修正部分函数中未完全释放对象,造成内在泄漏的问题;
 *修正进程cpu使用率计算错误的问题。


LOFTER

让兴趣,更有趣

简单随性的记录
丰富多彩的内容
让生活更加充实

下载移动端
关注最新消息