AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein GUI-Design mit VCL / FireMonkey / Common Controls Kann mir das einer mit ListBoxDrawItem und odFocused erklären
Thema durchsuchen
Ansicht
Themen-Optionen

Kann mir das einer mit ListBoxDrawItem und odFocused erklären

Ein Thema von Popov · begonnen am 14. Feb 2012 · letzter Beitrag vom 15. Okt 2012
Antwort Antwort
Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#1

AW: Kann mir das einer mit ListBoxDrawItem und odFocused erklären

  Alt 15. Okt 2012, 19:10
Tstststs ... anstatt stundenlang die Haare zu raufen und irgendwas auszuprobieren, hätten ein paar gezielte Strg-Clicks auf DrawFocusRect zunächst hierhin gebracht:
Delphi-Quellcode:
unit Vcl.Graphics;
...
procedure TCanvas.DrawFocusRect(const Rect: TRect);
begin
  Changing;
  RequiredState([csHandleValid, csBrushValid]);
  Winapi.Windows.DrawFocusRect(FHandle, Rect);
  Changed;
end;
Dann hierhin:
Delphi-Quellcode:
unit Winapi.Windows;
...
function DrawFocusRect; external user32 name 'DrawFocusRect';
Und schließlich hierhin: MSDN: DrawFocusRect function
Und was finden wir da?
Zitat von MSDN: DrawFocusRect function:
Because DrawFocusRect is an XOR function, calling it a second time with the same rectangle removes the rectangle from the screen.
Aha, damit ist also auch geklärt, warum das explizite Löschen des Canvas eher kontraproduktiv als hilfreich ist
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)
  Mit Zitat antworten Zitat
Popov
(Gast)

n/a Beiträge
 
#2

AW: Kann mir das einer mit ListBoxDrawItem und odFocused erklären

  Alt 15. Okt 2012, 19:35
Nun, ich gebe zu, dass ich mir alles angeguckt habe, nur nicht die DrawFocusRect Funktion. Hielt ich nicht für nötig.

Trotzdem sehe ich hier nicht die Antwort auf meine Verwirrung. Vielleicht sehe ich es einfach nur nicht. Das DrawFocusRect Xor zeichnet ist mir klar und auch, dass ein erneutes Zeichnen es wieder löscht. Das habe ich ja auch gemacht. In einem der Beispiel habe ich es vor FillRect gemacht, dann mal danach und zuletzt ganz am Ende.

Wie auch, nach meinem Verständnis sollte von dem Rahmen schon in den ersten Beispielen nichts mehr übrig sein.

Oder habe ich dich missverstanden?
  Mit Zitat antworten Zitat
Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#3

AW: Kann mir das einer mit ListBoxDrawItem und odFocused erklären

  Alt 15. Okt 2012, 19:41
Das sich 2x XOR aufhebt, funktioniert nur dann, wenn ich das, was das erste XOR verändert hat, vor dem 2. XOR nicht verändere.

Das hast du aber immer gemacht (mit FillRect, TextRect, etc.)

Darum ist es am sichersten alles auf den Canvas zu klatschen, ganz am Ende DrawFocusRect (ja, den Rahmen malen lassen) und das Control macht auch nochmal DrawFocusRect und schwupps ist der Rahmen weg
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)
  Mit Zitat antworten Zitat
Popov
(Gast)

n/a Beiträge
 
#4

AW: Kann mir das einer mit ListBoxDrawItem und odFocused erklären

  Alt 15. Okt 2012, 20:08
Das mache ich ja auch, ist ja inzwischen auch nicht das Problem. Und ich muß zugeben, dass ich damals durch harte Versuche selbst drauf gekommen bin. Zuletzt habe ich Blut gespuckt. Denn entweder hatte nie ein anderer je dieses Problem, weil das Entfernen des Rahmens so simpel ist und jeder einen angeborenen Instinkt hat es immer zuletzt zu plazieren, oder es ich weiß es nicht.

Wenn du dir aber das Beispiel 2 anguckst, dann lösche ich da vor FillRect den Rahmen. Aber auch das sehe ich nicht als das Problem an, denn Xor zeichnen verändert nicht die Eigenschaften der Pixel. Wenn also zu Anfang der Prozedur bereits ein Rahmen existiert, dann wird er spätestens nach FillRect weg sein. Xor hin, Xor her.

Wenn ich also (nach meiner Logik) am Ende der Prozedur selbst ein Xor Rahmen zeichne und das System danach wieder einen Xor Rahmen zeichnet, dann ist er weg. Somit müßte nach meinem Verständnis nach dem Ende der Prozedur wieder ein Xor Rahmen gezeichnet werden. Nur ich sehe nicht wo.
  Mit Zitat antworten Zitat
Benutzerbild von Bummi
Bummi

Registriert seit: 15. Jun 2010
Ort: Augsburg Bayern Süddeutschland
3.470 Beiträge
 
