Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2006.12.03;
Скачать: CL | DM;

Вниз

IE + data: url   Найти похожие ветки 

 
wal ©   (2006-11-13 16:27) [0]

Время от времени возникают вопросы о том, как внедрить изображения в html-документ. Для таких случаев существует URL-схема "data" (RFC2397). Предлагаю вашему вниманию реализацию для IE. Крититика приветствуется.

Cобственно проект:

library DataProtocol;

uses
 ComServ,
 DataUrlShemeImpl in "DataUrlShemeImpl.pas";

exports
 DllGetClassObject,
 DllCanUnloadNow,
 DllRegisterServer,
 DllUnregisterServer;
begin
end.

Продолжение следует.


 
wal ©   (2006-11-13 16:30) [1]

DataUrlShemeImpl.pas:

unit DataUrlShemeImpl;

{$WARN SYMBOL_PLATFORM OFF}

interface

uses
 Windows, Classes, ComObj, UrlMon;

const
 Class_DataUrlSheme: TGUID = "{83D2BD1C-AC16-4121-B888-CF2D291E5337}";

const
 QUERY_IS_SECURE = QUERY_USES_CACHE + 1;
 QUERY_IS_SAFE   = QUERY_IS_SECURE + 1;
 QUERY_USES_HISTORYFOLDER = QUERY_IS_SAFE + 1;

type

 TDataUrlSheme = class(TComObject, IInternetProtocolInfo,  IInternetProtocol)
 private
   FProtSink: IInternetProtocolSink;
   FBindInfo: IInternetBindInfo;
   FMediaType: String;
   FData:TStream;
   FPos: Cardinal;
   FSize: Cardinal;
   function ParseDataURL(Url: string): boolean;
   function DecodeData(const Data: string; const IsBase64: boolean):TStream;
 protected
 // IInternetProtocolInfo
   function ParseUrl(pwzUrl: LPCWSTR; ParseAction: TParseAction; dwParseFlags: DWORD;
     pwzResult: LPWSTR; cchResult: DWORD; pcchResult: DWORD;
     dwReserved: DWORD): HResult; stdcall;
   function CombineUrl(pwzBaseUrl, pwzRelativeUrl: LPCWSTR; dwCombineFlags: DWORD;
     pwzResult: LPWSTR; cchResult: DWORD; out pcchResult: DWORD;
     dwReserved: DWORD): HResult; stdcall;
   function CompareUrl(pwzUrl1, pwzUrl2: LPCWSTR; dwCompareFlags: DWORD): HResult; stdcall;
   function QueryInfo(pwzUrl: LPCWSTR; QueryOption: TQueryOption; dwQueryFlags: DWORD;
     pBuffer: Pointer; cbBuffer: DWORD; var cbBuf: DWORD; dwReserved: DWORD): HResult; stdcall;
 // IInternetProtocolRoot
   function Start(szUrl: LPCWSTR; OIProtSink: IInternetProtocolSink;
     OIBindInfo: IInternetBindInfo; grfPI, dwReserved: DWORD): HResult; stdcall;
   function Continue(const ProtocolData: TProtocolData): HResult; stdcall;
   function Abort(hrReason: HResult; dwOptions: DWORD): HResult; stdcall;
   function Terminate(dwOptions: DWORD): HResult; stdcall;
   function Suspend: HResult; stdcall;
   function Resume: HResult; stdcall;
 // IInternetProtocol
   function Read(pv: Pointer; cb: ULONG; out cbRead: ULONG): HResult; stdcall;
   function Seek(dlibMove: LARGE_INTEGER; dwOrigin: DWORD; out libNewPosition: ULARGE_INTEGER): HResult; stdcall;
   function LockRequest(dwOptions: DWORD): HResult; stdcall;
   function UnlockRequest: HResult; stdcall;
 end;

implementation

uses ComServ, SysUtils, StrUtils, IdCoderMime, IdUri;

{ TDataUrlSheme }

function TDataUrlSheme.ParseDataURL(Url:string): boolean;
var I, J: integer;
   Params: string;
   Shema: string;
   Data: String;
   IsBase64: Boolean;
