Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Multimedia (https://www.delphipraxis.net/16-multimedia/)
-   -   Delphi Mehrere Icons nebeneinander darstellen (https://www.delphipraxis.net/136948-mehrere-icons-nebeneinander-darstellen.html)

schwa226 10. Jul 2009 21:07


Mehrere Icons nebeneinander darstellen
 
Hi,

da ich mit Graphik noch nicht viel gemacht habe komme ich nicht weiter!

Ich will so etwas machen wie die Tray Icon Bar (TNA).
Ich habe mehere Icon-Handles die sich aber auch ständig ändern. HIcon zu TIcon wandlen und in einem Image funktioniert schon mal.

Wie stelle ich die am besten auf einer Form dar wenn es nun mehrere Icons sind? Also auch mit Hinzufügen & Entfernen von Icons. Auch sollte das mit der Mouse so funktionieren wie in der Taskbar. D.H. ich muss erkennen über welchen Icon der Mouse Zeiger ist.

Wie gesagt ich habe aber keine Ahnung wie ich das machen könnte!

Luckie 10. Jul 2009 23:30

Re: Mehrere Icons nebeneinander darstellen
 
Meinst du eventuell eine Toolbar?

schwa226 11. Jul 2009 08:01

Re: Mehrere Icons nebeneinander darstellen
 
Sowas wie die in der TNA bei Windows. Da sind ja auch rechts die Icon.

Ich möchte so eine Form machen, wo ich die Icons draufkriege.
Die muss aber zur Laufzeit veränderbar sein, da ständig Icons dazu oder wegkommen.

Sowas wie TIconList. Habe aber jetzt nichts gefunden und glaube TIconList ist nicht kostenlos!
http://www.greatis.com/delphicb/bonus/iconlist.html

toms 11. Jul 2009 08:49

Re: Mehrere Icons nebeneinander darstellen
 
Zitat:

Zitat von schwa226
Sowas wie die in der TNA bei Windows.

Das ist eine Toolbar (ToolbarWindow32)

schwa226 11. Jul 2009 09:37

Re: Mehrere Icons nebeneinander darstellen
 
Gibt es zu Toolbar ein Sample?

Habe mit Toolbars noch nie gearbeitet.

Wie gesagt ich möchte HIcons darin auflisten.
Brauche eigentlich keine Buttons, nur ein Onclick auf das jeweilige Icon will ich erkennen.
Add, Remove von HIcons sollte gehen.

turboPASCAL 11. Jul 2009 09:46

Re: Mehrere Icons nebeneinander darstellen
 
Zitat:

möchte HIcons darin auflisten
Du kannst auch normale Icons nemen. HIcons ist das Handle also die Speicheradresse des Icons. ;)

Nimmdoch eine Imagelist und packe die Icons dort hinein.

Zeichnen hannst du diese dann zB. in eine Paintbox oder direct auf einen Canvas.

Oder verwende ein Array ... of TIcon.

schwa226 11. Jul 2009 14:12

Re: Mehrere Icons nebeneinander darstellen
 
Aus den HIcons kann ich schon TIcons erzeugen. Auf einem Image sehe ich es dann auch.

Habe versucht eine Toolbar zu erstellen, als Image dann die Imagelist die meine TIcons enthält.
Jedoch sehe ich nichts auf der Toolbar.

Wie bringe ich die Toolbar dazu die Icons zu zeichen, wenn sich die Imagelist ändert?

Andreas L. 11. Jul 2009 16:11

Re: Mehrere Icons nebeneinander darstellen
 
Zitat:

Zitat von schwa226
Aus den HIcons kann ich schon TIcons erzeugen. Auf einem Image sehe ich es dann auch.

Habe versucht eine Toolbar zu erstellen, als Image dann die Imagelist die meine TIcons enthält.
Jedoch sehe ich nichts auf der Toolbar.

Wie bringe ich die Toolbar dazu die Icons zu zeichen, wenn sich die Imagelist ändert?

Du musst der Toolbar TToolButtons hinzufügen (mit einem Rechtsklick auf die Toolbar) und dann den ImageIndex des Buttons anpassen.

schwa226 11. Jul 2009 17:56

Re: Mehrere Icons nebeneinander darstellen
 
Also kann ich nicht dynamisch ToolButtons hinzufügen, oder?

Dann muss ich mir was anderes suchen...

Andreas L. 11. Jul 2009 20:47

Re: Mehrere Icons nebeneinander darstellen
 
Zitat:

Zitat von schwa226
Also kann ich nicht dynamisch ToolButtons hinzufügen, oder?

Dann muss ich mir was anderes suchen...

Das geht natürlich auch:

Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var
  neuerButton: TToolButton;
begin
  neuerButton := TToolButton.Create(ToolBar1);
  with neuerButton do
  begin
    Caption := 'Beschriftung';
    ImageIndex := 0;
    Parent := ToolBar1;
  end;
end;

turboPASCAL 11. Jul 2009 21:26

Re: Mehrere Icons nebeneinander darstellen
 
Man könnte ja auch so:

Delphi-Quellcode:
type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure Button1Click(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

type
  TIconBar = class(TGraphicControl)
  private
    FIconSize: integer;
    FIconSpace: integer;
    FClickedIndex: integer;
    FIconArray: Array of HIcon;
    procedure Sort;
    procedure SetIconSpacer(Value: integer);
  public
    constructor Create(Owner: TComponent); override;
    destructor Destroy; override;
    procedure Paint; override;
    procedure MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override;
    procedure AddIcon(Icon: HIcon);
    procedure DeleteIcon(Index: integer);
    property IconSize: integer read FIconSize;
    property ClickedIndex: integer read FClickedIndex;
    property IconSpacer: integer read FIconSpace write SetIconSpacer;
  end;

var
  Form1: TForm1;
  IconBar: TIconBar;

implementation

{$R *.dfm}

constructor TIconBar.Create;
begin
  inherited Create(Owner);

  FIconSize := 32;
  FIconSpace := 5;

  Width := FIconSize;
  Height := FIconSize;
end;

destructor TIconBar.Destroy;
var i: integer;
begin
  for i := 0 to length(FIconArray)-1 do
    DeleteObject(FIconArray[i]);
  SetLength(FIconArray, 0);

  inherited Destroy;
end;

procedure TIconBar.Sort;
var i,j,help, entrys: cardinal;
begin
  Entrys := length(FIconArray)-1;
  if Entrys > 0 then
  begin
    for i := 0 to Entrys - 1 do
      for j := i + 1 to Entrys do
        if FIconArray[i] < FIconArray[j] then
        begin
          help := FIconArray[i];
          FIconArray[i] := FIconArray[j];
          FIconArray[j] := help;
        end;
  end;
end;

procedure TIconBar.SetIconSpacer(Value: integer);
begin
  FIconSpace := Value;
end;

procedure TIconBar.Paint;
var i: integer;
begin
  Canvas.Brush.Color := Color;
  Canvas.Brush.Style := bsSolid;
  Canvas.FillRect(ClientRect);

  for i := 0 to length(FIconArray)-1 do
    DrawIconEx(Canvas.Handle, i * (FIconSize + FIconSpace), 0, FIconArray[i], FIconSize, FIconSize, 0, 0, DI_NORMAL);
end;

procedure TIconBar.MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin

end;

procedure TIconBar.AddIcon;
begin
  Width := length(FIconArray) * (FIconSize + FIconSpace) + FIconSize;
  SetLength(FIconArray, length(FIconArray) + 1);
  FIconArray[length(FIconArray)-1] := Icon;
  Invalidate;
end;

procedure TIconBar.DeleteIcon;
begin
  // todo:

  if (index >= 0) and (index < length(FIconArray)) then
  begin
    DeleteObject(FIconArray[index]);
    FIconArray[index] := 0;

    // (Re) Sort ... die Lücke muss nach oben
    Sort;

    // Löschen des Null-Eintrags
    SetLength(FIconArray, length(FIconArray));

    Width := length(FIconArray) * (FIconSize + FIconSpace) - FIconSpace;
    Invalidate;
  end;
end;

// -------------------------------------------------------------------------//

procedure TForm1.FormCreate(Sender: TObject);
begin
  IconBar := TIconBar.Create(Self);
  IconBar.Top := 40;
  IconBar.Left := 40;
  IconBar.Parent := Self;
  IconBar.AddIcon( LoadIcon(0, IDI_APPLICATION) );
  IconBar.AddIcon( LoadIcon(0, IDI_ASTERISK) );
  IconBar.AddIcon( LoadIcon(0, IDI_EXCLAMATION) );
  IconBar.AddIcon( LoadIcon(0, IDI_HAND) );
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  IconBar.Free;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  IconBar.DeleteIcon(1);
end;

schwa226 11. Jul 2009 21:54

Re: Mehrere Icons nebeneinander darstellen
 
Danke!

Habe jetzt beide Ausprobiert!

Bei der Toolbox habe ich das Problem, dass die neuen Icons immer links, also Index = 0 hinzugefügt werden!
Kann man das umstellen, dass die Icons immer am Ende hinzugefügt werden?
Denn sonst ist es ja genau anders rum wie mein Dyn Array.

Auch schaffe ich es nicht die Icon Größe zu verändern.
Ich möchte gern die Icons mit 32x32 darstellen.



Die zweite Methode schaut auch gut aus, aber da habe ich das nächste Problem: ToolTip zu jedem Icon.
Wie erkenne ich auch auf welches Icon mit der Mouse gedrückt wurde?

Andreas L. 11. Jul 2009 22:00

Re: Mehrere Icons nebeneinander darstellen
 
Zitat:

Zitat von schwa226

Bei der Toolbox habe ich das Problem, dass die neuen Icons immer links, also Index = 0 hinzugefügt werden!
Kann man das umstellen, dass die Icons immer am Ende hinzugefügt werden?
Denn sonst ist es ja genau anders rum wie mein Dyn Array.

Entweder mit ToolButton.Left oder ToolButton.Index an die richtige Position schieben.
Zitat:

Zitat von schwa226
Auch schaffe ich es nicht die Icon Größe zu verändern.
Ich möchte gern die Icons mit 32x32 darstellen.

Delphi-Quellcode:
ToolButton.AutoSize := True;
Toolbar.AutoSize := True;
ImageList.Width := 32;
ImageList.height := 32;
Du könntest dir auch mal tListView mit ViewStyle := vsLargeIcons anschauen.

schwa226 11. Jul 2009 22:29

Re: Mehrere Icons nebeneinander darstellen
 
Tut leid aber,

Index kann nichts zugewiesen werden.

Das mit der Größe geht auch nicht.

Wenn ich dem TIcon sagen will das es 32x32 sein soll gibt es ein Fehler: Göße kann nicht geändert werden.

Wenn ich nun also das 16x16 Icon auf die ImageList mit 32x32 lege bekomme ich auch einen Error, da unterschiedliche Größe :wall:

Andreas L. 12. Jul 2009 09:33

Re: Mehrere Icons nebeneinander darstellen
 
Zitat:

Zitat von schwa226
Tut leid aber,

Index kann nichts zugewiesen werden.

Dann machs mit Left oder schau dir die anderen Methoden / Eigenschaften von TToolButton und TToolbar an. Steht recht ausführlich in der Delphi-Hilfe und genügend Beispiele findet man hier im Forum auch...
Zitat:

Zitat von schwa226
Das mit der Größe geht auch nicht.

Wenn ich dem TIcon sagen will das es 32x32 sein soll gibt es ein Fehler: Göße kann nicht geändert werden.

Wenn ich nun also das 16x16 Icon auf die ImageList mit 32x32 lege bekomme ich auch einen Error, da unterschiedliche Größe :wall:

Wie holst du dir denn das Icon-Handle?

schwa226 12. Jul 2009 09:54

Re: Mehrere Icons nebeneinander darstellen
 
Hab es nun so gelößt:

ich steppe mein Array durch bis ich das richtige Item gefunden habe, dann:

ButtonIndex := Buttoncount - i - 1.

Das geht so ganz gut!

Die HIcons bekomme ich von der TNA, TNotificationData. Und da sind nur die Handles von den 16x16 Icons drinnen.
Man müsste also das Icon Stretchen.

Andreas L. 12. Jul 2009 10:27

Re: Mehrere Icons nebeneinander darstellen
 
Zitat:

Zitat von schwa226
Hab es nun so gelößt:

ich steppe mein Array durch bis ich das richtige Item gefunden habe, dann:

ButtonIndex := Buttoncount - i - 1.

Das geht so ganz gut!

Die HIcons bekomme ich von der TNA, TNotificationData. Und da sind nur die Handles von den 16x16 Icons drinnen.
Man müsste also das Icon Stretchen.

Du kannst bestimmt die Dateinamen der dort angezeigten Programme ermitteln, also kannst du dir auch 32er Bildchen holen...

schwa226 12. Jul 2009 10:57

Re: Mehrere Icons nebeneinander darstellen
 
Ich glaube das ist ein Problem,

den die Icons der gleichen Application ändern sich!
D.H. die exe bleibt die gleiche aber das Icon-Handle ändert sich.

Andreas L. 12. Jul 2009 11:04

Re: Mehrere Icons nebeneinander darstellen
 
Zitat:

Zitat von schwa226
Ich glaube das ist ein Problem,

den die Icons der gleichen Application ändern sich!
D.H. die exe bleibt die gleiche aber das Icon-Handle ändert sich.

Dann musst du Bilder eben strecken. Hier im Forum suchenStretchDraw

schwa226 12. Jul 2009 17:03

Re: Mehrere Icons nebeneinander darstellen
 
Danke!

WErds mir noch ansehen!

Jetzt habe ich dazu noch eine Frage. Wie geht das dann bei der Toolbar mit OnMouseDown?
Wie finde ich heraus welcher Button gedrückt wurde?

Andreas L. 12. Jul 2009 18:18

Re: Mehrere Icons nebeneinander darstellen
 
Zitat:

Zitat von schwa226
Danke!

WErds mir noch ansehen!

Jetzt habe ich dazu noch eine Frage. Wie geht das dann bei der Toolbar mit OnMouseDown?
Wie finde ich heraus welcher Button gedrückt wurde?

Du definierst dir ein OnClick-Event und weist es jeden Button beim erstellen zu:
Delphi-Quellcode:

procedure TForm1.ToolButtonClick(Sender: TObject);
begin
  if Sender is TToolButton then
    ShowMessage('Button mit dem Index "' + IntToStr(TToolButton(Sender).Index) + '" gedrückt."');
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  neuerButton: TToolButton;
begin
  neuerButton := TToolButton.Create(ToolBar1);
  with neuerButton do
  begin
    Caption := 'Beschriftung';
    ImageIndex := 0;
    Parent := ToolBar1;
    OnClick := ToolButtonClick;
  end;
end;
Soll deine IconListe so aussehen: http://www.greatis.com/delphicb/bonu...listdesign.gif ?
Dann solltest du dir mal TListView anschauen.

schwa226 12. Jul 2009 18:28

Re: Mehrere Icons nebeneinander darstellen
 
Liste der Anhänge anzeigen (Anzahl: 1)
Danke für dein Hilfe!

Ich habe mir nun eine neue Class erzeugt, die die Funktionen MouseDown & MouseUp enthält.
Beim erzeugen des Buttons weise ich die Methode dann zu.

In der Methode erkenne ich dadurch welcher Button gedrückt wurde:
Delphi-Quellcode:
ButtonIndex := (Sender as TToolButton).Index;
Anbei wie es jetzt aussieht! Es soll ja sowas wie ein Tray Ersatz werden!

Jetzt muss ich mich halt noch mit dem Vergrößern der Transparanten Icons beschäftigen!

schwa226 12. Jul 2009 19:49

Re: Mehrere Icons nebeneinander darstellen
 
Nun doch noch eine Frage!

Ich habe meinen Code in einer andern Unit. Diese Unit legt auf die Toolbar Buttons an.

Hätte nun probiert:
Delphi-Quellcode:
Function CreateToolBar(Sender : TObject) : Boolean;
var
ToolBarObject : TToolBar;
begin

  ToolBarObject := (Sender as TToolbar);
Aufgerufen wird es so:
Delphi-Quellcode:
CreateToolBar(Form4.Toolbar1);
Es gibt keinen Error, jedoch bleibt auch die Toolbar leer!?

Wie kann ich das Toolbar Objekt übergeben damit es geht ohne die Form4 in die Uses von der Unit aufnehmen zu müssen?

Andreas L. 12. Jul 2009 20:39

Re: Mehrere Icons nebeneinander darstellen
 
1. Musst du dem Parameter var voranstellen damit du ihn als Referenzparameter d. h. Zeiger auf den Speicherbereich des Objekts (Call-by-Reference) verwenden kannst. Bei normalen Parametern erhältst du nur eine Kopie die natürlich nicht ins Original-Objekt zurück kopiert wird.
Delphi-Quellcode:
procedure Test_1(Param: String);
begin
  Param := 'TEST';
end;

procedure Test_2(var Param: String);
begin
  Param := 'TEST';
end;

procedure ButtonClick;
var
  S: String;
begin
  S := 'Hallo';

  Test_1(S); //S = Hallo

  Test_2(S); //S = TEST
end;
2. warum machst du das über eine lokale Variable?

Delphi-Quellcode:
procedure AddToolBarButton(var AToolbar: TToolbar);
var
  NewButton: TToolButton;
begin
  NewButton := TToolButton.Create(AToolbar);
  ...
  NewButton.Parent := AToolbar;
end;
EDIT: Verflixte Schlechtschreibung...

schwa226 13. Jul 2009 07:32

Re: Mehrere Icons nebeneinander darstellen
 
Super Danke für dein Hilfe Andreas!

Jetzt bin ich etwas mehr mit der Toolbox vertraut

Habe das mit der Übergabe per var TToolbox noch probiert!
Geht einwandfrei!

Was mir mit den Icons noch aufgefallen ist:
Auch wenn ich ein 32x32 Icon lade wird dies 16x16 dargestellt. Es kann sein, das die Toolbutton das mit Icons automatisch machen. Werds einmal mit einem Image versuchen!

turboPASCAL 13. Jul 2009 08:08

Re: Mehrere Icons nebeneinander darstellen
 
Liste der Anhänge anzeigen (Anzahl: 1)
Delphi-Quellcode:
// --- Easy - IconBar Version 1.0 by turboPASCAL --- //
;)

Andreas L. 13. Jul 2009 10:10

Re: Mehrere Icons nebeneinander darstellen
 
Zitat:

Zitat von schwa226
Auch wenn ich ein 32x32 Icon lade wird dies 16x16 dargestellt. Es kann sein, das die Toolbutton das mit Icons automatisch machen. Werds einmal mit einem Image versuchen!

Nein, die Toolbar stellt die Symbole in dem Format dar, welches du bei der ImageList mit Hight und Width eingestellt hast.

schwa226 13. Jul 2009 10:45

Re: Mehrere Icons nebeneinander darstellen
 
Danke @turboPASCAL!

Werd's mir ansehen!!

schwa226 16. Jul 2009 05:59

Re: Mehrere Icons nebeneinander darstellen
 
Jetzt habe ich noch eine kleine Frage zu dem Thema!

Ich habe nun mehrere Icons nebeneinander. Per MouseDown/MouseUp & Sender weis ich welches Icon gedrückt wurde.

Nun möchte ich aber die ganze Message die durch das draufclicken entsteht per Sendmessage weiterleiten.

D.h. ich sollte eigentlich nicht auf MouseClick reagieren sondern auf die Message. Jedoch weis ich dann nicht wie ich herausfinden kann, welches Icon gedrückt wurde!?

Ich hoffe das ist verständlich :oops:

turboPASCAL 16. Jul 2009 07:21

Re: Mehrere Icons nebeneinander darstellen
 
Zitat:

Zitat von schwa226
Nun möchte ich aber die ganze Message die durch das draufclicken entsteht per Sendmessage weiterleiten.

D.h. ich sollte eigentlich nicht auf MouseClick reagieren sondern auf die Message.

Welche Message meinst du und was möchtest du mit Sendmessage weiterleiten ? :gruebel:

Andreas L. 16. Jul 2009 10:56

Re: Mehrere Icons nebeneinander darstellen
 
Zitat:

Zitat von schwa226
Jedoch weis ich dann nicht wie ich herausfinden kann, welches Icon gedrückt wurde!?

Wieso verwendest du nicht einfach das OnClick-Ereignis des TToolButtons wie ich es oben schon gepostet habe?

schwa226 16. Jul 2009 14:01

Re: Mehrere Icons nebeneinander darstellen
 
Ich benutze ja die TMS Komponente. :zwinker:

Jedem Icon wird die gleiche OnMouseDown zugewiesen. Durch Filtern des Senders habe ich dann den Index für mein Array, indem das HWND, HICON, Callback usw drinnen steht.

In der OnMouseDown unterscheide ich dann ob linke/rechte/mittlere Mouse Button und schicke dann ein Sendmessage zu dem jeweiligen Hwnd mit z.B. WM_LBUTTONDOWN oder WM_RBUTTONDOWN. Das gleiche natürlich auch mit Up usw.

Jedoch spricht mir nicht jedes Icon auf diese Codes an! Das Realtek HD Audio Manager z.B. gar nichts. Kaspersky Icon jedoch funktionert linke und rechte Mouse.

Deswegen möchte ich die Message die beim Mouseclick entsteht 1:1 weiterleiten, denn in der originalen TNA geht es ja!

so was halt wie: WndProc(var Message: TMessage)

Jedoch habe ich beim OnMouseDown nur diese Parameter:
Delphi-Quellcode:
procedure TForm2.OnMouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
Sender wie gesagt filtere ich heraus, Button filtere ich nach links/rechts/middle.

Wie bekomme ich die TMessage die ich dann per Sendmessage weiterleiten kann?

schwa226 3. Aug 2009 12:04

Re: Mehrere Icons nebeneinander darstellen
 
@turboPASCAL


Habe nun deine Lösung schon eingebaut.

Jedoch hatte ich einige Probleme mit den hIcons.

Ich bekomme meine Icon Handles über TNotifyIconData.

Wenn ich also dem FIconArray dieses Handle zuweise werden nicht alle Icons dargestellt.
Gezeichnet werden sie schon, aber sie tauchen nur kurz auf und sind dann wieder nicht sichtbar.

Wenn ich zuerst mit CopyIcon eine Kopie erzeuge und dieses Handle zuweise sieht es schon besser aus:

Delphi-Quellcode:
IconBar.FIconArray[i].hIcon := CopyIcon(nicData.hIcon);
Wobei nicData den Inhalt von TNotifyIconData enthält!

Beim löschen/entfernen eines Icons lösche ich es wieder mit DestroyIcon.


Alle Zeitangaben in WEZ +1. Es ist jetzt 09:39 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