Die ganze Panel Klasse ansprechen

Für allgemeine Fragen zur Programmierung, welche nicht! direkt mit Lazarus zu tun haben.
Boneless
Beiträge: 52
Registriert: So 1. Dez 2013, 14:15
OS, Lazarus, FPC: Windows 7 (L 1.0.14 - FPC 2.6.0)
CPU-Target: 64Bit
Wohnort: Ostsee

Re: Die ganze Panel Klasse ansprechen

Beitrag von Boneless »

wp_xyz hat geschrieben:ok - also Kommando zurück und ganz von vorne: Du hast ein Menu mit MenuItems, bei denen ein Klick ein bestimmtes Panel sichtbar macht? In solchen Fällen verwende ich die "Tag"-Eigenschaft, die jedem Control zugeordnet ist, hier kann man Zusatzinformation speichern, "Tag" wird ansonsten für nichts anderes verwendet. "Tag" ist vom Typ ein PtrInt, das ist ein Integer, der genauso viel Speicher belegt wie ein Pointer - das ist für 32-Bit Programme egal, wird aber bei 64-Bit wichtig, wo Pointer und Integer unterschiedliche Größen haben. Deine Panels, die im Object Inspektor als "Panel1", "Panel2" etc. bezeichnet werden, sind intern nichts anderes als Pointer. Du kannst damit jedem Tag eines MenuItems das zugehörige Panel zuweisen; leider geht das nicht im Object-Inspektor, und du musst das in der FormCreate-Methode erledigen:

Code: Alles auswählen

 
procedure TForm1.FormCreate(Sender: TObject);
begin
  MenuItem1.Tag := PtrInt(Panel1);
  MenuItem2.Tag := PtrInt(Panel2);
  // etc.
end;
 
Dabei bewirkt das PtrInt(...) eine Typ-Umwandlung, d.h. der Compiler wird angewiesen, den Pointer Panel1 als Integer zu interpretieren. Nach dieser längeren Schreibprozedur kennt jeder MenuItem das ihm zugewiesene Panel, und man kann in der OnClick-Routine das Panel aus- und einschalten:

Code: Alles auswählen

 
procedure TForm1.MenuItemClick(Sender: TObject);
var
  panel: TPanel;
  mnuitem: TMenuItem;
begin
  if (Sender is TMenuItem) then begin
    mnuitem := TMenuItem(mnuItem);
    panel := TPanel(mnuItem.Tag);
    panel.Visible := mnuItem.Checked;
    panel.Enabled := mnuItem.Checked;
  end;
end;
 