begin
 Result:=false;
 I := Pos(":", Url);
 J := Pos(",", Url);
 if (I=0) or (J=0) or (I>=J) then
   Exit;
 Shema := LeftStr(Url, I);
 if LowerCase(Shema) <> "data:" then
   Exit;
 Inc(I);
 Params := MidStr(Url, I, J-I);
 Inc(J);
 Data := MidStr(Url, J, High(Integer));
 Params := LowerCase(Params);
 I := Pos(";base64", Params);
 IsBase64 := not(I=0);
 if IsBase64
   then FMediaType := LeftStr(Params, I-1)
   else FMediaType := Params;
 if FMediaType = "" then FMediaType := "text/plain;charset=US-ASCII";
 FPos := 0;
 try
   FData := DecodeData(Data, IsBase64);
   FSize := FData.Size;
   Result := true;
 except
   FSize := 0;
   Result := False;
 end;
end;

function TDataUrlSheme.DecodeData(const Data: string;
 const IsBase64: boolean): TStream;
var
 Src: String;
 Decoder: TIdDecoderMIME;
 I: Cardinal;
begin
 if IsBase64 then
 begin
   Src := "";
   for I := 1 to Length(Data) do
     if Data[I] in ["A".."Z", "a".."z", "0".."9", "/", "+"]
       then Src := Src+Data[I];
   while (Length(Src) mod 4) > 0 do
     Src := Src + "=";
   Result := TMemoryStream.Create;
   Decoder := TIdDecoderMIME.Create(nil);
   try
     Decoder.DecodeToStream(Src, Result);
   finally
     Decoder.Free;
   end;
 end else
 begin
    Result := TStringStream.Create(TIdURI.URLDecode(Data));
 end;
end;


 
wal ©   (2006-11-13 16:31) [2]


{ TDataUrlSheme as IInternetProtocolInfo}

function TDataUrlSheme.ParseUrl(pwzUrl: LPCWSTR; ParseAction: TParseAction;
 dwParseFlags: DWORD; pwzResult: LPWSTR; cchResult, pcchResult,
 dwReserved: DWORD): HResult;
begin
 Result := INET_E_DEFAULT_ACTION;
end;

function TDataUrlSheme.CombineUrl(pwzBaseUrl, pwzRelativeUrl: LPCWSTR;
 dwCombineFlags: DWORD; pwzResult: LPWSTR; cchResult: DWORD;
 out pcchResult: DWORD; dwReserved: DWORD): HResult;
begin
 Result := INET_E_DEFAULT_ACTION
end;

function TDataUrlSheme.CompareUrl(pwzUrl1, pwzUrl2: LPCWSTR;
 dwCompareFlags: DWORD): HResult;
begin
 Result := INET_E_DEFAULT_ACTION
end;

function TDataUrlSheme.QueryInfo(pwzUrl: LPCWSTR;
 QueryOption: TQueryOption; dwQueryFlags: DWORD; pBuffer: Pointer;
 cbBuffer: DWORD; var cbBuf: DWORD; dwReserved: DWORD): HResult;
begin
 Result := INET_E_DEFAULT_ACTION;
 case QueryOption of
   QUERY_USES_NETWORK,
   QUERY_IS_SECURE,
   QUERY_IS_SAFE,
   QUERY_USES_HISTORYFOLDER:
   begin
     cbBuf := SizeOf(LongBool);
     if cbBuffer >= cbBuf then
     begin
       LongBool(pBuffer^):=False;
       Result := S_OK;
     end else
       Result := S_FALSE;
   end;
 end;
end;


 
Курдль ©   (2006-11-13 16:31) [3]

Вау-у-у!!!


 
wal ©   (2006-11-13 16:32) [4]


{ TDataUrlSheme as IInternetProtocolRoot}

function TDataUrlSheme.Start(szUrl: LPCWSTR;
 OIProtSink: IInternetProtocolSink; OIBindInfo: IInternetBindInfo; grfPI,
 dwReserved: DWORD): HResult;
var
 Wc: array[0..255] of WideChar;
