Autor Beitrag
idefix123456
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 23



BeitragVerfasst: Mo 30.08.10 18:37 
Hallo,

Ich versuche eine einfache procedur zu erstellen um ein mouseover bei bildern zu realisieren!
Bisher habe ich folgenden Code erstellt!

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
procedure TForm1.imgOnChange(Sender: TObject; Shift: TShiftState; X, Y: Integer);
begin
  img_change(TImage(Sender).Name, TImage(Sender).Hint);
end;

procedure img_OnMove_change(NAME, str: string);
begin
  TImage(Form1.FindComponent(NAME)).Hint := str;
  TImage(Form1.FindComponent(NAME)).OnMouseMove := Form1.imgOnChange;
end;


ich rufe die procedure so auf:

ausblenden Delphi-Quelltext
1:
img_OnMove_change('BILDNAME''left:20; path:neuesbild.bmp');					


Das ganze ist so gedacht, setze ich img_OnMove_change(), dann wird beim bild der Abstand vom Linken Rand auf 20px gesetzt, und das bisherige bild durch neuesbild.bmp ersetzt. Das klappt auch soweit!

Jedoch bleibt das dann so. Ich möchte jedoch, das beim verlassen des Bildes wieder alles so wie zuvor gesetzt wird quasi so (kommentare):

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
procedure TForm1.imgOnChange(Sender: TObject; Shift: TShiftState; X, Y: Integer);
begin
  img_change(TImage(Sender).Name, TImage(Sender).Hint);
end;

procedure img_OnMove_change(NAME, str: string);
begin

  // Lese hier alle bildeigenschaften aus und schreibe in globale Variable

  // if Mauszeiger über bild then begin

  TImage(Form1.FindComponent(NAME)).Hint := str;
  TImage(Form1.FindComponent(NAME)).OnMouseMove := Form1.imgOnChange;

  // end else begin    // Mauszeiger nichtmehr auf bild

  // img_change(NAME, Vorheriger Bildeigenschaft aus globaler Variable);

  // end;

end;


Das Problem ist, ich finde einfach keine Lösung dafür Die Bildeigenschaften wieder zurück zu setzen


Moderiert von user profile iconNarses: Topic aus Delphi Language (Object-Pascal) / CLX verschoben am Mo 30.08.2010 um 22:12
Xion
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
EE-Maler
Beiträge: 1952
Erhaltene Danke: 128

Windows XP
Delphi (2005, SmartInspect), SQL, Lua, Java (Eclipse), C++ (Visual Studio 2010, Qt Creator), Python (Blender), Prolog (SWIProlog), Haskell (ghci)
BeitragVerfasst: Mo 30.08.10 22:03 
user profile iconidefix123456 hat folgendes geschrieben Zum zitierten Posting springen:
Ich versuche eine einfache procedur zu erstellen um ein mouseover bei bildern zu realisieren!

www.delphi-forum.de/...p;highlight=advimage

In diesem Post hab ich weiter unten die Klasse TAdvImage gepostet, die kann das. Du musst sie halt dynamisch erstellen.

user profile iconidefix123456 hat folgendes geschrieben Zum zitierten Posting springen:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
procedure TForm1.imgOnChange(Sender: TObject; Shift: TShiftState; X, Y: Integer);
begin
  img_change(TImage(Sender).Name, TImage(Sender).Hint);
end;

procedure img_OnMove_change(NAME, str: string);
begin
  TImage(Form1.FindComponent(NAME)).Hint := str;
  TImage(Form1.FindComponent(NAME)).OnMouseMove := Form1.imgOnChange;
end;

Wenn du der procedure img_OnMove_Change gleich Sender: TImage übergibst sparst du dir das langsame FindComponent.


Deinen "Lückentext" mal ausgefüllt:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
procedure TForm1.imgOnChange(Sender: TObject; Shift: TShiftState; X, Y: Integer);
begin
  img_change(TImage(Sender).Name, TImage(Sender).Hint);
end;

