Netspirit, пора тебе в майкрософт уходить дополнил тест от мелковатых Add(MainForm,16722343,329,133) { Height=615 Caption="Base64" Position=1 } Add(Edit,2817984,413,91) { Left=5 Top=10 Width=375 Text="123abcАБВг" } Add(Button,2641083,238,203) { Left=5 Top=35 Width=80 Caption="To Base64" link(onClick,11970995:doStrToBase64,[]) } Add(Edit,7077382,420,133) { Left=5 Top=60 Width=375 Text="QUJDRA==" } Add(Button,6813296,280,210) { Left=5 Top=85 Width=80 Caption="To Str" link(onClick,11970995:doBase64ToStr,[]) } Add(Edit,4532808,553,210) { Left=5 Top=110 Width=375 Text="" } Add(Button,16683581,322,217) { Left=5 Top=135 Width=95 Caption="Benchmark" link(onClick,11970995:doBenchmark,[]) } Add(InlineCode,11970995,413,203) { WorkPoints=#13:doStrToBase64|13:doBase64ToStr|11:doBenchmark|16:doStrToBase64Api|16:doBase64ToStrApi|0:| EventPoints=#13:onStrToBase64|13:onBase64ToStr|7:onError|11:onBenchmark| DataPoints=#4:dStr|10:dBase64Str| Code=#15:unit HiAsmUnit;|0:|9:interface|0:|4:uses|28: KOL, Share, Debug, Windows;|0:|5:const|26: crypt32 = 'crypt32.dll';|11: // Flags:|32: CRYPT_STRING_BASE64HEADER = 0;|58: // Base64, with certificate beginning and ending headers|26: CRYPT_STRING_BASE64 = 1;|28: // Base64, without headers|26: CRYPT_STRING_BINARY = 2;|21: // Pure binary copy|39: CRYPT_STRING_BASE64REQUESTHEADER = 3;|54: // Base64, with request beginning and ending headers|23: CRYPT_STRING_HEX = 4;|21: // Hexadecimal only|27: CRYPT_STRING_HEXASCII= 5;|46: // Hexadecimal, with ASCII character display|39: CRYPT_STRING_BASE64X509CRLHEADER = 9;|56: // Base64, with X.509 CRL beginning and ending headers|28: CRYPT_STRING_HEXADDR = 10;|38: // Hexadecimal, with address display|33: CRYPT_STRING_HEXASCIIADDR = 11;|58: // Hexadecimal, with ASCII character and address display|28: CRYPT_STRING_HEXRAW = 12; |0:|4:type|29: THiAsmClass = class(TDebug)|11: private|0:|10: public|22: dStr: THI_Event;|28: dBase64Str: THI_Event;|6: |31: onStrToBase64: THI_Event;|31: onBase64ToStr: THI_Event;|30: onBenchmark: THI_Event; |25: onError: THI_Event;|7: |61: procedure doStrToBase64(var _Data: TData; Index: Word);|61: procedure doBase64ToStr(var _Data: TData; Index: Word);|64: procedure doStrToBase64Api(var _Data: TData; Index: Word);|70: procedure doBase64ToStrApi(var _Data: TData; Index: Word); |59: procedure doBenchmark(var _Data: TData; Index: Word);|6: end;|2: |73:function ToBase64(s: string; Flags: dword = CRYPT_STRING_BASE64): string;|75:function FromBase64(s: string; Flags: dword = CRYPT_STRING_BASE64): string;|80:function CryptStringToBinary(pszString: PChar; cchString: dword; dwFlags: dword;|69: pbBinary: pointer; var pcbBinary: dword; var pdwSkip: dword;|48: var pdwFlags: dword): boolean; stdcall;|80:function CryptBinaryToString(pbBinary: pointer; cbBinary: dword; dwFlags: dword;|68: pszString: PChar; var pcchString: dword): boolean; stdcall;|81:function CryptStringToBinaryA(pszString: PChar; cchString: dword; dwFlags: dword;|69: pbBinary: pointer; var pcbBinary: dword; var pdwSkip: dword;|48: var pdwFlags: dword): boolean; stdcall;|81:function CryptBinaryToStringA(pbBinary: pointer; cbBinary: dword; dwFlags: dword;|68: pszString: PChar; var pcchString: dword): boolean; stdcall;|85:function CryptStringToBinaryW(pszString: PWideChar; cchString: dword; dwFlags: dword;|69: pbBinary: pointer; var pcbBinary: dword; var pdwSkip: dword;|48: var pdwFlags: dword): boolean; stdcall;|81:function CryptBinaryToStringW(pbBinary: pointer; cbBinary: dword; dwFlags: dword;|74: pszString: PWideChar; var pcchString: dword): boolean; stdcall; |0:|14:implementation|0:|75:function CryptStringToBinary; external crypt32 name 'CryptStringToBinaryA';|75:function CryptBinaryToString; external crypt32 name 'CryptBinaryToStringA';|76:function CryptStringToBinaryA; external crypt32 name 'CryptStringToBinaryA';|76:function CryptBinaryToStringA; external crypt32 name 'CryptBinaryToStringA';|76:function CryptStringToBinaryW; external crypt32 name 'CryptStringToBinaryW';|76:function CryptBinaryToStringW; external crypt32 name 'CryptBinaryToStringW';|0:|54:// ================ Старые функции ================ //|5:const|89: Base64ABC: string = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';|0:|73:function ToBase64(s: string; Flags: dword = CRYPT_STRING_BASE64): string;|14:var sz: dword;|5:begin|61: CryptBinaryToString(pointer(s), Length(s), Flags, nil, sz);|24: SetLength(result, sz);|73: CryptBinaryToString(pointer(s), Length(s), Flags, pointer(result), sz);|4:end;|0:|75:function FromBase64(s: string; Flags: dword = CRYPT_STRING_BASE64): string;|20:var sz, skip: dword;|5:begin|74: CryptStringToBinary(pointer(s), Length(s), Flags, nil, sz, skip, Flags);|24: SetLength(result, sz);|86: CryptStringToBinary(pointer(s), Length(s), Flags, pointer(result), sz, skip, Flags);|4:end;|0:|0:|74:function Base64_Code(const s:string):string; // standard MIME-Version: 1.0|26:var rlen,len,i:cardinal;|19: strIn:string;|5:begin|16: Result := '';|23: if s = '' then exit;|21: rlen := Length(s);|25: if rlen mod 3 = 1 then|23: strIn := s + #0#0|30: else if rlen mod 3 = 2 then|21: strIn := s + #0|19: else strIn := s;|24: len := Length(strIn);|10: i := 1;|28: while i <= len-2 do begin|62: Result := Result + Base64ABC[byte(strIn[i]) shr 2 + 1] +|97: Base64ABC[(byte(strIn[i]) and $03) shl 4 + byte(strIn[i+1]) shr 4 + 1] +|99: Base64ABC[(byte(strIn[i+1]) and $0f) shl 2 + byte(strIn[i+2]) shr 6 + 1] +|67: Base64ABC[(byte(strIn[i+2]) and $3f) + 1];|15: inc(i,3);|7: end;|25: if rlen mod 3 = 1 then|38: Result[length(result)-1] := '=';|25: if rlen mod 3 > 0 then|36: Result[length(result)] := '=';|4:end;|0:|47:function Base64_CodeNew(const s:string):string;|28:var rlen,len,i,k:cardinal;|19: strIn:string;|5:begin|16: Result := '';|23: if s = '' then exit;|21: rlen := Length(s);|25: if rlen mod 3 = 1 then|23: strIn := s + #0#0|30: else if rlen mod 3 = 2 then|21: strIn := s + #0|19: else strIn := s;|24: len := Length(strIn);|10: i := 1;|38: SetLength(Result, (len div 3) * 4);|10: k := 1;|28: while i <= len-2 do begin|59: Result[k] := Base64ABC[byte(strIn[i]) shr 2 + 1];|94: Result[k + 1] := Base64ABC[(byte(strIn[i]) and $03) shl 4 + byte(strIn[i+1]) shr 4 + 1];|96: Result[k + 2] := Base64ABC[(byte(strIn[i+1]) and $0f) shl 2 + byte(strIn[i+2]) shr 6 + 1];|65: Result[k + 3] := Base64ABC[(byte(strIn[i+2]) and $3f) + 1];|59: inc(i,3); |15: inc(k,4);|7: end;|25: if rlen mod 3 = 1 then|38: Result[length(result)-1] := '=';|25: if rlen mod 3 > 0 then|36: Result[length(result)] := '=';|4:end;|0:|76:function Base64_DeCode(const s:string):string; // standard MIME-Version: 1.0|21:var i,len:cardinal;|19: strIn:string;|0:|34: function Index(c:char):byte;|19: var i:byte;|11: begin|21: Result := 0;|30: if c = '=' then exit;|28: for i := 1 to 64 do|42: if base64ABC[i] = c then begin|31: Result := i - 1;|21: break;|16: end;|10: end;|6: |5:begin|16: Result := '';|44: if (s = '') or (length(s) < 4) then exit;|14: strIn := s;|24: len := length(strIn);|10: i := 1;|28: while i <= len-3 do begin|80: Result := Result + char(Index(strIn[i]) shl 2 + Index(strIn[i+1]) shr 4) +|92: char((Index(strIn[i+1]) and $0f) shl 4 + Index(strIn[i+2]) shr 2) +|85: char((Index(strIn[i+2]) and $03) shl 6 + Index(strIn[i+3]));|15: inc(i,4);|7: end;|29: if strIn[len-1] = '=' then|40: SetLength(Result,Length(Result)-2)|32: else if strIn[len] = '=' then|41: SetLength(Result,Length(Result)-1);|6:end; |2: |60:// ====================================================== //|60:// Реализация кодирования/декодирования данных в Base64 //|60:// Автор: Netspirit //|60:// Редакция от 01.12.2016 //|60:// ====================================================== //|2: |7:const |19: // Алфавит Base64|108: Base64Chars: array [0..63] of Char = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'; |0:|3:var|46: // Таблица индексов для декодирования Base64|40: Base64Indexes: array [0..255] of Byte;|0:|45:// Функция возвращает размер выходного буфера|66:// для заданного размера входного буфера при кодировании в Base64 |1: |64:function TextSizeForBase64Enc(const DataSize: Integer): Integer;|5:begin|27: Result := DataSize div 3;|45: if Result * 3 <> DataSize then Inc(Result);|23: Result := Result * 4;|4:end;|0:|45:// Функция возвращает размер выходного буфера|67:// для заданного размера входного буфера при декодировании в Base64|68:// Возвращает 0, если размер входного буфера некратный 4 или равен 0|2: |63:function BufSizeForBase64Dec(const TextSize: Integer): Integer;|5:begin|29: if TextSize mod 4 <> 0 then|15: Result := 0|6: else|33: Result := TextSize div 4 * 3;|4:end;|0:|59:// Процедура заполняет таблицу индексов для декодера Base64|56:// В Base64Indexes по смещению (Буква) содержится индекс|37:// этой Буквы в алфавите Base64Chars.|79:// Символы, не входящие в алфавит Base64 при заполнении будут иметь индекс 255.|75:// Ищется индекс входящего символа по таблице, символ не входящий в алфавит|41:// имеет индекс 255 и считается ошибочным|0:|32:procedure FillBase64DecodeTable;|3:var|13: I: Integer;|5:begin|57: FillChar(Base64Indexes[0], Length(Base64Indexes), 255);|36: for I := 0 to High(Base64Chars) do|45: Base64Indexes[Byte(Base64Chars[I])] := I;|4:end;|0:|49:// Преобразование в Base64 данных в буфере Buffer|38:// и занесение результата в буфер Text|0:|50:// Возвращает количество данных, записанных в Text|0:|57:// Размер Text должен быть не меньше (BufSize * 4) div 3 |0:|69:function BinToBase64(Buffer, Text: PChar; BufSize: Integer): Integer;|3:var|13: I: Integer;|13: B: Integer;|13: L: Integer;|5:begin|14: Result := 0;|9: I := 0;|27: L := (BufSize div 3) * 3;|16: while I < L do|7: begin|82: B := (Byte(Buffer[0]) shl 16) or (Byte(Buffer[1]) shl 8) or (Byte(Buffer[2]));|4: |51: Text[Result] := Base64Chars[(B shr 18) and 63];|55: Text[Result + 1] := Base64Chars[(B shr 12) and 63];|54: Text[Result + 2] := Base64Chars[(B shr 6) and 63];|46: Text[Result + 3] := Base64Chars[B and 63];|4: |19: Inc(Result, 4);|19: Inc(Buffer, 3);|14: Inc(I, 3);|6: end;|2: |75: //=====================================================================//|75: // Исходные данные нужно дополнить 0-ми до кратных 3-ом //|75: // Результирующие данные нужно дополнить символом "=" до кратных 4-ом //|75: //=====================================================================//|0:|21: I := BufSize mod 3;|16: if I <> 0 then|7: begin|62: B := Byte(Buffer[0]) shl 16; // I = 1 или 2. B = $00xx0000|94: if I = 2 then B := B or (Byte(Buffer[1]) shl 8); // I = 2 - так должно быть! B = $00xxyy00|4: |19: // I = 1 или 2:|51: Text[Result] := Base64Chars[(B shr 18) and 63];|55: Text[Result + 1] := Base64Chars[(B shr 12) and 63];|4: |17: if I = 2 then|12: begin |56: Text[Result + 2] := Base64Chars[(B shr 6) and 63];|7: end|8: else|30: Text[Result + 2] := '=';|6: |28: Text[Result + 3] := '=';|4: |36: // При I = 1 Text[0..3] = 'AB=='|36: // При I = 2 Text[0..3] = 'ABC='|4: |4: |19: Inc(Result, 4);|6: end;|4:end;|0:|0:|47:// Преобразование в оригинальный вид из Base64 |61:// данных в буфере Text и занесение результата в буфер Buffer|0:|53:// Возвращает количество данных, записанных в Buffer,|66:// или 0, если TextSize некратный 4 или недопустимый символ в Text|0:|48:// Размер Buffer не меньше (TextSize div 4) * 3 |32:// TextSize должно быть кратно 4|0:|70:function Base64ToBin(Text, Buffer: PChar; TextSize: Integer): Integer;|3:var|13: I: Integer;|23: B0, B1, B2, B3: Byte;|13: L: Integer;|5:begin|14: Result := 0;|55: if (TextSize = 0) or (TextSize mod 4 <> 0) then exit;|9: I := 0;|20: L := TextSize - 4;|16: while I < L do|7: begin|39: B0 := Base64Indexes[Byte(Text[I])];|43: B1 := Base64Indexes[Byte(Text[I + 1])];|44: B2 := Base64Indexes[Byte(Text[I + 2])]; |43: B3 := Base64Indexes[Byte(Text[I + 3])];|4: |82: if (B0 = 255) or (B1 = 255) or (B2 = 255) or (B3 = 255) // Недопустимый символ|9: then |9: begin|18: Result := 0;|11: exit;|8: end;|4: |48: Buffer[0] := Char((B0 shl 2) or (B1 shr 4));|48: Buffer[1] := Char((B1 shl 4) or (B2 shr 2));|42: Buffer[2] := Char((B2 shl 6) or (B3));|4: |19: Inc(Buffer, 3);|19: Inc(Result, 3);|14: Inc(I, 4);|6: end;|2: |67: //=============================================================//|67: // Если исходные данные оканчиваются на 1-2 символа "=", //|67: // в результирующие данные не добавляется последние 1-2 байта //|67: //=============================================================//|2: |37: B0 := Base64Indexes[Byte(Text[I])];|41: B1 := Base64Indexes[Byte(Text[I + 1])];|2: |52: if (B0 = 255) or (B1 = 255) // Недопустимый символ|7: then |7: begin|16: Result := 0;|9: exit;|6: end;|2: |46: Buffer[0] := Char((B0 shl 2) or (B1 shr 4));|14: Inc(Result);|2: |28: if Text[I + 2] <> '=' then|8: begin |43: B2 := Base64Indexes[Byte(Text[I + 2])];|40: if (B2 = 255) // Недопустимый символ|9: then |9: begin|18: Result := 0;|11: exit;|8: end;|48: Buffer[1] := Char((B1 shl 4) or (B2 shr 2));|16: Inc(Result);|4: |30: if Text[I + 3] <> '=' then|9: begin|45: B3 := Base64Indexes[Byte(Text[I + 3])];|42: if (B3 = 255) // ???????????? ??????|11: then |11: begin|20: Result := 0;|13: exit;|10: end;|44: Buffer[2] := Char((B2 shl 6) or (B3));|18: Inc(Result);|8: end;|6: end;|4:end;|0:|34:// Преобразовывает строку в Base64|46:function StrToBase64(const S: string): string;|3:var|13: L: Integer;|5:begin|17: L := Length(S);|21: if L = 0 then exit;|2: |45: SetLength(Result, TextSizeForBase64Enc(L));|46: BinToBase64(Pointer(S), Pointer(Result), L);|4:end;|0:|54:// Преобразовывает строку из Base64 в оригинальный вид|55:// Если исходная строка непустая, а результат - пустая,|32:// значит, ошибка декодирования |46:function Base64ToStr(const S: string): string;|3:var|16: L, C: Integer;|5:begin|17: L := Length(S);|71: C := BufSizeForBase64Dec(L); // Исходная строка должна быть кратной 4|21: if C = 0 then exit;|2: |51: // Чтобы избежать лишней подгонки размера строки,|48: // заранее определяем точный размер результата|32: if S[L-1] = '=' then Dec(C, 2)|33: else if S[L] = '=' then Dec(C);|2: |23: SetLength(Result, C);|51: L := Base64ToBin(Pointer(S), Pointer(Result), L);|105: if L <> C then SetLength(Result, L); // После предыдущей подгонки L <> C только в случае ошибки (L = 0)|4:end;|0:|67:procedure THiAsmClass.doStrToBase64(var _Data: TData; Index: Word);|3:var|12: S: string;|5:begin|35: S := ReadString(_Data, dStr, '');|57: _hi_CreateEvent(_Data, @onStrToBase64, StrToBase64(S));|4:end;|0:|67:procedure THiAsmClass.doBase64ToStr(var _Data: TData; Index: Word);|3:var|17: S1, S2: string;|5:begin|42: S1 := ReadString(_Data, dBase64Str, '');|24: S2 := Base64ToStr(S1);|34: if (S1 <> '') and (S2 = '') then|36: _hi_CreateEvent(_Data, @onError)|6: else|47: _hi_CreateEvent(_Data, @onBase64ToStr, S2);|4:end;|0:|70:procedure THiAsmClass.doStrToBase64Api(var _Data: TData; Index: Word);|3:var|12: S: string;|5:begin|35: S := ReadString(_Data, dStr, '');|54: _hi_CreateEvent(_Data, @onStrToBase64, ToBase64(S));|4:end;|0:|71:procedure THiAsmClass.doBase64ToStrApi(var _Data: TData; Index: Word); |3:var|17: S1, S2: string;|5:begin|42: S1 := ReadString(_Data, dBase64Str, '');|57: _hi_CreateEvent(_Data, @onBase64ToStr, FromBase64(S1));|4:end;|0:|55:function RoundTo(Number: Double; Digits: Byte): Double;|3:var|13: I: Integer;|5:begin|35: I := Trunc(IntPower(10, Digits));|34: Result := Trunc(Number * I) / I;|4:end;|0:|65:procedure THiAsmClass.doBenchmark(var _Data: TData; Index: Word);|5:const|18: StrL = 512*1024;|25: StrL2 = 100*1024*1024; |3:var|23: TC1, TC2, I: Integer;|34: R1, R2, R3, R4, R5, R6: Integer;|18: S{, S2}: string;|13: RR: Double;|5:begin|48: // Тест корректности кодирования-декодирования|21: {SetLength(S, 256);|22: for I := 0 to 255 do|22: S[I+1] := Char(I);|1: |22: for I := 1 to 256 do|7: begin|24: S2 := Copy(S, 1, I);|46: if S2 <> Base64ToStr(StrToBase64(S2)) then|95: _hi_OnEvent(onBenchmark, 'Новые функции - тест корректности ПРОВАЛЕН для L='+Int2Str(I));|6: end;|58: _hi_OnEvent(onBenchmark, 'Тест корректности завершен');}|2: |2: |0:|0:|21: SetLength(S, StrL);|2: |22: TC1 := GetTickCount;|0:|67: Base64_Code(S); // Оригинальная Base64_Code - чрезвычайно долго|2: |22: TC2 := GetTickCount;|18: R1 := TC2 - TC1;|15: //TC1 := TC2;|2: |2: |22: SetLength(S, StrL2);|29: FillChar(S[1], StrL2, '/');|2: |2: |22: TC1 := GetTickCount;|2: |2: |21: for I := 1 to 20 do|54: Base64_CodeNew(S); // Оптимизированная Base64_Code|4: |22: TC2 := GetTickCount;|18: R2 := TC2 - TC1;|13: TC1 := TC2;|2: |21: for I := 1 to 20 do|40: StrToBase64(S); // Новая StrToBase64|2: |22: TC2 := GetTickCount;|18: R3 := TC2 - TC1;|13: TC1 := TC2;|2: |21: for I := 1 to 20 do|40: Base64ToStr(S); // Новая Base64ToStr|2: |22: TC2 := GetTickCount;|18: R4 := TC2 - TC1;|16: //TC1 := TC2; |2: |0:|45://-------------------------------------------|0:|21: for I := 1 to 20 do|23: ToBase64(S); // Api|2: |22: TC2 := GetTickCount;|18: R5 := TC2 - TC1;|13: TC1 := TC2;|2: |21: for I := 1 to 20 do|25: FromBase64(S); // Api|2: |22: TC2 := GetTickCount;|18: R6 := TC2 - TC1;|16: //TC1 := TC2; |2: |42://-------------------------------------- |0:|2: |0:|18: RR := R1 / 1000;|57: _hi_OnEvent(onBenchmark, 'Оригинальная Base64_Code: ' +|38: #13#10' - объём задачи: 0.5 Мб' +|60: #13#10' - время выполнения: ' + Double2Str(RR) + ' с' +|98: #13#10' - примерная скорость: ' + Double2Str(RoundTo(StrL / 1024 / 1024 / RR, 5)) + ' МБ/с');|2: |18: RR := R2 / 1000;|64: _hi_OnEvent(onBenchmark, 'Усовершенствованная Base64_Code: ' +|39: #13#10' - объём задачи: 2000 Мб' +|60: #13#10' - время выполнения: ' + Double2Str(RR) + ' с' +|104: #13#10' - примерная скорость: ' + Double2Str(RoundTo(StrL2 * 20 / 1024 / 1024 / RR, 3)) + ' МБ/с');|4: |18: RR := R3 / 1000;|50: _hi_OnEvent(onBenchmark, 'Новая StrToBase64: ' +|39: #13#10' - объём задачи: 2000 Мб' +|60: #13#10' - время выполнения: ' + Double2Str(RR) + ' с' +|104: #13#10' - примерная скорость: ' + Double2Str(RoundTo(StrL2 * 20 / 1024 / 1024 / RR, 3)) + ' МБ/с');|4: |18: RR := R4 / 1000;|50: _hi_OnEvent(onBenchmark, 'Новая Base64ToStr: ' +|39: #13#10' - объём задачи: 2000 Мб' +|60: #13#10' - время выполнения: ' + Double2Str(RR) + ' с' +|107: #13#10' - примерная скорость: ' + Double2Str(RoundTo(StrL2 * 20 / 1024 / 1024 / RR, 3)) + ' МБ/с'); |0:|18: RR := R5 / 1000;|48: _hi_OnEvent(onBenchmark, 'API StrToBase64: ' +|39: #13#10' - объём задачи: 2000 Мб' +|60: #13#10' - время выполнения: ' + Double2Str(RR) + ' с' +|107: #13#10' - примерная скорость: ' + Double2Str(RoundTo(StrL2 * 20 / 1024 / 1024 / RR, 3)) + ' МБ/с'); |0:|18: RR := R6 / 1000;|48: _hi_OnEvent(onBenchmark, 'API Base64ToStr: ' +|39: #13#10' - объём задачи: 2000 Мб' +|60: #13#10' - время выполнения: ' + Double2Str(RR) + ' с' +|107: #13#10' - примерная скорость: ' + Double2Str(RoundTo(StrL2 * 20 / 1024 / 1024 / RR, 3)) + ' МБ/с'); |0:|0:|0:|4:end;|0:|0:|14:initialization|24: FillBase64DecodeTable;|0:|0:|4:end.| link(onStrToBase64,7077382:doText,[(466,209)(466,185)(408,185)(408,139)]) link(onBase64ToStr,4532808:doText,[]) link(onError,5410225:doMessage,[]) link(onBenchmark,14440732:doAdd,[]) link(dStr,2817984:Text,[]) link(dBase64Str,7077382:Text,[]) } Add(Message,5410225,511,217) { Message="Ошибка декодирования" Caption="Error" Icon=3 } Add(Memo,14440732,476,224) { Left=5 Top=160 Width=375 Height=350 ScrollBars=2 } Add(Button,10049184,324,267) { Left=5 Top=520 Width=120 Caption="To Base64 API" link(onClick,11970995:doStrToBase64Api,[(384,273)(384,230)]) } Add(Button,4155309,322,315) { Left=5 Top=550 Width=120 Caption="To Str API" link(onClick,11970995:doBase64ToStrApi,[(395,321)(395,237)]) }
Редактировалось 3 раз(а), последний 2018-06-28 20:21:44
|