Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   GUI-Design mit VCL / FireMonkey / Common Controls (https://www.delphipraxis.net/18-gui-design-mit-vcl-firemonkey-common-controls/)
-   -   Delphi OnMouseOver bei selbst erzeugtem TPicture (https://www.delphipraxis.net/55815-onmouseover-bei-selbst-erzeugtem-tpicture.html)

tobi1701 27. Okt 2005 12:18


OnMouseOver bei selbst erzeugtem TPicture
 
hallo,

ich habe eine liste erzeugt, die aus records besteht. in diesem record sind wiederum TPicture elemente enthalten.
in der liste wird jeder eintrag angezeigt und das darin enthaltene TPicture wird als verkleinertes thumbnail angezeigt.
ich möchte jetzt, wenn ich mit dem mauszeiger über dem TPicture bin, eine vergrösserte ansicht in einer anderen TPaintBox anzeigen lassen.

doch wie kann ich das machen? es muss ja irgendwie für alle TPictures in allen einträgen der liste die gleiche prozedur aufgerufen werden.
oder kann man das nur machen, wenn mein eintrag ein object ist? und wenn ja, wie?

um hier nicht zu allgemein rumzureden, kann ich ja mal meinen eintrag hinzufügen:

Delphi-Quellcode:
BasicGameEntry = record
   Name,Genre,System,Publisher,Released: string;
   Description: TStrings;
   Rating: integer;
   Picture: Array[1..6] of TPicture;
  end;
so. wie man sehen kann, solle es eine kleine datenbank für spiele werden und so ein eintrag soll bis zu 6 bilder bekommen, die in der listenansicht als thumbs (stretchdraw) angezeigt werden.

Net7 27. Okt 2005 13:30

Re: OnMouseOver bei selbst erzeugtem TPicture
 
Erweitere doch TPicture doch um das Ereignis OnMouseOver. Wo ist das Problem??

tobi1701 27. Okt 2005 15:20

Re: OnMouseOver bei selbst erzeugtem TPicture
 
genau das möchte ich ja machen. da ich aber nicht weiss wie ich das machen kann, frage ich ja hier.
wie kann ich TPicture um das ereignis OnMouseOver erweitern und vor allem verstehe ich nicht so ganz, wie ich dann allgemein jedes TPicture an meine paintbox senden kann.
während das programm läuft, sollen ja einträge erstellt und der liste hinzugefügt werden. und auch diese einträge sollen schon diese OnMouseOver eigenschaft besitzen. das ist mein problem.

Net7 27. Okt 2005 16:50

Re: OnMouseOver bei selbst erzeugtem TPicture
 
Ahhhh jetzt verstehe ich was du meinst...

Vergiss das mit TPicture und On MouseOver.. :wall: Das geht ja garnet weils ein Container ist


Aber mal als Anstoß.. Setze mal eine Paintbox auf deinen Formular. Und Create ein TPicture das etwa halb so groß ist wie deine Paintbox. Über die X-Y Koordinaten müsste sich ja rausfinden lassen wo sich dein Picture aufhält.


Bisschen pseudocode aus einem meiner Projekte (leicht abgeändert) :stupid:

Delphi-Quellcode:
function TPictuere.Erkennen(Punkt:Tpoint): boolean;
var
PunktOL:Tpoint; //Punkt oben links deines Pictures
PunktUR:Tpoint; //Punkt unten rechts deines Pictures
begin
   
     PunktOL.X:=self.x1+10;
     PunktOL.Y:=self.y1+10;
     PunktUR.X:=self.x2-10;
     PunktUR.Y:=self.y2-10;
     
     if (punkt.X >=PunktOL.X) and (punkt.X <=PunktUR.X) and (Punkt.Y>=punktOL.Y) and (Punkt.Y<=punktUR.Y) then
     begin
        result:=true;
       
        //Tpicture berührt
     end
      else
        begin
          result:=false;
          // ausserhalb von Tpicture
        end;




end;

Ich hoffe es hilft dir etwas.

tobi1701 27. Okt 2005 17:17

Re: OnMouseOver bei selbst erzeugtem TPicture
 
ja, so kenne ich das auch noch aus der guten alten DOS-zeit. ich dachte nur, dass es unter windows vielleicht etwas leichter geht und man das nicht mehr alles per hand machen muss.

ich meine, ein Button weiss ja auch, wann auf ihn geklickt wird, ohne das vorher gefragt wird, wo der cursor ist.
und wenn ich ein TPicture aus dercomponenten-leiste auswähle und auf meine form lege, dann kann ich ihm ja auch die eigenschaft OnMouseOver (oder OnClick...) zuweisen.
daher denke ich auch, dass das es irgendwie möglich sein muss, allen TPictures, die in meiner liste kreiert werden, den Event OnMouseOver zuzuweisen und das TPicture schreibt sich dann auf zB PaintBox1.Canvas, oder?

Net7 27. Okt 2005 17:32

Re: OnMouseOver bei selbst erzeugtem TPicture
 
Zitat:

Zitat von tobi1701
ja, so kenne ich das auch noch aus der guten alten DOS-zeit. ich dachte nur, dass es unter windows vielleicht etwas leichter geht und man das nicht mehr alles per hand machen muss.

ich meine, ein Button weiss ja auch, wann auf ihn geklickt wird, ohne das vorher gefragt wird, wo der cursor ist.
und wenn ich ein TPicture aus dercomponenten-leiste auswähle und auf meine form lege, dann kann ich ihm ja auch die eigenschaft OnMouseOver (oder OnClick...) zuweisen.
daher denke ich auch, dass das es irgendwie möglich sein muss, allen TPictures, die in meiner liste kreiert werden, den Event OnMouseOver zuzuweisen und das TPicture schreibt sich dann auf zB PaintBox1.Canvas, oder?

Wie kann man denn ein TPicture aus der Kompoleiste verwenden?? :gruebel:

Meinst manchmal ein du Timage??

tobi1701 27. Okt 2005 17:54

Re: OnMouseOver bei selbst erzeugtem TPicture
 
err, sorry, ich rede natürlich die ganze zeit von TImage.

Net7 27. Okt 2005 18:06

Re: OnMouseOver bei selbst erzeugtem TPicture
 
also sieht dein Record so aus??

Delphi-Quellcode:

BasicGameEntry = record
   Name,Genre,System,Publisher,Released: string;
   Description: TStrings;
   Rating: integer;
   Picture: Array[1..6] of TImage;
  end;

öhhm dann hat doch jedes Picture dieses Event :gruebel:

Und du kannst es abfragen.

tobi1701 27. Okt 2005 18:24

Re: OnMouseOver bei selbst erzeugtem TPicture
 
ich glaube, wir reden hier aneinander vorbei.

also: ich habe eine paintbox, in der alle ainträge meiner liste dargestellt werde. die einträge sind das oben genannte record, das bilder in einer verkleinerten thumbnail-ansicht darstellt.
das funktioniert auch einwandfrei so.

es gibt jetzt noch eine zweite paintbox, in der die bilder in der originalgrösse (oder zumindest grösser) dargestellt werden sollen, wenn ich mit dem mauszeiger über das verkleinert dargestellte TImage des listeneintrags gehe.

das problem ist: von alleine tut es das nicht. was muss ich machen, damit genau das realisiert wird?
ich weiss, dass irgendwie irgendwo etwas in einen .OnMouseOver event geschrieben werden muss, habe aber wirklich keine ahnung wie und wo.

Khabarakh 27. Okt 2005 18:33

Re: OnMouseOver bei selbst erzeugtem TPicture
 
Zitat:

Zitat von tobi1701
ich glaube, wir reden hier aneinander vorbei.

Du solltest eben die Klassennamen nicht so umeinander werfen :stupid: .
Zitat:

also: ich habe eine paintbox, in der alle ainträge meiner liste dargestellt werde.
[...], wenn ich mit dem mauszeiger über das verkleinert dargestellte TImage des listeneintrags gehe.
Was denn nun :gruebel: ? :mrgreen:
Wie zeigst du die thumbnails in der Paintbox an? Auf jeden Fall musst du bei deren OnMouseMove aus den Koordinaten den Index des Bildes errechnen und dieses dann in der zweiten Paintbox anzeigen.

[add]Sind im Record die Thumbnails oder die Original-Bilder enthalten? [/add]

tobi1701 27. Okt 2005 18:42

Re: OnMouseOver bei selbst erzeugtem TPicture
 
ok, ich gebe einfach mal alles an:

Delphi-Quellcode:
unit main;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ExtCtrls, StdCtrls, GraphicEx, JPEG, Menus, ImgList, DXDraws,
  ComCtrls,Contnrs;

type
  pGameEntry = ^BasicGameEntry;
  BasicGameEntry = record
   Name,Genre,System,Publisher,Released: string;
   Description: TStrings;
   Rating: integer;
   Picture: Array[1..6] of TPicture;
  end;


TForm1 = class(TForm)
 PaintBox1:TPaintBox;
 PreviewBox:TPaintBox;
//[...]

 private

 public
    GameEntry: pGameEntry;
    GameList: tList;
    MainImageList: TObjectList;
 end;

var
  Form1: TForm1;

implementation

uses NewEntry;

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
  Width:=1024;
  Height:=768;
  Color:=clCream;
  GameList:=TList.Create;
  PaintBox1.Canvas.Pen.Style:=psDot;
  PaintBox1.Left:=2;
  PaintBox1.Top:=100;;
  PaintBox1.Width:=604;
  PaintBox1.Height:=600;

  ScrollBox.Top:=PaintBox1.Top;
  ScrollBox.Left:=PaintBox1.Left+PaintBox1.Width+2;
  ScrollBox.Width:=15;
  ScrollBox.Height:=PaintBox1.Height;

  PreviewBox.Top:=PaintBox1.Top;
  PreviewBox.Left:=PaintBox1.Left+PaintBox1.Width+2+ScrollBox.Width+2;
  PreviewBox.Width:=370;
  PreviewBox.Height:=278;

  DXImageList1.Items.Add;
  DXImageList1.Items[0].Picture:=TPicture.Create;
  DXImageList1.Items[0].Picture.Bitmap.LoadFromFile('template_gp32x.bmp');
  DXImageList1.Items.Add;
  DXImageList1.Items[1].Picture:=TPicture.Create;
  DXImageList1.Items[1].Picture.Bitmap.LoadFromFile('blank120x90.bmp');
  DXImageList1.Items.Add;
  DXImageList1.Items[2].Picture:=TPicture.Create;
  DXImageList1.Items[2].Picture.Bitmap.LoadFromFile('scrollbar_gp32x.bmp');
  DXImageList1.Items.Add;
  DXImageList1.Items[3].Picture:=TPicture.Create;
  DXImageList1.Items[3].Picture.Bitmap.LoadFromFile('scrollup_gp32x.bmp');
  DXImageList1.Items.Add;
  DXImageList1.Items[4].Picture:=TPicture.Create;
  DXImageList1.Items[4].Picture.Bitmap.LoadFromFile('scrolldown_gp32x.bmp');
  DXImageList1.Items.Add;
  DXImageList1.Items[5].Picture:=TPicture.Create;
  DXImageList1.Items[5].Picture.Bitmap.LoadFromFile('scrollCursor_gp32x.bmp');

  new(GameEntry);
  GameEntry^.Name:='Test Name 1';
  GameEntry^.Genre:='Platformer';
  GameEntry^.Released:='1992';
  GameEntry^.Publisher:='Konami';
  GameEntry^.Rating:=80;
  GameEntry^.Picture[1]:=TPicture.Create;
  GameEntry^.Picture[1].Assign(DXImageList1.Items[1].Picture);
  GameEntry^.Picture[2]:=TPicture.Create;
  GameEntry^.Picture[2].Assign(DXImageList1.Items[1].Picture);
  GameList.Add(GameEntry);

end;

procedure TForm1.FormPaint(Sender: TObject);
begin
  UpdateLayout;
  UpdateList;
end;

procedure TForm1.FormResize(Sender: TObject);
begin
  MenuBox.Width:=Form1.Width-15;
end;

procedure TForm1.FormShow(Sender: TObject);
begin
  UpdateLayout;
end;

procedure TForm1.DrawEntry(y:integer;Entry:pGameEntry);
var
        Rect: TRect;

begin
  PaintBox1.Canvas.Brush.Color:=clWhite;
  PaintBox1.Canvas.Draw(2,y+2,DXImageList1.Items[0].Picture.Bitmap);

  PaintBox1.Canvas.Brush.Style:=bsClear;
  PaintBox1.Canvas.Font.Size:=8;
  PaintBox1.Canvas.Font.Style:=[fsBold];
  // Outline Color
  PaintBox1.Canvas.Font.Color:=clSilver;
  PaintBox1.Canvas.TextOut(6-1,y+6-1,Entry.Name);
  PaintBox1.Canvas.TextOut(6+1,y+6-1,Entry.Name);
  PaintBox1.Canvas.TextOut(6-1,y+6+1,Entry.Name);
  PaintBox1.Canvas.TextOut(6+1,y+6+1,Entry.Name);
  // Inner Color
  PaintBox1.Canvas.Font.Color:=clBlack;
  PaintBox1.Canvas.TextOut(6,y+6,Entry.Name);

  PaintBox1.Canvas.Font.Size:=6;
  PaintBox1.Canvas.Font.Style:=[];
  PaintBox1.Canvas.Font.Color:=clBlack;
  PaintBox1.Canvas.TextOut(6,y+40,'Genre:');
  PaintBox1.Canvas.TextOut(60,y+40,Entry.Genre);
  PaintBox1.Canvas.TextOut(6,y+55,'Released:');
  PaintBox1.Canvas.TextOut(60,y+55,Entry.Released);
  PaintBox1.Canvas.TextOut(6,y+70,'Publisher:');
  PaintBox1.Canvas.TextOut(60,y+70,Entry.Publisher);
  PaintBox1.Canvas.TextOut(6,y+85,'Rating:');
  PaintBox1.Canvas.TextOut(60,y+85,IntToStr(Entry.Rating)+'%');
  Rect.Left:=(50)+220;
  Rect.Top:=(y+10);
  Rect.Right:=Rect.Left+120;
  Rect.Bottom:=Rect.Top+90;
  if (Entry.Picture[1].Graphic<>nil) then PaintBox1.Canvas.StretchDraw(Rect,Entry.Picture[1].Graphic)
  else PaintBox1.Canvas.StretchDraw(Rect,DXImageList1.Items[1].Picture.Bitmap);
  Rect.Left:=(190)+220;
  Rect.Top:=(y+10);
  Rect.Right:=Rect.Left+120;
  Rect.Bottom:=Rect.Top+90;
  if (Entry.Picture[2].Graphic<>nil) then PaintBox1.Canvas.StretchDraw(Rect,Entry.Picture[2].Graphic)
  else PaintBox1.Canvas.StretchDraw(Rect,DXImageList1.Items[1].Picture.Bitmap);
end;

procedure TForm1.UpdateList;
var i: integer;

begin
  if GameList.Count>0 then begin
  for i:=0 to (GameList.Count-1) do begin
    GameEntry:=GameList.Items[i];
    DrawEntry(i*101,GameEntry);
  end;
  end;
end;

procedure TForm1.UpdateLayout;
var
        Rect: TRect;

begin
  Rect.Top:=0;
  Rect.Left:=0;
  Rect.Bottom:=MenuBox.Height;
  Rect.Right:=MenuBox.Width;
  MenuBox.Canvas.Brush.Color:=clWhite;
  MenuBox.Canvas.FillRect(Rect);
  MenuBox.Canvas.Brush.Color:=clBlack;
  MenuBox.Canvas.FrameRect(Rect);

  Rect.Top:=0;
  Rect.Left:=0;
  Rect.Bottom:=ScrollBox.Height;
  Rect.Right:=ScrollBox.Width;
  ScrollBox.Canvas.Brush.Color:=clWhite;
  ScrollBox.Canvas.FillRect(Rect);
  ScrollBox.Canvas.Brush.Color:=clBlack;
  ScrollBox.Canvas.FrameRect(Rect);
  Rect.Top:=Rect.Top+14;
  Rect.Bottom:=Rect.Bottom-14;
  Rect.Left:=Rect.Left+1;
  Rect.Right:=Rect.Right-1;
  ScrollBox.Canvas.StretchDraw(Rect,DXImageList1.Items[2].Picture.Bitmap);
  ScrollBox.Canvas.Draw(1,1,DXImageList1.Items[3].Picture.Bitmap);
  ScrollBox.Canvas.Draw(1,ScrollBox.Height-14,DXImageList1.Items[4].Picture.Bitmap);

  Rect.Top:=0;
  Rect.Left:=0;
  Rect.Bottom:=PreviewBox.Height;
  Rect.Right:=PreviewBox.Width;
  PreviewBox.Canvas.Brush.Color:=clWhite;
  PreviewBox.Canvas.FillRect(Rect);
  PreviewBox.Canvas.Brush.Color:=clBlack;
  PreviewBox.Canvas.FrameRect(Rect);

  Rect.Top:=0;
  Rect.Left:=0;
  Rect.Bottom:=PaintBox1.Height;
  Rect.Right:=PaintBox1.Width;
  PaintBox1.Canvas.Brush.Color:=clWhite;
  PaintBox1.Canvas.FillRect(Rect);
  PaintBox1.Canvas.Brush.Color:=clBlack;
  PaintBox1.Canvas.FrameRect(Rect);
end;

procedure TForm1.Button1Click(Sender: TObject);
var
        i,Code:integer;

begin
  Form2.Image1.Picture:=nil;
  Form2.Image2.Picture:=nil;
  if Form2.ShowModal=mrOK then begin
    new(Form1.GameEntry);
    GameEntry^.Name:=Form2.Edit1.Text;
    GameEntry^.Genre:=Form2.ComboBox1.Text;
    GameEntry^.Publisher:=Form2.Edit2.Text;
    GameEntry^.Released:=Form2.Edit3.Text;
    val(Form2.Edit4.Text,i,Code);
    if Code<>0 then i:=0;
    GameEntry^.Rating:=i;
    //GameEntry^.System:=Form2.ComboBox2.Text;
    GameEntry^.Picture[1]:=TPicture.Create;
    GameEntry^.Picture[1].Assign(Form2.Image1.Picture);
    GameEntry^.Picture[2]:=TPicture.Create;
    GameEntry^.Picture[2].Assign(Form2.Image2.Picture);
    GameList.Add(GameEntry);
    UpdateList;
  end;
end;


end.
so. wie beschrieben werden die einträge der der liste mit DrawEntry in die PaintBox1 gemalt und in einem Eintrag werden 2 Images mit der grösse 120x90 gemalt.
und wenn ich über genau eines dieser 120x90 images mit der maus gehe, soll das glaiche Image (über dem sich der cursor befindet) in die PreviewBox gemalt werden.

Khabarakh 27. Okt 2005 19:30

Re: OnMouseOver bei selbst erzeugtem TPicture
 
So?
Delphi-Quellcode:
//EventHandler für PreviewBox.OnMouseMove
begin
  if InRange(y div 101, 10, 100) then
    if InRange(x, 50 + 220, 50 + 220 + 120) then
    begin
      PreviewBox.Canvas.Draw(0, 0, Entry.Picture[1].Graphic);
      Exit
    end
    else
      if InRange(x, 190 + 220, 190 + 220 + 120) then
      begin
        PreviewBox.Canvas.Draw(0, 0, Entry.Picture[2].Graphic);
        Exit
      end;
  PreviewBox.Canvas.FillRect(...); // gesamte Paintbox mit weiß füllen
end;

tobi1701 27. Okt 2005 20:47

Re: OnMouseOver bei selbst erzeugtem TPicture
 
ah, ja. so funktioniert es zwar, aber so ganz ist es nicht, was ich wollte.

ich frage ja so "per hand" ab, ob der cursor gerade über dem jeweiligen Image in der PaintBox ist.
würde ich allerdings ein TImage auf die Form legen, so könnte ich ja im ObjectInspector dem TImage den OnMouseOver - Event geben und dann einfach das TImage in die PaintBox malen.
somit müsste ich ja nicht abfragen, ob der cursor gerade über dem TImage liegt, sondern es würde es "von selbst" tun.
daher war meine frage, ob ich nicht auch bei TImages, die ich nicht auf die Form gelegt habe, sondern die erst kreiert werden, wenn das programm läuft, so einen event definieren kann.

Puhbaehr 10. Nov 2005 11:31

Re: OnMouseOver bei selbst erzeugtem TPicture
 
Wird denn das Thema noch behandelt?
Würde mich auch interessieren ob das Möglich ist für mehrere (viele) verschiedene Objekte immer ein und das selbe Mausevent auszuführen.

Ich hab zum Beispiel ein Formular mit sehr vielen Radiobuttons, Checkboxen, Edit-Felder, Buttons und viele Tabellen.
Ich möchte nun zu jedem "Element" wenn du Maus drüber ist z.B. einen Hilfetext in der Statuszeile anzeigen lassen oder andere Sachen machen lassen.
Klar jetzt könnt ich bei jedem einzelnen im Objektinspektor ein und das selbe Mausevent zuweisen.
Aber es muss doch auch eleganter gehen?

Ich stell mir irgendwas mit Überschreiben irgendwelcher Prozeduren oder so vor. Aber welche?

Ein
Delphi-Quellcode:
procedure MouseMove (Shift: TShiftState; X, Y: Integer); override;
mit entsprechendem Inhalt funktioniert schonmal prima. Allerdings nur da wo ich das Mausevent im Objektinspektor eingetragen hab. Mpf.

Khabarakh 10. Nov 2005 11:49

Re: OnMouseOver bei selbst erzeugtem TPicture
 
Du könntest jedes Control ableiten und TControl.MouseMove überschreiben. Willst du aber wohl eher nicht :mrgreen: .
Oder:
Delphi-Quellcode:
// in einer Methode der Form, z.B. im OnCreate-Eventhandler
for i := 0 to ComponentCount do
  if Components[i] is TControl then
    TControl(Components[i]).OnMouseMove := MyEventHandler;
MyEventHandler muss natürlich die Parameter von TMouseMoveEvent besitzen.

Puhbaehr 10. Nov 2005 12:02

Re: OnMouseOver bei selbst erzeugtem TPicture
 
Öhm ist das nicht das selbe Prinzip wie das Beispiel von Hagen?
Doch ich möchte wohl jedes Control ableiten, denn so erspar ich mir viel Arbeit *g*. In meiner Prozedur kann ich ja so jedes einzelne Abfangen und so wie ich möchte anders behandeln. Sofern es funktioniert. Habs noch nicht ausprobiert. Aber das werde ich jetzt tun :) :hi:

Puhbaehr 10. Nov 2005 13:44

Re: OnMouseOver bei selbst erzeugtem TPicture
 
Ich muss leider doch noch mal nachhacken.
Denn ich hab es bis jetzt nicht geschafft den EventHandler auf die Controls anzuwenden.

Delphi-Quellcode:
constructor TFm_Einstellungen.Create (Owner : TComponent);        
var
  i : word;
 begin
  inherited Create (Owner);
 
  //...
 
  for i := 0 to ComponentCount do
   begin
 
    if (Components[i] is TControl) then
     begin
      TControl (Components[i]).OnMouseMove := MyMouseMove;
     end;
   end;
 end;
Mein Problem: "OnMouseMove" -> Undefinierter Bezeichner. Und nun? :gruebel:


Alle Zeitangaben in WEZ +1. Es ist jetzt 10:01 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz