AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Implement ListView

Ein Thema von EWeiss · begonnen am 10. Jan 2017 · letzter Beitrag vom 10. Jan 2017
Antwort Antwort
Seite 1 von 2  1 2      
EWeiss
(Gast)

n/a Beiträge
 
#1

Implement ListView

  Alt 10. Jan 2017, 02:18
Habe kleine Probleme beim implementieren einer ListView.
Meine DLL schickt folgende Message beim WM_LBUTTONDBLCLK.
Delphi-Quellcode:
var
  MessageStructure: PNMHdr;
Delphi-Quellcode:
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;
in der Anwendung wird die Message so verarbeitet.
Delphi-Quellcode:
    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;
Das Problem ist ich kann die MessageStructure nicht füllen.

Error:
Zitat:
Erste Gelegenheit für Exception bei $005544BE. Exception-Klasse Zugriffsverletzung ($C0000005) mit Meldung 'access violation at 0x005544be: write of address 0x017a0090'. Prozess Soundmachine.exe (5252)
Was läuft falsch?

gruss
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.071 Beiträge
 
Delphi 12 Athens
 
#2

AW: Implement ListView

  Alt 10. Jan 2017, 03:13
Was läuft falsch?
Du gehst fahrlässig davon aus, dass in LPARAM ein gewisser Record-Zeiger übergeben wird, aber was sagt denn die Dokumentation dazu?
https://msdn.microsoft.com/de-de/lib.../ms645606.aspx

Zitat:
Integer(IrgendeinPointer)
Und niemals Pointer mit Integern casten.
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.
Neuste Erkenntnis:
Seit Pos einen dritten Parameter hat,
wird PoSex im Delphi viel seltener praktiziert.
  Mit Zitat antworten Zitat
EWeiss
(Gast)

n/a Beiträge
 
#3

AW: Implement ListView

  Alt 10. Jan 2017, 03:24
Zitat:
Du gehst fahrlässig davon aus, dass in LPARAM ein gewisser Record-Zeiger übergeben wird, aber was sagt denn die Dokumentation dazu?
Nur was soll ich dann verwenden anstelle von WM_LBUTTONDBLCLK
WM_NOTIFY in meiner ListViewProc funktioniert nicht

if(PNMHdr(lp)^.hwndFrom = PLList.Handle) then

tritt niemals ein.
Logisch weil WM_NOTIFY an das MainWindow gesendet wird.

Zitat:
für Casts bei Messages gibt es extra die Typen LPARAM, WPARAM und LRESULT
Habe es geändert
Aber dazu muss ich erst mal erfolgreich die Message senden können.
SendMessageW(ListViewParent, WM_NOTIFY, DlgItemID, LParam(MessageStructure));

Ich könnte es jetzt auf diese weise machen
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

