Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Lazarus (IDE) (https://www.delphipraxis.net/81-lazarus-ide/)
-   -   Objekte Bewegen (https://www.delphipraxis.net/176194-objekte-bewegen.html)

Finki 19. Aug 2013 06:31

Objekte Bewegen
 
Hey, ich habe mal wieder eine Frage/Problem.

Ich habe einen Button, btnMove, wenn ich den drücke dann kann ich auf ein Objekt, z.B. Label, Editfeld oder Memo, drücken um dieses zubewegen.

Bei einem Textfeld funktioniert das auch, aber nicht bei einem Label. Da kommt dann ein Fehler bei meinControl.Left:=.....

Warum geht das nicht bei einem Label??

Hier der Move Code

Delphi-Quellcode:
procedure TForm3.FormMouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
var
   meinControl: TWinControl;

   j : integer; //Schleifen Variable
begin
 MDown:=true;
  if move=true then begin
 if (Sender is TWinControl) then
 if (Sender<>Form3) then
 meinControl := (Sender as TWinControl)
 else
 Exit;
 while MDown=true do
   begin
   meinControl.Left:=(Mouse.CursorPos.x-Form3.Left-Form3.BorderWidth); //Hierhin verweist die Fehlermeldung
   meinControl.Top:=(Mouse.CursorPos.y-Form3.Top-50);
   //Form3.Refresh;
   Application.ProcessMessages;

     for j:=3 to Memo1.Lines.Count do
     begin

       if Memo1.Lines[j]=meinControl.Name then
       begin
         Memo1.Lines[j+2]:=(inttostr(meinControl.BoundsRect.Left));
         Memo1.Lines[j+3]:=(inttostr(meinControl.BoundsRect.Top));
         Memo1.Lines[j+4]:=(inttostr(meinControl.Width));
         Memo1.Lines[j+5]:=(inttostr(meinControl.Height));
       end;

     end;

   end;

  end
  else
  Exit;
end;

DeddyH 19. Aug 2013 07:02

AW: Objekte Bewegen
 
Abgesehen davon, dass ein TLabel kein TWinControl ist: unterliegt die Fehlermeldung der Geheimhaltung, oder wieso nennst Du sie nicht?

CarlAshnikov 19. Aug 2013 07:09

AW: Objekte Bewegen
 
Genau, weil TLabel kein WinControl ist wird auch dein meinControl in dem Moment nicht zugewiesen. Sieht man besser wenn der Code ordentlich formatiert ist. Witziger Weise bewegt sich bei mir das Label obwohl es nie auf meinControl zugewiesen wird :shock:

Finki 19. Aug 2013 07:46

AW: Objekte Bewegen
 
Liste der Anhänge anzeigen (Anzahl: 1)
Hier ist mal des Programm. Ich kann leider grad nicht den genauen Inhalt der Fehlermeldung sagen, da ich gerade kein Lazarus auf dem Computer habe.

Ich kann es erst später sagen.

Falls ihr das Problem jetzt lösen wollt könnt ja mal selber schauen was passiert. Hier müsstet nur kurz in der Unit Newformframe beim erstellen des Labels Enabled:=true setzen, zur Zeit setht das drin:
Code:
Label1.Enabled:=false;
Wenn ihr das programm dann starte, müsst ihr folgendes machen:

1. Formular Reiter öffnen
2. Formular Button drücken
3. Eigene Reiter öffnen
4. Neues Formular Button drücken
5. Label erstellen (also Label Button drücken und etwas in das Textfeld "Befehlsname" eingeben und dann auf das andere (fast leere) Fenster klicken)
6. Im kleinen Fenster den Move Button drücken und auf das, eben erstellte, Label klicken und dann koommt der fehler

Vielen dank ich melde mich nochmal wenn ich Lazarus zur Verfügung habe.

Finki 19. Aug 2013 15:34

AW: Objekte Bewegen
 
Liste der Anhänge anzeigen (Anzahl: 2)
Hier ist mal ein Bild von dem Fehler, und eines von der Zeile auf welche der Fehler verweist

DeddyH 19. Aug 2013 15:48

AW: Objekte Bewegen
 
Und wenn Du
Zitat:

Delphi-Quellcode:
if (Sender is TWinControl) then
 if (Sender<>Form3) then
 meinControl := (Sender as TWinControl)
 else
 Exit;

mal in
Delphi-Quellcode:
if (Sender is TWinControl) and (Sender<>Form3) then
  meinControl := (Sender as TWinControl)
else
  Exit;
änderst? Sonst kann es nämlich passieren, dass in Deiner meinControl-Variablen irgendwelcher Müll drinsteht, da knallt es dann beim Zugriff darauf.

[edit] Oder mal im Ganzen ohne unnötige Klammern, Boolean-Vergleiche, Zugriffe auf die globale Form-Variable und Schreiben über die Zeilenanzahl des Memos hinaus, dafür aber mit Einrückungen:
Delphi-Quellcode:
procedure TForm3.FormMouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
var
   meinControl: TControl;
   j : integer; //Schleifen Variable
begin
  MDown := true;
  meinControl := nil;
  if move then
    begin
      if Sender is TControl then
        if Sender <> self then
          meinControl := Sender as TControl;
      if not Assigned(meinControl) then
        exit;
      while MDown do
        begin
          meinControl.Left := Mouse.CursorPos.x - Left - BorderWidth;
          meinControl.Top := Mouse.CursorPos.y - Top - 50;
          Application.ProcessMessages;
          for j := 3 to Memo1.Lines.Count - 6 do
            begin
              if Memo1.Lines[j] = meinControl.Name then
                begin
                  Memo1.Lines[j + 2] := inttostr(meinControl.BoundsRect.Left);
                  Memo1.Lines[j + 3] := inttostr(meinControl.BoundsRect.Top);
                  Memo1.Lines[j + 4] := inttostr(meinControl.Width);
                  Memo1.Lines[j + 5] := inttostr(meinControl.Height);
                end;
            end;
        end;
    end;
end;
[/edit]

Finki 20. Aug 2013 06:50

AW: Objekte Bewegen
 
Hey DeddyH,

du hast in deinem letzten Quelltext ausschnitt nur
Delphi-Quellcode:
  if move then
geschrieben! Warum nicht move=true??

DeddyH 20. Aug 2013 07:00

AW: Objekte Bewegen
 
http://www.delphi-treff.de/tutorials...faengerfehler/ oder auch http://www.detlef-heibing.de/program...onstanten.html, das sollte die Frage beantworten.

Finki 20. Aug 2013 07:12

AW: Objekte Bewegen
 
Liste der Anhänge anzeigen (Anzahl: 1)
Wow vielen dank das ist mal echt interessant.

Zu deinen beiden Lösungsmöglichkeiten, die funktionieren beide nicht:

der erste geht zwar aber man kann ein Label nicht auswählen (obwohl enabled), was wahrscheinlich daran liegt das, wie ihr mir ja schon gesagt habt, kein TWinControl ist.

der zweite Quelltext verursacht ein Fehler in der Zeile:

Delphi-Quellcode:
     meinControl := Sender as TControl;
Fehler siehe Bild

DeddyH 20. Aug 2013 07:17

AW: Objekte Bewegen
 
Und bei
Delphi-Quellcode:
meinControl := TControl(Sender);
:?:

Finki 20. Aug 2013 07:50

AW: Objekte Bewegen
 
ach ich dachte des wäre ein Fehler deinerseits, sry, ne dann meckert er(der Kompiler) rum, weil er ein TObject bekommen hat und ein TWinControl erwartet

DeddyH 20. Aug 2013 07:53

AW: Objekte Bewegen
 
Das verstehe ich nicht, habe hier aber auch kein Lazarus zur Verfügung. Ich könnte das höchstens zu Hause einmal ausprobieren, das wird aber vor heute Abend nichts.

Finki 20. Aug 2013 08:23

AW: Objekte Bewegen
 
Das wäre echt net. Ganz kurz noch, vielleicht kannst du mir was anderes beantworten.

und zwar arbeite ich gerade daran das man sieht wie viel zeichen man geschrieben hat.
Delphi-Quellcode:
StatusBar.Panels.Items[1].Text := Format('%d Zeichen', [Length(Memo1.Text)-(2*Memo1.Lines.Count)+1]); // 2*Anzahl der Zeillen weil der Umbruch Befehl als zwei Zeichen gezählt wird
das Problem ist das Sonderzeichen wie ß ü ö ä, usw. sind zwei Zeichen.

Gibt es einen "einfachen" Weg wie ich das vermeinden kann, also das sie als ein Zeichen gezählt werden?

DeddyH 20. Aug 2013 08:33

AW: Objekte Bewegen
 
Ehrlich gesagt verstehe ich Deinen ganzen Rechenweg nicht. Was ist denn mit WordWrap und solchen Dingen? Ich würde mir eher die Länge des Textes merken und später dann die aktuelle Textlänge mit der gemerkten vergleichen.

Finki 20. Aug 2013 08:43

AW: Objekte Bewegen
 
Was bitte genau ist des WordWrap, des hab ich immer noch nicht geschnallt (auch nach wiederholtem googlen).

DeddyH 20. Aug 2013 08:46

AW: Objekte Bewegen
 
Das ist der automatische Zeilenumbruch, d.h. die Zeile wird umgebrochen, wenn sie nicht mehr komplett im Memo darstellbar ist.

Finki 20. Aug 2013 09:05

AW: Objekte Bewegen
 
Achso ist das. und wie kann ich den Befehl ansprechen/zählen???

DeddyH 20. Aug 2013 09:21

AW: Objekte Bewegen
 
Was genau möchtest Du denn zählen? Ich habe das immer noch nicht ganz begriffen.

Finki 20. Aug 2013 09:23

AW: Objekte Bewegen
 
Egal, also das mit dem WordWrap, weil den Zeilen Umbruch hab ich ja in meiner normalen Rechnung schon abgezogen.

was ich zählen möchte: ich möchte die Zeichen in der Memo zählen

DeddyH 20. Aug 2013 09:41

AW: Objekte Bewegen
 
Dann ist Length(Memo.Text) doch korrekt.

Finki 20. Aug 2013 09:53

AW: Objekte Bewegen
 
Das Problem ist ü ö ä werden als zwei Zeichen gezählt

DeddyH 20. Aug 2013 10:13

AW: Objekte Bewegen
 
Das glaub ich nicht. Es sind zwar ggf. 2 Byte, aber immer noch ein Zeichen.

Finki 20. Aug 2013 10:16

AW: Objekte Bewegen
 
Liste der Anhänge anzeigen (Anzahl: 2)
hier sind bilder

DeddyH 20. Aug 2013 10:18

AW: Objekte Bewegen
 
Und womit errechnest Du die Zeichenanzahl?

Finki 20. Aug 2013 10:32

AW: Objekte Bewegen
 
Delphi-Quellcode:
StatusBar.Panels.Items[1].Text := Format('%d Zeichen', [Length(Memo1.Text)-(2*Memo1.Lines.Count)+1]);

DeddyH 20. Aug 2013 10:38

AW: Objekte Bewegen
 
So, einfaches Beispielprojekt unter Delphi XE: ein Memo und eine Statusbar, im OnChange des Memos folgender Code
Delphi-Quellcode:
StatusBar1.SimpleText := Format('%d Zeichen', [Length(Memo1.Text)]);
Eingabe:
Zitat:

Dies ist ein Testäöü
Anzeige in der Statusbar:
Zitat:

20 Zeichen
Das Einzige, was hier 2 Zeichen produziert, ist der Zeilenumbruch, da dieser unter Windows ja tatsächlich aus 2 Zeichen (#13#10) besteht.

DeddyH 20. Aug 2013 16:43

AW: Objekte Bewegen
 
So, unter Lazarus auf Linux Mint ausprobiert: Umlaute werden tatsächlich als 2 Zeichen gezählt, siehe auch dieser Thread. Ich hatte jetzt keine Lust, den komplett zu lesen, aber wenn dort keine Lösung steht, kann ich Dir auch nicht helfen, das ist wohl in Lazarus so gewollt.

Finki 21. Aug 2013 06:18

AW: Objekte Bewegen
 
Gut vielen dank für deine Mühe

JamesTKirk 22. Aug 2013 08:34

AW: Objekte Bewegen
 
Zitat:

Zitat von Finki (Beitrag 1225450)
Das Problem ist ü ö ä werden als zwei Zeichen gezählt

Lazarus verwendet UTF-8 als Zeichenkodierung und nicht ASCII oder eine der Ansi Kodierungen. Bei UTF-8 haben Sonderzeichen unterschiedliche Längen (ich glaub bis zu 6 Byte maximal).
Delphi-Quellcode:
Length()
unterstützt dies jedoch nicht (es gibt dir hier nur die Anzahl der Bytes zurück). Lazarus bietet allerdings eine
Delphi-Quellcode:
UTF8Length()
Funktion in der Unit
Delphi-Quellcode:
lazutf8
. Für weitere Informationen lies dir bitte diesen Artikel im Lazarus Wiki durch.

Gruß,
Sven


Alle Zeitangaben in WEZ +1. Es ist jetzt 00:40 Uhr.

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