Delphi XE3 Enterprise
 
#5

AW: Kann mir das einer mit ListBoxDrawItem und odFocused erklären

  Alt 15. Okt 2012, 20:21
Delphi-Quellcode:
unit Unit3;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type

  TListbox=Class(StdCtrls.TListBox)
    procedure CNDrawItem(var Message: TWMDrawItem); message CN_DRAWITEM;
  End;


  TForm3 = class(TForm)
    ListBox1: TListBox;
    procedure FormCreate(Sender: TObject);
    procedure ListBox1DrawItem(Control: TWinControl; Index: Integer; Rect: TRect; State: TOwnerDrawState);
  private
    Fcanvas:TCanvas;
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  Form3: TForm3;

implementation

{$R *.dfm}

procedure TForm3.FormCreate(Sender: TObject);
var
 i:Integer;
begin
    Fcanvas := TCanvas.Create;
    for I := 1 to 10 do
      Listbox1.Items.Add('testdfdsf');
end;

procedure TForm3.ListBox1DrawItem(Control: TWinControl; Index: Integer; Rect: TRect; State: TOwnerDrawState);
begin
 with TListBox(Control).Canvas do
      begin
      if odSelected in State then Brush.Color := clLime else Brush.Color := $EEEEEE;
      Fillrect(rect);
      Textout(rect.Left,rect.Top,TListBox(Control).Items[Index]);
      end;

end;

{ TListbox }


procedure TListbox.CNDrawItem(var Message: TWMDrawItem);
var
 w:TOwnerDrawState;
begin
  w := TOwnerDrawState(LoWord(Message.DrawItemStruct^.itemState));
  Exclude(w , odFocused);
  Message.DrawItemStruct^.itemState := Message.DrawItemStruct^.itemState and ( $FFFF0000 + Word(w));
  inherited;
end;

end.
Thomas Wassermann H₂♂
Das Problem steckt meistens zwischen den Ohren
DRY DRY KISS
H₂ (wenn bei meinen Snipplets nichts anderes angegeben ist Lizenz: WTFPL)
  Mit Zitat antworten Zitat
Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#6

AW: Kann mir das einer mit ListBoxDrawItem und odFocused erklären

  Alt 15. Okt 2012, 20:29
Das mache ich ja auch, ist ja inzwischen auch nicht das Problem. Und ich muß zugeben, dass ich damals durch harte Versuche selbst drauf gekommen bin. Zuletzt habe ich Blut gespuckt. Denn entweder hatte nie ein anderer je dieses Problem, weil das Entfernen des Rahmens so simpel ist und jeder einen angeborenen Instinkt hat es immer zuletzt zu plazieren, oder es ich weiß es nicht.

Wenn du dir aber das Beispiel 2 anguckst, dann lösche ich da vor FillRect den Rahmen. Aber auch das sehe ich nicht als das Problem an, denn Xor zeichnen verändert nicht die Eigenschaften der Pixel. Wenn also zu Anfang der Prozedur bereits ein Rahmen existiert, dann wird er spätestens nach FillRect weg sein. Xor hin, Xor her.

Wenn ich also (nach meiner Logik) am Ende der Prozedur selbst ein Xor Rahmen zeichne und das System danach wieder einen Xor Rahmen zeichnet, dann ist er weg. Somit müßte nach meinem Verständnis nach dem Ende der Prozedur wieder ein Xor Rahmen gezeichnet werden. Nur ich sehe nicht wo.
zu finden ist das hier:
Delphi-Quellcode:
unit Vcl.StdCtrls;
...
procedure TCustomListBox.CNDrawItem(var Message: TWMDrawItem);
var
  State: TOwnerDrawState;
begin
  with Message.DrawItemStruct{$IFNDEF CLR}^{$ENDIF} do
  begin

    ... // unwichtiger Krams ... wenigstens für diese Betrachtung :o)

    if Integer(itemID) >= 0 then
      DrawItem(itemID, rcItem, State) // <-- hier wird auch das OnDrawItem-Event ausgelöst
    else
      FCanvas.FillRect(rcItem);
    if (odFocused in State) and not TStyleManager.IsCustomStyleActive then

      DrawFocusRect(hDC, rcItem); // <-- da ist der schlimme Finger

    FCanvas.Handle := 0;
  end;
end;
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)
  Mit Zitat antworten Zitat
Popov
(Gast)

n/a Beiträge
 
#7

AW: Kann mir das einer mit ListBoxDrawItem und odFocused erklären

  Alt 15. Okt 2012, 21:09
Siehst du, ich wußte, dass es einfach ist. Wo der "Schlimme Finger" war/ist, wußte/weiß ich, ich hab nur bei den zwei Dutzend mal wo ich mir die Prozedur angesehen habe die DrawItem Zeile nicht wahrgenommen.

Ok, Frage beantwortet. Danke euch.
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 09:11 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