Klaro?
Ich muss dich enttäuschen. Ich komm da noch nicht so ganz mit :(

Hier sonst mal mein Code

Code: Alles auswählen

unit Unit1;
 
{$mode objfpc}{$H+}
 
interface
 
uses
  Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, Menus,
  ExtCtrls, StdCtrls;
 
type
 
  { TForm1 }
 
  TForm1 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    Button3: TButton;
    Button4: TButton;
    Button5: TButton;
    Image1: TImage;
    Image2: TImage;
    Image3: TImage;
    Image4: TImage;
    Image5: TImage;
    Label1: TLabel;
    Label2: TLabel;
    Label3: TLabel;
    Label4: TLabel;
    Label5: TLabel;
    Label6: TLabel;
    Label7: TLabel;
    MainMenu1: TMainMenu;
    MenuItem1: TMenuItem;
    MenuItem10: TMenuItem;
    MenuItem11: TMenuItem;
    MenuItem12: TMenuItem;
    MenuItem13: TMenuItem;
    MenuItem14: TMenuItem;
    MenuItem15: TMenuItem;
    MenuItem16: TMenuItem;
    MenuItem17: TMenuItem;
    MenuItem18: TMenuItem;
    MenuItem19: TMenuItem;
    MenuItem2: TMenuItem;
    MenuItem20: TMenuItem;
    MenuItem21: TMenuItem;
    MenuItem22: TMenuItem;
    MenuItem23: TMenuItem;
    MenuItem24: TMenuItem;
    MenuItem25: TMenuItem;
    MenuItem26: TMenuItem;
    MenuItem27: TMenuItem;
    MenuItem28: TMenuItem;
    MenuItem29: TMenuItem;
    MenuItem3: TMenuItem;
    MenuItem30: TMenuItem;
    MenuItem31: TMenuItem;
    MenuItem32: TMenuItem;
    MenuItem33: TMenuItem;
    MenuItem34: TMenuItem;
    MenuItem35: TMenuItem;
    MenuItem36: TMenuItem;
    MenuItem37: TMenuItem;
    MenuItem38: TMenuItem;
    MenuItem39: TMenuItem;
    MenuItem4: TMenuItem;
    MenuItem40: TMenuItem;
    MenuItem41: TMenuItem;
    MenuItem42: TMenuItem;
    MenuItem43: TMenuItem;
    MenuItem44: TMenuItem;
    MenuItem45: TMenuItem;
    MenuItem46: TMenuItem;
    MenuItem47: TMenuItem;
    MenuItem48: TMenuItem;
    MenuItem49: TMenuItem;
    MenuItem5: TMenuItem;
    MenuItem50: TMenuItem;
    MenuItem51: TMenuItem;
    MenuItem52: TMenuItem;
    MenuItem53: TMenuItem;
    MenuItem54: TMenuItem;
    MenuItem55: TMenuItem;
    MenuItem56: TMenuItem;
    MenuItem57: TMenuItem;
    MenuItem58: TMenuItem;
    MenuItem59: TMenuItem;
    MenuItem6: TMenuItem;
    MenuItem60: TMenuItem;
    MenuItem61: TMenuItem;
    MenuItem62: TMenuItem;
    MenuItem63: TMenuItem;
    MenuItem64: TMenuItem;
    MenuItem65: TMenuItem;
    MenuItem66: TMenuItem;
    MenuItem67: TMenuItem;
    MenuItem68: TMenuItem;
    MenuItem69: TMenuItem;
    MenuItem7: TMenuItem;
    MenuItem70: TMenuItem;
    MenuItem71: TMenuItem;
    MenuItem72: TMenuItem;
    MenuItem73: TMenuItem;
    MenuItem74: TMenuItem;
    MenuItem75: TMenuItem;
    MenuItem76: TMenuItem;
    MenuItem77: TMenuItem;
    MenuItem78: TMenuItem;
    MenuItem79: TMenuItem;
    MenuItem8: TMenuItem;
    MenuItem80: TMenuItem;
    MenuItem81: TMenuItem;
    MenuItem82: TMenuItem;
    MenuItem83: TMenuItem;
    MenuItem84: TMenuItem;
    MenuItem85: TMenuItem;
    MenuItem86: TMenuItem;
    MenuItem87: TMenuItem;
    MenuItem88: TMenuItem;
    MenuItem89: TMenuItem;
    MenuItem9: TMenuItem;
    MenuItem90: TMenuItem;
    Panel1: TPanel;
    Panel2: TPanel;
    Panel3: TPanel;
    Panel4: TPanel;
    Panel5: TPanel;
    Panel6: TPanel;
    Panel7: TPanel;
    Panel8: TPanel;
    Panel9: TPanel;
    Panel10: TPanel;
    Panel11: TPanel;
    Panel12: TPanel;
    Panel13: TPanel;
    Panel14: TPanel;
    Panel15: TPanel;
    Panel16: TPanel;
    Panel17: TPanel;
    Panel18: TPanel;
    Panel19: TPanel;
    Panel20: TPanel;
    Panel21: TPanel;
    Panel22: TPanel;
    Panel23: TPanel;
    Panel24: TPanel;
    Panel25: TPanel;
    Panel26: TPanel;
    Panel27: TPanel;
    Panel28: TPanel;
    Panel29: TPanel;
    Panel30: TPanel;
    Panel31: TPanel;
    Panel32: TPanel;
    Panel33: TPanel;
    Panel34: TPanel;
    Panel35: TPanel;
    Panel36: TPanel;
    Panel37: TPanel;
    Panel38: TPanel;
    Panel39: TPanel;
    Panel40: TPanel;
    Panel41: TPanel;
    Panel42: TPanel;
    Panel43: TPanel;
    Panel44: TPanel;
    Panel45: TPanel;
    Panel46: TPanel;
    Panel47: TPanel;
    Panel48: TPanel;
    Panel49: TPanel;
    Panel50: TPanel;
    Panel51: TPanel;
    Panel52: TPanel;
    Panel53: TPanel;
    Panel54: TPanel;
    Panel55: TPanel;
    Panel56: TPanel;
    Panel57: TPanel;
    Panel58: TPanel;
    Panel59: TPanel;
    Panel60: TPanel;
    Panel61: TPanel;
    Panel62: TPanel;
    Panel63: TPanel;
    Panel64: TPanel;
    Panel65: TPanel;
    Panel66: TPanel;
    Panel67: TPanel;
    Panel68: TPanel;
    Panel69: TPanel;
    Panel70: TPanel;
    Panel71: TPanel;
    Panel72: TPanel;
    Panel73: TPanel;
    Panel74: TPanel;
    Panel75: TPanel;
    Panel76: TPanel;
    Panel77: TPanel;
    Panel78: TPanel;
    Panel79: TPanel;
    Panel80: TPanel;
    Panel81: TPanel;
    Panel82: TPanel;
    Panel83: TPanel;
    Panel84: TPanel;
    Panel85: TPanel;
    Panel86: TPanel;
    Panel87: TPanel;
    Panel88: TPanel;
    Panel89: TPanel;
    procedure FormCreate(Sender: TObject);
    procedure MenuItem9Click(Sender: TObject);
  private
  public
    { public declarations }
  end;
 
var
  Form1: TForm1;
  ArrPanel: array[1..20] of Record
  Panel: TPanel;
  Button: TButton;
  end;
implementation
 
{$R *.lfm}
 
{ TForm1 }
 
procedure Aufruflink;
begin
  ShowMessage('Das Programm wurde Ihnen auf das Desktop gelegt.');
end;
 
procedure TForm1.FormCreate(Sender: TObject);
begin
  MenuItem9.Tag := PtrInt(Panel2);
end;
 
procedure TForm1.MenuItem9Click(Sender: TObject);
var
  panel: TPanel;
  mnuitem: TMenuItem;
begin
  if (Sender is TMenuItem) then begin
    mnuitem := TMenuItem(mnuItem);
    panel := TPanel(mnuItem.Tag);
    panel.Visible := mnuItem.Checked;
    panel.Enabled := mnuItem.Checked;
  end;
  end;
end.
 
Diese eine Funktion Aufruflink ist für später gedacht

Code: Alles auswählen

program Boneless;
 
 {$mode Einsteiger}{H+}

wp_xyz
Beiträge: 5135
Registriert: Fr 8. Apr 2011, 09:01

Re: Die ganze Panel Klasse ansprechen

Beitrag von wp_xyz »

Bei einem Klick auf MenuItem9 müsste Panel9 sichtbar werden. Es tut sich sich natürlich nichts, wenn Panel9 per Default schon sichtbar ist, setze es im Object Inspector mal auf Visisble = false. Au0erdem solltest du schon noch ein paar MenuItems entsprechend behandeln, um einen Effekt zu sehen...

Ansonsten poste das komplette Project (alle pas, lfm, lpi und lpr-Dateien in ein zip-Archiv packen), ich habe keine Lust, mir hier ein Formular mit 89 Panels und 90 MenuItems zusammenzuklicken.

Michl
Beiträge: 2511
Registriert: Di 19. Jun 2012, 12:54

Re: Die ganze Panel Klasse ansprechen

Beitrag von Michl »

Boneless hat geschrieben:Ich komm da noch nicht so ganz mit
Das hat er doch sehr gut beschrieben! Zum Verständnis noch folgende Anmerkung: Du brauchst nur eine Procedure MenuItemClick schreiben, diese dann mit allen MenuItems.OnClick verknüpfen (im Objektinspektor), evtl. ist das noch nicht so ganz klar?!
wp_xyz hat geschrieben:Bei einem Klick auf MenuItem9 müsste Panel9 sichtbar werden.
Dies funktioniert aber nur, wenn

Code: Alles auswählen

procedure TForm1.FormCreate(Sender: TObject);
begin
  MenuItem9.Tag := PtrInt(Panel2);
//in
  MenuItem9.Tag := PtrInt(Panel9);
//geändert wird!
end;
:)

