![]() |
Implement ListView
Habe kleine Probleme beim implementieren einer ListView.
Meine DLL schickt folgende Message beim WM_LBUTTONDBLCLK.
Delphi-Quellcode:
var
MessageStructure: PNMHdr;
Delphi-Quellcode:
in der Anwendung wird die Message so verarbeitet.
function TSkinListView.ListViewProc(WinHandle: hWnd; Msg: UINT; wP: WParam; lP: LParam): LRESULT;
begin case Msg of WM_LBUTTONDBLCLK: begin MessageStructure := PNMHdr(lP); MessageStructure.hwndFrom := WinHandle; MessageStructure.idFrom := DlgItemID; MessageStructure.code := NM_DBLCLK; SendMessageW(ListViewParent, WM_NOTIFY, DlgItemID, integer(MessageStructure)); Result := 0; exit; end; end; Result := CallWindowProc(Pointer(FPrevClientProc), WinHandle, Msg, wP, lP); end;
Delphi-Quellcode:
Das Problem ist ich kann die MessageStructure nicht füllen.
WM_NOTIFY:
begin if(PNMHdr(lp)^.hwndFrom = PLList.Handle) then begin case PNMHdr(lp)^.code of NM_DBLCLK: begin nItem := PLList.GetCursel(lP); if nItem > 0 then begin LastPlayListTitle := nItem; HiddenPLList.ListSelectPlus(HiddenPLList.Handle, nItem); getAudioFile := HiddenPLList.ListGetText(HiddenPLList.Handle, nItem); SKAERO_UpdateWindow(lP, False); HiddenPLList.ListSetTopIndex(HiddenPLList.Handle, nItem); // PLList.ListSetTopIndex(PLList.Handle, nItem); BassChannelPlay; end; end; end; end; end; Error: Zitat:
gruss |
AW: Implement ListView
Zitat:
![]() Zitat:
Intel und Co. haben beschlossen, dass der Integer beim Sprung von 32 auf 64 nicht mehr mit wächst und haben ihn eingefrohren. (früher war der mal 16 Bit, in 16 Bit Systemen) Besser Typen verwenden, die für solche Casts vorgesehn sind, wie z.B. UIntPtr und IntPtr, oder die "neuen" Integer-Typen verwenden, welche man nun erfunden hat und die ab jetzt wachsen sollen. In Delphi sind das NativeInt und NativeUInt. Bzw. für Casts bei Messages gibt es extra die Typen LPARAM, WPARAM und LRESULT, damit immer alles richtig läuft, auch wenn man irgendwann auf 64 Bit umstellen würde. |
AW: Implement ListView
Zitat:
WM_NOTIFY in meiner ListViewProc funktioniert nicht
Delphi-Quellcode:
if(PNMHdr(lp)^.hwndFrom = PLList.Handle) then
tritt niemals ein. Logisch weil WM_NOTIFY an das MainWindow gesendet wird. Zitat:
Aber dazu muss ich erst mal erfolgreich die Message senden können.
Delphi-Quellcode:
SendMessageW(ListViewParent, WM_NOTIFY, DlgItemID, LParam(MessageStructure));
Ich könnte es jetzt auf diese weise machen
Delphi-Quellcode:
SendMessageW(GetParent(WinHandle), WM_COMMAND, MAKELONG(DlgItemID, LBN_DBLCLK), lp);
Aber das ist nicht das typische ListView verhalten beim Doubleclick. Wenn dann jemand anderes damit arbeitet kommt er nicht mehr zurecht. gruss |
AW: Implement ListView
Zitat:
Im Moment schreibst du, da der Parameter, den du einfach auf einen Pointer auf den Record castest, ja nicht einmal ein Pointer ist, an eine quasi zufällige Stelle im Speicher und hoffst, dass das gut geht... Auffallen tut das bei dir, weil du eben nicht einfach überall in den Speicher schreiben darfst. Deshalb die Zugriffsverletzung. Deiner Meldung zufolge hast du übrigens an Position 378/144 geklickt. // edit Mal ein Beispiel was du da machst:
Delphi-Quellcode:
Die Fehlermeldung sollte deiner aktuellen sehr ähnlich sein.
var
a: Integer; MessageStructure: PNMHdr; begin a := $017a0090; MessageStructure := PNMHdr(a); MessageStructure.hwndFrom := WinHandle; ... end; |
AW: Implement ListView
Zitat:
Mein Problem ist das ich nicht weis welche Message ich anstelle von WM_LBUTTONDBLCLK verwenden soll. Damit im MainWindow WM_NOTIFY NM_DBLCLK: auch ausgelöst wird. Das macht ärger MessageStructure (nicht immer).. Zitat:
Eigentlich sollte sich dann der Record-Zeiger über lP zugewiesen werden. Scheint aber nicht immer der Fall zu sein. gruss |
AW: Implement ListView
Hier findest du entsprechenden Code mit Erläuterungen:
![]() Es fehlt vor der Verwendung lediglich die Reservierung des Speichers mit New und nach dem SendMessage die Freigabe mit Dispose. |
AW: Implement ListView
Zitat:
Delphi-Quellcode:
Jetzt kann ich mich mit den anderen Kram Ownerdraw usw. .beschäftigen.
function TSkinListView.ListViewProc(WinHandle: hWnd; Msg: UINT; wP: WParam; lP: LParam): LRESULT;
begin case Msg of WM_LBUTTONDBLCLK: begin OldSelected := GetCurSel(WinHandle); new(MessageStructure); MessageStructure.hwndFrom := WinHandle; MessageStructure.idFrom := DlgItemID; MessageStructure.code := NM_DBLCLK; SendMessageW(GetParent(WinHandle), WM_NOTIFY, DlgItemID, LParam(MessageStructure)); Dispose(MessageStructure); Result := 0; exit; end; end; Result := CallWindowProc(Pointer(FPrevClientProc), WinHandle, Msg, wP, lP); end; Hab ich so groß noch nicht verwendet NEW.. man lernt immer was dazu. Wann ist das grundsätzlich gegeben den Speicher mit NEW zu Reservieren? gruss |
AW: Implement ListView
Zitat:
Nebenbei: Du musst auch nicht WM_NOTIFY benutzen. Du kannst ruhig eine eigene Windows Message und einem eigenen Recordtyp verwenden, wenn du vielleicht noch andere Informationen weitergeben möchtest. |
AW: Implement ListView
Zitat:
Zitat:
Delphi-Quellcode:
SendMessageW(GetParent(WinHandle), WM_COMMAND, MAKELONG(DlgItemID, LBN_DBLCLK), lp);
Das Problem dabei ist nur das LBN_DBLCLK (Listbox DoubleClick) eigentlich nichts mit dem ListView gemein hat. Wenn man über WM_NOTIFY geht weis jeder was mit NM_DBLCLK: in Verbindung mit dem ListView gemeint ist. gruss |
AW: Implement ListView
Natürlich kann man auch direkt den Datentypen verwenden und spart sich dann die manuelle Speicherreservierung und den von dir vergessenen Ressourcenschutzblock (Try-Finally). :zwinker:
Delphi-Quellcode:
var
MessageStructure: TNMHdr; SendMessage(..., LPARAM(@MessageStructure)); PS: Eigentlich müsste man beim Zugriff auf Pointer noch den Zeiger dereferenzieren
Delphi-Quellcode:
,
MessageStructure^.hwndFrom
aber Delphi macht das netterweise implizit, von sich aus, wenn man
Delphi-Quellcode:
auf den Zeiger anwendet.
.irgendwas
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 06:21 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