procedure img_OnMove_change(NAME, str: string);
begin

  // Lese hier alle bildeigenschaften aus und schreibe in globale Variable
  storageHint:='left:'+inttostr(TImage(Form1.FindComponent(NAME)).Left)+'; path:'+TImage(Form1.FindComponent(NAME)).FileName;

  // if Mauszeiger über bild then begin
  // Mauszeiger: Mouse.CursorPos, PtInRect gibts da auch als Vereinfachung


  TImage(Form1.FindComponent(NAME)).Hint := str;
  TImage(Form1.FindComponent(NAME)).OnMouseMove := Form1.imgOnChange;

  // end else begin    // Mauszeiger nichtmehr auf bild

      img_change(NAME, storageHint);

  // end;

end;


Das ist natürlich...öhm...etwas seltsam.

Besser:

TImageInfo=record
Path: String;
Left: integer;
end;

verwenden, dann musst du nicht die Informationen wieder aus dem Hint rausparsen. Außerdem würde ich nicht jedesmal wieder neu FindComponent aufrufen (wenn du das schon verwendest) sondern nur einmal und die Referenz die du bekommst in ne lokale Variable schreiben.

_________________
a broken heart is like a broken window - it'll never heal
In einem gut regierten Land ist Armut eine Schande, in einem schlecht regierten Reichtum. (Konfuzius)
idefix123456 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 23



BeitragVerfasst: Di 31.08.10 16:01 
Hallo,

Danke für deine Antwort, leider hat das ganze von dir nicht funktioniert. Vieleicht hab ich mich auch falsch ausgedrückt. Aufjedenfall bin ich jetzt schon ein kleines stück weiter...

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
type
  TForm1 = class(TForm)
    procedure CMMouseLeave(var Message: TMessage); message CM_MOUSELEAVE;
    procedure imgOnChange(Sender: TObject; Shift: TShiftState; X, Y: Integer);
...


...
procedure TForm1.CMMouseLeave(var Message: TMessage);
begin
  TImage(Form1.FindComponent('TESTimg')).Visible := true;
end;

procedure TForm1.imgOnChange(Sender: TObject; Shift: TShiftState; X, Y: Integer);
begin
  TImage(Form1.FindComponent('TESTimg')).Visible := false;
  //img_change(TImage(Sender).Name, TImage(Sender).Hint); -> Zum Testen Als Kommentar gesetzt
end;

procedure img_OnMove_change(NAME, str: string);
begin
  TImage(Form1.FindComponent(NAME)).Hint := str;
  TImage(Form1.FindComponent(NAME)).OnMouseMove := Form1.imgOnChange;
end;
...


...
img_OnMove_change('TESTimg''left:20; path:neuesbild.bmp');


Das bild wird jetzt erstmal zum Testen einfach nur Ausgeblendet!!!

Funtkionsweise Bisher... Das bild wird Dynamisch geladen und Angezeigt. Procedure img_OnMove_cnange wird gestertet... Daraufhin soll das Bild mit einem Rollover Effekt versehen werden. Das Funktioniert so: Fahre ich mit der Maus über das Bild (d.h. Mauszeiger befindet sich irgendwo auf dem Bild), dann wird das Bild Jetzt erstmal Testweise ausgeblendet! Fahre ich mit dem Mauszeiger wieder vom Bild runter, soll es wieder eingeblendet werden! Also Quasi ein Rollover Bild!
Ich habe jetzt die procedure CMMouseLeave hinzugefügt. Jedoch wird das bild nicht eingeblendet wenn ich dieses mit dem mauszeiger verlasse, sondern es wird erst Eingeblendet, sobald ich das Fenter (TForm1 Fenster) mit dem Mauszeiger verlasse!

Ich vermute es liegt daran, das CMMouseLeave auf das TForm1 bezieht, also sobald ich Form verlasse, Startet er die procedure und blendet das Bild wieder ein!

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
...

// bezieht sich auf TForm1
procedure TForm1.CMMouseLeave(var Message: TMessage);
...


Das ganze soll ich auf des Bild beziehen, jedoch weis ich nicht genau wie man das macht. Etwa so:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
...
// Soll sich auf das bild 'TESTimg' beziehen also irgendwie so!?
procedure TImage(Form1.FindComponent('TESTimg')).CMMouseLeave(var Message: TMessage);

// Klappt jedoch nicht!
// Ich weis nicht genau was man da eintragen muss damit es sich auf das Bild bezieht!!!


begin
...



