Entwickler-Ecke

Grafische Benutzeroberflächen (VCL & FireMonkey) - ImageList auf BitBtn geht nur einmal


J.Borchert - Do 29.09.05 20:26
Titel: ImageList auf BitBtn geht nur einmal
Habe 48 BitBtn dehnen der User ein Glyph zuweisen soll. Zur Auswahl stehen 3 BMP-Grafiken 19x19 in einer ImageList.

Gehe momentan diesen Weg:

Delphi-Quelltext
1:
2:
3:
4:
5:
procedure TForm1.BitBtn1ContextPopup(Sender: TObject; MousePos: TPoint;
 var Handled: Boolean);
begin 
       Tag:=1// so merke ich mir, welcher Button per PopUp geändert werden soll 
end;


Das Popupmenu1 ist allen Button zugeordnet.


Delphi-Quelltext
1:
2:
3:
4:
procedure TForm1.SetzeIcon1Click(Sender: TObject); // PopUpMenu1 1.Eintrag
begin 
       ImageList1.GetBitmap(0,TBitBtn(Form1.FindComponent('BitBtn'+inttoStr(Tag))).Glyph);
end;


Das Ganze geht nur einmal. Danach geht scheinbar das Glyph nichtmehr zu ändern.

Kann mir mal einer einen Tip geben, wie ich das einfacher löse und warum es nach dem ersten Mal nichtmehr geht ?

mfG Juergen


jensemann - Do 29.09.05 22:03

Du setzt für alle BitBtns auf deiner Form den Tag entsprechend der Nummer im Namen des BitBtns im Objektinspektor:

BitBtn1.Tag := 1;
BitBtn1.Tag := 2;
u.s.w.

Dann hinterlegst du hinter allen BitBtns die gleiche MouseDown Procedure wie folgt:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
procedure TForm1.BitBtn1MouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
  if shift = [ssRight] then
  begin
    Form1.Tag := (Sender as TBitBtn).Tag;
  end;
end;


Die ContextPopup Events in den BitBtns kannst du weg lassen. Nun sollte deine SetzeIcon1Click Procedure funktionieren.


J.Borchert - Fr 30.09.05 08:28

Der Aufwand bleibt der Gleiche, da ich für alle BitBtn eine Prozedur vervielfältigen muß genau wie vorher mit OnContextPopUp.

Es lässt sich mit Deiner Variante auch nur einmal das Glyph wechseln. Danach ist es nichtmehr möglich. Der Fehler scheint also woanders zu liegen.

Hoffentlich fällt es noch jemandem auf... bin schon ein bisschen am Verzweifeln...

mfG Jürgen


Lannes - Fr 30.09.05 09:06

Hallo,

damit ein BitBtn ein anderes Glyph annimmt,
musst Du es erst auf nil setzen.
Bei Deiner Variante mit Tag und FindComponent bist Du auf
die Einhaltung einer eindeutigen Bezeichnung der BitBtns angewiesen.
Ich schlage Dir mal folgenden Ansatz vor:

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:
//...
  MyBitBtn :TBitBtn;
//...
implementation
{$R *.DFM}

procedure TForm1.Icon0Click(Sender: TObject);
begin
  MyBitBtn.Glyph := nil;
  ImageList1.GetBitmap(0,MyBitBtn.Glyph);
end;

procedure TForm1.Icon1Click(Sender: TObject);
begin
  MyBitBtn.Glyph := nil;
  ImageList1.GetBitmap(1,MyBitBtn.Glyph);
end;

procedure TForm1.Icon2Click(Sender: TObject);
begin
  MyBitBtn.Glyph := nil;
  ImageList1.GetBitmap(2,MyBitBtn.Glyph);
end;

procedure TForm1.PopupMenu1Popup(Sender: TObject);
begin
  MyBitBtn := TBitBtn(PopupMenu1.PopupComponent);
end;


J.Borchert - Fr 30.09.05 09:40

Danke Lannes,

dank dem Forum und auch dir, ich bin ebenfalls gerade auf die Lösung gestossen:

http://www.delphi-forum.de/viewtopic.php?t=43512

Für weitere Suchende hier meine Variante:


Delphi-Quelltext
1:
2:
3:
4:
procedure TForm1.BitBtn1ContextPopup(Sender: TObject; MousePos: TPoint;
  var Handled: Boolean);
begin Tag:=1// Form1.Tag wird als Merker, welcher BitBtn geklickt wurde benutzt
end// Objektinspektor-OnContextPopUp- für alle BitBtn anlegen !


BitBtn's dürfen keine neuen Namen erhalten, damit FindComponent funzt

folgende drei Procedure werden bei Klick im Kontextmenü ausgeführt