Code: Alles auswählen

type
  TLiveSelection = (lsMoney, lsChilds, lsTime);
  TLive = Array[0..1] of TLiveSelection;  

wp_xyz
Beiträge: 5135
Registriert: Fr 8. Apr 2011, 09:01

Re: Die ganze Panel Klasse ansprechen

Beitrag von wp_xyz »

Michl hat geschrieben: Dies funktioniert aber nur, wenn
MenuItem9.Tag := PtrInt(Panel2);
in
MenuItem9.Tag := PtrInt(Panel9);
geändert wird!
Gut beobachtet!

Boneless
Beiträge: 52
Registriert: So 1. Dez 2013, 14:15
OS, Lazarus, FPC: Windows 7 (L 1.0.14 - FPC 2.6.0)
CPU-Target: 64Bit
Wohnort: Ostsee

Re: Die ganze Panel Klasse ansprechen

Beitrag von Boneless »

Ja ich weiß. Es ist sehr sehr sehr extrem verwirrend. Tut mir auch Leid.
Aber was ich eigentlich ja nur möchte, dass es funktioniert, dass ich alle Panels (von 1 bis 89) ansprechen kann. Das reicht mir schon! Dann kann ich glücklich schlafen gehen! :)
Bitte versteht das nicht falsch und seid mir auch nicht böse deswegen :wink:

