Форум: "Прочее";
Текущий архив: 2006.12.03;
Скачать: [xml.tar.bz2];
Вниз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;
Скачать: [xml.tar.bz2];
Память: 0.49 MB
Время: 0.04 c