Kenne mich mit Delphi nochnicht so gut aus, habe es ausgewählt, weil es mir einfacher als C++ vorkommt. Aber dieses Problem ist schon etwas Nervenzerreisend. Weil bei google find ich auch nix. Arbeite auchnoch nicht lange mit Delphi ca. 3 Monate, hab zuvor nur mit PHP Programmiert!


Ich hoffe ihr könnt mir helfen???

Danke
bummi
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 1248
Erhaltene Danke: 187

XP - Server 2008R2
D2 - Delphi XE
BeitragVerfasst: Di 31.08.10 19:20 
vielleicht kannst Du damit was anfangen, es als Basis nehmen...
Du muß die Komponente nicht registrieren, sondern kannst sie auch dynamisch verwenden...

Aufruf:
ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
unit Unit5;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ImgList;

type
  TForm5 = class(TForm)
    ImageList1: TImageList;
    procedure FormCreate(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  Form5: TForm5;

implementation
uses Rollover;
{$R *.dfm}

procedure TForm5.FormCreate(Sender: TObject);
begin
    With TRollover.Create(Self) do
      begin
        Left := 10;
        Top  := 10;
        Width := 32;
        Height := 32;
        Imagelist := ImageList1;
        Parent := self;
      end;
end;

end.




Komponente

ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
114:
115:
116:
117:
118:
119:
120:
121:
122:
123:
124:
125:
126:
127:
128:
129:
130:
131:
132:
133:
134:
135:
136:
137:
138:
139:
140:
141:
142:
unit Rollover;

interface
uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
           ExtCtrls,StdCtrls,Dialogs,ADODB;
type
TRollOver=Class(TGraphicControl)
  private
    FmouseDown : Boolean;
    FMouseIn   : Boolean;
    FimageList:TimageList;
    FOffSetPoint: TPoint;
    FX,FY:Integer;
    procedure WMLButtonDown(var Message: TWMLButtonDown); message WM_LBUTTONDOWN;
    procedure WMLButtonUp(var Message: TWMLButtonUp); message WM_LBUTTONUP;
    procedure WMMouseMove(var Message: TWMMouseMove); message WM_MOUSEMOVE;
    procedure CMMouseLeave(var Message: TMessage); message CM_MOUSELEAVE;
    procedure CMMouseEnter(var Message: TMessage); message CM_MOUSEEnter;
    procedure SetImageList(const Value: TImageList);


    function CalcCursorPos: TPoint;

    Protected
    procedure Paint; override;
    Public
    Constructor Create(AOwner:TComponent);override;
    Destructor Destroy ; Override;

    Published
    Property Align;
    Property ImageList:TImageList read FImageList write SetImageList;
    property Visible;
End;

procedure Register;
implementation

{ TRollOver }






procedure TRollOver.CMMouseEnter(var Message: TMessage);
begin
   FMouseIn := true;
   invalidate;
end;

procedure TRollOver.CMMouseLeave(var Message: TMessage);
begin
   FMouseIn := false;
   invalidate;
end;

constructor TRollOver.Create(AOwner: TComponent);
begin
  inherited;
    visible := true;
    Width  := 60;
    Height := 25;
end;

destructor TRollOver.Destroy;
begin
  inherited;
end;


function TRollOver.CalcCursorPos: TPoint;
begin
  GetCursorPos(Result);
  Result := ScreenToClient(Result);
end;


procedure TRollOver.Paint;
Var
  Index:Integer;
  mr:TRect;
  s:String;
begin
  Canvas.Brush.Style := bsClear;
  if FMouseIn then Index := 0 else Index := 1;

  inherited;
  if Assigned(FimageList) and (FimageList.Count>1then
      begin
        FimageList.Draw(Canvas,0,0,Index);

      end
   else
      begin
         mr.Left   := 0;
         mr.Top    := 0;
         mr.Right  := width;
         mr.Bottom := Height;
         s := 'BITTE EINRICHTEN';
         Canvas.TextRect( mr , s,[tfVerticalCenter,tfCenter,tfSingleLine]);
      end;
end;



procedure TRollOver.SetImageList(const Value: TImageList);
begin
  FImageList := Value;
  invalidate;
end;


procedure TRollOver.WMLButtonDown(var Message: TWMLButtonDown);
begin
  FmouseDown := true;
  With CalcCursorPos do
    begin
      FX := x;
      FY := Y;
    end;
  inherited;
end;

procedure TRollOver.WMLButtonUp(var Message: TWMLButtonUp);
begin
  FmouseDown := false;
  inherited;

end;

procedure TRollOver.WMMouseMove(var Message: TWMMouseMove);
begin
   inherited;
end;

procedure Register;
begin
  RegisterComponents('Bummi', [TRollOver]);
end;

end.
Xion
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
EE-Maler
Beiträge: 1952
Erhaltene Danke: 128

Windows XP
Delphi (2005, SmartInspect), SQL, Lua, Java (Eclipse), C++ (Visual Studio 2010, Qt Creator), Python (Blender), Prolog (SWIProlog), Haskell (ghci)
BeitragVerfasst: Di 31.08.10 21:09 
user profile iconidefix123456 hat folgendes geschrieben Zum zitierten Posting springen:

Ich habe jetzt die procedure CMMouseLeave hinzugefügt. Jedoch wird das bild nicht eingeblendet wenn ich dieses mit dem mauszeiger verlasse, sondern es wird erst Eingeblendet, sobald ich das Fenter (TForm1 Fenster) mit dem Mauszeiger verlasse!

Ja, die angesprochende Klasse ist ja auch ein TImage, welches dann (wie die Form) ein OnMouseEnter und OnMouseLeave-Event hat.


user profile iconidefix123456 hat folgendes geschrieben Zum zitierten Posting springen:
Ich vermute es liegt daran, das CMMouseLeave auf das TForm1 bezieht, also sobald ich Form verlasse, Startet er die procedure und blendet das Bild wieder ein!

Genau.

Ich erklärs mal "problemorientiert" ;)

Du machst eine neue Unit in deinem Delphi. Die nennst du AdvImage; und kopierst den von mir verklinkten Code da rein.

In deine Main-Unit (also Unit1) fügst du dann ein

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
...
uses [...], AdvImage; //Unit verwenden
...
var Img: TAdvImage; 

...
procedure TForm1.Form1Create(...);
begin
  //Img dynamisch erstellen
  Img:=TAdvImage.Create(Form1);
  Img.Parent:=Form1;
  Img.Picture.LoadfromFile('Pfad+Blabla.bmp');
  Img.OnMouseEnter:=OnImgMouseEnter;
 // Img.OnMouseLeave:=OnImgMouseLeave;
end;


OnImgMouseEnter wird jetzt immer aufgerufen, wenn man mit der Maus in das Bild reingeht. Das könnte etwa so aussehen:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
procedure TForm1.OnImgMouseEnter(Sennder: TObject);
begin
  Img.Picture.LoadfromFile('Pfad+WasAndres.bmp');
end;


Hintergrund:
Die Funktion
ausblenden Delphi-Quelltext
1:
procedure CMMouseLeave(var Message: TMessage); message CM_MOUSELEAVE;					

wird immer aufgerufen, wenn die entsprechende Klasse, zu der diese Funktion gehört, die Message CM_MOUSELEAVE von Windows erhält. Da du sie so in die Form platziert hast, betrifft es eben immer die Form. Wir müssen es daher dem TImage zuweisen, dazu erben wir TImage in TAdvImage. Erstellen wir jetzt eine Instanz von TAdvImage, dann ist die Funktionalität enthalten.

_________________
a broken heart is like a broken window - it'll never heal
In einem gut regierten Land ist Armut eine Schande, in einem schlecht regierten Reichtum. (Konfuzius)
idefix123456 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 23



BeitragVerfasst: Mi 01.09.10 19:33 
Hallo,

Danke für die Hilfen, bin jetzt fast fertig. Habe das ganze erst in einer test unit zusammengeschustert, und es hat funktioniert... Den Code unten hab ich schon mit in mein Script eingebunden... Funktionsweise: Eine andere prozedur erstellt das bild dynamisch und verwendet als Klasse TMoveImage. Die unten geposteten prozeduren sollen nun das bild "NAME" mit einem rollovereffekt versehen. Klappt auch soweit ganz gut, Jedoch habe ich noch ein Problem bei der Variablenübergabe.

Mein Jetziger Code:

ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
type
  TMoveImage = class(TImage)
    procedure CMMouseLeave(var Msg: TMessage); message CM_MouseLeave;
  end;


  TForm1 = class(TForm)
    ...

    ...
    procedure imgOnChange(Sender: TObject; Shift: TShiftState; X, Y: Integer);


...

procedure TMoveImage.CMMouseLeave(var Msg: TMessage);
begin
  (* PROBLEM! In Dieser Prozedur muss ich irgendwie den Bildnamen auslesen, weil das ganze soll nicht nur bei einem bild funktionieren!
     Sondern bei mehreren Bildern. Deswegen kann ich hier den Namen "testbild2" nicht einfach Fix setzen!

     Ich brächte hier eine Art Sender: Variable wie bei TForm1.imgOnChange oder eine Art ElementReadSettings um so an die
     Objektsettings, des Bildes zu kommen. *)


  img_change('testbild2', str_val_after(TImage(Form1.FindComponent('testbild2')).Hint, '#'));
end;

procedure TForm1.imgOnChange(Sender: TObject; Shift: TShiftState; X, Y: Integer);
begin
  img_change(TImage(Sender).Name, str_val_before(TImage(Sender).Hint, '#'));
end;

procedure img_OnMove_change(NAME, str: string);
begin
  TImage(Form1.FindComponent(NAME)).Hint := str_kompat(str) + '#' + img_read(NAME);
  TImage(Form1.FindComponent(NAME)).OnMouseMove := Form1.imgOnChange;
end;




(* Mit einer anderen procedure wird das Bild erstellt, die ich hier jedoch nicht speziell mit aufführe,
   da ich vermute das es nicht entscheidend ist. Musste nur bei der Image Erstellungs Prozedur kein TImage
   mehr erstellen, sondern jetzt ein TMoveImage um dort auch MouseLeave zu nutzen *)



Das ganze ist so wie es scheint Sicherlich nicht die beste Möglichkeit. Aber das ist auch nicht für ein Kommerzielles 1.000.000 User Programm gedacht. Und vorerst bin ich froh wenn das ganze erstmal so funktioniert wie es funktionieren soll. Verbessern kann ich es irgendwann immernoch, wenn ich mich etwas besser mit Delphi auskenne. Ich Arbeite bei immernoch viel zu viel nach dem PHP Programmierstil, wo man einfach schön der reihe nach die PHP funktionen Ab Arbeitet. Objektorientiert mit Klassen etc. ist mir neu, deswegen kommt das ganze noch etwas verwirrend rüber!

Übrigens benötige ich noch eine klitze kleine Hilfe bei einer anderen function
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
// So lese ich die Breite eines Bildes aus
TImage(Form1.FindComponent(NAME)).Width

// So die Höhe
TImage(Form1.FindComponent(NAME)).Height

// Wie lese ich den Dateinamen????
TImage(Form1.FindComponent(NAME)).FileName // Funzt ned
TImage(Form1.FindComponent(NAME)).Picture.FileName // Funzt ned
TImage(Form1.FindComponent(NAME)). ????


Währe nochmals Dankbar über eine Antwort!
Xion
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
EE-Maler
Beiträge: 1952
Erhaltene Danke: 128

Windows XP
Delphi (2005, SmartInspect), SQL, Lua, Java (Eclipse), C++ (Visual Studio 2010, Qt Creator), Python (Blender), Prolog (SWIProlog), Haskell (ghci)
BeitragVerfasst: Do 02.09.10 10:28 
user profile iconidefix123456 hat folgendes geschrieben Zum zitierten Posting springen:
Die unten geposteten prozeduren sollen nun das bild "NAME" mit einem rollovereffekt versehen. Klappt auch soweit ganz gut, Jedoch habe ich noch ein Problem bei der Variablenübergabe.


Kannst du nicht Self verwenden? (Self in Delphi = This in C++)
ausblenden Delphi-Quelltext
1:
img_change(Self.Name, Self, '#');					



Das stimmt so ja auch nicht mehr ganz, der Typ ist ja jetzt TMoveImage:
ausblenden Delphi-Quelltext
1:
TImage(Form1.FindComponent(NAME)).Width					


user profile iconidefix123456 hat folgendes geschrieben Zum zitierten Posting springen:
Übrigens benötige ich noch eine klitze kleine Hilfe bei einer anderen function
ausblenden Delphi-Quelltext
1:
2:
3:
4:
// Wie lese ich den Dateinamen????
TImage(Form1.FindComponent(NAME)).FileName // Funzt ned
TImage(Form1.FindComponent(NAME)).Picture.FileName // Funzt ned
TImage(Form1.FindComponent(NAME)). ????


Hab mich gewundert, aber stimmt, das ist der Murks an dem ganzen ;) Der Blödmann speichert den FileName nicht. Du kannst ihn höchstens in den Hint schreiben beim laden. Oder du fügst in TMoveImage noch die property ein (das wäre natürlich das beste):

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
type
  TMoveImage = class(TImage)
    private
       VFileName: String;
       procedure SetFileName(V: String);
    public
      property FileName: String read VFileName write SetFileName;
      procedure CMMouseLeave(var Msg: TMessage); message CM_MouseLeave;
  end;

