Einzelnen Beitrag anzeigen

tommie-lie
(Gast)

n/a Beiträge
 
#5
  Alt 9. Jun 2003, 14:33
Dafür hatte ich dir doch die kleine Demo geschrieben!
Hat eigentlich alles richtig gemacht, außer das ich dort auch das stdcall vergessen habe, aber bei mir scheint sich das nicht negativ auf das Verhalten auszuwirken...

Also gut, zu 1:
Warum gibst du denn als Antwortprozedur auch die aufrufprozedur an? Das gibt eine Endlosschleife!
Das Prinzip von Callbacks ist folgendermaßen:
Du läufst durch die Gegend. Plötzlich siehst du ein Reh und schickst jemandem 'n Brief und läufst anschließend weiter. In dem Brief stand eine Adresse, an die auf jeden fall eine Antwort geschickt wird. Der andere kriegt jetzt den Brief und macht darauf hin was (holt sein Gewehr raus ) und du kriegst an diese Adresse wieder einen Brief.
Im Programmierleben sieht das dann so aus:
Message an hWnd, Programm läuft weiter. hWnd kriegt Message, schnappt sie sich und macht was. @SendAsyncProc wird aufgerufen, falls angegeben.
Und bei deinem speziellen Beispiel sieht das so aus:
Lese Record, sende Nachricht. Nachricht wird bearbeitet und EnumRecords wird erneut aufgerufen (während es noch läuft, ob Windows da automatisch 'nen Thread erzeugt, weiß ich nicht). Jeder Aufruf einer Schleife ruft die Schleife erneut auf, und dieser Aufruf erzeugt wieder so viele Schleifen wie es Durchläuft gibt usw. Und irgendwann ist dein Stack voll.
Im Prinzip ist es für dich doch uninteressant, ob der User etwas mit der TCM_ENUMRECORDS-Message gemacht hat, oder nicht, also musst du auch keine Prozedur angeben, mit der du die Antwort erhälst, einfach losschicken und weiter machen. Bearbeitet der User deiner Klasse dann deine Message nicht, stört dich das nicht, bearbeitet er sie (zeigt Dialog oder weiß der Geier was), ist auch nicht schlimm.
Korrekt also:
SendMessageCallback(hWnd, TCM_ENUMRECORDS, 0, 0, nil, 0); // oder 0, bin mir grad' nicht sicher Zu 2: Was aufrufen? Die Nachricht (TCM_ENUMRECORDS) wird wie jede andere Nachricht an das Fenster geschickt und kann bearbeitet werden, entweder in der WndProc, oder bei VCL über eine message-procedure ("message TCM_ENUMPROCS;" hinter Deklaration schreiben).
Und wie du EnumRecords aufrufst, sollte wohl klar sein:
Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
begin
  MyTypedFile.EnumRecords;
end;


3: SDK unter SendCallbackMessage, die Demo von mir für dir oder Christians Antwort

4: Pointer im dwData. Guckst du PSDK:
Zitat von PSDK:
BOOL SendMessageCallback(
HWND hWnd
UINT Msg,
WPARAM wParam,
LPARAM lParam,

SENDASYNCPROC lpCallBack,
ULONG_PTR dwData
);
Daraus folgt:
Delphi-Quellcode:
function TTypedFile.EnumRecords(hWnd: Cardinal; var Data: TRecord): Boolean;
var
  i : Integer;
begin
  result := TRUE;
  SendMessage(hWnd, TCM_MAXRECORDS, 0, FRecordsCount);
  for i := 1 to FRecordsCount-1 do
  begin
    seek(f, i);
    read(f, Data);
    SendMessageCallback(hWnd, TCM_ENUMRECORDS, 0, Integer(@data), 0, 0);
  end;
end;
Dann steht im wParam der Pointer auf das Record, und du kannst das lesen. Allerdings weiß ich nicht, ob der Speicherinhalt gelöscht wird, wenn die Schleife weiterläuft (d.h. mit Sicherheit wird er das...), daher würde ich ein Array of Record nehmen und dieses übergeben. Dann macht auch die Callbackprozedur wieder sinn, denn wenn der Record dann vom Programm bearbeitet wurde, wird die aufgerufen und kann den Record wieder entfernen und somit für den nächsten freimachen.
Wenn der Record allerdings 4 Byte groß ist und in den wParam passt, ist's kein Problem *g*


Alle Klarheiten beseitigt? *g*


Edit: Oh, hab' 3 falsch interpretiert, im Programm sieht die Prozedur, die die Nachricht von deiner Callback gar nicht aus, denn das Callback ist der 5. Parameter. Wie die Prozedur aussieht, die deine Message abfängt, müsstest du am besten wissen: wie jede andere Prozedur, die eine Nachricht abfängt, auch -> WndProc bei nonVCL

Edit2: Copy&Paste-Fehler bereinigt.

Edit3: (hopefully) completed neverending quest for error-free posts
  Mit Zitat antworten Zitat