user defined image


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
procedure TForm1.SetzeIcon1Click(Sender: TObject); // Bitmap 0
begin
  // damit das neue Glyph angezeigt werden kann
  TBitBtn(Form1.FindComponent('BitBtn'+inttoStr(Tag))).Glyph:=nil;
  // Das neue Glyph aus der ImageList zuweisen
  ImageList1.GetBitmap(0,TBitBtn(Form1.FindComponent('BitBtn'+inttoStr(Tag))).Glyph);
  // Glyph-Index im BitBtn.Tag speichern für ini.WriteInteger ...
  TBitBtn(Form1.FindComponent('BitBtn'+inttoStr(Tag))).Tag:=0;
end;

procedure TForm1.Setzerechter1Click(Sender: TObject); // Bitmap 2
begin TBitBtn(Form1.FindComponent('BitBtn'+inttoStr(Tag))).Glyph:=nil;
      ImageList1.GetBitmap(2,TBitBtn(Form1.FindComponent('BitBtn'+inttoStr(Tag))).Glyph);
      TBitBtn(Form1.FindComponent('BitBtn'+inttoStr(Tag))).Tag:=2;
end;
procedure TForm1.Setzelinker1Click(Sender: TObject); // Bitmap 1
begin TBitBtn(Form1.FindComponent('BitBtn'+inttoStr(Tag))).Glyph:=nil;
      ImageList1.GetBitmap(1,TBitBtn(Form1.FindComponent('BitBtn'+inttoStr(Tag))).Glyph);
      TBitBtn(Form1.FindComponent('BitBtn'+inttoStr(Tag))).Tag:=1;
end;


Mein Prog. als Beispiel: http://www.emsat.de/d/p.zip

Nochmals Danke und schönes Wochenende...Jürgen


Lannes - Fr 30.09.05 12:53

Hallo,

warum einfach wenn es auch umständlich geht :wink:
user profile iconJ.Borchert hat folgendes geschrieben:

...Objektinspektor-OnContextPopUp- für alle BitBtn anlegen !...
...BitBtn's dürfen keine neuen Namen erhalten, damit FindComponent funzt...

genau das kann man sich mit meinem Vorschlag sparen, bzw. die BitBtns können beliebige Namen haben.
Das mit den Namen ist so eine Sache, hab mir mal Deinen Code in der Zip angeschaut, ein Ausschnitt:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
procedure TForm1.BitBtn1Click(Sender: TObject);
begin BitBtn1.Enabled:=True; ladePickel(1);end;
procedure TForm1.BitBtn2Click(Sender: TObject);
begin BitBtn2.Enabled:=True; ladePickel(2);end;
procedure TForm1.BitBtn3Click(Sender: TObject);
begin BitBtn3.Enabled:=True; ladePickel(3);end;
procedure TForm1.BitBtn4Click(Sender: TObject);
begin BitBtn4.Enabled:=True; ladePickel(4);end;
procedure TForm1.BitBtn13Click(Sender: TObject);
begin BitBtn13.Enabled:=True; ladePickel(5);end;
procedure TForm1.BitBtn14Click(Sender: TObject);
begin BitBtn14.Enabled:=True; ladePickel(6);end;
//...
procedure B_aus(pickel:integer);
begin if Pickel=1 then Form1.BitBtn1.Enabled:=False;
      if Pickel=2 then Form1.BitBtn2.Enabled:=False;
      if Pickel=3 then Form1.BitBtn3.Enabled:=False;
      if Pickel=4 then Form1.BitBtn4.Enabled:=False;
      if Pickel=5 then Form1.BitBtn13.Enabled:=False;
      if Pickel=6 then Form1.BitBtn14.Enabled:=False;
//...

Das Programm möchte ich nicht pflegen/erweitern müssen :wink:

Bei meinem Vorschlag ist nur folgendes zu erledigen:
Variable MyBitBtn eintragen
die 4 Prozeduren anlegen
den BitBtns das Popup-Menü zuweisen

Die Geschichte kann man ohne globale Variable und noch kürzer mit nur einer Prozedur gestalten:
die Tag-Eigenschaft im OI der TMenuItems mit dem Index der TImageList vorbelegen
(SetzeIcon1 = 0,SetzeIcon2 = 1,SetzeIcon3 = 2)
den BitBtns das Popup-Menü zuweisen
SetzeIcon1Click erzeugen (nachfolgender Code) und
diese Prozedur im OI bei SetzeIcon2.OnClick und SetzeIcon3.OnClick eintragen

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
procedure TForm1.SetzeIcon1Click(Sender: TObject);
begin
  with TBitBtn(PopupMenu1.PopupComponent) do
    begin
      Glyph := nil;
      ImageList1.GetBitmap(TMenuItem(Sender).Tag,Glyph);
    end;
end;


J.Borchert - Fr 30.09.05 16:08

Danke für die Ratschläge. Das ist es, was ich gesucht habe.

mfG Jürgen