Der Source der Fensterfunktion wäre hier wichtig.
Ansonsten geht es etwa so:
SetWindowLong(hwnd, GWL_USERDATA, SetWindowLong(hwnd, GWL_WNDPROC, @WndProc));
Wir bekommen damit in user data die Adresse der ursprünglichen Fensterfunktion, wobei die neue direkt damit gesetzt wird.
Das Defaulthandling übernimmt dann in deiner WndProc die alte Fensterfunktion dank:
result := CallWindowProc({hier muß ein Cast hin ->}GetWindowLong(hwnd, GWL_USERDATA), ...);
Habe den o.g. Cast nicht im Kopf, sorry. Wahrscheinlich "Pointer()" ...?!
Nachtrag:
Du kannst die beiden obigen Aufrufe von SetWindowLong() auch aufdröseln, damit es threadsafe wird. Dazu müßtest du dann wohl sowas hier machen:
Delphi-Quellcode:
SetWindowLong(hwnd, GWL_USERDATA, GetWindowLong(hwnd, GWL_WNDPROC));
SetWindowLong(hwnd, GWL_WNDPROC, @WndProc);
Statt GWL_USERDATA kannste auch was anderes sinnvolles oder z.B. SetProp/GetProp benutzen.
Noch'n Nachtrag:
Wahrscheinlich
MUSST du sogar die letzte Variante nehmen, weil beim geschachtelten SetWindowLong() der Fall eintreten könnte, daß deine eigene Funktion gesetzt ist und durch eine externe Message aufgerufen wird, während der Wert in GWL_USERDATA (oder wo auch immer) noch nicht gesetzt ist. Dieser wird aber benötigt, damit die
alte Fensterfunktion aufgerufen werden kann.