Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   Delphi [NonVCL] Hintergrundbild in scrollbarer Listbox (https://www.delphipraxis.net/168874-%5Bnonvcl%5D-hintergrundbild-scrollbarer-listbox.html)

NickelM 15. Jun 2012 13:12

[NonVCL] Hintergrundbild in scrollbarer Listbox
 
Hallo,
Wie der Titel schon sagt, bin ich am versuchen ein Bild als Hintergrund für eine Listbox einzubauen.
Wenn sie nicht scrollbar wäre, wäre dies kein Problem, aber irgendwie macht er mir das nicht richtig, wenn ich scrollen will.
Ich hab auserdem die Listbox auf OwnerDraw gesetzt.
Hab die WndProc "gehooked" und habe folgendes schon versucht:
- WM_ERASEBKGND : Bild gezeichnet, Einträge nochmal extra gezeichnet. Kein Unterschied.

- WM_CTLCOLORLISTBOX: Bild gezeichnet, Einträge nochmal extra gezeichnet. Kein Unterschied.

- WM_PAINT Bild gezeichnet, Einträge nochmal extra gezeichnet. Kein Unterschied.

Machte kein unterschied. Egal in welcher Combi oder alle zusammen, immer hab ich eine Schleife, oder eine Überlappung der Msgs, sodass nicht alle Einträge angezeigt werden.
So was ich immer hab ist natürlich WM_DRAWITEM. Hier der Code:
Delphi-Quellcode:
with DrawStruct^ do
begin
  State := TOwnerDrawState(LoWord(itemState));
  if itemState and ODS_DEFAULT <> 0 then
    Include(State, odDefault);

            //InvalidateRect(hFileList,@rcItem,False); //Hab ich versucht, entsteht ein Flackern. Ohne WM_PAINT und WM_ERASEBKGND Msg ändern.
            //RedrawWindow(hFileList,@rcItem,0,RDW_NOINTERNALPAINT or RDW_VALIDATE); //Hab ich versucht, mit allen RDW_Flag Combos die mir einfallen. Entweder dauerhaftes flackern, oder beim scroll verschwindet das gezeichnete.
            if odSelected in State then
            begin
              FillRect(hDC,rcItem,GetSysColorBrush(COLOR_HIGHLIGHT));
              FontColor := GetSysColor(COLOR_HIGHLIGHTTEXT);
            end
            else
            begin
              //FillRect(hDC,rcItem,CreateSolidBrush(RGB(255,255,204))); Weil ich ein bild normal als Hintergrund habe, brauch ich das nicht
              FontColor := GetSysColor(COLOR_WINDOWTEXT);
            end;
            if (odFocused in State) then
              DrawFocusRect(hDC,rcItem);
            if Integer(itemID) > -1 then
            begin
            SetBkMode(hDC,TRANSPARENT);
            SetTextColor(hDC,FontColor);

            rcItem.Left := 5;
            TextL := SendMessage(hFileList, LB_GETTEXTLEN, itemID,0);
            Text := AllocMem((TextL+1)*2);
            SendMessage(hFileList, LB_GETTEXT, itemID,Integer(Text));
            DrawText(hDC,Text,TextL,rcItem,DT_LEFT or DT_VCENTER or DT_SINGLELINE);
            FreeMem(Text,(TextL+1)*2);
            end;
          end;
        end;
Hab ich eine Msg vergessen zubehandeln? SB_THUMBTRACK hab ich auch schon versucht, neuzeichnen zulassen, wird aber nicht immer aufgerufen, beim Scrollen. Keine Veränderung. Ich weis, dass es irgendwie geht, da es sowas für VCL gibt. Ich brauch es halt für NonVCL :-D.
Theoretisch müsste ich irgendwie die Offset-Pixel, die relativ zum ClientRect sind wissen.
Also wenn ich 5 Pixel gescrollt hab, das ich diese 5 Pixel irgendwie rausbekomme.
Dann könnte ich bei DrawItem, den ItemRect relativ zum ClientRect berechnen. Nur ich hab bisher keine Funktion gefunden.
Danke schonmal im vorraus.
Gruß NickelM

EWeiss 15. Jun 2012 14:19

AW: [NonVCL] Hintergrundbild in scrollbarer Listbox
 
Sieh dir VPiano an
In der Lib SKaero uListBox.pas solltest du fündig werden.

Das problem ist das hier mehrere Faktoren eine rolle spielen das kann man nicht mal ebend so kurz erklären.

gruss

NickelM 15. Jun 2012 14:48

AW: [NonVCL] Hintergrundbild in scrollbarer Listbox
 
Danke, werd ich mir durchlesen. So wie es scheint, muss ich alles, wo man zum scrollen benutzen kann
"hooken" und selber ausführen. Hm, das wird nen Aufwand. Trotzdem danke.

EWeiss 15. Jun 2012 15:08

AW: [NonVCL] Hintergrundbild in scrollbarer Listbox
 
Zitat:

Zitat von NickelM (Beitrag 1171052)
Danke, werd ich mir durchlesen. So wie es scheint, muss ich alles, wo man zum scrollen benutzen kann
"hooken" und selber ausführen. Hm, das wird nen Aufwand. Trotzdem danke.

Das sind 5 Befehle inklusive ein Subclassing
Wenn du es von einer Standard ListBox (VCL-Form) ableiten willst.

CallWindowProc
SetWindowLong
InvalidateRect
SetBkMode
CreatePatternBrush

WM_ERASEBKGND
WM_CTLCOLORLISTBOX

Was willst du mit WM_DRAWITEM?
Wenn du den Text der ListBox nicht selber Ownerdrawen willst ist das nicht von nöten.

gruss

EWeiss 15. Jun 2012 15:34

AW: [NonVCL] Hintergrundbild in scrollbarer Listbox
 
Hier mein Sample!
Nicht fertig da Hier als ich es geschrieben habe kein interesse daran bestand.
Deshalb habe ich es nicht weiter verfolgt.

Es zeigt dir aber im Ansatz wie es funktioniert.
Nimm dir also raus was du brauchst.


gruss

NickelM 15. Jun 2012 19:51

AW: [NonVCL] Hintergrundbild in scrollbarer Listbox
 
Liste der Anhänge anzeigen (Anzahl: 1)
Hm, also bei deinem Projekt ist der gleiche Fehler, wie bei mir wenn ich auf mehrere Items nacheinder geklickt habe. Hier ein Bild, darum geht es ja. Das andere funkt auch bei mir :-D

EDIT : Ach und ich rufe DRAWITEM deshalb auf, da ich den Text vertikal zentriert haben will. Auf der normalen Höhe find ich siehen die Items so zusammen gequetscht auf.

EWeiss 15. Jun 2012 20:50

AW: [NonVCL] Hintergrundbild in scrollbarer Listbox
 
Zitat:

Zitat von NickelM (Beitrag 1171091)
Hm, also bei deinem Projekt ist der gleiche Fehler, wie bei mir wenn ich auf mehrere Items nacheinder geklickt habe. Hier ein Bild, darum geht es ja. Das andere funkt auch bei mir :-D

EDIT : Ach und ich rufe DRAWITEM deshalb auf, da ich den Text vertikal zentriert haben will. Auf der normalen Höhe find ich siehen die Items so zusammen gequetscht auf.

Ich sagte ja das ich es nicht weiter verfolgt habe da hier kein interesse bestand. ;)
Denke da fehlt noch irgendwo ein invalidaterect.

