Zum Inhalt springen

Delphi4: Seltsames Problem


Chrischn

Empfohlene Beiträge

Hallo,

in meinem kleinen Tool (siehe Bild) kopiere ich die kleinen Symbole hin und her(Images). Dies hat bisher auch immer ohne Probleme funktioniert. Ich baue nun gerade das Optionsfenster um, wo ich noch einige Grafiken zur Optischen Aufbesserung einbauen will. Sobald ich jedoch einige Grafiken (Images) in das Optionsfenster einfüge, dann wird im Hauptprogramm das letzte untere Icon nicht mehr kopiert, so dass das Feld grau bleibt. ( Dann sieht man unten das Explorer Icon nicht mehr).

Das ganze tritt nur unter Windows 98 auf. Bei Win2000 funktioniert alles.

Die Images des Optionsfensters und des Hauptprogramms(Form) haben eigentlich nichts miteinander zu tun. Lösche ich die neuen Images wieder, funktioniert wieder alles. Es hat nichts mit den Namen und Bezeichnungen der Images zu tun. Es ist völlig egal wie die neuen Images heissen. Sie können auch leer sein. Sobald ich sie einfüge wird das Letzte Icon im "Hauptform" nicht mehr kopiert und angezeigt.

Kann es sein, dass man nur eine bestimmte Anzahl Images verwenden darf?

Hat jemand eine Idee?

bild1.jpg

http://www.cfrerichs.de/download

Link zu diesem Kommentar
Auf anderen Seiten teilen

Es wäre mir neu, dass man nur eine bestimmte Anzahl Images verwenden darf.

Was und wie kopierst du denn genau? du beschreibst zwar ganz schön was da so passiert, aber das hlft mir nicht wirklich weiter das ganze genauer einordnen zu können.

Hast du mal probiert das ganze über eine TImageList zu mache? Die TImageList stellt z.B. eine Function zur Verfügung (Ich glaube TImageList.GetBitmap(Index)) mit der du nicht für jedes Bild eine eigene TImage Komponente bräuchtest (so wie ich verstehe dass du es machst).

Link zu diesem Kommentar
Auf anderen Seiten teilen

Hallo,

also ich habe 15 Images untereinander. Dann habe ich 5 Zusätzliche Images, wo die jeweiligen Bilder der Laufwerke gespeichert sind.( Festplatte,CD,....) Ist das 3.Laufwerk D z.B. ein CD-ROM, dann kopiere ich einfach von den zusätzlichen Images das CD-ROM Bild in das 3. Image von den 15. (siehe Bild)

test.jpg

Kopiert wird dann ganz einfach so :

Image3.Picture := Image_CD.Picture

Vielleicht nicht ganz die glücklichste Methode? Aber bisher hats halt immer funktioniert.

Die TImageList schaue ich mir mal an.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Original geschrieben von Chrischn

Vielleicht nicht ganz die glücklichste Methode? Aber bisher hats halt immer funktioniert.

Ich würde auch sagen, dass die Methode nicht die glücklichste ist.

In deinem Bild oben sind z.B. nur 9 Bilder zu sehen. Ich gehe mal davon aus, dass in diesem Fall die anderen einfach durch die Form.Height "abgeschnitten" wurden. Ist nicht wirklich schlimm, aber auch nicht wirklich schön programmiert.

Und was ist wenn ein Computer mehr als 15 Laufwerke hat? Theorethisch sind ja mit Windows 26 möglich. Dann noch der Explorer (das Icon was die wohl Probleme macht). Wenn jetzt jemand mehr als 14 Laufwerke hat sieht das mit deinem Programm blöd aus ;) Ob das so oft vorkommt weiss man nicht, dennoch ist es keine grosse Arbeit dein Programm so flexibel zu gestalten, dass es auch dafür geht. Nein, ich meine nicht 27 TImages ;)

Ich würde das mit zur Laufzeit erzeugten Images machen:

Zuallererst würde ich aber alle Bildervorlagen in eine ImageList laden. Den Index der ImageList würde ich mir als Konstante definieren.

Bsp. Die CD ist das erste Bild in der ImageList, hat also den ImageIndex 0.


Const

  cImgCD = 0;

und so weiter. Dann würde ich mir ein dynamische Array von TImages definieren:

TForm1

[...]

private

  arImg: Array of TImage;

[...]

Dann bestimmst du die Laufwerke (hast du ja schon irgendwie)

var i, DriveType: Integer;

      s: String;