[...]
TMoveImage.SetFileName(V: String);
begin
  Self.Picture.LoadFromFile(FileName);
  VFileName:=V;
end;


Klar ist, wenn du jetzt deine Datei per Img.Picture.LoadFromFile:='-pfad-'; lädst, dann stimmt der Dateipfad nicht. Du musst immer schreiben Img.FileName:='-pfad-';
Ist aber beim Hint nicht anders ;) Alternativ kannst du natürlich FileName auch einfach als "Stringbehälter" verwenden:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
type
  TMoveImage = class(TImage)
    private
       VFileName: String;
    public
      property FileName: String read VFileName write VFileName;
      procedure CMMouseLeave(var Msg: TMessage); message CM_MouseLeave;
  end;

Ein Aufruf müsste dann so aussehen:
ausblenden Delphi-Quelltext
1:
2:
Img.Picture.LoadFromFile('-pfad-');
Img.FileName:='-pfad-';

_________________
a broken heart is like a broken window - it'll never heal
In einem gut regierten Land ist Armut eine Schande, in einem schlecht regierten Reichtum. (Konfuzius)
idefix123456 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 23



BeitragVerfasst: Do 02.09.10 18:29 
Hi,

Danke für die Antworten, die Antworten haben mir sehr viel weitergeholfen. Das ganze ist jetzt immerhin funktionsfähig so wie ich mir das vorgestellt habe...