begin
 FProtSink := OIProtSink;
 FBindInfo := OIBindInfo;
 Result := S_OK;
 if ParseDataURL(szUrl) then
 begin
   StringToWideChar(FMediaType, @Wc[0], 256);
   FProtSink.ReportProgress(BINDSTATUS_MIMETYPEAVAILABLE, PWideChar(@WC));
   FProtSink.ReportData(BSCF_FIRSTDATANOTIFICATION, 0, FSize);
 end
   else Result := INET_E_DATA_NOT_AVAILABLE;
end;

function TDataUrlSheme.Continue(
 const ProtocolData: TProtocolData): HResult;
begin
 Result := S_OK
end;

function TDataUrlSheme.Abort(hrReason: HResult; dwOptions: DWORD): HResult;
begin
 Result := S_OK
end;

function TDataUrlSheme.Terminate(dwOptions: DWORD): HResult;
begin
 FProtSink := nil;
 FBindInfo := nil;
 FData.Free;
 Result := S_OK
end;

function TDataUrlSheme.Suspend: HResult;
begin
 Result := S_OK
end;

function TDataUrlSheme.Resume: HResult;
begin
 Result := S_OK
end;


 
wal ©   (2006-11-13 16:32) [5]


{ TDataUrlSheme as IInternetProtocol}

function TDataUrlSheme.Read(pv: Pointer; cb: ULONG;
 out cbRead: ULONG): HResult;
begin
 if FPos = FSize then
 begin
   Result := S_FALSE;
   Exit;
 end;
 FData.Position := FPos;
 cbRead :=  FData.Read(pv^, cb);
 FPos := FPos + cbRead;
 if FSize - FPos > 0 then
 begin
   FProtSink.ReportData(BSCF_INTERMEDIATEDATANOTIFICATION, FPos, FSize);
   Result := S_OK;
 end else
 begin
   FProtSink.ReportData(BSCF_LASTDATANOTIFICATION, FSize, FSize);
   FProtSink.ReportResult(S_OK, 0, nil);
   Result := S_FALSE;
 end;
end;

function TDataUrlSheme.Seek(dlibMove: LARGE_INTEGER; dwOrigin: DWORD;
 out libNewPosition: ULARGE_INTEGER): HResult;
begin
 Result := E_FAIL;
end;

function TDataUrlSheme.LockRequest(dwOptions: DWORD): HResult;
begin
 Result := S_OK
end;

function TDataUrlSheme.UnlockRequest: HResult;
begin
 Result := S_OK
end;

initialization
 TComObjectFactory.Create(ComServer, TDataUrlSheme, Class_DataUrlSheme,
   "DataUrlSheme", "", ciMultiInstance, tmApartment);
end.


 
wal ©   (2006-11-13 16:33) [6]

И небольшой reg

Windows Registry Editor Version 5.00

[HKEY_CLASSES_ROOT\PROTOCOLS\Handler\data]
@="data: Asychronous Pluggable Protocol Handler"
"CLSID"="{83D2BD1C-AC16-4121-B888-CF2D291E5337}"


С уважением.


 
WondeRu ©   (2006-11-14 11:11) [7]

Кинь проект в Кладовку http://kladovka.net.ru/


 
Ketmar ©   (2006-11-14 16:30) [8]

эх... жаль, что я IE не пользуюсь. %-)



Страницы: 1 вся ветка

Текущий архив: 2006.12.03;
Скачать: CL | DM;

Наверх




Память: 0.5 MB
Время: 0.039 c
5-1144670521
james25
2006-04-10 16:02
2006.12.03
создание составных компонентов


4-1153811578
Romas81
2006-07-25 11:12
2006.12.03
серийный номер винчестера (НЕ GetVolumeInformation !)


2-1163334112
Max.66RUS
2006-11-12 15:21
2006.12.03
Простейшие вопросы по текстовым файлам и строкам...


2-1163327804
lsvit
2006-11-12 13:36
2006.12.03
Работа с exe файлами


15-1163143166
Орион
2006-11-10 10:19
2006.12.03
Служба тех. поддержки американского хостинга