Geändert von EWeiss (10. Jan 2017 um 04:27 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von jaenicke
jaenicke

Registriert seit: 10. Jun 2003
Ort: Berlin
9.586 Beiträge
 
Delphi 11 Alexandria
 
#4

AW: Implement ListView

  Alt 10. Jan 2017, 05:49
Zitat:
Du gehst fahrlässig davon aus, dass in LPARAM ein gewisser Record-Zeiger übergeben wird, aber was sagt denn die Dokumentation dazu?
Nur was soll ich dann verwenden anstelle von WM_LBUTTONDBLCLK
Du kannst das ja verwenden, aber wenn du per WM_NOTIFY einen Record weizergehen möchtest, musst du auch den nötigen Speicher reservieren.

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:
var
  a: Integer;
  MessageStructure: PNMHdr;
begin
  a := $017a0090;
  MessageStructure := PNMHdr(a);
  MessageStructure.hwndFrom := WinHandle;
...
end;
Die Fehlermeldung sollte deiner aktuellen sehr ähnlich sein.
Sebastian Jänicke
Alle eigenen Projekte sind eingestellt, ebenso meine Homepage, Downloadlinks usw. im Forum bleiben aktiv!

Geändert von jaenicke (10. Jan 2017 um 05:59 Uhr)
  Mit Zitat antworten Zitat
EWeiss
(Gast)

n/a Beiträge
 
#5

AW: Implement ListView

  Alt 10. Jan 2017, 05:56
Zitat:
Du kannst das ja verwenden, aber wenn du per WM_NOTIFY einen Record weizergehen möchtest, musst du auch den nötigen Speicher reservieren.
Kleines Beispiel anhand meines Codes?

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:
Die Fehlermeldung sollte deiner aktuellen sehr ähnlich sein.
Ich habe das ListView gesubclassed.
Eigentlich sollte sich dann der Record-Zeiger über lP zugewiesen werden.
Scheint aber nicht immer der Fall zu sein.

gruss

Geändert von EWeiss (10. Jan 2017 um 06:03 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von jaenicke
jaenicke

Registriert seit: 10. Jun 2003
Ort: Berlin
9.586 Beiträge
 
Delphi 11 Alexandria
 
#6

AW: Implement ListView

  Alt 10. Jan 2017, 06:03
Hier findest du entsprechenden Code mit Erläuterungen:
https://de.m.wikibooks.org/wiki/Prog...elphi:_Pointer
Es fehlt vor der Verwendung lediglich die Reservierung des Speichers mit New und nach dem SendMessage die Freigabe mit Dispose.
Sebastian Jänicke
Alle eigenen Projekte sind eingestellt, ebenso meine Homepage, Downloadlinks usw. im Forum bleiben aktiv!
  Mit Zitat antworten Zitat
EWeiss
(Gast)

n/a Beiträge
 
#7

AW: Implement ListView

  Alt 10. Jan 2017, 06:11
Hier findest du entsprechenden Code mit Erläuterungen:
https://de.m.wikibooks.org/wiki/Prog...elphi:_Pointer
Es fehlt vor der Verwendung lediglich die Reservierung des Speichers mit New und nach dem SendMessage die Freigabe mit Dispose.
Supi.. Sebastian hast mir sehr geholfen.

Delphi-Quellcode:
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;
Jetzt kann ich mich mit den anderen Kram Ownerdraw usw. .beschäftigen.
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

Geändert von EWeiss (10. Jan 2017 um 06:36 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von jaenicke
jaenicke

Registriert seit: 10. Jun 2003
Ort: Berlin
9.586 Beiträge
 
Delphi 11 Alexandria
 
#8

AW: Implement ListView

  Alt 10. Jan 2017, 06:17
Wann ist das grundsätzlich gegeben den Speicher mit NEW zu Reservieren?
Immer wenn du einen Pointer hast, der auf nichts Bekanntes zeigt. Sprich einen Pointer auf eine lokale Variable musst du nicht initialisieren, einen Pointer, den du ohne weitere Zusammenhänge lokal als Variable deklariert hast, schon.

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.
Sebastian Jänicke
Alle eigenen Projekte sind eingestellt, ebenso meine Homepage, Downloadlinks usw. im Forum bleiben aktiv!
  Mit Zitat antworten Zitat
EWeiss
(Gast)

n/a Beiträge
 
#9

AW: Implement ListView

  Alt 10. Jan 2017, 06:35
Zitat:
Immer wenn du einen Pointer hast, der auf nichts Bekanntes zeigt. Sprich einen Pointer auf eine lokale Variable musst du nicht initialisieren, einen Pointer, den du ohne weitere Zusammenhänge lokal als Variable deklariert hast, schon.
Das ist mal Aussagekräftig Danke.

Zitat:
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.
Jo wie ich es hier schon gemacht habe.

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
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.071 Beiträge
 
Delphi 12 Athens
 
#10

AW: Implement ListView

  Alt 10. Jan 2017, 10:23
Natürlich kann man auch direkt den Datentypen verwenden und spart sich dann die manuelle Speicherreservierung und den von dir vergessenen Ressourcenschutzblock (Try-Finally).
Delphi-Quellcode:
var
  MessageStructure: TNMHdr;

SendMessage(..., LPARAM(@MessageStructure));

PS: Eigentlich müsste man beim Zugriff auf Pointer noch den Zeiger dereferenzieren MessageStructure^.hwndFrom ,
aber Delphi macht das netterweise implizit, von sich aus, wenn man .irgendwas auf den Zeiger anwendet.
Neuste Erkenntnis:
Seit Pos einen dritten Parameter hat,
wird PoSex im Delphi viel seltener praktiziert.

Geändert von himitsu (10. Jan 2017 um 10:50 Uhr)
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 23:17 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