Eigener Cursor will nicht...:-(

Für Fragen von Einsteigern und Programmieranfängern...
Antworten
LazGreenhorn
Beiträge: 7
Registriert: Do 7. Feb 2013, 20:01

Eigener Cursor will nicht...:-(

Beitrag von LazGreenhorn »

Hallo!
Mal wieder eine Frage.
Ich möchte für mein Projekt an einer bestimmten Stelle einen eigenen Mauszeiger verwenden. Nun bin ich aber gerade am verzweifeln...

Code: Alles auswählen

procedure TfmHauptmenue.FormCreate(Sender: TObject);
begin
  Screen.Cursors[crCursor]:= LoadCursor(HInstance, 'Cursor.cur');
  Screen.Cursors[crCursorClicked]:= LoadCursor(HInstance, 'CursorClicked.cur');
end;
 
procedure TfmHauptmenue.FormShow(Sender: TObject);
begin
  Screen.Cursor:= crCursor;
end;  
So hab ich mir das aus diversen Quellen zusammengebastelt. Außerdem verwende ich noch

Code: Alles auswählen

{$R Cursors.res}
am Anfang unter "implementation".
Trotzdem bekomme ich nach dem Kompilieren jedes mal die Nachricht:

Code: Alles auswählen

[TCustomIcon.LoadFromResourceName] The resource "Cursor.cur" was not found.
Muss ich da noch irgendwo den Pfad zu der *.res Datei angeben, wenn ja, wo? Oder ist meine *.res Datei falsch aufgebaut (Habe sie mit XN Resource Editor erstellt)?
Ich bin echt am Verzweifeln... :(

Benutzeravatar
theo
Beiträge: 10884
Registriert: Mo 11. Sep 2006, 19:01

Re: Eigener Cursor will nicht...:-(

Beitrag von theo »

Ich weiss nicht, ob das der beste Weg ist, aber im Verzeichnis <lazarus>/examples/cursors gibt es ein Beispiel.

Die lrs Datei kann man wahrsch. damit erstellen: http://git.altlinux.org/gears/l/lazarus ... 4d7;sf=tgz

Es gibt bestimmt andere Wege.

Thomas B.
Beiträge: 90
Registriert: Fr 2. Nov 2007, 13:32
OS, Lazarus, FPC: Win (L 1.0 FPC 2.6.0)
CPU-Target: 32Bit
Wohnort: Ulm

Re: Eigener Cursor will nicht...:-(

Beitrag von Thomas B. »

ich habe auf die schnelle nur eine Beschreibung auf Englisch gefunden
http://www.lazarus.freepascal.org/index ... ic=14866.0

Michl
Beiträge: 2511
Registriert: Di 19. Jun 2012, 12:54

Re: Eigener Cursor will nicht...:-(

Beitrag von Michl »

Hab Dir mal was zusammengebaut ... siehe Beispiel von ...Lazarus\Examples\Cursor\Prjekt1

Code: Alles auswählen

function LoadCursorFromIcon(AIcon: String): HCursor;
var
  CursorImage:TCursorImage;
begin
  CursorImage := TCursorImage.Create;
  try
    CursorImage.LoadFromFile(AIcon);
    Result := CursorImage.ReleaseHandle;
  finally
    CursorImage.Free;
  end;
end;
 
procedure TForm1.FormCreate(Sender: TObject);
begin
  Screen.Cursors[1]:=LoadCursorFromIcon('c:\1\brown.ico');  //Hier Deinen ICON einfügen
  Screen.Cursor:=1;
 
{
Wenn kein eigener ICON, können auch ganz einfach die vordefinierten TCursors genommen werden
 
crHigh        = TCursor(0);
 
crDefault     = TCursor(0);
crNone        = TCursor(-1);
crArrow       = TCursor(-2);
crCross       = TCursor(-3);
crIBeam       = TCursor(-4);
crSize        = TCursor(-22);
crSizeNESW    = TCursor(-6); // diagonal north east - south west
crSizeNS      = TCursor(-7);
crSizeNWSE    = TCursor(-8);
crSizeWE      = TCursor(-9);
crSizeNW      = TCursor(-23);
crSizeN       = TCursor(-24);
crSizeNE      = TCursor(-25);
crSizeW       = TCursor(-26);
crSizeE       = TCursor(-27);
crSizeSW      = TCursor(-28);
crSizeS       = TCursor(-29);
crSizeSE      = TCursor(-30);
crUpArrow     = TCursor(-10);
crHourGlass   = TCursor(-11);
crDrag        = TCursor(-12);
crNoDrop      = TCursor(-13);
crHSplit      = TCursor(-14);
crVSplit      = TCursor(-15);
crMultiDrag   = TCursor(-16);
crSQLWait     = TCursor(-17);
crNo          = TCursor(-18);
crAppStart    = TCursor(-19);
crHelp        = TCursor(-20);
crHandPoint   = TCursor(-21);
crSizeAll     = TCursor(-22);
 
crLow         = TCursor(-30);
}
 
end;                                 
gutes Gelingen!
Michl

Code: Alles auswählen

type
  TLiveSelection = (lsMoney, lsChilds, lsTime);
  TLive = Array[0..1] of TLiveSelection;  

Komoluna
Beiträge: 565
Registriert: So 26. Aug 2012, 09:03
OS, Lazarus, FPC: Windows(10), Linux(Arch)
CPU-Target: 64Bit

Re: Eigener Cursor will nicht...:-(

Beitrag von Komoluna »

wie kann ich eine Animierte Cursordatei(*.ani) laden?
wenn ich das auf dem selben weg, wie mit dem normalen cursor versuche, dann kommt immer eine Fehlermeldung:

Code: Alles auswählen

TCursorImage: Unsupported Cursor File: ANI
wie muss ich das machen? oder muss ich die Datei vorher noch in ein anderes Format konvertieren?

MFG
Komoluna
Programmer: A device to convert coffee into software.

Rekursion: siehe Rekursion.

Michl
Beiträge: 2511
Registriert: Di 19. Jun 2012, 12:54

Re: Eigener Cursor will nicht...:-(

Beitrag von Michl »

Habs mal getestet (eine .ani hab ich nicht nehmen können, ein animiertes .gif geht aber) :

Lösung1, die funktioniert: lade deine animierte Datei in ein Grafikprogramm deiner Wahl (Gimp) und speicher die einzelnen Icons. Lade sie alle nacheinander beim Starten und änder diese mittels eines Timers (siehe unten).

Lösung2, die funktioniert: (Cursor unsichtbar machen, an diese Stelle, wo sich die Maus befindet das animierte Bild zeichnen): Leere Form, Timer drauf, Package BGRABitmap (http://wiki.freepascal.org/BGRABitmap/de) installieren (http://sourceforge.net/projects/lazpaint/files/src/)

Code: Alles auswählen

unit Unit1;
 
{$mode objfpc}{$H+}
 
interface
 
uses
  SysUtils, Forms, Controls, Graphics, Classes, LCLintf, ExtCtrls, BGRAAnimatedGif;
 
type
 
  { TForm1 }
 
  TForm1 = class(TForm)
    Timer1: TTimer;                             //Timer zum Neuzeichnen der Form (Intervall=50)
    procedure FormCreate(Sender: TObject);
    procedure FormPaint(Sender: TObject);
    procedure Timer1Timer(Sender: TObject);
  private
    AniGif:TBGRAAnimatedGif;                    //Animiertes Gif
    { private declarations }
  public
    { public declarations }
  end;
 
var
  Form1: TForm1;
 
implementation
 
{$R *.lfm}
 
{ TForm1 }
 
procedure TForm1.FormCreate(Sender: TObject);
begin
  AniGif:=TBGRAAnimatedGif.Create('maus-ani.gif');  //Das animierte Gif wird geladen
  Screen.Cursor:=-1;                            //Cursor unsichtbar;
end;
 
procedure TForm1.FormPaint(Sender: TObject);    //Beim Zeichen der Form animiertes Bild an Mauskoordinaten zeichnen
var
  Rect:TRect;
  p:TPoint;
begin
  getcursorpos(p);
 
  p:=ScreenToClient(p);
 
  Rect.Left:=p.x;
  Rect.Top:=p.y;
  Rect.Right:=p.x+AniGif.Width;
  Rect.Bottom:=p.y+AniGif.Height;
 
  AniGif.Show(Canvas,Rect);
end;
 
procedure TForm1.Timer1Timer(Sender: TObject);  //Timer zum Neuzeichnen der Form (Intervall=50)
begin
  Refresh;
end;
 
end.
Lösung3, die teilweise funktioniert (Transparenz konnte ich nicht setzen, evtl. hat da noch jemand eine Idee??): Leere Form, Timer drauf, Package BGRABitmap (http://wiki.freepascal.org/BGRABitmap/de) installieren (http://sourceforge.net/projects/lazpaint/files/src/)

Code: Alles auswählen

unit Unit1;
 
{$mode objfpc}{$H+}
 
interface
 
uses
  SysUtils, Forms, Controls, Graphics, Classes, ExtCtrls, BGRAAnimatedGif;
 
type
 
  { TForm1 }
 
  TForm1 = class(TForm)
    Timer1: TTimer;                             //Timer zum ständigen Tausch des Cursors (Intervall=50)
    procedure FormCreate(Sender: TObject);
    procedure Timer1Timer(Sender: TObject);
  private
    AniGif:TBGRAAnimatedGif;                    //Animiertes Gif
    procedure SpeicherIcons;                    //Animiertes Gif in Icons speichern
    { private declarations }
  public
    { public declarations }
  end;
 
var
  Form1: TForm1;
 
implementation
 
{$R *.lfm}
 
{ TForm1 }
 
procedure TForm1.SpeicherIcons;                 //Animiertes Gif in Icons speichern
 
var
  AIcon:TIcon;                                  //Icon zum Speichern
  ABitmap:TBitmap;                              //Bitmap, auf dem die einzelnen Bilder des Animierten Gifs gespchert werden
  CursorImage:TCursorImage;
  ImageList:TImageList;                         //Imagelist stellt "masked" zur Verfügung, um Icons zu erstellen
  Stream:TMemoryStream;
  i:integer;
begin
  AniGif:=TBGRAAnimatedGif.Create('maus-ani.gif');  //Das animierte Gif wird geladen
 
  for i:=0 to AniGif.Count-1 do begin           //alle Bilder des animierten Gifs speichern
 
    ABitmap:=TBitmap.Create;
    AIcon:=TIcon.Create;
    CursorImage:=TCursorImage.Create;
    Stream:=TMemoryStream.Create;
 
    try
 
      AniGif.CurrentImage:=i;                   //nacheinander die einzelnen Bilder aufrufen
      ABitmap.Width:=AniGif.Width;              //Bitmap bekommt die Größe des Bitmaps vom animierten Gif
      ABitmap.Height:=AniGif.Height;
      ABitmap.Canvas.Brush.Color:=$000000;      //Hintergrund füllen
      ABitmap.Canvas.FillRect(0,0,ABitmap.Width,ABitmap.Height);
//      ABitmap.TransparentColor:=$000000;
//      ABitmap.Transparent:=true;
//      AniGif.Transparent:=true;
 
      AniGif.Show(ABitmap.Canvas,ABitmap.Canvas.ClipRect);  //Kopieren des aktuell sichtbaren Bitmaps des animierten Gifs auf Speicher-Bitmap
 
      ImageList:=TImageList.CreateSize(ABitmap.Width, ABitmap.Height);  //einzigste Möglichkeit, die ich gefunden habe, ein Bild zu einem Icon zu konvertieren
      ImageList.GetIcon(ImageList.AddMasked(ABitmap, ABitmap.Canvas.Pixels[1, 1]), AIcon);
 
      Stream.Clear;                             //jetzt noch die Zuweisung der einzelnen Icons in Speicher
      AIcon.SaveToStream(Stream);
      Stream.Position:=0;
      CursorImage.LoadFromStream(Stream);
 
//      AIcon.SaveToFile('Ani'+inttostr(i)+'.ico');
//      CursorImage.LoadFromFile('Ani'+inttostr(i)+'.ico');
 
      Screen.Cursors[i+1]:=CursorImage.ReleaseHandle;
 
    finally
 
      ImageList.Free;
      Stream.Free;
      CursorImage.Free;
      AIcon.Free;
      ABitmap.Free;
 
    end;
  end;
end;
 
procedure TForm1.FormCreate(Sender: TObject);
begin
  SpeicherIcons;
end;
 
procedure TForm1.Timer1Timer(Sender: TObject);  //Timer zum ständigen Tausch des Cursors (Intervall=50)
const
  CursorNr:integer=1;
begin
  if CursorNr=AniGif.Count then CursorNr:=1
                           else inc(CursorNr);
  Screen.Cursor:=CursorNr;
end;
 
end.                          
 
Viel Erfolg!

Code: Alles auswählen

type
  TLiveSelection = (lsMoney, lsChilds, lsTime);
  TLive = Array[0..1] of TLiveSelection;  

Antworten