Also ich brauch einfach nur n Code-Schnipsel, womit ich es schaffen kann, dass alle Panels "gleichzeitig" behandelt werden können - mit nur einem Klick! :wink:

Code: Alles auswählen

program Boneless;
 
 {$mode Einsteiger}{H+}

Michl
Beiträge: 2511
Registriert: Di 19. Jun 2012, 12:54

Re: Die ganze Panel Klasse ansprechen

Beitrag von Michl »

Hab nochmal ein funktionierendes Bsp angefügt, ähnlich Code oben. Es gäbe auch dazu noch viel zu sagen, doch versuchs erstmal, viel Erfolg!

Hauptsächliche Änderung:

Code: Alles auswählen

procedure TForm1.MenuItem1Click(Sender: TObject);
var
  panel: TPanel;
  mnuitem: TMenuItem;
begin
  if (Sender is TMenuItem) then begin
    mnuitem := TMenuItem(Sender);  //hier stand "mnuitem"
    panel := TPanel(mnuItem.Tag);
 
    if assigned(panel) then begin  //und nachfolgendes habe ich anders gemacht
      panel.Visible := not panel.Visible;
      panel.Enabled := not panel.Enabled;
    end;
  end;
end;
Bitte versteht das nicht falsch und seid mir auch nicht böse deswegen :wink:
Hier ist niemand jemanden böse, nur der Ton ist manchmal etwas knisternd und nicht Knigge'rnd. Im Vergleich zu anderen deutschsprachigen Fach-Foren aber akzeptabel...

Code: Alles auswählen

type
  TLiveSelection = (lsMoney, lsChilds, lsTime);
  TLive = Array[0..1] of TLiveSelection;  

Boneless
Beiträge: 52
Registriert: So 1. Dez 2013, 14:15
OS, Lazarus, FPC: Windows 7 (L 1.0.14 - FPC 2.6.0)
CPU-Target: 64Bit
Wohnort: Ostsee

Re: Die ganze Panel Klasse ansprechen

Beitrag von Boneless »

OK gut zu wissen :)

