mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-04-05 16:37:54 +02:00
218 lines
5.8 KiB
PHP
218 lines
5.8 KiB
PHP
{%MainUnit ../graphics.pp}
|
|
|
|
{******************************************************************************
|
|
TCursorImage
|
|
******************************************************************************
|
|
|
|
*****************************************************************************
|
|
This file is part of the Lazarus Component Library (LCL)
|
|
|
|
See the file COPYING.modifiedLGPL.txt, included in this distribution,
|
|
for details about the license.
|
|
*****************************************************************************
|
|
}
|
|
const
|
|
CursorSignature: array [0..3] of Byte = (0, 0, 2, 0);
|
|
|
|
function TestStreamIsCursor(const AStream: TStream): boolean;
|
|
var
|
|
Signature: array[0..3] of char;
|
|
ReadSize: Integer;
|
|
OldPosition: TStreamSeekType;
|
|
begin
|
|
OldPosition:=AStream.Position;
|
|
ReadSize:=AStream.Read(Signature, SizeOf(Signature));
|
|
Result:=(ReadSize=SizeOf(Signature)) and CompareMem(@Signature,@CursorSignature,4);
|
|
AStream.Position:=OldPosition;
|
|
end;
|
|
|
|
{ TSharedCursorImage }
|
|
|
|
procedure TSharedCursorImage.FreeHandle;
|
|
begin
|
|
if FHandle = 0 then Exit;
|
|
|
|
DestroyCursor(FHandle);
|
|
FHandle := 0;
|
|
end;
|
|
|
|
class function TSharedCursorImage.GetImagesClass: TIconImageClass;
|
|
begin
|
|
Result := TCursorImageImage;
|
|
end;
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
{ TCursorImage }
|
|
|
|
class function TCursorImage.GetFileExtensions: string;
|
|
begin
|
|
Result := 'cur';
|
|
end;
|
|
|
|
function TCursorImage.GetResourceType: TResourceType;
|
|
begin
|
|
Result := RT_GROUP_CURSOR;
|
|
end;
|
|
|
|
procedure TCursorImage.LoadFromResourceHandle(Instance: TLCLHandle; ResHandle: TFPResourceHandle);
|
|
var
|
|
GlobalHandle: TFPResourceHGlobal;
|
|
Dir: PNewHeader;
|
|
DirEntry: PGrpCursorDirEntry;
|
|
IconEntry: TIconDirEntry;
|
|
LocalHeader: TLocalHeader;
|
|
i, offset: integer;
|
|
Stream: TMemoryStream;
|
|
CursorStream: TResourceStream;
|
|
ResourceStreams: TObjectList;
|
|
begin
|
|
// build a usual cur stream using several RT_CURSOR resources
|
|
GlobalHandle := LoadResource(Instance, ResHandle);
|
|
if GlobalHandle = 0 then
|
|
Exit;
|
|
Dir := LockResource(GlobalHandle);
|
|
if Dir = nil then
|
|
Exit;
|
|
|
|
Stream := TMemoryStream.Create;
|
|
try
|
|
// write cursor header
|
|
Stream.Write(Dir^, SizeOf(TIconHeader));
|
|
// write cursor entries headers
|
|
ResourceStreams := TObjectList.Create(True);
|
|
try
|
|
offset := Stream.Position + SizeOf(IconEntry) * LEtoN(Dir^.idCount);
|
|
DirEntry := PGrpCursorDirEntry(PChar(Dir) + SizeOf(Dir^));
|
|
for i := 0 to LEtoN(Dir^.idCount) - 1 do
|
|
begin
|
|
CursorStream := TResourceStream.CreateFromID(Instance, LEtoN(DirEntry^.nID), RT_CURSOR);
|
|
ResourceStreams.Add(CursorStream);
|
|
|
|
// hot spots are stored in the local header of cursor
|
|
CursorStream.Read(LocalHeader, SizeOf(LocalHeader));
|
|
|
|
IconEntry.bWidth := Byte(DirEntry^.wWidth);
|
|
IconEntry.bHeight := Byte(DirEntry^.wHeight) div 2; // in cursor resource the height is doubled
|
|
IconEntry.bColorCount := 0;
|
|
IconEntry.bReserved := 0;
|
|
IconEntry.wXHotSpot := LocalHeader.xHotSpot;
|
|
IconEntry.wYHotSpot := LocalHeader.yHotSpot;
|
|
IconEntry.dwImageOffset := NtoLE(offset);
|
|
IconEntry.dwBytesInRes := DirEntry^.dwBytesInRes - SizeOf(LocalHeader);
|
|
inc(offset, LEtoN(IconEntry.dwBytesInRes));
|
|
Stream.Write(IconEntry, SizeOf(IconEntry));
|
|
Inc(DirEntry);
|
|
end;
|
|
// write cursors data
|
|
for i := 0 to ResourceStreams.Count - 1 do
|
|
begin
|
|
CursorStream := TResourceStream(ResourceStreams[i]);
|
|
Stream.CopyFrom(CursorStream, CursorStream.Size - CursorStream.Position);
|
|
end;
|
|
finally
|
|
ResourceStreams.Free;
|
|
end;
|
|
Stream.Position := 0;
|
|
ReadData(Stream);
|
|
finally
|
|
Stream.Free;
|
|
UnLockResource(GlobalHandle);
|
|
FreeResource(GlobalHandle);
|
|
end;
|
|
end;
|
|
|
|
class function TCursorImage.GetSharedImageClass: TSharedRasterImageClass;
|
|
begin
|
|
Result := TSharedCursorImage;
|
|
end;
|
|
|
|
class function TCursorImage.GetTypeID: Word;
|
|
begin
|
|
Result := 2;
|
|
end;
|
|
|
|
function TCursorImage.LazarusResourceTypeValid(const ResourceType: string): boolean;
|
|
var
|
|
ResType: String;
|
|
begin
|
|
if Length(ResourceType) < 3 then Exit(False);
|
|
|
|
ResType := UpperCase(ResourceType);
|
|
case ResType[1] of
|
|
'C': begin
|
|
Result := (ResType = 'CUR') or (ResType = 'CURSOR');
|
|
end;
|
|
else
|
|
Result := inherited LazarusResourceTypeValid(ResType);
|
|
end;
|
|
end;
|
|
|
|
function TCursorImage.ReleaseHandle: HCURSOR;
|
|
begin
|
|
HandleNeeded;
|
|
Result := FSharedImage.ReleaseHandle;
|
|
end;
|
|
|
|
function TCursorImage.GetCursorHandle: HCURSOR;
|
|
begin
|
|
Result := GetHandle;
|
|
end;
|
|
|
|
procedure TCursorImage.SetCursorHandle(AValue: HCURSOR);
|
|
begin
|
|
SetHandle(AValue);
|
|
end;
|
|
|
|
function TCursorImage.GetHotSpot: TPoint;
|
|
begin
|
|
if FCurrent = -1
|
|
then Result := Point(0, 0)
|
|
else Result := TCursorImageImage(TSharedCursorImage(FSharedImage).FImages[FCurrent]).HotSpot;
|
|
end;
|
|
|
|
procedure TCursorImage.SetHotSpot(const P: TPoint);
|
|
begin
|
|
if FCurrent >= 0 then
|
|
TCursorImageImage(TSharedCursorImage(FSharedImage).FImages[FCurrent]).HotSpot := P;
|
|
end;
|
|
|
|
procedure TCursorImage.SetCenterHotSpot;
|
|
var
|
|
AImage: TCursorImageImage;
|
|
begin
|
|
if FCurrent >= 0 then
|
|
begin
|
|
AImage := TCursorImageImage(TSharedCursorImage(FSharedImage).FImages[FCurrent]);
|
|
AImage.HotSpot := Point(AImage.Width div 2, AImage.Height div 2);
|
|
end;
|
|
end;
|
|
|
|
procedure TCursorImage.HandleNeeded;
|
|
var
|
|
IconInfo: TIconInfo;
|
|
h: TPoint;
|
|
begin
|
|
if FSharedImage.FHandle <> 0 then Exit;
|
|
|
|
IconInfo.fIcon := False;
|
|
H := HotSpot;
|
|
IconInfo.xHotspot := H.X;
|
|
IconInfo.yHotSpot := H.Y;
|
|
IconInfo.hbmMask := MaskHandle;
|
|
IconInfo.hbmColor := BitmapHandle;
|
|
FSharedImage.FHandle := WidgetSet.CreateIconIndirect(@IconInfo);
|
|
end;
|
|
|
|
class function TCursorImage.GetDefaultSize: TSize;
|
|
begin
|
|
Result := Size(GetSystemMetrics(SM_CXCURSOR), GetSystemMetrics(SM_CYCURSOR));
|
|
end;
|
|
|
|
class function TCursorImage.GetStreamSignature: Cardinal;
|
|
begin
|
|
Result := Cardinal(CursorSignature);
|
|
end;
|
|
|
|
|