Code:

ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
  TMoveImage = class(TImage)

  private
    VFileName: String;

  public
    property FileName: String read VFileName write VFileName; // Zusätzliches Property hinzufügen!
    procedure CMMouseLeave(var Msg: TMessage); message CM_MouseLeave;
  end;

...

procedure TMoveImage.CMMouseLeave(var Msg: TMessage);
begin
  if Self.Tag = 1 then begin
    img_change(Self.Name, str_val_after(Self.Hint, '#'));
    Self.Tag := 0;
  end;
end;

procedure TForm1.imgOnChange(Sender: TObject; Shift: TShiftState; X, Y: Integer);
begin
  if TMoveImage(Sender).Tag = 0 then begin
    img_change(TMoveImage(Sender).Name, str_val_before(TMoveImage(Sender).Hint, '#'));
    TMoveImage(Sender).Tag := 1;
  end;
end;

procedure img_OnMove_change(NAME, str: string);
begin
  TMoveImage(Form1.FindComponent(NAME)).Hint := str + '#' + img_read(NAME);
  TMoveImage(Form1.FindComponent(NAME)).Tag := 0;
  TMoveImage(Form1.FindComponent(NAME)).OnMouseMove := Form1.imgOnChange;
end;


Jetzt funktioniert Alles. Ein kleiner Bug ist mir zwar jedoch noch Aufgefallen, bsp.: Das Bild im Originalzustand ist 100px vom Linken Rand entfernt, und im Hoverzustand z.b. nur 50px vom Linken Rand.