Aber ich glaube, wir reden etwas aneinander vorbei...
Gibt es nicht eine Möglichkeit? Einfach durch eine Schleife alle Panels beim Unterpunkt Enabled und Visible auf False zu setzen?
Einfach nur ne for-Schleife, die jedes Panel einmal durchgeht und die Werte dementsprechend verändert.
Weil diese for-Schleife, die ich meine und suche, würde mir schon sowas von weiterhelfen. Auch wenn es nicht programmiererfreundlich sein mag... diese for-Schleife... Dennoch würde mich das sehr weit bringen.

Trotzdem vielen vielen Dank für deinen Aufwand und deine Mühe!!

Verstehst wie ich meine? :wink:

Code: Alles auswählen

program Boneless;
 
 {$mode Einsteiger}{H+}

Michl
Beiträge: 2511
Registriert: Di 19. Jun 2012, 12:54

Re: Die ganze Panel Klasse ansprechen

Beitrag von Michl »

Hast Du das Projekt Dir angesehen? Nein! Ich denke, bevor Du Dich beschwerst, solltest Du das erstmal machen. Ich war einfach nur zu faul, die Autochecked-Eigenschaften einzustellen, daher hatte ich den Code umgestellt. Eine Procedure stellt alle Panels an/aus mit dem Klick auf das jeweilige Menu-Item!

Um später zu prüfen, ob Panel sichtbar/enabled ist, könntest Du, wie von wp_xyz vorgeschalgen, auf MenuItem.checked prüfen (müsstest, da halt die Checked-Eigenschaften einschalten), genauso aber auch auf Panel.. .visible/enabled. Dies in eine Schleife zu packen führt Dich aber wieder zum Array (oder zur Überprüfung aller Componenten der Form)...

Code: Alles auswählen

type
  TLiveSelection = (lsMoney, lsChilds, lsTime);
  TLive = Array[0..1] of TLiveSelection;  

Michl
Beiträge: 2511
Registriert: Di 19. Jun 2012, 12:54

Re: Die ganze Panel Klasse ansprechen

Beitrag von Michl »

Boneless hat geschrieben:Weil diese for-Schleife, die ich meine und suche, würde mir schon sowas von weiterhelfen. Auch wenn es nicht programmiererfreundlich sein mag... diese for-Schleife... Dennoch würde mich das sehr weit bringen.
Anbei noch die Schleife und MenuItem.Checked im Projekt.

Schleife z.B. so:

Code: Alles auswählen

procedure TForm1.Button1Click(Sender: TObject);
var
  i: Integer;
begin
  memo1.Lines.Clear;
  memo1.Lines.Add('Folgende Panels sind sichtbar:');
  for i:=0 to ComponentCount-1 do
    if Components[i] is TPanel then
      if TPanel(Components[i]).Visible then
        memo1.Lines.Add(TPanel(Components[i]).Name);
end;  

Code: Alles auswählen

type
  TLiveSelection = (lsMoney, lsChilds, lsTime);
  TLive = Array[0..1] of TLiveSelection;  

Boneless
Beiträge: 52
Registriert: So 1. Dez 2013, 14:15
OS, Lazarus, FPC: Windows 7 (L 1.0.14 - FPC 2.6.0)
CPU-Target: 64Bit
Wohnort: Ostsee

Re: Die ganze Panel Klasse ansprechen

Beitrag von Boneless »

Ich habe es mir zwar angesehen, aber muss dazu auch sagen:
Es tut mir aufrichtig Leid, ich denke, ich habe mich nochmals falsch ausgedrückt. :oops: :oops: :oops:

So ist dieses Programmchen ja schon richtig. Es funktioniert ja auch alles. Bloß es soll ja nur ein Panel zur Zeit sichtbar sein.
Wenn MenuItem2 angeklickt wurde, ist nur Panel 2 zusehen. Alle anderen sind unabled und visibled sozusagen.
Wenn MenuItem8 angeklickt wurde, ist nur Panel 8 zusehen - kein anderes.

