| Autor |
Beitrag |
D. Annies
      
Beiträge: 1843
windows 7
D6 Enterprise, D7 Pers und TD 2006
|
Verfasst: Do 22.01.09 10:48
Hi, Delpher,
kleine Spielerei, aber warum ist die Linie nicht (dauerhaft) sichtbar?
Code:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16:
| listbox6.clear; n := 0; with Listbox6.Items do begin while n < klmax-1 do begin inc(n); if total[n] > 0 then begin Add(Format('Personen in R%2d : %3d = %3d / %3d ', [n, total[n], female[n], male[n]])); Add(' '); end; end; Add('----------------------------------'); end; listbox6.Canvas.MoveTo(Left,Top); listbox6.Canvas.LineTo(clientrect.Right, clientrect.Bottom); |
Danke für eine Idee/Abhilfe,
Detlef
_________________ ut vires desint, tamen est laudanda voluntas
|
|
Lannes
      
Beiträge: 2352
Erhaltene Danke: 4
Win XP, 95, 3.11, IE6
D3 Prof, D4 Standard, D2005 PE, TurboDelphi, Lazarus, D2010
|
Verfasst: Do 22.01.09 10:59
Hallo,
wo steht der Code?
Wenn er in einer Routine ausgeführt wird, kann es nicht funktionieren.
_________________ MfG Lannes
(Nichts ist nicht Nichts) and ('' <> nil ) and (Pointer('') = nil ) and (@('') <> nil )
|
|
D. Annies 
      
Beiträge: 1843
windows 7
D6 Enterprise, D7 Pers und TD 2006
|
Verfasst: Do 22.01.09 17:33
Hi, Lannes,
ja, der Code steht in einer Prozedur.
Und jetzt?
_________________ ut vires desint, tamen est laudanda voluntas
|
|
jaenicke
      
Beiträge: 19339
Erhaltene Danke: 1752
W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Do 22.01.09 17:41
Naja, sobald die ListBox neu gezeichnet wird, ist die Linie auch wieder weg.
Da es kein OnPaint bei der ListBox gibt, wäre die sinnvollste Möglichkeit, eine eigene abgeleitete Klasse zu erstellen, die dies beinhaltet. Ich vermute wo etwas gibt es auch im Netz.
// EDIT:
Ach ja: was Lannes meinte:
Mit Left und Top usw. greifst du ja nicht auf die Werte der ListBox zu, sondern auf die des Formulars...
// EDIT2:
Was auch gehen müsste um das neu zeichnen in den Griff zu bekommen:
WndProc überschreiben und auf WM_PAINT reagieren. 
|
|
D. Annies 
      
Beiträge: 1843
windows 7
D6 Enterprise, D7 Pers und TD 2006
|
Verfasst: Do 22.01.09 18:11
Ich haben verstanden - ich lassen es!
Gruß, Detlef
_________________ ut vires desint, tamen est laudanda voluntas
|
|
Lannes
      
Beiträge: 2352
Erhaltene Danke: 4
Win XP, 95, 3.11, IE6
D3 Prof, D4 Standard, D2005 PE, TurboDelphi, Lazarus, D2010
|
Verfasst: Do 22.01.09 18:11
Hallo,
jaenicke hat folgendes geschrieben : | // EDIT:
Ach ja: was Lannes meinte:
Mit Left und Top usw. greifst du ja nicht auf die Werte der ListBox zu, sondern auf die des Formulars... |
so in etwa, oder auch nicht
jetzt weis ich immer noch nicht wo genau der Code steht
a.
Der Code steht in ListBoxDrawItem = dort sollte man keine Einträge schreiben die ein Neuzeichnen auslösen
b.
Der Code steht in einer anderen Prozedur = dort sollte man nicht auf das canvas der Listbox zeichnen, den das wird übermalt wenn die interne Zeichenprozedur durch etwas anderes aufgerufen wird. z.B. ein überdecken der Listbox durch ein anderes Fenster.
Du kannst den Vorschlag von jaenicke (WndProc etc.) nehmen, ich meine es ist einfacher die Linie in ListBoxDrawItem zu zeichnen.
Was soll denn die Linie bezwecken?
_________________ MfG Lannes
(Nichts ist nicht Nichts) and ('' <> nil ) and (Pointer('') = nil ) and (@('') <> nil )
|
|
D. Annies 
      