[...]

  SetLength(arImg, 0); // Initialisieren

  for i:= 65 to 90 do //A-Z in ASCII

  begin

     s:= chr(i);

      DriveTyp:= GetDriveType(PChar(s));

      if DriveType <> 0 then

      begin

         // Bild erzeugen

         SetLength(arImg, Length(arImg)+1);

         arImg[High(arImg)]:= TImage.create(nil);

         with arImg[High(arImg)] do

         begin

           Width:= cImgWidth;

           Hight:= cImgHeight; // Breite und Höhe als Konstante

           if High(arImg) = 0 then // erstes Bild

             Top:= 0

           else

             Top:= arImg[high(arImg)-1].Top + cImgHeight; // Bild unter vorheriges


         end;

         case DriveType of

             DRIVE_FIXED:

               arImg[High(arImg)].Picture.Bitmap:= imlImages.GetBitmap(cImgFixed); // Bild kopieren

// imlImages ist die ImageList

             [ usw. ]

         end;

      end;

  end;

[...]

So in der Art würde ich das machen. Achtung: Code könnte Fehler enthalten, ist nicht getestet und einfach so hier geschrieben ;) EDIT: Ach ja, nicht vergessen am Ende deine Images wieder freizugeben:

  for i:= 0 to High(arImg) Do

    arImg[i].free;

Link zu diesem Kommentar
Auf anderen Seiten teilen

Hallo, ich habe damals wo ich das Programm angefangen habe noch nicht so ganz viel Durchblick in Delphi gehabt. Dann sucht man sich oft den einfachsten Weg :-)

Deinen Vorschlag werde ich bei Gelegenheit mal austesten. Wird dann schon ein größerer Umbau meines Programms. Aber im Grunde hast du natürlich Recht, das man das ganze besser dynamisch angeht. Ist ja auch viel flexibler. Vor allen Dingen, weil ich noch weitere Buttons (Systemeigenschaften/Netzwerkeigenschaften/...) einbauen will. Im Moment baue ich aber gerade meine HP für die CFMiniBar um. ( Bei den Wolken bekommt man ja Augenkrebs :-)

Trotzdem ist es doch seltsam das Delphi da so "rumzickt".

Ich habe da gerade mal was getestet. Ich habe einfach einen Button ins Optionsfenster kopiert und diesen dann mit dem gleichen Kopierbefehl versehen.

Und siehe da, wenn ich auf den Button klicke wird das Bild korrekt eingefügt.

Irgendwie kriege ich das schon noch hin.

Und wenn ich dann mal Zeit habe versuche ich das mal komplett umzustricken.

Gruß

Chrischn

Link zu diesem Kommentar
Auf anderen Seiten teilen

Original geschrieben von Chrischn

Trotzdem ist es doch seltsam das Delphi da so "rumzickt".

Ja, und so "auf den ersten Blick" fällt mir dazu auch nichts ein. Wahrscheinlich ist es irgendwo ein kleiner Fehler. Muss garnicht mal ein wirklicher Fehler sein, sondern das irgendwas eben nicht ganz so abläuft wie gewollt.

Ich glaube hier in einer Sig. hab ich mal gelesen:

Ein Programm macht das was du schreibst, nicht das was du willst. :D

viel glück bei der "Fehler"-Suche :)

Link zu diesem Kommentar
Auf anderen Seiten teilen

  • 3 Wochen später...

Hallo,

wollte auf deine PN antworten, aber du hast PNs deaktiviert ;)

Hab mir den Code nochmal angesehen... ich denke es liegt daran, das das TImage ein Parent braucht. Also nach dem Erzeugen noch TImage.Parent füllen, dort muss dann die Komponente stehen, auf der das TImage angezeigt werden soll (muss eine TWinControl Komponente sein).

Link zu diesem Kommentar
Auf anderen Seiten teilen

Hallo,

sorry, dass ich jetzt erst antworte aber ich konnte meine Accountdaten nicht mehr ändern und jetzt seltsamerweise auch keine Beiträge mehr verfassen. Hab mich halt nochmal angemeldet. (Meine Mailadresse war veraltet)

"das das TImage ein Parent braucht"

Verstehe wohl ungefähr was du meinst, aber wie wende ich das dann an ? Ich habe jetzt einfach mal ein Formular(Form1) erstellt, dort die Imagelist eingefügt und den Code eingetragen.

Komme irgendwie alleine nicht weiter.....:confused:

In stiller Hoffnung....

Chrischn

Link zu diesem Kommentar
Auf anderen Seiten teilen

Original geschrieben von Pupando

Verstehe wohl ungefähr was du meinst, aber wie wende ich das dann an ? Ich habe jetzt einfach mal ein Formular(Form1) erstellt, dort die Imagelist eingefügt und den Code eingetragen.

Komme irgendwie alleine nicht weiter.....:confused:

also dann kannst du einfach sagen:



  // Schleife, in der die TImages erzeugt werden

  // ...

  blabla[i]:= TImage.create(nil);

  blabla[i].Parent:= Form1;

  // ...


dann wird das TImage auf Form1 angezeigt (an den Koordinaten, die du einstellst).

Link zu diesem Kommentar
Auf anderen Seiten teilen

Original geschrieben von Pupando

Wie kann man den selbst erzeugten Images nun z.B. ein OnClick Ereignis oder z.B. einen Hint zuweisen?