Wenn ich jetzt Mit der Maus auf das Bild fahre, Dann wird es auf die 50px verschoben. Fahre ich nun mit der Maus langsam über den Rechten Rand aus dem Bild heraus, wird das bild sobald der mauszeiger dieses verlässt, wieder auf seine standardposition, also die 100px verschoben. Weil der mauszeiger sich noch in diesem bereich befindet in dem zuvor kein bild war, aber durch das verlassen jetzt wieder ein bild ist, wird das bild quasi wieder in den hoverzustand gesetzt, obwohl sich der mauszeiger außerhalb des bildes befindet. Ist zwar kein großer Bug, jedoch macht dieser Das Verschieben eines bildes durch Mousehover quasi fast unbrauchbar. CM_MOUSELEAVE erkennt das verlassen des bildes richtig, jedoch muss ich das irgendwie durch ein if machen.

Mir Ist bisher noch keine Sinnvolle Lösung eingefallen.
Mein erster gedanke war in der prozedur CMMouseLeave den 'Self.Tag := 0;' erst nach einer gewissen zeit zu setzen jedoch verbessschlechtert es das problem nur, weil dann ist kein kontinuierliches hovern mehr gewährleistet, da ein erneuter hover erst dann beginnt wenn die zeit abgelaufen ist! Da fällt mir bestinnt noch etwas ein...


