Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   Delphi GDI-Zeichnungen entfernen (https://www.delphipraxis.net/6730-gdi-zeichnungen-entfernen.html)

Chewie 20. Jul 2003 12:53


GDI-Zeichnungen entfernen
 
Ich bastele gerade mit der GDI herum, komme aber jetzt nicht weiter.
Ich zeichne um die Spalten eines Report-Listviews einen Markierungsrahmen. Oder besser gesagt, ich zeichne die an die Position der Spalte via DrawText den Text der Spalte mit der Hintergrundfarbe COLOR_HIGHLIGHT. Um die Spalte wieder zu deselektieren, habe ich versucht, den Text nit Standard-Hintergrund und -schriftfarbe an die gleuiche Stelle zeichnen. Aber das klappt nicht.
Folgendermaßen sieht der Code zum Zeichnen der Markierung aus:

Delphi-Quellcode:
procedure THexListView.ColDrawRoutine(Rect: TRect; iItem, iSubItem: Integer);
var
  LVDC: HDC;
  lpText: String[255];
  TextLen: Integer;
begin
  LVDC := GetDC(ListViewHandle);

  //alte Markierung entfernen
  DeselectColumns;

  //neuen Eintrag Zeichnen
  SetBkColor(LVDC, GetSysColor(COLOR_HIGHLIGHT));
  SetTextColor(LVDC, RGB($FF, $FF, $FF));
  SelectObject(LVDC, FhLVFont);
  TextLen := 255;
  lpText := StringOfChar(#0, TextLen);
  ListView_GetItemText(ListViewHandle, iItem, iSubItem, @lpText[1], TextLen);
  DrawText(LVDC, @lpText[1], -1, Rect, DT_CENTER or DT_SINGLELINE or DT_VCENTER);
  FSelCol.iItem := iItem;
  FSelCol.iSubItem := iSubItem;
  FSelCol.Selected := True;

  ReleaseDC(ListViewHandle, LVDC);
end;
Und so versuche ich, die Markierung wieder zu entfernen:
Delphi-Quellcode:
procedure THexListView.DeselectColumns;
var
  LVDC: HDC;
  lpText: String[255];
  TextLen: Integer;
  Rect: TRect;
begin
  //stoppen, falls nichts markiert ist
  if not FSelCol.Selected then Exit;

  LVDC := GetDC(ListViewHandle);

  //Device Context modifizieren
  SetBkColor(LVDC, ListView_GetTextBkColor(ListViewHandle));
  SetTextColor(LVDC, ListView_GetTextBkColor(ListViewHandle));
  SetBkColor(LVDC, GetSysColor(COLOR_HIGHLIGHT));
  SetTextColor(LVDC, RGB($FF, $FF, $FF));
  SelectObject(LVDC, FhLVFont);

  //zeichnen
  TextLen := 255;
  lpText := StringOfChar(#0, TextLen);
  Rect := GetSubItemRect(FSelCol.iItem, FSelCol.iSubItem)^;
  ListView_GetItemText(ListViewHandle, FSelCol.iItem, FSelCol.iSubItem, @lpText[1], TextLen);
  DrawText(LVDC, @lpText[1], -1, Rect,
    DT_CENTER or DT_SINGLELINE or DT_VCENTER);

  FSelCol.Selected := False;

  ReleaseDC(ListViewHandle, LVDC);
end;
Leider wird in der zweiten Prozedur nichts gezeichnet.

Die zweite Möglichkeit wäre, eigentlich die bessere, alle selbst gezeichneten Elemente zu entfernen. Geht das irgendwie?
Die GDI ist völliges Neuland für mich, und ein umfassendes Tutorial habe ich auch noch nicht gefunden. Und das PSDK hilft mir auch nur bedingt weiter.

Chewie 22. Jul 2003 19:16

Re: GDI-Zeichnungen entfernen
 
Komisch. Wenn ich in der zweiten Prozedur den Aufruf von SetBkColor und SetTextColor weglasse, geht es.
Ach ja, ich sehe gerade, da sind ja zwei Aufrufe in dieser Prozedur. Das war aber nicht das Problem, das war nur zum testen. Aber seis drum, immerhin dieses Problem wär gelöst. Jetzt warten noch ein paar andere...

neolithos 1. Aug 2003 08:36

Re: GDI-Zeichnungen entfernen
 
Vielleicht hilft es

Code:
var
  hDC: HDC;  
  hOldFont : HFONT;
  cText : array [0..255] of char;
begin
  hDC := GetDC(ListViewHandle);

  //alte Markierung entfernen
  DeselectColumns;

  //neuen Eintrag Zeichnen
  SetBkColor(hDC, GetSysColor(COLOR_HIGHLIGHT));
  SetTextColor(hDC, GetSysColor(COLOR_HIGHLIGHTTEXT));

  hOldFont := SelectObject(hDC, FhLVFont); // merke Vorgänder
  ListView_GetItemText(ListViewHandle, iItem, iSubItem, cText, 256);
  DrawText(hDC, cText, -1, Rect, DT_CENTER or DT_SINGLELINE or DT_VCENTER);
  FSelCol.iItem := iItem;
  FSelCol.iSubItem := iSubItem;
  FSelCol.Selected := True;

  // ganz wichtig immer aufräümen
  // sonst verliert Windows-Speicher welcher nur durch neustart wieder
  // hergestellt werden kann (Vorsicht bei HBITMAP, HFONT, HBRUSH
  // größten fresser
  SelectObject(hDC, hOldFont);
  ReleaseDC(ListViewHandle, hDC);
end
das sollte gehen

Warum bringst du nicht alles in einer Zeichenroutine unter
ungefähr so
Delphi-Quellcode:
  if Selected then
     begin
       SetTextColor( ????
       SetBkolor( ???? 
     end
   else
      begin
       SetTextColor( ????
       SetBkolor( ???? 
     end;

  Zeichen-Funktionen

DeselectItem könnte so aussehen

  FSelCol.Select := false
  Rect := GetSubItemRect(
  InvalidateRect(ListViewHandle, @Rect, true);


SelectItem:

  FSelCol.iItem := iItem;
  FSelCol.iSubItem := iSubItem;
  FSelCol.Selected := True;
  Rect := GetSubItemRect(
  InvalidateRect(ListViewHandle, @Rect, true);
nur ein Vorschlag, denn so lassen sich Änderungen besser verwalten!

[edit=Luckie]Man kann auch mehr als einen Code-Block verwenden. Mfg, Luckie[/edit]


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