Einen Hint zuweisen ist ganz einfach:

Image.Hint:= 'Hallo, ich bin ein Hint';

Image.ShowHint:= True;

Das OnClick Ereigniss lässt sich genauso leicht zuweisen.

(Ich mach das jetzt mal zur Erklärung ganz ausführlich)

Erstmal sieht man nach was die OnClick Property eigentlich ist, z.B. irgendwo das OnClick-Ereigniss im Objektinspektor anklicken und F1 drücken.

Da steht dann:

Delphi-Syntax:

property OnClick: TNotifyEvent;

wir wissen also, das OnClick etwas vom Typ TNotifyEvent will.

Wir sehen also nach was das ist und lesen da:

Link zu diesem Kommentar
Auf anderen Seiten teilen

  • 3 Wochen später...

Hallo,

so, ich habe jetzt mal ein wenig Zeit gefunden weiter zu machen. Die dynamische

"Icon-Erstellung" funktioniert schon. :-) Vielen Dank nochmal für deine Tipps. :uli Nun habe ich jedoch noch eine Frage.

Bei jedem erstellten dynamischen Icon müsste ich nun ja ein onclick-Ereignis zuweisen. Das heisst, ich hätte dann schon wieder <ironie>85</ironie> onclick-Ereignisse, da ich ja nicht weiss, wieviele Laufwerke der Benutzer eventuell hat.

Da ich das Ganze aber ja dynamisch machen will, würde ich gerne nur 1 onclick Ereignis erstellen und dort ermitteln, auf welches Icon geklickt worden ist. Alle Icons verweisen also dann auf diese onclick-Procedure.

Ist es also möglich zu erfahren, von welchem Icon die Procedure aufgerufen wird ?

Ich hoffe ich habe es genaugenug erklärt was ich meine.

Bis denn dann....

:cool: Chrischn :cool:

Link zu diesem Kommentar
Auf anderen Seiten teilen

Beim OnClick Ereigniss wird der Sender übergeben, dass ist die Komponente, die das Ereigniss ausgelöst hat.

Für ähnliche Dinge hab ich schon oft die Eigenschaft Tag "missbraucht", da die Eigenschaft keinen Wirklichen Sinn hat :

Beschreibung

Tag hat keine vordefinierte Bedeutung. Die Eigenschaft Tag steht zur freien Benutzung durch Entwickler zur Verfügung. Sie können in dieser Eigenschaft zusätzliche Informationen über die Komponente in Form einer Ganzzahl speichern oder die Eigenschaft in einen 32-Bit-Wert, wie z.B. in eine Komponentenreferenz oder einen Zeiger, umgewandelt werden.

Also das erste Icon hat Tag=1 (oder Tag=0, jenach deinen Wünschen), das zweite Tag=2 (bzw. Tag=1) usw.

Im OnClick Ereigniss frägst du das folgendermassen ab:


procedure TForm1.IconClick(Sender: TObject);

begin

  [...]

  case TImage(Sender).Tag of

    0: ;

    1: ;

    [...]

  end;  

  [...]

end;

Sender wird als TObject übergeben, weil das der kleinste gemeinsame Nenner aller Klassen ist.

Du musst ihn also "casten" um darauf zuzugreifen.

Wenn du dir sicher bist, das es nur ein TImage sein kann, kannst du das so einfach machen.

Ansonsten sollte das z.B. so

if Sender is TImage then

[...]

geprüft werden. Das ist auf jeden Fall die sichere und saubere Methode.

P.S. Das Umwandeln geht auch so:

(Sender as TImage).Tag

Link zu diesem Kommentar
Auf anderen Seiten teilen

Dein Kommentar

Du kannst jetzt schreiben und Dich später registrieren. Wenn Du ein Konto hast, melde Dich jetzt an, um unter Deinem Benutzernamen zu schreiben.

Gast
Auf dieses Thema antworten...

×   Du hast formatierten Text eingefügt.   Formatierung wiederherstellen

  Nur 75 Emojis sind erlaubt.

×   Dein Link wurde automatisch eingebettet.   Einbetten rückgängig machen und als Link darstellen

×   Dein vorheriger Inhalt wurde wiederhergestellt.   Editor leeren

×   Du kannst Bilder nicht direkt einfügen. Lade Bilder hoch oder lade sie von einer URL.

Fachinformatiker.de, 2024 by SE Internet Services

fidelogo_small.png

Schicke uns eine Nachricht!

Fachinformatiker.de ist die größte IT-Community
rund um Ausbildung, Job, Weiterbildung für IT-Fachkräfte.

Fachinformatiker.de App

Download on the App Store
Get it on Google Play

Kontakt

Hier werben?
Oder sende eine E-Mail an

Social media u. feeds

Jobboard für Fachinformatiker und IT-Fachkräfte

×
×
  • Neu erstellen...