gruss

NickelM 15. Jun 2012 20:52

AW: [NonVCL] Hintergrundbild in scrollbarer Listbox
 
Hm, hab jetzt mal den ganzen Code umgebaut soweit, wie bei deinem Beispiel.
Hm jetzt klapps. Es flackert ab und zu aber Double

Eins ist mir aufgefallen. Das du das Bild "anders" zeichnest.
Delphi-Quellcode:
//Du mast das so:
hDCBack := CreateCompatibleDC(DC);
SelectObject(hDCBack, FBackBitmap.Handle);
BitBlt(DC, 0, 0, rc.Right, rc.Bottom, hDCBack, 0, 0, SRCCOPY);
DeleteDC(hDCBack);
//Und ich so direkt:
BitBlt(DC,0,0,ListBoxBild.Width-18,ListBoxBild.Height,ListBoxBild.Canvas.Handle,0,0,SRCCOPY);
Darf ich mal fragen, warum man so macht, wie bei dir?
Und du hast oft
Delphi-Quellcode:
RedrawWindow(hFileList, nil, 0,RDW_FRAME or RDW_INVALIDATE or RDW_UPDATENOW);
drin RDW_INVALIDATE und RDW_UPDATENOW verstehe ich. Nur was macht RDW_FRAME?

EDIT: Irgendwie, hat es bei mir funktioniert, ohne den "Bug", als ich es eingefügt habe.
Und es Fehlt nur ein FillRect, wegen der Füllfrabe der Items.

daywalker9 15. Jun 2012 20:57

AW: [NonVCL] Hintergrundbild in scrollbarer Listbox
 
Msdn:

Zitat:

rdw_frame

causes any part of the nonclient area of the window that intersects the update region to receive a wm_ncpaint message. The rdw_invalidate flag must also be specified; otherwise, rdw_frame has no effect. The wm_ncpaint message is typically not sent during the execution of redrawwindow unless either rdw_updatenow or rdw_erasenow is specified.

EWeiss 15. Jun 2012 21:00

AW: [NonVCL] Hintergrundbild in scrollbarer Listbox
 
Das Frame gehört meineserachtens zum Nonclientbereich des Fensters da du hier ein bild in die ListbBox
packst mußt du Das Frame zwingen das es neugezeichnet wird die Listbox selbst macht das nicht.
Ohne RDW_FRAME also RDW_NOFRAME würde nur der Clientbereich neu gezeichnet werden.


Zitat:

EDIT: Irgendwie, hat es bei mir funktioniert, ohne den "Bug", als ich es eingefügt habe.
Versteh ich jetzt nicht.

Edit:
Zitat:

Und du hast oft
Zu der zeit habe ich auch noch nach möglichkeiten gesucht das neuzeichnen zu erzwingen
Das war zu testzwecken erstmal ausreichend für mich.
Das Projekt wurde nie Komplett abgeschlossen ;)
Mittlerweile habe ich ja schon einige verbesserungen in meiner Lib vom VPiano Sample.


gruss


Alle Zeitangaben in WEZ +1. Es ist jetzt 15:51 Uhr.
Seite 1 von 2  1 2      

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