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
Benutzerbild von jaenicke
jaenicke

Registriert seit: 10. Jun 2003
Ort: Berlin
10.022 Beiträge
 
Delphi 12 Athens
 
#1

AW: Implement ListView

  Alt 10. Jan 2017, 04: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
AppCentral

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

n/a Beiträge
 
#2

AW: Implement ListView

  Alt 10. Jan 2017, 04: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 05:03 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von jaenicke
jaenicke

Registriert seit: 10. Jun 2003
Ort: Berlin
10.022 Beiträge
 
Delphi 12 Athens
 
#3

AW: Implement ListView

  Alt 10. Jan 2017, 05: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
AppCentral
  Mit Zitat antworten Zitat
EWeiss
(Gast)

n/a Beiträge
 
#4

AW: Implement ListView

  Alt 10. Jan 2017, 05: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 05:36 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von jaenicke
jaenicke

Registriert seit: 10. Jun 2003
Ort: Berlin
10.022 Beiträge
 
Delphi 12 Athens
 
#5

AW: Implement ListView

  Alt 10. Jan 2017, 05: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
AppCentral
  Mit Zitat antworten Zitat
EWeiss
(Gast)

n/a Beiträge
 
#6

AW: Implement ListView

  Alt 10. Jan 2017, 05: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
Online

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

AW: Implement ListView

  Alt 10. Jan 2017, 09: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.
Ein Therapeut entspricht 1024 Gigapeut.

Geändert von himitsu (10. Jan 2017 um 09:50 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von jaenicke
jaenicke

Registriert seit: 10. Jun 2003
Ort: Berlin
10.022 Beiträge
 
Delphi 12 Athens
 
#8

AW: Implement ListView

  Alt 10. Jan 2017, 09:56
Jo wie ich es hier schon gemacht habe.

SendMessageW(GetParent(WinHandle), WM_COMMAND, MAKELONG(DlgItemID, LBN_DBLCLK), lp);
Ich meinte so etwas wie:
Delphi-Quellcode:
const
  WM_MySuperSpecialOperation = WM_USER + 777; // ab WM_USER oder WM_APP kannst du eigene Botschaften definieren
var
  MyValue: TMyVeryOwnRecord;
begin
  SendMessageW(GetParent(WinHandle), WM_MySuperSpecialOperation, 0, @MyValue);
Kompiliert so wohl nicht, aber was ich damit zeigen möchte ist, dass du auch eine ganz eigene Message und einen ganz eigenen Recordtyp deklarieren kannst und damit arbeiten kannst.
WM_COMMAND gibt es ja im Standard auch schon. Du bist aber nicht auf diese Standard-Messages beschränkt.
Sebastian Jänicke
AppCentral
  Mit Zitat antworten Zitat
Antwort Antwort


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:48 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