Scrollen ListIconGadget,Zeile bleibt in der Mitte - Flimmern

Windowsspezifisches Forum , API ,..
Beiträge, die plattformübergreifend sind, gehören ins 'Allgemein'-Forum.
Benutzeravatar
hjbremer
Beiträge: 822
Registriert: 27.02.2006 22:30
Computerausstattung: von gestern
Wohnort: Neumünster

Scrollen ListIconGadget,Zeile bleibt in der Mitte - Flimmern

Beitrag von hjbremer »

Wenn man in einem ListIconGadget mit den Pfeiltasten sich bewegt, und man ist oben/unten, dann störte mich, das ich die folgenden Einträge nicht sehen konnte.
Hier die Abhilfe.

Meine Frage: in der 2.Prozedur flimmert es etwas auf meinem etwas betagten Rechner (1 Ghz). Gibt es eine bessere Lösung als meine in der 1.Prozedur ?

Code: Alles auswählen

;Beim Scrollen in einem ListIconGadget bleibt die markierte Zeile in der Mitte
;außer am Anfang und am Ende
;
;die beiden Prozeduren tun im Ergebnis das Gleiche, nur eine flimmert etwas auf
;langsameren Rechnern, dafür ist Sie aber kürzer und einfacher.

Declare Api_LVM_Scroll_zurMitte_Version1 (hdc,actPos)
Declare Api_LVM_Scroll_zurMitte_Version2 (hdc,actPos)

Enumeration 
#list_nr0
#list_nr1
EndEnumeration

#alle=-1

#list_sp=10
#list_br=600
#list_hh=200
#list_ze0=10
#list_ze1=230
#list_brCol0=289
#list_brCol1=289

