Forum | | | | - Seite 1 - |
| Normann Strübli | Hallo Frank, hallo Community,
ich bastel gerade an einem Listview welches Bargraphen und Bilder enthalten kann. (war ja auch schon mal irgendwo gefordert ) Dieser Code ist lediglich ein Anfang aber kann und soll mit Eurer Hilfe weiterentwickelt werden. Leider habe ich ihn auch noch nicht auskommentiert, aber so schwer ist er glaub ich auch nicht zu verstehen.
Ich hoffe allerdings Frank davon überzeugen zu können so eine Funktion in seine Listview mit aufzunehmen ;D Als Anhang habe ich mal Vorlagen die mit masm programmiert sind beigefügt. -Am besten mal angucken die Beispiele sind auch als ausführbare Datei vorhanden. FRANK BITTE GUCK DIR DAS AN!!!
Gleich noch eine Frage: Ich habe dem Listview den LVS_OWNDERDRAWFIXED Style verpasst, da ja ansonsten keine wm_drawitem nachricht an das Elternfenster gesand wird. Kann man es hinbekommen das nur bei einer Spalte diese Nachricht verschickt wird, dann müsste man nicht das komplette control selbst zeichnen?!...
Gruß Normann KompilierenMarkierenSeparieren $H Windows.ph
$H Structs.ph
$H Messages.ph
$H Commctrl.ph
$H Structs.ph
Set(FastMode,1)
Def Hiword(1) And(&(1)>>16,$Ffff)
Def Loword(1) And(&(1),$Ffff)
declare test&,itemtext$
itemtext$ = TestItem
Struct Hd_notify = ~Hd_notify
Declare Hd_notify#
Dim Hd_notify#,Hd_notify
Struct NMHDR = ~NMHDR
Declare NMHDR#
Dim NMHDR#,NMHDR
Struct DRAWITEMSTRUCT = ~DRAWITEMSTRUCT
Declare DRAWITEMSTRUCT#
Dim DRAWITEMSTRUCT#,DRAWITEMSTRUCT
Struct Rect = ~Rect
Declare Rect#
Dim Rect#,Rect
struct TWindowClass = ~WndClass
struct TMsg = ~Msg
declare WindowClass#, Msg#
declare AppName$
$I Listview_Funktionen.inc
Declare lvdll&
lvdll&=usedll(Listview.dll)
AppName$ = Listview Test
proc WindowProc
parameters Window&, Message&, WParam&, LParam&
If Message& = ~Wm_notify
NMHDR# = Lparam&
if NMHDR#.hwndfrom& = listview&
if NMHDR#.code& = ~NM_KILLFOCUS Das Control hat den Focus verloren
elseif NMHDR#.code& = ~NM_SETFOCUS Das Control hat den Focus bekommmen
elseif NMHDR#.code& = ~NM_CLICK Der Anwender hat die linke Maustaste im Control geklickt
elseif NMHDR#.code& = ~NM_DBLCLK Der Anwender hat die linke Maustaste im Control doppel-geklickt
elseif NMHDR#.code& = ~NM_OUTOFMEMORY Das Control konnte die Aktion Aufgrund zu wenig Speicher nicht ausführen
elseif NMHDR#.code& = ~NM_RCLICK Der Anwender hat die rechte Maustaste im Control geklickt.
elseif NMHDR#.code& = ~NM_RDBLCLK Der Anwender hat die rechte Maustaste im Control doppel-geklickt.
elseif NMHDR#.code& = ~NM_RETURN Der Anwender hat die ENTER-Taste im Control gedrückt
elseif NMHDR#.code& = ~LVN_COLUMNCLICK Das Control hat den Focus bekommmen
Endif
endif
endif
if Message& = ~wm_drawitem
if Wparam& = listviewid&
DRAWITEMSTRUCT# = lparam&
Long Rect#,0 = Long(DRAWITEMSTRUCT#,28)
Long Rect#,4 = Long(DRAWITEMSTRUCT#,32)
Long Rect#,8 = Long(DRAWITEMSTRUCT#,36)
Long Rect#,12 = Long(DRAWITEMSTRUCT#,40)
If And(Long(Lparam&,16),1)
~SelectObject(DRAWITEMSTRUCT#.Hdc&,~CreateSolidBrush(@RGB(200,0,0)))
~SetBkColor(DRAWITEMSTRUCT#.hdc&,@RGB(100,100,200))
else
~SetBkColor(DRAWITEMSTRUCT#.hdc&,@RGB(200,200,200))
~SelectObject(DRAWITEMSTRUCT#.Hdc&,~CreateSolidBrush(@RGB(0,200,0)))
endif
~Exttextout(DRAWITEMSTRUCT#.Hdc&,rect#.left&,rect#.top&,~Eto_OPAQUE,Rect#,Addr(Itemtext$),Len(Itemtext$),0)
~Rectangle(DRAWITEMSTRUCT#.Hdc&,120,rect#.top&,120 + rect#.top&,rect#.bottom&)
endif
endif
if Message& = ~wm_Destroy
CloseProc
~PostQuitMessage(0)
END
endif
return ~DefWindowProc(Window&, Message&, WParam&, LParam&)
endproc
proc WinMain
declare Window&, Message&
dim WindowClass#,TWindowClass
dim Msg#,TMsg
with WindowClass#
.style& = 0
.lpfnWndProc& = ProcAddr(WindowProc,4)
.cbClsExtra& = 0
.cbWndExtra& = 0
.hInstance& = %HInstance
.hIcon& = ~LoadIcon(0,~idi_Information)
.hCursor& = ~LoadCursor(0, ~idc_Arrow)
.hbrBackground& = ~GetStockObject(~white_Brush)
.lpszMenuName& = Addr(AppName$)
.lpszClassName& = Addr(AppName$)
endwith
if ~RegisterClass(WindowClass#) = 0
~MessageBox(0,Fenster konnte nicht registriert werden!,Fehler,0)
end
endif
Window& = ~CreateWindowEx(
0,
Addr(AppName$),
Addr(AppName$),
~ws_OverlappedWindow,
~cw_UseDefault,
~cw_UseDefault,
~cw_UseDefault,
~cw_UseDefault,
0,
0,
%HInstance,
0)
~ShowWindow(Window&, ~sw_ShowNormal)
~UpdateWindow(Window&)
InitMessages(Window&)
Declare listview&,ListviewId&,Column$
Listview& = CreateListview(Window&,%HInstance,0,-1,-1,$23)
~SetWindowLong(Listview&,~GWL_STYLE,@Or(~Getwindowlong(Listview&,~GWL_STYLE),~LVS_OWNERDRAWFIXED))
~Setprop(Listview&,OldCallback,~Setwindowlong(Listview&,~Gwl_wndproc, Procaddr(Listviewcallback,4)))
ListviewId& = ~Getwindowlong(Listview&,~GWL_ID)
Autosortlistview Listview&,1,1,1,1,2,2
Column$ = Column 1
IColumn(Listview&,addr(Column$),120,0)
Column$ = Column 2
IColumn(Listview&,addr(Column$),120,0)
Column$ = Column 3
IColumn(Listview&,addr(Column$),120,0)
Declare bereich#,text1$,text2$,text3$
dim bereich#,1000
text1$=Neues_Item 1
text2$=Neues_Item 2
text3$=Neues_Item 3
long bereich#,0=addr(text1$)
long bereich#,4=addr(text2$)
long bereich#,8=addr(text3$)
WhileLoop 8
SItem(listview&,bereich#,3)
EndWhile
Showlistview(Listview&,32,32,500,400)
Dispose bereich#
while ~GetMessage(Msg#, 0, 0, 0) > 0
~TranslateMessage(Msg#)
~DispatchMessage(Msg#)
endwhile
end
endproc
WinMain
Proc Listviewcallback
Parameters Wnd&, Msg&, Wparam&, Lparam&
If Msg& = ~Wm_notify
NMHDR# = Lparam&
If (NMHDR#.code& = ~Hdn_begintrackw) OR (NMHDR#.code& = ~Hdn_DIVIDERDBLCLICKw) Die HDN_BeginTrack Botschaft abfangen und löschen!
Hd_notify# = Lparam&
if (Hd_notify#.iButton& = 0) OR (Hd_notify#.iButton& = 1)
Return 1
Endif
Endif
Endif
Return ~Callwindowproc(~Getprop(Wnd&,OldCallback),Wnd&, Msg&,Wparam&,Lparam&)
Endproc
Proc Closeproc
CloseMessages(window&)
$I Listview_dispose.inc
endproc
|
| | | | |
| | | | | - Seite 1 - |
| Normann Strübli | Hallo,
@Frank: ich hoffe Du hast die Feier schadenfrei überstanden
ich werd noch wahnsinnig bei der Owerdraw-Geschichte bitte helft mir !!!
folgendes Problem:
Die WM_DRAWITEM -Nachricht wird immer nur einmal pro Zeile verschickt, die SubItems müssen ja aber auch neu gezeichnet werden und genau da fehlt mir der richtige Lösungsansatz.
Jetzt lese in einer Schleife die einzelnen Spalten aus, aber das ist nun wirklich nicht optimal...
Bitte schaut Euch das Beispiel einmal an und gebt mir etwas Hilfestellung wie ich es besser lösen kann. |
| | | | |
| | Frank Abbing | Hallo Normann,
ja, die Feier war gut. Mein Computer war aber in Reparatur und verhält sich immer noch etwas seltsam. Ich bin noch nicht zu deinen Sachen gekommen. Morgen, hoffe ich. |
| | | | |
| | Normann Strübli | Hi,
Neue Version, bitte Testen! (Jetzt ohne gleich einen Farbflash zu bekommen) Sollte sich jetzt wie ein ganz normales Listview-Control verhalten.
Der Vorteil ist z.B. das die Hintergrundfarbe der selektierten Zeile immer erkennbar bleibt
Gruß Normann
Hier maln Screenshot: |
| | | | |
| | Frank Abbing | Hi,
Normann, poste hier auch mal deine ph-Dateien. Ich bekomme eine Fehlermeldung und kanns nicht testen.
Die Assembler.dll kannte ich schon. Wenn ich mich richtig erinnere, ist sie aber nie fertig geworden. Warum soll ich die Dll-Funktionen denn für die Listview.dll umsetzen, wenn du die zusätzliche Dll schon hast? Kombiniere doch einfach beide Dlls. |
| | | | |
| | Normann Strübli | Aarrghh!!!
Stimmt die Structs.ph hat einen Fehler, hier die korrigierte Version. |
| | | | |
| | Frank Abbing | Hi,
ok, habs getestet. Aber was bezweckst du jetzt damit? Was genau möchtest du von mir? Willst du Balken und Torten in Listviews? |
| | | | |
| | Michael Wodrich | Zumindest doch die Balken. Kann ich mir als Prozentbalken bei einem Datei-Downloader gut vorstellen. Da gibt es mit Sicherheit viele Möglichkeiten.
Schöne Grüße Michael Wodrich |
| | | Programmieren, das spannendste Detektivspiel der Welt. | 09.11.2005 ▲ |
| |
| | Normann Strübli | Hallo Frank,
ich möchte eigentlich (inzwischen) damit bezwecken was ich vor langer Zeit mal mit dem X-menü bezweckt habe. Ein Listview-Control komplett den eigenen Bedürfnissen anzupassen. Ursprünglich wollte ich ja nur eine Balkenanzeige einbauen, da dies nicht so ohne weiters funktioniert hat, habe ich ich mich mit dem Ownerdraw-Listview beschäftigt, und so gings dann weiter...
Eine Unterstützung von z.B. Bargraphen von Deiner Dll wäre eine Super Sache, ich glaube so denken nicht nur Michael und ich.
Mein Ansatz soll eine Nischenlösung sein für denjenigen der eben noch etwas anderes als Text- oder icons in den Zeilen stehen haben möchte, was ja theroretisch so schon funktioniert. (z.B. Bitmaps, Graphen, mehzeilige Felder usw...)
Deine Dll kann das natürlich nicht ersetzen und soll dem interessierten nur mal aufzeigen das so eine hübsch bunte Listview auch in reinem (X-)Profan zu erschaffen ist.
Mein Hauptproblem ist nun die Geschwindigkeit bei der ganzen Geschichte, und da war meine Frage wie ich meinen Code- besonders bei der Abarbeitung der Wm_notify-Nachricht optimieren und schneller machen kann. Und wer hat da mehr Ahnung von Tabellen als Du, Frank
Wie gesagt für Deine Listview.dll wäre das was ich vorhabe zu individuell, und da ich das ganze jetzt zu Fuß erledige wäre ich für jeden Tip dankbar wie ich das ganze optimieren kann...
mehr wollte ich doch gar nicht |
| | | | |
| | Normann Strübli | @Frank:
Je länger ich mich mit der Listview-Geschichte beschäftige umso mehr Probleme ergeben sich da Jetzt habe ich die Sortierung der Zeilen mit Hilfe des XPIA fertiggestellt und mal ein Vergleich mit Deiner Listview.dll gemacht. Bei ca. 20.000 Einträgen dauert es bei meiner Variante immer noch stolze 21 sekunden, bei der Listviev.dll nur knapp 3 sekunden. (also ca. 10mal schneller) Das wird ja bestimmt durch den lahmen Aufruf von Profan kommen.
Da in meiner Liste aber bestimmt 13.000 Einträge vorhanden sein werden, habe ich mir die ganze Arbeit wohl umsonst gemacht -aber immerhin habe ich viel dazugelernt.
Also habe Deine Listview.dll schnell wieder eingebunden, leider gehen nun die Zeilenfarben nach einer Sortierung flöten. Ist ja auch klar da ich das lParam& member von LV_ITEM# dazu mißbraucht habe die Farbinformationen für die Entsprechende Zeile zu Speichern. Du benutzt richtigerweise den Wert von lParam um nach der Sortierung den neuen Index der Zeilen zu speichern.
Aber wenn ich nicht mehr weiß welche Zeile nach der Sortierung welchen index hat, und der Befehl RaiseLine auf nur 1024 Zeilen beschränk ist muß ich wohl anfangen zu Zaubern um einer Zeile einen eindeutigen Farbwert zuzuordnen der unabhängig von der Sortierung ist. Irgendwo hast Du schonmal auf eine Frage geantwortet: [quote:06c4627aa6]Wenn du Zeilen einfügst und möchtest, das die farbige Markierung mitwandert, mußt du das selber programmieren.[/quote:06c4627aa6] Zum Glück ist das Superdupieinfach
...nein, ich habe keine Ahnung! Irgendeinen Vorschlag??? *verzweifel*
Gruß Normann |
| | | | |
| | Normann Strübli | hab ich noch vergessen:
Frank, kannst Du vielleicht eine Funktion einbauen um die Zeilenhöhe einzustellen? Oder weiß jmd. wie das bei einer Listview funktioniert??? |
| | | | |
| | | | - Seite 2 - |
| | Frank Abbing | Zumindest zu deiner letzten Frage gibt es irgendeine Message. Sobald mein Computer wieder läuft, kümmere ich mich darum. |
| | | | |
| | Frank Abbing | Hi,
hab die Zeilenhöhe eingebaut. Eine Message gab es hierzu nicht, hab ein wenig mit Imagelisten getricks. In der nächsten Version.
Übrigens. Hier Fortschrittsbalken im Listview: KompilierenMarkierenSeparierenRandomize
Declare listview&,lvdll&,text$,text2$,x&,y&,z&,font&
Def GetSysColor(1) !USER32,GetSysColor
$I Listview_Funktionen.inc
lvdll&=usedll(Listview.dll)
Windowstyle 543
Windowtitle Listview.dll / Prozentanzeige
Window 0,0-400,256
Cls GetSysColor(15)
font&=Create(Font,MS Sans Serif,13,0,0,0,0)
x&=MixRGBs(GetSysColor(15),$00ffffffff)
listview&=CreateListView(%hwnd,%hinstance,0,x&,-1,$31)
SetFont listview&,font&
InsertColumn listview&,Text,60,0
InsertColumn listview&,Prozent,240,0
Whileloop 12
text2$=
x&=Rnd(30)
Whileloop x&
text2$=text2$+Chr$(127)
Wend
text2$=text2$+ +Str$(Int(100/30*x&))+%
text$=Item +Str$(&loop)
SetItem listview&,text$,text2$
Wend
AutoSortListview listview&,1,1
ShowListView(listview&,8,8,370,200)
InitMessages(%hwnd)
SetTimer 1500
While 1
waitinput
Case %key=2:BREAK
y&=Rnd(4)
Whileloop 12
text2$=
x&=Rnd(30)
Whileloop x&
text2$=text2$+Chr$(127)
Wend
Case y&=0:text2$=text2$+ +Str$(Int(100/30*x&))+%
SetItemText(listview&,addr(text2$),1,(&loop-1))
Wend
Wend
KillTimer
DestroyWindow(listview&)
CloseMessages(%hwnd)
freedll lvdll&
DeleteObject font&
$I Listview_Dispose.inc
End
|
| | | | |
|
AntwortenThemenoptionen | 9.502 Betrachtungen |
ThemeninformationenDieses Thema hat 3 Teilnehmer: |