Beiträge: 1843
windows 7
D6 Enterprise, D7 Pers und TD 2006
|
Verfasst: Do 22.01.09 18:27
Hi, Lannes,
der Code steht in "b".
Entscheidend ist ja auch deine Frage, was bewirkt werden soll. --> Nichts, VOID, es ist wirklich nur eine Spielerei, deshalb lasse ich es auch. Wenn es wichtig wäre, würde ich mehr "beißen".
Vielen Dank für deine "Nachsorge",
Detlef
_________________ ut vires desint, tamen est laudanda voluntas
|
|
jaenicke
      
Beiträge: 19339
Erhaltene Danke: 1752
W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Do 22.01.09 19:19
|
|
D. Annies 
      
Beiträge: 1843
windows 7
D6 Enterprise, D7 Pers und TD 2006
|
Verfasst: Do 22.01.09 20:41
Sebastian, du bist "unmöglich" !!
Danke, Detlef
_________________ ut vires desint, tamen est laudanda voluntas
|
|
delfiphan
      
Beiträge: 2684
Erhaltene Danke: 32
|
Verfasst: Fr 23.01.09 00:32
jaenicke hat folgendes geschrieben : | Das funktioniert, wie ich schon vermutet hatte, wunderbar.  |
Die Lösung ist leider trotzdem etwas schief geraten
Du überschreibst die WndProc der MainForm, um darin ein Child-Control zu überzeichnen :O. Wieso das niemand so macht:
- Um einzelne Messages abzufangen, würde man nicht die WndProc überschreiben, sondern eine message Prozedur definieren: procedure WMPaint(var Message: TWMPaint); message WM_PAINT;
- Um das Neuzeichnen der MainForm abzufangen, würde man aber auch das nicht machen, sondern gleich das OnPaint-Event benutzen.
- Aber: Um das Neuzeichnen eines Child-Controls abzufangen, fängt man nicht die Paint-Message der MainForm ab, sondern wenn schon die des Child-Controls selbst, sofern das Child-Control natürlich kein eigenes Paint-Ereignis besitzt (was die TListBox ja tut, zu mindest für einzelne Items). Denn es kann sein, dass die MainForm gar nicht neugezeichnet werden muss, die ListBox aber schon.
- Bietet ein Control kein OnPaint an, sollte man das entsprechende Control erweitern, in dem man von ihr eine Ableitung macht, und dort entweder die Paint Methode überschreibt (sofern vorhanden), und falls nicht, eine message-Prozedur wie oben gezeigt definiert und von dort aus das selbstdefinierte OnPaint-Ereignis aufruft. Hier sollte man darauf achten, dass man die WinApi Doku beachtet.
- Wenn man "global" Messages abfangen muss, dann über Application.OnMessage. Dort würde man das Handle der Message überprüfen, ob es mit der der ListBox übereinstimmt, etc.. Die globale Lösung ist natürlich schlecht, aber so würde man es machen.
Zuletzt bearbeitet von delfiphan am Fr 23.01.09 00:39, insgesamt 1-mal bearbeitet
|
|
jaenicke
      
Beiträge: 19339
Erhaltene Danke: 1752
W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Fr 23.01.09 00:37
delfiphan hat folgendes geschrieben : | | - Bietet ein Control kein OnPaint an, sollte man das entsprechende Control erweitern, indem man entweder die Paint Methode überschreibt (sofern vorhanden), und falls nicht, eine message-Prozedur wie oben gezeigt definiert und von dort aus das selbstdefinierte OnPaint-Ereignis aufruft. |
Das habe ich ja auch geschrieben, aber dann kann man eben keine Standard-ListBox verwenden.
Dass das in einem richtigen Anwendungsfall natürlich die bessere Lösung ist, ist klar.
|
|
delfiphan
      
Beiträge: 2684
Erhaltene Danke: 32
|
Verfasst: Fr 23.01.09 00:57
jaenicke hat folgendes geschrieben : | Das habe ich ja auch geschrieben, aber dann kann man eben keine Standard-ListBox verwenden.
Dass das in einem richtigen Anwendungsfall natürlich die bessere Lösung ist, ist klar. |
Naja  Trotzdem hätte man ein korrektes Beispiel posten können...
Die ganze Paint-Geschichte über WM_PAINT ist genau genommen noch etwas komplizierter, da man den beim WM_PAINT übergebenen DC noch mit BeginPaint/EndPaint umgeben muss. Bei TWinControls übernimmt das PaintHandler, der dann PaintWindow aufruft. Einige dieser Methode sind virtual, können als überschrieben werden. Dort würde man dann dem Canvas das DC als Handle geben und das eigene Event aufrufen.
Und falls global, mit Original-Listbox und ohne VCL-Event, dann über Application.OnMessage. Dann muss man sich um die oben genannten Sachen jedoch selbst kümmern.
|
|
|