hwnd = OpenWindow(0,0,0,640,480,"Testfenster")
   
    CreateGadgetList(hwnd) 
    
    maxlist = 500
    listflags = #PB_ListIcon_GridLines|#PB_ListIcon_FullRowSelect

    hdc0=ListIconGadget(#list_nr0,#list_sp,#list_ze0, #list_br, #list_hh, "Test 0" ,#list_brCol0,listflags) 
    AddGadgetColumn(#list_nr0, 1, "Spalte 2", #list_brCol1)

    hdc1=ListIconGadget(#list_nr1,#list_sp,#list_ze1, #list_br, #list_hh, "Test 1" ,#list_brCol0,listflags) 
    AddGadgetColumn(#list_nr1, 1, "Spalte 2", #list_brCol1)

    ;für schnelleren Bildaufbau, 
    SendMessage_(hdc0, #WM_SETREDRAW, #False, 0) 
    SendMessage_(hdc1, #WM_SETREDRAW, #False, 0) 
    
    backfarbe = $F0F0F0 ;oder GetSysColor_(#COLOR_INACTIVEBORDER)

    ;Gadget füllen 
    For i = 1 To maxlist
      AddGadgetItem(#list_nr0,-1,"Test"+Str(i)+#LF$+"Spalte 2")
      AddGadgetItem(#list_nr1,-1,"Test"+Str(i))
      ;jede 2.Zeile farbiger Hintergrund
      If i % 2            
         SetGadgetItemColor(#list_nr0, i-1, #PB_Gadget_BackColor, backfarbe, #alle)    
         SetGadgetItemColor(#list_nr1, i-1, #PB_Gadget_BackColor, backfarbe, #alle)    
      EndIf
    Next
    
    ;Gadget anzeigen/redraw
    SendMessage_(hdc0, #WM_SETREDRAW, #True, 0) 
    SendMessage_(hdc1, #WM_SETREDRAW, #True, 0) 
    
    
  Repeat 
  
    EventID = WaitWindowEvent() 
    
    
    If EventID = #PB_Event_Gadget 
    
      welcherButton=EventGadget() 

      Select welcherButton      
              
        Case #list_nr0
                                                  
          ;welche Zeile, mit der Maus angeklickt oder mit den Pfeiltasten
          listzeiger = GetGadgetState(#list_nr0) 
          
          Api_LVM_Scroll_zurMitte_Version1(hdc0,listzeiger)          
                    
        Case #list_nr1
          
          listzeiger = GetGadgetState(#list_nr1) 
          
          Api_LVM_Scroll_zurMitte_Version2(hdc1,listzeiger)          
                    
     EndSelect
            
    EndIf 
    
  Until EventID = #PB_Event_CloseWindow 
  
End 


Procedure Api_LVM_Scroll_zurMitte_Version1(hdc,actPos)

  ;ermittelt Höhe einer Zeile
  SendMessage_(hdc,#LVM_GETITEMRECT,0,r.RECT) 
  lvm_itemhh = r\bottom - r\top          
  
  ;lvm_mitte kann auch einen anderen Wert haben, z.b. 2
  ; / 2 = ca mittlere Zeile des Listicongadget 
  lvm_mitte = SendMessage_(hdc,#LVM_GETCOUNTPERPAGE	,0,0) / 2

  ;1.sichtbare Zeile
  lvm_topidx = SendMessage_(hdc,#LVM_GETTOPINDEX,0,0)                   
  
  ;errechnet Anzahl Pixel zum scrollen
  abstand2 = lvm_itemhh * actPos 
  abstand1 = lvm_itemhh * (lvm_topidx + lvm_mitte)           
  diff = abstand2 - abstand1 
  
  ;oder das Gleiche nur etwas unverständlicher
  ;diff = lvm_itemhh * (actPos - (lvm_topidx+lvm_mitte))
      
  SendMessage_(hdc, #LVM_SCROLL, 0, diff)      

EndProcedure

Procedure Api_LVM_Scroll_zurMitte_Version2(hdc,actPos)

;diese Version flimmert bei langsamen Rechnern etwas, besonders der rechte Scrollbalken 
;ist dafür aber kürzer und einfacher 
;#WM_SETREDRAW hilft nicht viel gegen das Flimmern, im Gegenteil, 
;Windows kommt durcheinander, wenn man den Finger auf den Pfeiltasten läßt, auch mit InvalidateRect_

  SendMessage_(hdc,#LVM_GETITEMRECT,0,r.RECT) 
  lvm_itemhh = r\bottom - r\top          
  
  lvm_mitte = SendMessage_(hdc,#LVM_GETCOUNTPERPAGE	,0,0) / 2                                  

  ;scrollt zuerst ganz nach oben
  SendMessage_(hdc,#LVM_ENSUREVISIBLE,0,0) 
  
  ;scrollt in die mitte
  SendMessage_(hdc, #LVM_SCROLL, 0, (actPos-lvm_mitte) * lvm_itemhh)      
  
EndProcedure

Purebasic 5.70 x86 5.72 X 64 - Windows 10

Der Computer hat dem menschlichen Gehirn gegenüber nur einen Vorteil: Er wird benutzt
grüße hjbremer
Benutzeravatar
Fluid Byte
Beiträge: 3110
Registriert: 27.09.2006 22:06
Wohnort: Berlin, Mitte

Beitrag von Fluid Byte »

Das lässt sich nicht abstellen. Selbst die Windows-eigenen Listen flackern/flimmern beim scrollen.
Windows 10 Pro, 64-Bit / Outtakes | Derek
Benutzeravatar
hjbremer
Beiträge: 822
Registriert: 27.02.2006 22:30
Computerausstattung: von gestern
Wohnort: Neumünster

Beitrag von hjbremer »

SHIT :(
Purebasic 5.70 x86 5.72 X 64 - Windows 10

Der Computer hat dem menschlichen Gehirn gegenüber nur einen Vorteil: Er wird benutzt
grüße hjbremer
Benutzeravatar
edel
Beiträge: 3667
Registriert: 28.07.2005 12:39
Computerausstattung: GameBoy
Kontaktdaten:

Beitrag von edel »

Vielleicht hilft es ja wenn du Doublebuffer fuer das
Listview einschaltest (ab XP).

Du hast fuer deine Variablen ein recht ungluecklichen Namen
gewaehlt, falls es nur fuer dich ist, ist es zwar egal, aber hdc
ist eigentlich ein Handle zu einem Device Context.
Benutzeravatar
hjbremer
Beiträge: 822
Registriert: 27.02.2006 22:30
Computerausstattung: von gestern
Wohnort: Neumünster

Beitrag von hjbremer »

Meinst du LVS_EX_DOUBLEBUFFER ?

zum einen steht in der MSDN erst ab Version 6.00 der comctl.dll
ich habe 5.82

zum anderen kennt meine PB Version 4.02 die Konstante nicht

Hast du eine Lösung ?
Purebasic 5.70 x86 5.72 X 64 - Windows 10

Der Computer hat dem menschlichen Gehirn gegenüber nur einen Vorteil: Er wird benutzt
grüße hjbremer
Benutzeravatar
edel
Beiträge: 3667
Registriert: 28.07.2005 12:39
Computerausstattung: GameBoy
Kontaktdaten:

Beitrag von edel »

hjbremer hat geschrieben:Meinst du LVS_EX_DOUBLEBUFFER ?
Ja.
hjbremer hat geschrieben: zum einen steht in der MSDN erst ab Version 6.00 der comctl.dll
ich habe 5.82
Dann wird das wohl nichts
hjbremer hat geschrieben: zum anderen kennt meine PB Version 4.02 die Konstante nicht

Hast du eine Lösung ?

Code: Alles auswählen

#LVM_SETEXTENDEDLISTVIEWSTYLE = #lvm_first + 54
#LVM_GETEXTENDEDLISTVIEWSTYLE = #lvm_first + 55
#LVS_EX_DOUBLEBUFFER = 65536
Zu dem Code kann ich nichts sagen , da ich das Problem
nicht erkennen kann 8)
Benutzeravatar
hjbremer
Beiträge: 822
Registriert: 27.02.2006 22:30
Computerausstattung: von gestern
Wohnort: Neumünster

Beitrag von hjbremer »

Danke für die Info :D werds mir notieren bis zum neueren Compu
Purebasic 5.70 x86 5.72 X 64 - Windows 10

Der Computer hat dem menschlichen Gehirn gegenüber nur einen Vorteil: Er wird benutzt
grüße hjbremer
Benutzeravatar
Fluid Byte
Beiträge: 3110
Registriert: 27.09.2006 22:06
Wohnort: Berlin, Mitte

Beitrag von Fluid Byte »

Du könntest zur Not das ListIconGadget auch Ownerdraw machen und auf ein Bitmap zeichen. Währe ein wenig aufwendig aber ebenfalls "flicker-free".
Windows 10 Pro, 64-Bit / Outtakes | Derek
Antworten