unit FaceService; interface uses Classes, SysUtils, RealICQModel; type TWaitingFace = class FCreateTicket: Cardinal; FFormID: string; FFaceMD5Code: string; FFaceID: string; public constructor Create; property FormID: string read FFormID; property FaceMD5Code: string read FFaceMD5Code; property FaceID: string read FFaceID; end; TFaceService = class private FTempFaces, FFaces, FWaitingFaces: TStringList; function GetFacePath(AMD5String: string): string; public function GetFace(AIndex: Integer): TFace; function IsSystemFace(AIndex: Integer): Boolean; function ParseToHtml(AContent, AFormID: string; var NoFoundFaces: TStringList): string; class function GetService: TFaceService; static; constructor Create; destructor Destroy; override; property Faces : TStringList read FFaces; property TempFaces : TStringList read FTempFaces; property WaitingFaces : TStringList read FWaitingFaces; end; const FaceSmallBMP: string = '_SmallBMP'; FacePreviewBMP: string = '_PreviewBMP'; FaceSmallSize: Integer = 19; FacePreviewSize: Integer = 92; SystemFaceGroup: string = '默认表情'; NOFaceCategory: string = '未分组表情'; implementation uses DirectoryService, StrUtils, Windows,RealICQUtility, Forms; var AFaceService: TFaceService; const BaseTempFaceIndex: Integer = 10000; constructor TFaceService.Create; begin FTempFaces := TStringList.Create; FFaces := TStringList.Create; FWaitingFaces := TStringList.Create; end; destructor TFaceService.Destroy; begin TRealICQUtility.FreeStringList(FTempFaces); TRealICQUtility.FreeStringList(FFaces); TRealICQUtility.FreeStringList(FWaitingFaces); inherited; end; function TFaceService.GetFace(AIndex: Integer): TFace; begin if AIndex >= BaseTempFaceIndex then Result := FTempFaces.Objects[AIndex - BaseTempFaceIndex] as TFace else Result := FFaces.Objects[AIndex] as TFace; end; class function TFaceService.GetService: TFaceService; begin if AFaceService = nil then AFaceService := TFaceService.Create; Result := AFaceService; end; function TFaceService.IsSystemFace(AIndex: Integer): Boolean; begin end; function TFaceService.GetFacePath(AMD5String: string): string; var DSearchRec: TSearchRec; FindResult: Integer; begin Result := ''; FindResult := FindFirst(TDirectoryService.GetService.GetReceivedFaceDir + AMD5String + '.*', faAnyFile, DSearchRec); while FindResult = 0 do begin if (DSearchRec.Name <> '.') and (DSearchRec.Name <> '..') then begin if AnsiSameText(ExtractFileExt(DSearchRec.Name), '.BMP') or AnsiSameText(ExtractFileExt(DSearchRec.Name), '.PNG') or AnsiSameText(ExtractFileExt(DSearchRec.Name), '.JPG') or AnsiSameText(ExtractFileExt(DSearchRec.Name), '.JPEG') or AnsiSameText(ExtractFileExt(DSearchRec.Name), '.GIF') then begin Result := TDirectoryService.GetService.GetReceivedFaceDir + ExtractFileName(DSearchRec.Name); Exit; end; end; FindResult := FindNext(DSearchRec); end; end; function TFaceService.ParseToHtml(AContent, AFormID: string; var NoFoundFaces: TStringList): string; var Face: TFace; iLoop, iStart, iCount, iIndex: Integer; MD5String: String; AWaitingFace: TWaitingFace; FaceID, AFileName, ContextMenuStr: String; begin iCount := 0; iStart := AnsiPos('[IMG:', AContent); while iStart <> 0 do begin if Copy(AContent, iStart + 37, 1) = ']' then begin MD5String := Copy(AContent, iStart + 5, 32); ContextMenuStr := 'oncontextmenu="location.href=''FaceMenu_' + MD5String + ''';return false;"'; iIndex := FFaces.IndexOf(MD5String); if iIndex >= 0 then begin Face := GetFace(iIndex); AContent := AnsiReplaceStr(AContent, Copy(AContent, iStart, 38), ''); end else if FileExists(GetFacePath(MD5String)) then begin AFileName := GetFacePath(MD5String); AContent := AnsiReplaceStr(AContent, Copy(AContent, iStart, 38), ''); end else begin FaceID := MD5String + IntToStr(GetTickCount) + IntToStr(WaitingFaces.Count) + IntToStr(iStart); AContent := Copy(AContent, 1, iStart - 1) + '' + Copy(AContent, iStart + 38, Length(AContent)); Inc(iCount); AWaitingFace := TWaitingFace.Create; AWaitingFace.FFaceMD5Code := MD5String; AWaitingFace.FFormID := AFormID; AWaitingFace.FFaceID := FaceID; FWaitingFaces.AddObject(MD5String, AWaitingFace); if NoFoundFaces <> nil then NoFoundFaces.AddObject(MD5String, AWaitingFace); end; end else begin AContent := Copy(AContent, 1, iStart - 1) + '[/IMG:' + Copy(AContent, iStart + 5, Length(AContent)); end; iStart := AnsiPos('[IMG:', AContent); end; AContent := AnsiReplaceStr(AContent, '[/IMG:', '[IMG:'); //取系统表情 for iLoop := 0 to FFaces.Count - 1 do begin Face := FFaces.Objects[iLoop] as TFace; ContextMenuStr := 'oncontextmenu="location.href=''StandardFaceMenu_' + Face.ShortCut + ''';return false;"'; AContent := AnsiReplaceStr(AContent, Face.ShortCut, ''); end; Result := AContent; end; { TWaitingFace } constructor TWaitingFace.Create; begin FCreateTicket := GetTickCount; end; initialization finalization if AFaceService <> nil then FreeAndNil(AFaceService); end.