Kannst mir jetztz folgen, wie ich das meinte? :D

Code: Alles auswählen

program Boneless;
 
 {$mode Einsteiger}{H+}

Michl
Beiträge: 2511
Registriert: Di 19. Jun 2012, 12:54

Re: Die ganze Panel Klasse ansprechen

Beitrag von Michl »

Achso...

Ja warte, gleich ...

Code: Alles auswählen

type
  TLiveSelection = (lsMoney, lsChilds, lsTime);
  TLive = Array[0..1] of TLiveSelection;  

Boneless
Beiträge: 52
Registriert: So 1. Dez 2013, 14:15
OS, Lazarus, FPC: Windows 7 (L 1.0.14 - FPC 2.6.0)
CPU-Target: 64Bit
Wohnort: Ostsee

Re: Die ganze Panel Klasse ansprechen

Beitrag von Boneless »

Kein Problem :lol:
Falls du jetzt vor Wut deinen Schreibtisch oder was auch immer auseinander nimmst, übernehm ich keine Haftung ^^

Code: Alles auswählen

program Boneless;
 
 {$mode Einsteiger}{H+}

Michl
Beiträge: 2511
Registriert: Di 19. Jun 2012, 12:54

Re: Die ganze Panel Klasse ansprechen

Beitrag von Michl »

Ist zwar jetzt glaub ich für Dich gar nicht mehr nachzuvollziehen, aber ersetze mal die Procedure im letzten geposteten Projekt (Achtung Checked inside):

Code: Alles auswählen

procedure TForm1.MenuItem1Click(Sender: TObject);
var
  mnuitem: TMenuItem;
  i: Integer;
begin
  if (Sender is TMenuItem) then begin
    mnuitem := TMenuItem(Sender);
 
    if assigned(TPanel(mnuitem.Tag)) then
 
      for i:=0 to ComponentCount-1 do
        if (Components[i] is TMenuItem) and assigned(TPanel(Components[i].Tag)) then
          if Components[i]=mnuitem then begin
            TMenuItem(Components[i]).Checked:=True;
            TPanel(TMenuItem(Components[i]).Tag).Visible:=True;
            TPanel(TMenuItem(Components[i]).Tag).Enabled:=True;
          end else begin
            TMenuItem(Components[i]).Checked:=False;
            TPanel(TMenuItem(Components[i]).Tag).Visible:=False;
            TPanel(TMenuItem(Components[i]).Tag).Enabled:=False;
          end;
  end;
end;  
oder nochmal anbei als Projekt.

Evtl. ist für Dich leichter zu verstehen, wenn Du wie im ersten geposteten Bsp von wp_xyz ein Array nimmst???

Code: Alles auswählen

type
  TLiveSelection = (lsMoney, lsChilds, lsTime);
  TLive = Array[0..1] of TLiveSelection;  

Boneless
Beiträge: 52
Registriert: So 1. Dez 2013, 14:15
OS, Lazarus, FPC: Windows 7 (L 1.0.14 - FPC 2.6.0)
CPU-Target: 64Bit
Wohnort: Ostsee

Re: Die ganze Panel Klasse ansprechen

Beitrag von Boneless »

Ja super!

Das ist genau das, wonach ich suchte ! :D :) :lol:

Wirklich Tausend Dank an dich!

PS: Dein letzter Anhang kann man nur weiterempfehlen. Gute Basis - Daumen hoch

Code: Alles auswählen

program Boneless;
 
 {$mode Einsteiger}{H+}

Michl
Beiträge: 2511
Registriert: Di 19. Jun 2012, 12:54

Re: Die ganze Panel Klasse ansprechen

Beitrag von Michl »

Na dann weiterhin viel Erfolg, einen schönen Rest-1.-Advent und ach ja, noch ein herzliches Willkommen in deutschsprachigen Lazarusforum!

Code: Alles auswählen

type
  TLiveSelection = (lsMoney, lsChilds, lsTime);
  TLive = Array[0..1] of TLiveSelection;  

Antworten