Danke für die vielen Antworten!
Xion
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
EE-Maler
Beiträge: 1952
Erhaltene Danke: 128

Windows XP
Delphi (2005, SmartInspect), SQL, Lua, Java (Eclipse), C++ (Visual Studio 2010, Qt Creator), Python (Blender), Prolog (SWIProlog), Haskell (ghci)
BeitragVerfasst: Do 02.09.10 21:39 
user profile iconidefix123456 hat folgendes geschrieben Zum zitierten Posting springen:

Jetzt funktioniert Alles. Ein kleiner Bug ist mir zwar jedoch noch Aufgefallen, bsp.: Das Bild im Originalzustand ist 100px vom Linken Rand entfernt, und im Hoverzustand z.b. nur 50px vom Linken Rand.

Du musst vor allem aufpassen, dass NIE das normale Bild einen Bereich bedeckt, welches durch das Hoverbild nicht abgedeckt ist. Mal angenommen in deinem Beispiel sind beide Bilder gleich groß, nur das Hover-Bild ist um 50 nach links verschoben. Gehe ich jetzt mit der Maus RECHTS auf das Standard-Bild, dann läd er das Hover-Bild. Hmm, ok, die Maus ist NICHT auf dem Hoverbild, also CM_MOUSELEAVE. Oh, jetzt ist die Maus ja wieder auf dem Standardbild -> Hoverbild laden. Und so weiter bis in alle Ewigkeit. Sieht man auch manchen Websites, wenn sie den Link bei MouseOver in einer andren Schriftart anzeigen. Ich glaub das ist, was du meinst

user profile iconidefix123456 hat folgendes geschrieben Zum zitierten Posting springen:
Mir Ist bisher noch keine Sinnvolle Lösung eingefallen.
Mein erster gedanke war in der prozedur CMMouseLeave den 'Self.Tag := 0;' erst nach einer gewissen zeit zu setzen jedoch verbessschlechtert es das problem nur, weil dann ist kein kontinuierliches hovern mehr gewährleistet, da ein erneuter hover erst dann beginnt wenn die zeit abgelaufen ist! Da fällt mir bestinnt noch etwas ein...

Also was du machen könntest, setze Img.AutoSize:=False und Img.Stretch:=False nach dem Laden des Bildes und mache das Image so groß, dass es die komplette Fläche beider Bilder bedeckt. In deinem Fall also 50 Pixel für Width mehr. Klar ist, jetzt setzt der Hovereffekt auch schon bei 50Pixel weiter links ein. Alternativ kannst du diesen Effekt nur bei der "Hover"-Variante des Bildes machen, wichtig ist eben, dass das Hoverbild MINDESTENS die Fläche des normalen Bildes abdeckt.

Was noch ginge, du speicherst die Mausposition, wenn du das Hoverbild lädst und guckst beim CM_MOUSELEAVE, ob die sich geändert hat. Problem: Du kriegst ja kein neues CM_MOUSELEAVE mehr, du hast das Bild ja bereits verlassen, man müsste dann mit nem Timer arbeiten...ne, das ist Murks :mrgreen:

_________________
a broken heart is like a broken window - it'll never heal
In einem gut regierten Land ist Armut eine Schande, in einem schlecht regierten Reichtum. (Konfuzius)